LibWeb: Do not render SVG <symbol> elements unless part of <use>

We were always rendering <symbol> SVG elements, but we should only
render them if they are a child of a <use>'s shadow root. This caused
practically all instances of <symbol> to be drawn at least one time too
many.
This commit is contained in:
Jelle Raaijmakers 2025-11-26 13:04:20 +01:00 committed by Jelle Raaijmakers
parent 632854d870
commit 39ad7833f0
Notes: github-actions[bot] 2025-11-27 06:56:50 +00:00
5 changed files with 36 additions and 7 deletions

View file

@ -62,7 +62,12 @@ bool SVGSymbolElement::is_direct_child_of_use_shadow_tree() const
GC::Ptr<Layout::Node> SVGSymbolElement::create_layout_node(GC::Ref<CSS::ComputedProperties> style)
{
return heap().allocate<Layout::SVGGraphicsBox>(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<Layout::SVGGraphicsBox>(document(), *this, style);
}
}

View file

@ -3,7 +3,8 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not-
BlockContainer <body> 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 <svg> at [8,8] [0+0+0 300 0+0+0] [0+0+0 150 0+0+0] [SVG] children: inline
SVGGraphicsBox <symbol> at [8,8] [0+0+0 300 0+0+0] [0+0+0 150 0+0+0] [BFC] children: inline
SVGGraphicsBox <use> at [8,8] [0+0+0 300 0+0+0] [0+0+0 150 0+0+0] children: not-inline
SVGGraphicsBox <symbol#a> at [8,8] [0+0+0 300 0+0+0] [0+0+0 150 0+0+0] [BFC] children: inline
InlineNode <set#set> 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)
@ -13,7 +14,8 @@ ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x166]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x150]
SVGSVGPaintable (SVGSVGBox<svg>) [8,8 300x150]
SVGGraphicsPaintable (SVGGraphicsBox<symbol>) [8,8 300x150]
SVGGraphicsPaintable (SVGGraphicsBox<use>) [8,8 300x150]
SVGGraphicsPaintable (SVGGraphicsBox<symbol>#a) [8,8 300x150]
PaintableWithLines (InlineNode<set>#set) [8,8 0x18]
SC for Viewport<#document> [0,0 800x600] [children: 1] (z-index: auto)

View file

@ -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 <html> at [0,0] [0+0+0 800 0+0+0] [0+0+0 166 0+0+0] [BFC] children: not-inline
BlockContainer <body> 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 <svg> 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<HTML>) [0,0 800x166]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x150]
SVGSVGPaintable (SVGSVGBox<svg>) [8,8 300x150]
SC for Viewport<#document> [0,0 800x600] [children: 1] (z-index: auto)
SC for BlockContainer<HTML> [0,0 800x166] [children: 0] (z-index: auto)

View file

@ -1,5 +1,5 @@
<!DOCTYPE html>
<body><svg><symbol><set id="set"></set></symbol></body>
<body><svg><symbol id="a"><set id="set"></set></symbol><use href="#a"></use></body>
<script>
document.body.offsetWidth;
set.prepend("x");

View file

@ -0,0 +1,6 @@
<!DOCTYPE html>
<svg xmlns="http://www.w3.org/2000/svg">
<symbol viewBox="0 0 16 16">
<rect x="1" y="1" width="14" height="14" fill="red" />
</symbol>
</svg>