LibWeb: Skip unneeded style invalidation on custom element state change

If there are no :defined pseudo-class selectors anywhere in the
document, we don't have to invalidate style at all when an element's
custom element state changes.
This commit is contained in:
Andreas Kling 2024-12-25 00:52:36 +01:00 committed by Andreas Kling
commit f45e24864b
Notes: github-actions[bot] 2024-12-25 12:27:53 +00:00
3 changed files with 14 additions and 1 deletions

View file

@ -2520,6 +2520,9 @@ void StyleComputer::collect_selector_insights(Selector const& selector, Selector
if (simple_selector.pseudo_class().type == PseudoClass::Has) { if (simple_selector.pseudo_class().type == PseudoClass::Has) {
insights.has_has_selectors = true; insights.has_has_selectors = true;
} }
if (simple_selector.pseudo_class().type == PseudoClass::Defined) {
insights.has_defined_selectors = true;
}
for (auto const& argument_selector : simple_selector.pseudo_class().argument_selector_list) { for (auto const& argument_selector : simple_selector.pseudo_class().argument_selector_list) {
collect_selector_insights(*argument_selector, insights); collect_selector_insights(*argument_selector, insights);
} }
@ -3012,6 +3015,12 @@ bool StyleComputer::has_has_selectors() const
return m_selector_insights->has_has_selectors; return m_selector_insights->has_has_selectors;
} }
bool StyleComputer::has_defined_selectors() const
{
build_rule_cache_if_needed();
return m_selector_insights->has_defined_selectors;
}
bool StyleComputer::has_attribute_selector(FlyString const& attribute_name) const bool StyleComputer::has_attribute_selector(FlyString const& attribute_name) const
{ {
build_rule_cache_if_needed(); build_rule_cache_if_needed();

View file

@ -170,6 +170,7 @@ public:
void collect_animation_into(DOM::Element&, Optional<CSS::Selector::PseudoElement::Type>, GC::Ref<Animations::KeyframeEffect> animation, ComputedProperties&, AnimationRefresh = AnimationRefresh::No) const; void collect_animation_into(DOM::Element&, Optional<CSS::Selector::PseudoElement::Type>, GC::Ref<Animations::KeyframeEffect> animation, ComputedProperties&, AnimationRefresh = AnimationRefresh::No) const;
[[nodiscard]] bool has_has_selectors() const; [[nodiscard]] bool has_has_selectors() const;
[[nodiscard]] bool has_defined_selectors() const;
[[nodiscard]] bool has_attribute_selector(FlyString const& attribute_name) const; [[nodiscard]] bool has_attribute_selector(FlyString const& attribute_name) const;
size_t number_of_css_font_faces_with_loading_in_progress() const; size_t number_of_css_font_faces_with_loading_in_progress() const;
@ -250,6 +251,7 @@ private:
struct SelectorInsights { struct SelectorInsights {
bool has_has_selectors { false }; bool has_has_selectors { false };
bool has_defined_selectors { false };
HashTable<FlyString> all_names_used_in_attribute_selectors; HashTable<FlyString> all_names_used_in_attribute_selectors;
}; };

View file

@ -2266,6 +2266,8 @@ void Element::set_custom_element_state(CustomElementState state)
if (m_custom_element_state == state) if (m_custom_element_state == state)
return; return;
m_custom_element_state = state; m_custom_element_state = state;
if (document().style_computer().has_defined_selectors())
invalidate_style(StyleInvalidationReason::CustomElementStateChange); invalidate_style(StyleInvalidationReason::CustomElementStateChange);
} }