From 0af2795662f1640dbda80500a4c9f7200af01a15 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 20 Oct 2020 17:43:13 +0200 Subject: [PATCH] LibWeb: Tear down layout trees properly Instead of just ripping out the root of the layout tree from its RefPtr in Document, actually go through the DOM and gather up all the layout nodes. Then destroy them all in one swoop. Also, make sure to do this when detaching Document from Frame, to enforce the invariant that layout only occurs in framed documents. --- Libraries/LibWeb/DOM/Document.cpp | 29 +++++++++++++++++++++++++++-- Libraries/LibWeb/DOM/Document.h | 2 ++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/Libraries/LibWeb/DOM/Document.cpp b/Libraries/LibWeb/DOM/Document.cpp index 90526b6932d..edcde7700e5 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 0784e99ec5d..848989cd483 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;