From 39ad7833f09ae64dfe8215749d3a4e5f1bc2793f Mon Sep 17 00:00:00 2001 From: Jelle Raaijmakers Date: Wed, 26 Nov 2025 13:04:20 +0100 Subject: [PATCH] LibWeb: Do not render SVG elements unless part of We were always rendering SVG elements, but we should only render them if they are a child of a 's shadow root. This caused practically all instances of to be drawn at least one time too many. --- Libraries/LibWeb/SVG/SVGSymbolElement.cpp | 7 ++++++- .../simple-update-inside-svg-subtree.txt | 12 +++++++----- .../expected/svg/svg-symbol-without-use.txt | 16 ++++++++++++++++ .../simple-update-inside-svg-subtree.html | 2 +- .../Layout/input/svg/svg-symbol-without-use.html | 6 ++++++ 5 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 Tests/LibWeb/Layout/expected/svg/svg-symbol-without-use.txt create mode 100644 Tests/LibWeb/Layout/input/svg/svg-symbol-without-use.html diff --git a/Libraries/LibWeb/SVG/SVGSymbolElement.cpp b/Libraries/LibWeb/SVG/SVGSymbolElement.cpp index 879f02cc058..3b10f0f8e6b 100644 --- a/Libraries/LibWeb/SVG/SVGSymbolElement.cpp +++ b/Libraries/LibWeb/SVG/SVGSymbolElement.cpp @@ -62,7 +62,12 @@ bool SVGSymbolElement::is_direct_child_of_use_shadow_tree() const GC::Ptr SVGSymbolElement::create_layout_node(GC::Ref style) { - return heap().allocate(document(), *this, move(style)); + // https://svgwg.org/svg2-draft/render.html#TermNeverRenderedElement + // [..] it also includes a ‘symbol’ element that is not the instance root of a use-element shadow tree. + if (!is_direct_child_of_use_shadow_tree()) + return {}; + + return heap().allocate(document(), *this, style); } } diff --git a/Tests/LibWeb/Layout/expected/layout-tree-update/simple-update-inside-svg-subtree.txt b/Tests/LibWeb/Layout/expected/layout-tree-update/simple-update-inside-svg-subtree.txt index 7650acd04a0..b6afe14f132 100644 --- a/Tests/LibWeb/Layout/expected/layout-tree-update/simple-update-inside-svg-subtree.txt +++ b/Tests/LibWeb/Layout/expected/layout-tree-update/simple-update-inside-svg-subtree.txt @@ -3,9 +3,10 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not- BlockContainer at [8,8] [8+0+0 784 0+0+8] [8+0+0 150 0+0+8] children: inline frag 0 from SVGSVGBox start: 0, length: 0, rect: [8,8 300x150] baseline: 150 SVGSVGBox at [8,8] [0+0+0 300 0+0+0] [0+0+0 150 0+0+0] [SVG] children: inline - SVGGraphicsBox at [8,8] [0+0+0 300 0+0+0] [0+0+0 150 0+0+0] [BFC] children: inline - InlineNode at [8,8] [0+0+0 0 0+0+0] [0+0+0 18 0+0+0] - TextNode <#text> (not painted) + SVGGraphicsBox at [8,8] [0+0+0 300 0+0+0] [0+0+0 150 0+0+0] children: not-inline + SVGGraphicsBox at [8,8] [0+0+0 300 0+0+0] [0+0+0 150 0+0+0] [BFC] children: inline + InlineNode at [8,8] [0+0+0 0 0+0+0] [0+0+0 18 0+0+0] + TextNode <#text> (not painted) TextNode <#text> (not painted) TextNode <#text> (not painted) @@ -13,8 +14,9 @@ ViewportPaintable (Viewport<#document>) [0,0 800x600] PaintableWithLines (BlockContainer) [0,0 800x166] PaintableWithLines (BlockContainer) [8,8 784x150] SVGSVGPaintable (SVGSVGBox) [8,8 300x150] - SVGGraphicsPaintable (SVGGraphicsBox) [8,8 300x150] - PaintableWithLines (InlineNode#set) [8,8 0x18] + SVGGraphicsPaintable (SVGGraphicsBox) [8,8 300x150] + SVGGraphicsPaintable (SVGGraphicsBox#a) [8,8 300x150] + PaintableWithLines (InlineNode#set) [8,8 0x18] SC for Viewport<#document> [0,0 800x600] [children: 1] (z-index: auto) SC for BlockContainer [0,0 800x166] [children: 0] (z-index: auto) diff --git a/Tests/LibWeb/Layout/expected/svg/svg-symbol-without-use.txt b/Tests/LibWeb/Layout/expected/svg/svg-symbol-without-use.txt new file mode 100644 index 00000000000..de4f3d275f4 --- /dev/null +++ b/Tests/LibWeb/Layout/expected/svg/svg-symbol-without-use.txt @@ -0,0 +1,16 @@ +Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not-inline + BlockContainer at [0,0] [0+0+0 800 0+0+0] [0+0+0 166 0+0+0] [BFC] children: not-inline + BlockContainer at [8,8] [8+0+0 784 0+0+8] [8+0+0 150 0+0+8] children: inline + frag 0 from SVGSVGBox start: 0, length: 0, rect: [8,8 300x150] baseline: 150 + SVGSVGBox at [8,8] [0+0+0 300 0+0+0] [0+0+0 150 0+0+0] [SVG] children: inline + TextNode <#text> (not painted) + TextNode <#text> (not painted) + TextNode <#text> (not painted) + +ViewportPaintable (Viewport<#document>) [0,0 800x600] + PaintableWithLines (BlockContainer) [0,0 800x166] + PaintableWithLines (BlockContainer) [8,8 784x150] + SVGSVGPaintable (SVGSVGBox) [8,8 300x150] + +SC for Viewport<#document> [0,0 800x600] [children: 1] (z-index: auto) + SC for BlockContainer [0,0 800x166] [children: 0] (z-index: auto) diff --git a/Tests/LibWeb/Layout/input/layout-tree-update/simple-update-inside-svg-subtree.html b/Tests/LibWeb/Layout/input/layout-tree-update/simple-update-inside-svg-subtree.html index 3d3c6765807..ec7f1f59c46 100644 --- a/Tests/LibWeb/Layout/input/layout-tree-update/simple-update-inside-svg-subtree.html +++ b/Tests/LibWeb/Layout/input/layout-tree-update/simple-update-inside-svg-subtree.html @@ -1,5 +1,5 @@ - +