diff --git a/Libraries/LibWeb/CSS/SelectorEngine.cpp b/Libraries/LibWeb/CSS/SelectorEngine.cpp index cdc7a5ea3f2..80ae1ae204a 100644 --- a/Libraries/LibWeb/CSS/SelectorEngine.cpp +++ b/Libraries/LibWeb/CSS/SelectorEngine.cpp @@ -480,15 +480,18 @@ static inline bool matches_pseudo_class(CSS::Selector::SimpleSelector::PseudoCla } case CSS::PseudoClass::FirstChild: if (context.collect_per_element_selector_involvement_metadata) { - const_cast(element).set_affected_by_first_or_last_child_pseudo_class(true); + const_cast(element).set_affected_by_sibling_position_or_count_pseudo_class(true); } return !element.previous_element_sibling(); case CSS::PseudoClass::LastChild: if (context.collect_per_element_selector_involvement_metadata) { - const_cast(element).set_affected_by_first_or_last_child_pseudo_class(true); + const_cast(element).set_affected_by_sibling_position_or_count_pseudo_class(true); } return !element.next_element_sibling(); case CSS::PseudoClass::OnlyChild: + if (context.collect_per_element_selector_involvement_metadata) { + const_cast(element).set_affected_by_sibling_position_or_count_pseudo_class(true); + } return !(element.previous_element_sibling() || element.next_element_sibling()); case CSS::PseudoClass::Empty: { if (!element.has_children()) @@ -514,10 +517,19 @@ static inline bool matches_pseudo_class(CSS::Selector::SimpleSelector::PseudoCla case CSS::PseudoClass::Scope: return scope ? &element == scope : is(element); case CSS::PseudoClass::FirstOfType: + if (context.collect_per_element_selector_involvement_metadata) { + const_cast(element).set_affected_by_sibling_position_or_count_pseudo_class(true); + } return !previous_sibling_with_same_tag_name(element); case CSS::PseudoClass::LastOfType: + if (context.collect_per_element_selector_involvement_metadata) { + const_cast(element).set_affected_by_sibling_position_or_count_pseudo_class(true); + } return !next_sibling_with_same_tag_name(element); case CSS::PseudoClass::OnlyOfType: + if (context.collect_per_element_selector_involvement_metadata) { + const_cast(element).set_affected_by_sibling_position_or_count_pseudo_class(true); + } return !previous_sibling_with_same_tag_name(element) && !next_sibling_with_same_tag_name(element); case CSS::PseudoClass::Lang: return matches_lang_pseudo_class(element, pseudo_class.languages); diff --git a/Libraries/LibWeb/DOM/Element.cpp b/Libraries/LibWeb/DOM/Element.cpp index b38565c0b3f..fa228416c1f 100644 --- a/Libraries/LibWeb/DOM/Element.cpp +++ b/Libraries/LibWeb/DOM/Element.cpp @@ -620,7 +620,7 @@ CSS::RequiredInvalidationAfterStyleChange Element::recompute_style() m_affected_by_has_pseudo_class_with_relative_selector_that_has_sibling_combinator = false; m_affected_by_direct_sibling_combinator = false; m_affected_by_indirect_sibling_combinator = false; - m_affected_by_first_or_last_child_pseudo_class = false; + m_affected_by_sibling_position_or_count_pseudo_class = false; m_affected_by_nth_child_pseudo_class = false; m_sibling_invalidation_distance = 0; diff --git a/Libraries/LibWeb/DOM/Element.h b/Libraries/LibWeb/DOM/Element.h index d2ff1173263..772508734f1 100644 --- a/Libraries/LibWeb/DOM/Element.h +++ b/Libraries/LibWeb/DOM/Element.h @@ -453,8 +453,8 @@ public: bool affected_by_indirect_sibling_combinator() const { return m_affected_by_indirect_sibling_combinator; } void set_affected_by_indirect_sibling_combinator(bool value) { m_affected_by_indirect_sibling_combinator = value; } - bool affected_by_first_or_last_child_pseudo_class() const { return m_affected_by_first_or_last_child_pseudo_class; } - void set_affected_by_first_or_last_child_pseudo_class(bool value) { m_affected_by_first_or_last_child_pseudo_class = value; } + bool affected_by_sibling_position_or_count_pseudo_class() const { return m_affected_by_sibling_position_or_count_pseudo_class; } + void set_affected_by_sibling_position_or_count_pseudo_class(bool value) { m_affected_by_sibling_position_or_count_pseudo_class = value; } bool affected_by_nth_child_pseudo_class() const { return m_affected_by_nth_child_pseudo_class; } void set_affected_by_nth_child_pseudo_class(bool value) { m_affected_by_nth_child_pseudo_class = value; } @@ -464,7 +464,7 @@ public: bool style_affected_by_structural_changes() const { - return affected_by_direct_sibling_combinator() || affected_by_indirect_sibling_combinator() || affected_by_first_or_last_child_pseudo_class() || affected_by_nth_child_pseudo_class(); + return affected_by_direct_sibling_combinator() || affected_by_indirect_sibling_combinator() || affected_by_sibling_position_or_count_pseudo_class() || affected_by_nth_child_pseudo_class(); } size_t number_of_owned_list_items() const; @@ -573,7 +573,7 @@ private: bool m_affected_by_has_pseudo_class_in_non_subject_position : 1 { false }; bool m_affected_by_direct_sibling_combinator : 1 { false }; bool m_affected_by_indirect_sibling_combinator : 1 { false }; - bool m_affected_by_first_or_last_child_pseudo_class : 1 { false }; + bool m_affected_by_sibling_position_or_count_pseudo_class : 1 { false }; bool m_affected_by_nth_child_pseudo_class : 1 { false }; bool m_affected_by_has_pseudo_class_with_relative_selector_that_has_sibling_combinator : 1 { false }; diff --git a/Tests/LibWeb/Text/expected/css/pseudo-style-invalidation-after-node-removal.txt b/Tests/LibWeb/Text/expected/css/pseudo-style-invalidation-after-node-removal.txt new file mode 100644 index 00000000000..40e1014ce68 --- /dev/null +++ b/Tests/LibWeb/Text/expected/css/pseudo-style-invalidation-after-node-removal.txt @@ -0,0 +1,3 @@ +div#a p: rgb(0, 128, 0) +div#b p: rgb(0, 128, 0) +div#c p: rgb(0, 128, 0) diff --git a/Tests/LibWeb/Text/input/css/pseudo-style-invalidation-after-node-removal.html b/Tests/LibWeb/Text/input/css/pseudo-style-invalidation-after-node-removal.html new file mode 100644 index 00000000000..1a475661e29 --- /dev/null +++ b/Tests/LibWeb/Text/input/css/pseudo-style-invalidation-after-node-removal.html @@ -0,0 +1,30 @@ + + + +

foo

bar

+

foo

bar

+

foo

bar

+