LibWeb: Postpone :has() style invalidation until update_style()

This allows to do ancestors traversal only once even if
`invalidate_style()` was called multiple times for the same node.
This commit is contained in:
Aliaksandr Kalenik 2025-02-10 18:57:05 +01:00 committed by Andreas Kling
commit 90ba4b16c2
Notes: github-actions[bot] 2025-02-11 09:23:25 +00:00
3 changed files with 36 additions and 13 deletions

View file

@ -1438,7 +1438,7 @@ void Document::update_style()
// style change event. [CSS-Transitions-2]
m_transition_generation++;
invalidate_elements_affected_by_has_in_non_subject_position();
invalidate_style_of_elements_affected_by_has();
if (!needs_full_style_update() && !needs_style_update() && !child_needs_style_update())
return;
@ -1659,11 +1659,18 @@ static Node* find_common_ancestor(Node* a, Node* b)
return nullptr;
}
void Document::invalidate_elements_affected_by_has_in_non_subject_position()
void Document::invalidate_style_of_elements_affected_by_has()
{
if (!m_needs_invalidate_elements_affected_by_has_in_non_subject_position)
if (m_pending_nodes_for_style_invalidation_due_to_presence_of_has.is_empty()) {
return;
m_needs_invalidate_elements_affected_by_has_in_non_subject_position = false;
}
for (auto const& node : m_pending_nodes_for_style_invalidation_due_to_presence_of_has) {
if (node.is_null())
continue;
node->invalidate_ancestors_affected_by_has_in_subject_position();
}
m_pending_nodes_for_style_invalidation_due_to_presence_of_has.clear();
// Take care of elements that affected by :has() in non-subject position, i.e., ".a:has(.b) > .c".
// Elements affected by :has() in subject position, i.e., ".a:has(.b)", are handled by