mirror of
https://github.com/RGBCube/serenity
synced 2025-07-19 06:57:34 +00:00
LibWeb: Make document-level style invalidation fast
Add a flag to DOM::Document that means the whole document needs a style update. This saves us the trouble of traversing the entire DOM to mark all nodes as needing a style update.
This commit is contained in:
parent
f87edd4c14
commit
0b861e0c9d
3 changed files with 18 additions and 4 deletions
|
@ -595,6 +595,7 @@ void Document::update_layout()
|
||||||
|
|
||||||
[[nodiscard]] static bool update_style_recursively(DOM::Node& node)
|
[[nodiscard]] static bool update_style_recursively(DOM::Node& node)
|
||||||
{
|
{
|
||||||
|
bool const needs_full_style_update = node.document().needs_full_style_update();
|
||||||
bool needs_relayout = false;
|
bool needs_relayout = false;
|
||||||
|
|
||||||
if (is<Element>(node)) {
|
if (is<Element>(node)) {
|
||||||
|
@ -602,15 +603,15 @@ void Document::update_layout()
|
||||||
}
|
}
|
||||||
node.set_needs_style_update(false);
|
node.set_needs_style_update(false);
|
||||||
|
|
||||||
if (node.child_needs_style_update()) {
|
if (needs_full_style_update || node.child_needs_style_update()) {
|
||||||
if (node.is_element()) {
|
if (node.is_element()) {
|
||||||
if (auto* shadow_root = static_cast<DOM::Element&>(node).shadow_root()) {
|
if (auto* shadow_root = static_cast<DOM::Element&>(node).shadow_root()) {
|
||||||
if (shadow_root->needs_style_update() || shadow_root->child_needs_style_update())
|
if (needs_full_style_update || shadow_root->needs_style_update() || shadow_root->child_needs_style_update())
|
||||||
needs_relayout |= update_style_recursively(*shadow_root);
|
needs_relayout |= update_style_recursively(*shadow_root);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.for_each_child([&](auto& child) {
|
node.for_each_child([&](auto& child) {
|
||||||
if (child.needs_style_update() || child.child_needs_style_update())
|
if (needs_full_style_update || child.needs_style_update() || child.child_needs_style_update())
|
||||||
needs_relayout |= update_style_recursively(child);
|
needs_relayout |= update_style_recursively(child);
|
||||||
return IterationDecision::Continue;
|
return IterationDecision::Continue;
|
||||||
});
|
});
|
||||||
|
@ -624,10 +625,11 @@ void Document::update_style()
|
||||||
{
|
{
|
||||||
if (!browsing_context())
|
if (!browsing_context())
|
||||||
return;
|
return;
|
||||||
if (!needs_style_update() && !child_needs_style_update())
|
if (!needs_full_style_update() && !needs_style_update() && !child_needs_style_update())
|
||||||
return;
|
return;
|
||||||
if (update_style_recursively(*this))
|
if (update_style_recursively(*this))
|
||||||
invalidate_layout();
|
invalidate_layout();
|
||||||
|
m_needs_full_style_update = false;
|
||||||
m_style_update_timer->stop();
|
m_style_update_timer->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -334,6 +334,9 @@ public:
|
||||||
callback(*node_iterator);
|
callback(*node_iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool needs_full_style_update() const { return m_needs_full_style_update; }
|
||||||
|
void set_needs_full_style_update(bool b) { m_needs_full_style_update = b; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit Document(const AK::URL&);
|
explicit Document(const AK::URL&);
|
||||||
|
|
||||||
|
@ -438,6 +441,8 @@ private:
|
||||||
|
|
||||||
bool m_needs_layout { false };
|
bool m_needs_layout { false };
|
||||||
|
|
||||||
|
bool m_needs_full_style_update { false };
|
||||||
|
|
||||||
HashTable<NodeIterator*> m_node_iterators;
|
HashTable<NodeIterator*> m_node_iterators;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -176,6 +176,13 @@ void Node::set_node_value(const String& value)
|
||||||
|
|
||||||
void Node::invalidate_style()
|
void Node::invalidate_style()
|
||||||
{
|
{
|
||||||
|
if (is_document()) {
|
||||||
|
auto& document = static_cast<DOM::Document&>(*this);
|
||||||
|
document.set_needs_full_style_update(true);
|
||||||
|
document.schedule_style_update();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for_each_in_inclusive_subtree([&](Node& node) {
|
for_each_in_inclusive_subtree([&](Node& node) {
|
||||||
node.m_needs_style_update = true;
|
node.m_needs_style_update = true;
|
||||||
if (node.has_children())
|
if (node.has_children())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue