diff --git a/Tests/LibWeb/Ref/grid-items-painting-order-ref.html b/Tests/LibWeb/Ref/grid-items-painting-order-ref.html new file mode 100644 index 0000000000..c80af531c3 --- /dev/null +++ b/Tests/LibWeb/Ref/grid-items-painting-order-ref.html @@ -0,0 +1,8 @@ +
bar
diff --git a/Tests/LibWeb/Ref/grid-items-painting-order.html b/Tests/LibWeb/Ref/grid-items-painting-order.html new file mode 100644 index 0000000000..a37803df2a --- /dev/null +++ b/Tests/LibWeb/Ref/grid-items-painting-order.html @@ -0,0 +1,12 @@ +
foo
bar
diff --git a/Tests/LibWeb/Ref/manifest.json b/Tests/LibWeb/Ref/manifest.json index aad9eb7542..e76350ab57 100644 --- a/Tests/LibWeb/Ref/manifest.json +++ b/Tests/LibWeb/Ref/manifest.json @@ -1,5 +1,6 @@ { "img-srcset-viewport-relative-sizes.html": "img-srcset-viewport-relative-sizes-ref.html", + "grid-items-painting-order.html": "grid-items-painting-order-ref.html", "square-flex.html": "square-ref.html", "separate-borders-inline-table.html": "separate-borders-ref.html", "opacity-stacking.html": "opacity-stacking-ref.html", diff --git a/Tests/LibWeb/Text/expected/hit_testing/grid.txt b/Tests/LibWeb/Text/expected/hit_testing/grid.txt new file mode 100644 index 0000000000..cbe03600fd --- /dev/null +++ b/Tests/LibWeb/Text/expected/hit_testing/grid.txt @@ -0,0 +1 @@ + true diff --git a/Tests/LibWeb/Text/input/hit_testing/grid.html b/Tests/LibWeb/Text/input/hit_testing/grid.html new file mode 100644 index 0000000000..9028cf3800 --- /dev/null +++ b/Tests/LibWeb/Text/input/hit_testing/grid.html @@ -0,0 +1,23 @@ + +
+ + diff --git a/Userland/Libraries/LibWeb/Painting/StackingContext.cpp b/Userland/Libraries/LibWeb/Painting/StackingContext.cpp index 24374add45..8035d8461d 100644 --- a/Userland/Libraries/LibWeb/Painting/StackingContext.cpp +++ b/Userland/Libraries/LibWeb/Painting/StackingContext.cpp @@ -72,6 +72,20 @@ static PaintPhase to_paint_phase(StackingContext::StackingContextPaintPhase phas } } +void StackingContext::paint_node_as_stacking_context(Paintable const& paintable, PaintContext& context) const +{ + paint_node(paintable, context, PaintPhase::Background); + paint_node(paintable, context, PaintPhase::Border); + paint_descendants(context, paintable, StackingContextPaintPhase::BackgroundAndBorders); + paint_descendants(context, paintable, StackingContextPaintPhase::Floats); + paint_descendants(context, paintable, StackingContextPaintPhase::BackgroundAndBordersForInlineLevelAndReplaced); + paint_node(paintable, context, PaintPhase::Foreground); + paint_descendants(context, paintable, StackingContextPaintPhase::Foreground); + paint_node(paintable, context, PaintPhase::Outline); + paint_node(paintable, context, PaintPhase::Overlay); + paint_descendants(context, paintable, StackingContextPaintPhase::FocusAndOverlay); +} + void StackingContext::paint_descendants(PaintContext& context, Paintable const& paintable, StackingContextPaintPhase phase) const { paintable.before_children_paint(context, to_paint_phase(phase)); @@ -99,6 +113,19 @@ void StackingContext::paint_descendants(PaintContext& context, Paintable const& return; } + // NOTE: Grid specification https://www.w3.org/TR/css-grid-2/#z-order says that grid items should be treated + // the same way as CSS2 defines for inline-blocks: + // "For each one of these, treat the element as if it created a new stacking context, but any positioned + // descendants and descendants which actually create a new stacking context should be considered part of + // the parent stacking context, not this new one." + auto should_be_treated_as_stacking_context = child.layout_node().is_grid_item(); + if (should_be_treated_as_stacking_context) { + // FIXME: This may not be fully correct with respect to the paint phases. + if (phase == StackingContextPaintPhase::Foreground) + paint_node_as_stacking_context(child, context); + return; + } + bool child_is_inline_or_replaced = child.is_inline() || is(child); switch (phase) { case StackingContextPaintPhase::BackgroundAndBorders: @@ -214,16 +241,7 @@ void StackingContext::paint_internal(PaintContext& context) const paint_child(context, *child); return TraversalDecision::SkipChildrenAndContinue; } else { - paint_node(paintable, context, PaintPhase::Background); - paint_node(paintable, context, PaintPhase::Border); - paint_descendants(context, paintable, StackingContextPaintPhase::BackgroundAndBorders); - paint_descendants(context, paintable, StackingContextPaintPhase::Floats); - paint_descendants(context, paintable, StackingContextPaintPhase::BackgroundAndBordersForInlineLevelAndReplaced); - paint_node(paintable, context, PaintPhase::Foreground); - paint_descendants(context, paintable, StackingContextPaintPhase::Foreground); - paint_node(paintable, context, PaintPhase::Outline); - paint_node(paintable, context, PaintPhase::Overlay); - paint_descendants(context, paintable, StackingContextPaintPhase::FocusAndOverlay); + paint_node_as_stacking_context(paintable, context); } if (parent_paintable) parent_paintable->after_children_paint(context, PaintPhase::Foreground); diff --git a/Userland/Libraries/LibWeb/Painting/StackingContext.h b/Userland/Libraries/LibWeb/Painting/StackingContext.h index a79a888415..62739124b2 100644 --- a/Userland/Libraries/LibWeb/Painting/StackingContext.h +++ b/Userland/Libraries/LibWeb/Painting/StackingContext.h @@ -29,6 +29,7 @@ public: FocusAndOverlay, }; + void paint_node_as_stacking_context(Paintable const&, PaintContext&) const; void paint_descendants(PaintContext&, Paintable const&, StackingContextPaintPhase) const; void paint(PaintContext&) const; Optional hit_test(CSSPixelPoint, HitTestType) const;