diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/selectors/focus-within-009.txt b/Tests/LibWeb/Text/expected/wpt-import/css/selectors/focus-within-009.txt index afd5195f19c..34165eb0ad7 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/selectors/focus-within-009.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/selectors/focus-within-009.txt @@ -6,18 +6,18 @@ Rerun Found 12 tests -1 Pass -11 Fail +9 Pass +3 Fail Details Result Test Name MessagePass Initial State -Fail Focus 'target1' -Fail Focus 'target2' -Fail Focus 'target1' again -Fail Focus 'target2' again -Fail Focus 'target1' once again +Pass Focus 'target1' +Pass Focus 'target2' +Pass Focus 'target1' again +Pass Focus 'target2' again +Pass Focus 'target1' once again Fail Detach 'container1' from the document Fail Try to focus 'target1' -Fail Focus 'target2' once again -Fail Attach 'container1' in 'container2' -Fail Focus 'target1' for the last time +Pass Focus 'target2' once again +Pass Attach 'container1' in 'container2' +Pass Focus 'target1' for the last time Fail Move 'target1' in 'container2' \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/selectors/invalidation/target-pseudo-in-has.txt b/Tests/LibWeb/Text/expected/wpt-import/css/selectors/invalidation/target-pseudo-in-has.txt index fdc137e7e28..d96a15c52dd 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/selectors/invalidation/target-pseudo-in-has.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/selectors/invalidation/target-pseudo-in-has.txt @@ -6,6 +6,6 @@ Rerun Found 1 tests -1 Fail +1 Pass Details -Result Test Name MessageFail CSS Selectors Invalidation: :target pseudo-class in :has() argument \ No newline at end of file +Result Test Name MessagePass CSS Selectors Invalidation: :target pseudo-class in :has() argument \ No newline at end of file diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index d7bbc97bb46..00102526c36 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -2045,16 +2045,18 @@ void Document::set_focused_element(Element* element) if (m_focused_element.ptr() == element) return; - if (m_focused_element) { - m_focused_element->did_lose_focus(); - m_focused_element->set_needs_style_update(true); - } + JS::GCPtr old_focused_element = move(m_focused_element); + + if (old_focused_element) + old_focused_element->did_lose_focus(); m_focused_element = element; + if (auto* invalidation_target = find_common_ancestor(old_focused_element, m_focused_element) ?: this) + invalidation_target->invalidate_style(StyleInvalidationReason::FocusedElementChange); + if (m_focused_element) { m_focused_element->did_receive_focus(); - m_focused_element->set_needs_style_update(true); } if (paintable()) @@ -2078,8 +2080,12 @@ void Document::set_active_element(Element* element) if (m_active_element.ptr() == element) return; + JS::GCPtr old_active_element = move(m_active_element); m_active_element = element; + if (auto* invalidation_target = find_common_ancestor(old_active_element, m_active_element) ?: this) + invalidation_target->invalidate_style(StyleInvalidationReason::TargetElementChange); + if (paintable()) paintable()->set_needs_display(); } @@ -2089,13 +2095,11 @@ void Document::set_target_element(Element* element) if (m_target_element.ptr() == element) return; - if (m_target_element) - m_target_element->set_needs_style_update(true); - + JS::GCPtr old_target_element = move(m_target_element); m_target_element = element; - if (m_target_element) - m_target_element->set_needs_style_update(true); + if (auto* invalidation_target = find_common_ancestor(old_target_element, m_target_element) ?: this) + invalidation_target->invalidate_style(StyleInvalidationReason::TargetElementChange); if (paintable()) paintable()->set_needs_display(); diff --git a/Userland/Libraries/LibWeb/DOM/Node.h b/Userland/Libraries/LibWeb/DOM/Node.h index 5c73065c795..12ff41aab34 100644 --- a/Userland/Libraries/LibWeb/DOM/Node.h +++ b/Userland/Libraries/LibWeb/DOM/Node.h @@ -59,6 +59,7 @@ enum class IsDescendant { }; #define ENUMERATE_STYLE_INVALIDATION_REASONS(X) \ + X(ActiveElementChange) \ X(AdoptedStyleSheetsList) \ X(CSSFontLoaded) \ X(CSSImportRule) \ @@ -68,6 +69,8 @@ enum class IsDescendant { X(EditingInsertion) \ X(ElementAttributeChange) \ X(ElementSetShadowRoot) \ + X(FocusedElementChange) \ + X(HTMLHyperlinkElementHrefChange) \ X(HTMLInputElementSetChecked) \ X(HTMLObjectElementUpdateLayoutAndChildObjects) \ X(HTMLSelectElementSetIsOpen) \ @@ -84,7 +87,8 @@ enum class IsDescendant { X(StyleSheetDeleteRule) \ X(StyleSheetInsertRule) \ X(StyleSheetListAddSheet) \ - X(StyleSheetListRemoveSheet) + X(StyleSheetListRemoveSheet) \ + X(TargetElementChange) enum class StyleInvalidationReason { #define __ENUMERATE_STYLE_INVALIDATION_REASON(reason) reason, diff --git a/Userland/Libraries/LibWeb/HTML/HTMLAnchorElement.h b/Userland/Libraries/LibWeb/HTML/HTMLAnchorElement.h index 1014ea96776..4dfe9c9943f 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLAnchorElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLAnchorElement.h @@ -51,6 +51,7 @@ private: // ^HTML::HTMLHyperlinkElementUtils virtual DOM::Document& hyperlink_element_utils_document() override { return document(); } + virtual DOM::Element& hyperlink_element_utils_element() override { return *this; } virtual Optional hyperlink_element_utils_href() const override; virtual WebIDL::ExceptionOr set_hyperlink_element_utils_href(String) override; virtual Optional hyperlink_element_utils_referrerpolicy() const override; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLAreaElement.h b/Userland/Libraries/LibWeb/HTML/HTMLAreaElement.h index 2d7bfa69189..3ae0dc3d77b 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLAreaElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLAreaElement.h @@ -34,6 +34,7 @@ private: // ^HTML::HTMLHyperlinkElementUtils virtual DOM::Document& hyperlink_element_utils_document() override { return document(); } + virtual DOM::Element& hyperlink_element_utils_element() override { return *this; } virtual Optional hyperlink_element_utils_href() const override; virtual WebIDL::ExceptionOr set_hyperlink_element_utils_href(String) override; virtual Optional hyperlink_element_utils_referrerpolicy() const override; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.cpp b/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.cpp index 8023d077736..d574997db4a 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.cpp @@ -31,12 +31,14 @@ void HTMLHyperlinkElementUtils::set_the_url() auto href_content_attribute = hyperlink_element_utils_href(); if (!href_content_attribute.has_value()) { m_url = {}; + hyperlink_element_utils_element().invalidate_style(DOM::StyleInvalidationReason::HTMLHyperlinkElementHrefChange); return; } // 2. Otherwise, parse this element's href content attribute value relative to this element's node document. // If parsing is successful, set this element's url to the result; otherwise, set this element's url to null. m_url = hyperlink_element_utils_document().parse_url(*href_content_attribute); + hyperlink_element_utils_element().invalidate_style(DOM::StyleInvalidationReason::HTMLHyperlinkElementHrefChange); } // https://html.spec.whatwg.org/multipage/links.html#dom-hyperlink-origin diff --git a/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.h b/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.h index 34ed89c4255..17741d54240 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLHyperlinkElementUtils.h @@ -52,6 +52,7 @@ public: protected: virtual DOM::Document& hyperlink_element_utils_document() = 0; + virtual DOM::Element& hyperlink_element_utils_element() = 0; virtual Optional hyperlink_element_utils_href() const = 0; virtual WebIDL::ExceptionOr set_hyperlink_element_utils_href(String) = 0; virtual Optional hyperlink_element_utils_referrerpolicy() const = 0; diff --git a/Userland/Libraries/LibWeb/SVG/SVGAElement.cpp b/Userland/Libraries/LibWeb/SVG/SVGAElement.cpp index e1a06d9f6c5..32ebb36c3b0 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGAElement.cpp +++ b/Userland/Libraries/LibWeb/SVG/SVGAElement.cpp @@ -37,6 +37,9 @@ void SVGAElement::visit_edges(Cell::Visitor& visitor) void SVGAElement::attribute_changed(FlyString const& name, Optional const& old_value, Optional const& value) { Base::attribute_changed(name, old_value, value); + if (name == SVG::AttributeNames::href) { + invalidate_style(DOM::StyleInvalidationReason::HTMLHyperlinkElementHrefChange); + } if (name == HTML::AttributeNames::rel) { if (m_rel_list) m_rel_list->associated_attribute_changed(value.value_or(String {}));