1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 10:28:10 +00:00

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.
This commit is contained in:
Andreas Kling 2020-10-20 17:43:13 +02:00
parent 633b6fbc48
commit 0af2795662
2 changed files with 29 additions and 2 deletions

View file

@ -206,10 +206,35 @@ void Document::detach_from_frame(Badge<Frame>, 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<LayoutNode> 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()