diff --git a/Libraries/LibWeb/DOM/Document.cpp b/Libraries/LibWeb/DOM/Document.cpp index 90526b6932..edcde7700e 100644 --- a/Libraries/LibWeb/DOM/Document.cpp +++ b/Libraries/LibWeb/DOM/Document.cpp @@ -206,10 +206,35 @@ void Document::detach_from_frame(Badge, Frame& frame) node.document_will_detach_from_frame(frame); return IterationDecision::Continue; }); - m_layout_root = nullptr; + + tear_down_layout_tree(); m_frame = nullptr; } +void Document::tear_down_layout_tree() +{ + if (!m_layout_root) + return; + + // Gather up all the layout nodes in a vector and detach them from parents + // while the vector keeps them alive. + + NonnullRefPtrVector layout_nodes; + + for_each_in_subtree([&](auto& node) { + if (node.layout_node()) + layout_nodes.append(*node.layout_node()); + return IterationDecision::Continue; + }); + + for (auto& layout_node : layout_nodes) { + if (layout_node.parent()) + layout_node.parent()->remove_child(layout_node); + } + + m_layout_root = nullptr; +} + Color Document::background_color(const Palette& palette) const { auto default_color = palette.base(); @@ -256,7 +281,7 @@ URL Document::complete_url(const String& string) const void Document::invalidate_layout() { - m_layout_root = nullptr; + tear_down_layout_tree(); } void Document::force_layout() diff --git a/Libraries/LibWeb/DOM/Document.h b/Libraries/LibWeb/DOM/Document.h index 0784e99ec5..848989cd48 100644 --- a/Libraries/LibWeb/DOM/Document.h +++ b/Libraries/LibWeb/DOM/Document.h @@ -198,6 +198,8 @@ public: private: virtual RefPtr create_layout_node(const CSS::StyleProperties* parent_style) override; + void tear_down_layout_tree(); + unsigned m_referencing_node_count { 0 }; OwnPtr m_style_resolver;