diff --git a/Libraries/LibWeb/Layout/Node.cpp b/Libraries/LibWeb/Layout/Node.cpp index 4a3a99ade51..4680c495d89 100644 --- a/Libraries/LibWeb/Layout/Node.cpp +++ b/Libraries/LibWeb/Layout/Node.cpp @@ -174,7 +174,7 @@ bool Node::establishes_stacking_context() const if (!has_style()) return false; - if (is_svg_box() || is_svg_svg_box()) + if (is_svg_box()) return false; // We make a stacking context for the viewport. Painting and hit testing starts from here. diff --git a/Libraries/LibWeb/Painting/SVGPaintable.cpp b/Libraries/LibWeb/Painting/SVGPaintable.cpp index 30f53793186..95352a4dcee 100644 --- a/Libraries/LibWeb/Painting/SVGPaintable.cpp +++ b/Libraries/LibWeb/Painting/SVGPaintable.cpp @@ -17,26 +17,6 @@ SVGPaintable::SVGPaintable(Layout::SVGBox const& layout_box) { } -void SVGPaintable::before_paint(PaintContext& context, PaintPhase phase) const -{ - if (!is_visible()) - return; - if (!has_css_transform()) { - apply_clip_overflow_rect(context, phase); - } - apply_scroll_offset(context); -} - -void SVGPaintable::after_paint(PaintContext& context, PaintPhase phase) const -{ - if (!is_visible()) - return; - reset_scroll_offset(context); - if (!has_css_transform()) { - clear_clip_overflow_rect(context, phase); - } -} - Layout::SVGBox const& SVGPaintable::layout_box() const { return static_cast(layout_node()); diff --git a/Libraries/LibWeb/Painting/SVGPaintable.h b/Libraries/LibWeb/Painting/SVGPaintable.h index 203d426805e..2d592947755 100644 --- a/Libraries/LibWeb/Painting/SVGPaintable.h +++ b/Libraries/LibWeb/Painting/SVGPaintable.h @@ -22,9 +22,6 @@ protected: SVGPaintable(Layout::SVGBox const&); - virtual void before_paint(PaintContext&, PaintPhase) const override; - virtual void after_paint(PaintContext&, PaintPhase) const override; - virtual CSSPixelRect compute_absolute_rect() const override; }; diff --git a/Libraries/LibWeb/Painting/SVGSVGPaintable.cpp b/Libraries/LibWeb/Painting/SVGSVGPaintable.cpp index b5058c0d3de..cb9cb1e8b91 100644 --- a/Libraries/LibWeb/Painting/SVGSVGPaintable.cpp +++ b/Libraries/LibWeb/Painting/SVGSVGPaintable.cpp @@ -24,26 +24,6 @@ SVGSVGPaintable::SVGSVGPaintable(Layout::SVGSVGBox const& layout_box) { } -void SVGSVGPaintable::before_paint(PaintContext& context, PaintPhase phase) const -{ - if (!is_visible()) - return; - if (!has_css_transform()) { - apply_clip_overflow_rect(context, phase); - } - apply_scroll_offset(context); -} - -void SVGSVGPaintable::after_paint(PaintContext& context, PaintPhase phase) const -{ - if (!is_visible()) - return; - reset_scroll_offset(context); - if (!has_css_transform()) { - clear_clip_overflow_rect(context, phase); - } -} - Layout::SVGSVGBox const& SVGSVGPaintable::layout_box() const { return static_cast(layout_node()); @@ -107,10 +87,7 @@ void SVGSVGPaintable::paint_svg_box(PaintContext& context, PaintableBox const& s } if (!skip_painting) { - svg_box.before_paint(context, PaintPhase::Foreground); svg_box.paint(context, PaintPhase::Foreground); - svg_box.after_paint(context, PaintPhase::Foreground); - paint_descendants(context, svg_box, phase); } diff --git a/Libraries/LibWeb/Painting/SVGSVGPaintable.h b/Libraries/LibWeb/Painting/SVGSVGPaintable.h index 0fe68f64433..7a37c971d86 100644 --- a/Libraries/LibWeb/Painting/SVGSVGPaintable.h +++ b/Libraries/LibWeb/Painting/SVGSVGPaintable.h @@ -23,9 +23,6 @@ public: static void paint_svg_box(PaintContext& context, PaintableBox const& svg_box, PaintPhase phase); static void paint_descendants(PaintContext& context, PaintableBox const& paintable, PaintPhase phase); - virtual void before_paint(PaintContext&, PaintPhase) const override; - virtual void after_paint(PaintContext&, PaintPhase) const override; - protected: SVGSVGPaintable(Layout::SVGSVGBox const&); diff --git a/Libraries/LibWeb/Painting/StackingContext.cpp b/Libraries/LibWeb/Painting/StackingContext.cpp index a387099a5ce..acb0f1569f7 100644 --- a/Libraries/LibWeb/Painting/StackingContext.cpp +++ b/Libraries/LibWeb/Painting/StackingContext.cpp @@ -108,9 +108,9 @@ void StackingContext::paint_svg(PaintContext& context, PaintableBox const& paint if (phase != PaintPhase::Foreground) return; - paintable.before_paint(context, PaintPhase::Foreground); paint_node(paintable, context, PaintPhase::Background); paint_node(paintable, context, PaintPhase::Border); + paintable.before_paint(context, PaintPhase::Foreground); SVGSVGPaintable::paint_svg_box(context, paintable, phase); paintable.after_paint(context, PaintPhase::Foreground); } @@ -118,14 +118,14 @@ void StackingContext::paint_svg(PaintContext& context, PaintableBox const& paint void StackingContext::paint_descendants(PaintContext& context, Paintable const& paintable, StackingContextPaintPhase phase) { paintable.for_each_child([&context, phase](auto& child) { + if (child.has_stacking_context()) + return IterationDecision::Continue; + if (child.layout_node().is_svg_svg_box()) { paint_svg(context, static_cast(child), to_paint_phase(phase)); return IterationDecision::Continue; } - if (child.has_stacking_context()) - return IterationDecision::Continue; - // 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 @@ -199,10 +199,7 @@ void StackingContext::paint_descendants(PaintContext& context, Paintable const& void StackingContext::paint_child(PaintContext& context, StackingContext const& child) { VERIFY(!child.paintable_box().layout_node().is_svg_box()); - VERIFY(!child.paintable_box().layout_node().is_svg_svg_box()); - const_cast(child).set_last_paint_generation_id(context.paint_generation_id()); - child.paint(context); } @@ -210,10 +207,27 @@ void StackingContext::paint_internal(PaintContext& context) const { VERIFY(!paintable_box().layout_node().is_svg_box()); if (paintable_box().layout_node().is_svg_svg_box()) { - paint_svg(context, paintable_box(), PaintPhase::Foreground); + auto const& svg_svg_paintable = static_cast(paintable_box()); + paint_node(svg_svg_paintable, context, PaintPhase::Background); + paint_node(svg_svg_paintable, context, PaintPhase::Border); + + svg_svg_paintable.before_paint(context, PaintPhase::Foreground); + SVGSVGPaintable::paint_descendants(context, svg_svg_paintable, PaintPhase::Foreground); + svg_svg_paintable.after_paint(context, PaintPhase::Foreground); + + paint_node(svg_svg_paintable, context, PaintPhase::Outline); + if (context.should_paint_overlay()) { + paint_node(svg_svg_paintable, context, PaintPhase::Overlay); + paint_descendants(context, svg_svg_paintable, StackingContextPaintPhase::FocusAndOverlay); + } return; } + context.display_list_recorder().push_scroll_frame_id({}); + ScopeGuard restore_scroll_frame_id([&] { + context.display_list_recorder().pop_scroll_frame_id(); + }); + // For a more elaborate description of the algorithm, see CSS 2.1 Appendix E // Draw the background and borders for the context root (steps 1, 2) paint_node(paintable_box(), context, PaintPhase::Background); @@ -357,9 +371,7 @@ void StackingContext::paint(PaintContext& context) const } } - context.display_list_recorder().push_scroll_frame_id({}); paint_internal(context); - context.display_list_recorder().pop_scroll_frame_id(); if (filter.has_value()) { context.display_list_recorder().restore(); diff --git a/Tests/LibWeb/Ref/expected/css/svg-element-should-be-allowed-to-establish-stacking-context.html b/Tests/LibWeb/Ref/expected/css/svg-element-should-be-allowed-to-establish-stacking-context.html new file mode 100644 index 00000000000..f932fbae961 --- /dev/null +++ b/Tests/LibWeb/Ref/expected/css/svg-element-should-be-allowed-to-establish-stacking-context.html @@ -0,0 +1,32 @@ + + +
+
+
+
diff --git a/Tests/LibWeb/Ref/input/css/svg-element-should-be-allowed-to-establish-stacking-context.html b/Tests/LibWeb/Ref/input/css/svg-element-should-be-allowed-to-establish-stacking-context.html new file mode 100644 index 00000000000..2ea92e695b2 --- /dev/null +++ b/Tests/LibWeb/Ref/input/css/svg-element-should-be-allowed-to-establish-stacking-context.html @@ -0,0 +1,32 @@ + + + +
+
+ +
diff --git a/Tests/LibWeb/Screenshot/images/css-transform-box-ref.png b/Tests/LibWeb/Screenshot/images/css-transform-box-ref.png index 019e81f776d..43ddc0bba62 100644 Binary files a/Tests/LibWeb/Screenshot/images/css-transform-box-ref.png and b/Tests/LibWeb/Screenshot/images/css-transform-box-ref.png differ diff --git a/Tests/LibWeb/Screenshot/images/svg-filters-lb-website-ref.png b/Tests/LibWeb/Screenshot/images/svg-filters-lb-website-ref.png index 7356f597cec..684e485b989 100644 Binary files a/Tests/LibWeb/Screenshot/images/svg-filters-lb-website-ref.png and b/Tests/LibWeb/Screenshot/images/svg-filters-lb-website-ref.png differ