LibWeb: Allow partial update of SVG subtrees in layout tree

We were incorrectly always appending to the nearest ancestor in the
partial update case, even when the node was eligible for replacement.
This commit is contained in:
Andreas Kling 2025-01-20 21:45:46 +01:00 committed by Andreas Kling
parent 026fc6c1ca
commit 7ae46bf8b7
Notes: github-actions[bot] 2025-01-20 23:09:17 +00:00
3 changed files with 31 additions and 5 deletions

View file

@ -402,19 +402,22 @@ void TreeBuilder::update_layout_tree(DOM::Node& dom_node, TreeBuilder::Context&
if (dom_node.is_document()) {
m_layout_root = layout_node;
} else if (layout_node->is_svg_box()) {
m_ancestor_stack.last()->append_child(*layout_node);
} else if (should_create_layout_node) {
// Decide whether to replace an existing node (partial tree update) or insert a new one appropriately.
if (must_create_subtree == MustCreateSubtree::No
bool const may_replace_existing_layout_node = must_create_subtree == MustCreateSubtree::No
&& old_layout_node
&& old_layout_node->parent()
&& old_layout_node != layout_node) {
&& old_layout_node != layout_node;
if (may_replace_existing_layout_node) {
old_layout_node->parent()->replace_child(*layout_node, *old_layout_node);
} else {
if (layout_node->is_svg_box()) {
m_ancestor_stack.last()->append_child(*layout_node);
} else {
insert_node_into_inline_or_block_ancestor(*layout_node, display, AppendOrPrepend::Append);
}
}
}
auto shadow_root = is<DOM::Element>(dom_node) ? verify_cast<DOM::Element>(dom_node).shadow_root() : nullptr;

View file

@ -0,0 +1,17 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x150 children: inline
frag 0 from SVGSVGBox start: 0, length: 0, rect: [8,8 300x150] baseline: 150
SVGSVGBox <svg> at (8,8) content-size 300x150 [SVG] children: inline
SVGGraphicsBox <symbol> at (8,8) content-size 300x150 [BFC] children: inline
InlineNode <set#set>
TextNode <#text>
TextNode <#text>
TextNode <#text>
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x600]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x150]
SVGSVGPaintable (SVGSVGBox<svg>) [8,8 300x150]
SVGGraphicsPaintable (SVGGraphicsBox<symbol>) [8,8 300x150]
PaintableWithLines (InlineNode<set>#set)

View file

@ -0,0 +1,6 @@
<body><svg><symbol><set id="set"></set></symbol></body>
<script>
document.body.offsetWidth;
set.prepend("x");
document.body.offsetWidth;
</script>