diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/selectors/invalidation/has-with-pseudo-class.txt b/Tests/LibWeb/Text/expected/wpt-import/css/selectors/invalidation/has-with-pseudo-class.txt index c3c86685a7..dc21349e34 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/selectors/invalidation/has-with-pseudo-class.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/selectors/invalidation/has-with-pseudo-class.txt @@ -6,11 +6,11 @@ Rerun Found 41 tests -22 Pass -19 Fail +23 Pass +18 Fail Details Result Test Name MessagePass Before set checked on checkbox, testing subject -Fail Set checked on checkbox, testing subject assert_equals: expected "rgb(255, 0, 0)" but got "rgb(128, 128, 128)" +Pass Set checked on checkbox, testing subject Pass Unset checked on checkbox, testing subject Fail Set select on option assert_equals: expected "rgb(255, 0, 0)" but got "rgb(128, 128, 128)" Pass Reset select diff --git a/Userland/Libraries/LibWeb/DOM/Element.cpp b/Userland/Libraries/LibWeb/DOM/Element.cpp index 5ce4de7a45..7693dccee1 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.cpp +++ b/Userland/Libraries/LibWeb/DOM/Element.cpp @@ -1930,10 +1930,7 @@ void Element::invalidate_style_after_attribute_change(FlyString const& attribute // FIXME: Only invalidate if the attribute can actually affect style. (void)attribute_name; - if (document().style_computer().has_has_selectors()) - document().invalidate_style(StyleInvalidationReason::ElementAttributeChange); - else - invalidate_style(StyleInvalidationReason::ElementAttributeChange); + invalidate_style(StyleInvalidationReason::ElementAttributeChange); } // https://www.w3.org/TR/wai-aria-1.2/#tree_exclusion diff --git a/Userland/Libraries/LibWeb/DOM/Node.cpp b/Userland/Libraries/LibWeb/DOM/Node.cpp index a5b31f6743..e7a0c9d1c9 100644 --- a/Userland/Libraries/LibWeb/DOM/Node.cpp +++ b/Userland/Libraries/LibWeb/DOM/Node.cpp @@ -206,13 +206,7 @@ void Node::set_text_content(Optional const& maybe_content) // Otherwise, do nothing. if (is_connected()) { - // FIXME: If there are any :has() selectors, we currently invalidate style for the whole document. - // We need to find a way to invalidate less! - if (document().style_computer().has_has_selectors()) { - document().invalidate_style(StyleInvalidationReason::NodeSetTextContent); - } else { - invalidate_style(StyleInvalidationReason::NodeSetTextContent); - } + invalidate_style(StyleInvalidationReason::NodeSetTextContent); document().invalidate_layout_tree(); } @@ -397,6 +391,13 @@ void Node::invalidate_style(StyleInvalidationReason reason) if (is_character_data()) return; + // FIXME: This is very not optimal! We should figure out a smaller set of elements to invalidate, + // but right now the :has() selector means we have to invalidate everything. + if (!is_document() && document().style_computer().has_has_selectors()) { + document().invalidate_style(reason); + return; + } + if (!needs_style_update() && !document().needs_full_style_update()) { dbgln_if(STYLE_INVALIDATION_DEBUG, "Invalidate style ({}): {}", to_string(reason), debug_description()); } @@ -888,13 +889,7 @@ void Node::remove(bool suppress_observers) // Since the tree structure has changed, we need to invalidate both style and layout. // In the future, we should find a way to only invalidate the parts that actually need it. - // FIXME: If there are any :has() selectors, we currently invalidate style for the whole document. - // We need to find a way to invalidate less! - if (document().style_computer().has_has_selectors()) { - document().invalidate_style(StyleInvalidationReason::NodeRemove); - } else { - invalidate_style(StyleInvalidationReason::NodeRemove); - } + invalidate_style(StyleInvalidationReason::NodeRemove); // NOTE: If we didn't have a layout node before, rebuilding the layout tree isn't gonna give us one // after we've been removed from the DOM. diff --git a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp index d10bb54b6c..d34793399b 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -165,14 +165,7 @@ void HTMLInputElement::set_checked(bool checked, ChangeSource change_source) m_checked = checked; - // This element's :checked pseudo-class could be used in a sibling's sibling-selector, - // so we need to invalidate the style of all siblings. - if (parent()) { - parent()->for_each_child([&](auto& child) { - child.invalidate_style(DOM::StyleInvalidationReason::HTMLInputElementSetChecked); - return IterationDecision::Continue; - }); - } + invalidate_style(DOM::StyleInvalidationReason::HTMLInputElementSetChecked); } void HTMLInputElement::set_checked_binding(bool checked)