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) {
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) {
collect_selector_insights(*argument_selector, insights);
}
@ -3012,6 +3015,12 @@ bool StyleComputer::has_has_selectors() const
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
{
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;
[[nodiscard]] bool has_has_selectors() const;
[[nodiscard]] bool has_defined_selectors() const;
[[nodiscard]] bool has_attribute_selector(FlyString const& attribute_name) const;
size_t number_of_css_font_faces_with_loading_in_progress() const;
@ -250,6 +251,7 @@ private:
struct SelectorInsights {
bool has_has_selectors { false };
bool has_defined_selectors { false };
HashTable<FlyString> all_names_used_in_attribute_selectors;
};

View file

@ -2266,7 +2266,9 @@ void Element::set_custom_element_state(CustomElementState state)
if (m_custom_element_state == state)
return;
m_custom_element_state = state;
invalidate_style(StyleInvalidationReason::CustomElementStateChange);
if (document().style_computer().has_defined_selectors())
invalidate_style(StyleInvalidationReason::CustomElementStateChange);
}
// https://html.spec.whatwg.org/multipage/dom.html#html-element-constructors