diff --git a/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp b/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp index 984ed095c4..9ceed93f82 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp @@ -103,34 +103,42 @@ void CSSRuleList::for_each_effective_style_rule(Function(rule); - if (import_rule.has_import_result()) - import_rule.loaded_style_sheet()->evaluate_media_queries(window); + if (import_rule.has_import_result() && import_rule.loaded_style_sheet()->evaluate_media_queries(window)) + any_media_queries_changed_match_state = true; break; } case CSSRule::Type::Media: { auto& media_rule = verify_cast(rule); - if (media_rule.evaluate(window)) - media_rule.css_rules().evaluate_media_queries(window); + bool did_match = media_rule.condition_matches(); + 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; } case CSSRule::Type::Supports: { auto& supports_rule = verify_cast(rule); - if (supports_rule.condition_matches()) - supports_rule.css_rules().evaluate_media_queries(window); + if (supports_rule.condition_matches() && supports_rule.css_rules().evaluate_media_queries(window)) + any_media_queries_changed_match_state = true; break; } case CSSRule::Type::__Count: VERIFY_NOT_REACHED(); } } + + return any_media_queries_changed_match_state; } } diff --git a/Userland/Libraries/LibWeb/CSS/CSSRuleList.h b/Userland/Libraries/LibWeb/CSS/CSSRuleList.h index a8a76cbb4f..4c2fa5d9bd 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRuleList.h +++ b/Userland/Libraries/LibWeb/CSS/CSSRuleList.h @@ -52,7 +52,8 @@ public: DOM::ExceptionOr insert_a_css_rule(NonnullRefPtr, u32 index); void for_each_effective_style_rule(Function 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: explicit CSSRuleList(NonnullRefPtrVector&&); diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp index 783a84ae31..5aa5a03bd3 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp @@ -62,9 +62,9 @@ void CSSStyleSheet::for_each_effective_style_rule(Functionfor_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); } } diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h index 6ce28b1735..30d38337e5 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h @@ -47,7 +47,8 @@ public: DOM::ExceptionOr delete_rule(unsigned index); void for_each_effective_style_rule(Function 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: explicit CSSStyleSheet(NonnullRefPtrVector); diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index 3a992f8d34..e08d7ff42c 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -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! + bool any_media_queries_changed_match_state = false; 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! - // We should only invalidate when one or more @media rules changes evaluation status. - style_computer().invalidate_rule_cache(); + if (any_media_queries_changed_match_state) + style_computer().invalidate_rule_cache(); } NonnullRefPtr Document::implementation() const