diff --git a/Libraries/LibWeb/DOM/Document.cpp b/Libraries/LibWeb/DOM/Document.cpp index c3a005d85c6..4e8c8e4e738 100644 --- a/Libraries/LibWeb/DOM/Document.cpp +++ b/Libraries/LibWeb/DOM/Document.cpp @@ -1382,6 +1382,34 @@ void Document::update_layout() return invalidation; } +// This function makes a full pass over the entire DOM and converts "entire subtree needs style update" +// into "needs style update" for each inclusive descendant where it's found. +static void perform_pending_style_invalidations(Node& node, bool invalidate_entire_subtree) +{ + invalidate_entire_subtree |= node.entire_subtree_needs_style_update(); + + if (invalidate_entire_subtree) { + node.set_needs_style_update_internal(true); + if (node.has_child_nodes()) + node.set_child_needs_style_update(true); + } + + for (auto* child = node.first_child(); child; child = child->next_sibling()) { + perform_pending_style_invalidations(*child, invalidate_entire_subtree); + } + + if (node.is_element()) { + auto& element = static_cast(node); + if (auto shadow_root = element.shadow_root()) { + perform_pending_style_invalidations(*shadow_root, invalidate_entire_subtree); + if (invalidate_entire_subtree) + node.set_child_needs_style_update(true); + } + } + + node.set_entire_subtree_needs_style_update(false); +} + void Document::update_style() { if (!browsing_context()) @@ -1396,6 +1424,8 @@ void Document::update_style() if (!needs_full_style_update() && !needs_style_update() && !child_needs_style_update()) return; + perform_pending_style_invalidations(*this, false); + // NOTE: If this is a document hosting