diff --git a/Tests/LibWeb/Text/expected/setting-display-none-should-nuke-subtree.txt b/Tests/LibWeb/Text/expected/setting-display-none-should-nuke-subtree.txt new file mode 100644 index 0000000000..da1feed8cf --- /dev/null +++ b/Tests/LibWeb/Text/expected/setting-display-none-should-nuke-subtree.txt @@ -0,0 +1,2 @@ +100 +0 diff --git a/Tests/LibWeb/Text/input/setting-display-none-should-nuke-subtree.html b/Tests/LibWeb/Text/input/setting-display-none-should-nuke-subtree.html new file mode 100644 index 0000000000..9e9f093397 --- /dev/null +++ b/Tests/LibWeb/Text/input/setting-display-none-should-nuke-subtree.html @@ -0,0 +1,15 @@ + + diff --git a/Userland/Libraries/LibWeb/DOM/Node.cpp b/Userland/Libraries/LibWeb/DOM/Node.cpp index c67b5051a8..7406f10e1d 100644 --- a/Userland/Libraries/LibWeb/DOM/Node.cpp +++ b/Userland/Libraries/LibWeb/DOM/Node.cpp @@ -882,7 +882,7 @@ void Node::set_layout_node(Badge, JS::NonnullGCPtr l m_layout_node = layout_node; } -void Node::detach_layout_node(Badge) +void Node::detach_layout_node(Badge) { m_layout_node = nullptr; } diff --git a/Userland/Libraries/LibWeb/DOM/Node.h b/Userland/Libraries/LibWeb/DOM/Node.h index b3e319ce04..ca817cb9d0 100644 --- a/Userland/Libraries/LibWeb/DOM/Node.h +++ b/Userland/Libraries/LibWeb/DOM/Node.h @@ -185,7 +185,7 @@ public: Painting::Paintable const* paintable() const; void set_layout_node(Badge, JS::NonnullGCPtr); - void detach_layout_node(Badge); + void detach_layout_node(Badge); virtual bool is_child_allowed(Node const&) const { return true; } diff --git a/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp b/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp index aacef3e999..765733f786 100644 --- a/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp +++ b/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp @@ -210,8 +210,22 @@ ErrorOr TreeBuilder::create_pseudo_element_if_needed(DOM::Element& element ErrorOr TreeBuilder::create_layout_tree(DOM::Node& dom_node, TreeBuilder::Context& context) { + JS::GCPtr layout_node; Optional> has_svg_root_change; + ScopeGuard remove_stale_layout_node_guard = [&] { + // If we didn't create a layout node for this DOM node, + // go through the DOM tree and remove any old layout nodes since they are now all stale. + if (!layout_node) { + dom_node.for_each_in_inclusive_subtree([&](auto& node) { + node.detach_layout_node({}); + if (is(node)) + static_cast(node).clear_pseudo_element_nodes({}); + return IterationDecision::Continue; + }); + } + }; + if (dom_node.is_svg_container()) { has_svg_root_change.emplace(context.has_svg_root, true); } else if (dom_node.requires_svg_container() && !context.has_svg_root) { @@ -220,7 +234,6 @@ ErrorOr TreeBuilder::create_layout_tree(DOM::Node& dom_node, TreeBuilder:: auto& document = dom_node.document(); auto& style_computer = document.style_computer(); - JS::GCPtr layout_node; RefPtr style; CSS::Display display;