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:
parent
633b6fbc48
commit
0af2795662
2 changed files with 29 additions and 2 deletions
|
@ -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()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue