LibWeb: Update HTMLSlotElement subtree during partial layout tree build

Before this change, the layout tree for slots was only updated after
creating a layout node for the slot itself. This was not enough to
account for partial layout tree rebuilds when the slot content changed.
With this change, we always recurse into the slot content.

Fixes expanding and collapsing of nodes in DOM tree inspector broken in
9b26f7eb0f
This commit is contained in:
Aliaksandr Kalenik 2025-03-12 22:57:26 +01:00 committed by Jelle Raaijmakers
commit 76aa99a626
Notes: github-actions[bot] 2025-03-13 03:30:24 +00:00
3 changed files with 60 additions and 15 deletions

View file

@ -579,6 +579,25 @@ void TreeBuilder::update_layout_tree(DOM::Node& dom_node, TreeBuilder::Context&
}
}
if (is<HTML::HTMLSlotElement>(dom_node)) {
auto& slot_element = static_cast<HTML::HTMLSlotElement&>(dom_node);
if (slot_element.computed_properties()->content_visibility() != CSS::ContentVisibility::Hidden) {
auto slottables = slot_element.assigned_nodes_internal();
push_parent(as<NodeWithStyle>(*layout_node));
MustCreateSubtree must_create_subtree_for_slottable = must_create_subtree;
if (slot_element.needs_layout_tree_update())
must_create_subtree_for_slottable = MustCreateSubtree::Yes;
for (auto const& slottable : slottables) {
slottable.visit([&](auto& node) { update_layout_tree(node, context, must_create_subtree_for_slottable); });
}
pop_parent();
}
}
if (should_create_layout_node) {
update_layout_tree_after_children(dom_node, *layout_node, context, element_has_content_visibility_hidden);
wrap_in_button_layout_tree_if_needed(dom_node, *layout_node);
@ -694,21 +713,6 @@ void TreeBuilder::update_layout_tree_after_children(DOM::Node& dom_node, GC::Ref
layout_node->append_child(*list_item_marker);
}
if (is<HTML::HTMLSlotElement>(dom_node)) {
auto& slot_element = static_cast<HTML::HTMLSlotElement&>(dom_node);
if (slot_element.computed_properties()->content_visibility() == CSS::ContentVisibility::Hidden)
return;
auto slottables = slot_element.assigned_nodes_internal();
push_parent(as<NodeWithStyle>(*layout_node));
for (auto const& slottable : slottables)
slottable.visit([&](auto& node) { update_layout_tree(node, context, MustCreateSubtree::Yes); });
pop_parent();
}
if (is<SVG::SVGGraphicsElement>(dom_node)) {
auto& graphics_element = static_cast<SVG::SVGGraphicsElement&>(dom_node);
// Create the layout tree for the SVG mask/clip paths as a child of the masked element.