1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 02:47:34 +00:00

LibWeb: Only invalidate styles if a @media rule changes match status

This commit is contained in:
Sam Atkins 2022-02-17 12:34:36 +00:00 committed by Andreas Kling
parent 144ef3eb9f
commit fd24782d85
5 changed files with 26 additions and 15 deletions

View file

@ -103,34 +103,42 @@ void CSSRuleList::for_each_effective_style_rule(Function<void(CSSStyleRule const
} }
} }
void CSSRuleList::evaluate_media_queries(DOM::Window const& window) bool CSSRuleList::evaluate_media_queries(DOM::Window const& window)
{ {
bool any_media_queries_changed_match_state = false;
for (auto& rule : m_rules) { for (auto& rule : m_rules) {
switch (rule.type()) { switch (rule.type()) {
case CSSRule::Type::Style: case CSSRule::Type::Style:
break; break;
case CSSRule::Type::Import: { case CSSRule::Type::Import: {
auto& import_rule = verify_cast<CSSImportRule>(rule); auto& import_rule = verify_cast<CSSImportRule>(rule);
if (import_rule.has_import_result()) if (import_rule.has_import_result() && import_rule.loaded_style_sheet()->evaluate_media_queries(window))
import_rule.loaded_style_sheet()->evaluate_media_queries(window); any_media_queries_changed_match_state = true;
break; break;
} }
case CSSRule::Type::Media: { case CSSRule::Type::Media: {
auto& media_rule = verify_cast<CSSMediaRule>(rule); auto& media_rule = verify_cast<CSSMediaRule>(rule);
if (media_rule.evaluate(window)) bool did_match = media_rule.condition_matches();
media_rule.css_rules().evaluate_media_queries(window); bool now_matches = media_rule.evaluate(window);
if (did_match != now_matches)
any_media_queries_changed_match_state = true;
if (now_matches && media_rule.css_rules().evaluate_media_queries(window))
any_media_queries_changed_match_state = true;
break; break;
} }
case CSSRule::Type::Supports: { case CSSRule::Type::Supports: {
auto& supports_rule = verify_cast<CSSSupportsRule>(rule); auto& supports_rule = verify_cast<CSSSupportsRule>(rule);
if (supports_rule.condition_matches()) if (supports_rule.condition_matches() && supports_rule.css_rules().evaluate_media_queries(window))
supports_rule.css_rules().evaluate_media_queries(window); any_media_queries_changed_match_state = true;
break; break;
} }
case CSSRule::Type::__Count: case CSSRule::Type::__Count:
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }
} }
return any_media_queries_changed_match_state;
} }
} }

View file

@ -52,7 +52,8 @@ public:
DOM::ExceptionOr<unsigned> insert_a_css_rule(NonnullRefPtr<CSSRule>, u32 index); DOM::ExceptionOr<unsigned> insert_a_css_rule(NonnullRefPtr<CSSRule>, u32 index);
void for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const; void for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const;
void evaluate_media_queries(DOM::Window const&); // Returns whether the match state of any media queries changed after evaluation.
bool evaluate_media_queries(DOM::Window const&);
private: private:
explicit CSSRuleList(NonnullRefPtrVector<CSSRule>&&); explicit CSSRuleList(NonnullRefPtrVector<CSSRule>&&);

View file

@ -62,9 +62,9 @@ void CSSStyleSheet::for_each_effective_style_rule(Function<void(CSSStyleRule con
m_rules->for_each_effective_style_rule(callback); m_rules->for_each_effective_style_rule(callback);
} }
void CSSStyleSheet::evaluate_media_queries(DOM::Window const& window) bool CSSStyleSheet::evaluate_media_queries(DOM::Window const& window)
{ {
m_rules->evaluate_media_queries(window); return m_rules->evaluate_media_queries(window);
} }
} }

View file

@ -47,7 +47,8 @@ public:
DOM::ExceptionOr<void> delete_rule(unsigned index); DOM::ExceptionOr<void> delete_rule(unsigned index);
void for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const; void for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const;
void evaluate_media_queries(DOM::Window const&); // Returns whether the match state of any media queries changed after evaluation.
bool evaluate_media_queries(DOM::Window const&);
private: private:
explicit CSSStyleSheet(NonnullRefPtrVector<CSSRule>); explicit CSSStyleSheet(NonnullRefPtrVector<CSSRule>);

View file

@ -1161,13 +1161,14 @@ void Document::evaluate_media_queries_and_report_changes()
} }
// Also not in the spec, but this is as good a place as any to evaluate @media rules! // Also not in the spec, but this is as good a place as any to evaluate @media rules!
bool any_media_queries_changed_match_state = false;
for (auto& style_sheet : style_sheets().sheets()) { for (auto& style_sheet : style_sheets().sheets()) {
style_sheet.evaluate_media_queries(window()); if (style_sheet.evaluate_media_queries(window()))
any_media_queries_changed_match_state = true;
} }
// FIXME: This invalidates too often! if (any_media_queries_changed_match_state)
// We should only invalidate when one or more @media rules changes evaluation status. style_computer().invalidate_rule_cache();
style_computer().invalidate_rule_cache();
} }
NonnullRefPtr<DOMImplementation> Document::implementation() const NonnullRefPtr<DOMImplementation> Document::implementation() const