From 5098cd22a478b7264db9226c996f7fa229fcdb60 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Fri, 8 Oct 2021 20:21:46 +0100 Subject: LibWeb: Evaluate `@media` rules We now evaluate the conditions of `@media` rules at the same point in the HTML event loop as evaluation of `MediaQueryList`s. This is not strictly to spec, but since the spec doesn't actually say when to do this, it seems to make the most sense. In any case, it works! :^) --- Userland/Libraries/LibWeb/CSS/CSSGroupingRule.h | 1 + Userland/Libraries/LibWeb/CSS/CSSMediaRule.h | 3 ++- Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp | 30 +++++++++++++++++++++++++ Userland/Libraries/LibWeb/CSS/CSSRuleList.h | 1 + Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp | 5 +++++ Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h | 1 + Userland/Libraries/LibWeb/CSS/StyleSheetList.h | 3 ++- Userland/Libraries/LibWeb/DOM/Document.cpp | 5 +++++ 8 files changed, 47 insertions(+), 2 deletions(-) (limited to 'Userland') diff --git a/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.h b/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.h index cee8386bfe..127fbbf7a6 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.h +++ b/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.h @@ -22,6 +22,7 @@ public: ~CSSGroupingRule(); CSSRuleList const& css_rules() const { return m_rules; } + CSSRuleList& css_rules() { return m_rules; } size_t insert_rule(StringView const& rule, size_t index = 0); void delete_rule(size_t index); diff --git a/Userland/Libraries/LibWeb/CSS/CSSMediaRule.h b/Userland/Libraries/LibWeb/CSS/CSSMediaRule.h index 4c02dfc08e..be3ce292e3 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSMediaRule.h +++ b/Userland/Libraries/LibWeb/CSS/CSSMediaRule.h @@ -30,11 +30,12 @@ public: virtual String condition_text() const override; virtual void set_condition_text(String) override; - // FIXME: We need to evaluate() the query before matches() will work! virtual bool condition_matches() const override { return m_media->matches(); } NonnullRefPtr const& media() const { return m_media; } + bool evaluate(DOM::Window const& window) { return m_media->evaluate(window); } + private: explicit CSSMediaRule(NonnullRefPtr&&, NonnullRefPtrVector&&); diff --git a/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp b/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp index acca567e8a..f1fd30a58b 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp @@ -126,4 +126,34 @@ bool CSSRuleList::for_first_not_loaded_import_rule(Function(rule); + if (import_rule.has_import_result()) + import_rule.loaded_style_sheet()->evaluate_media_queries(window); + break; + } + case CSSRule::Type::Media: { + auto& media_rule = verify_cast(rule); + if (media_rule.evaluate(window)) + media_rule.css_rules().evaluate_media_queries(window); + break; + } + case CSSRule::Type::Supports: { + auto& supports_rule = verify_cast(rule); + if (supports_rule.condition_matches()) + supports_rule.css_rules().evaluate_media_queries(window); + break; + } + case CSSRule::Type::__Count: + VERIFY_NOT_REACHED(); + } + } +} + } diff --git a/Userland/Libraries/LibWeb/CSS/CSSRuleList.h b/Userland/Libraries/LibWeb/CSS/CSSRuleList.h index 069d67909b..81e773fea2 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRuleList.h +++ b/Userland/Libraries/LibWeb/CSS/CSSRuleList.h @@ -53,6 +53,7 @@ public: void for_each_effective_style_rule(Function const& callback) const; bool for_first_not_loaded_import_rule(Function const& callback); + void 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 b7dab97abd..10f1b04d5d 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp @@ -67,4 +67,9 @@ bool CSSStyleSheet::for_first_not_loaded_import_rule(Functionfor_first_not_loaded_import_rule(callback); } +void CSSStyleSheet::evaluate_media_queries(DOM::Window const& window) +{ + m_rules->evaluate_media_queries(window); +} + } diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h index dbbf197093..6ff2c2fc05 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h @@ -46,6 +46,7 @@ public: void for_each_effective_style_rule(Function const& callback) const; bool for_first_not_loaded_import_rule(Function const& callback); + void evaluate_media_queries(DOM::Window const&); private: explicit CSSStyleSheet(NonnullRefPtrVector); diff --git a/Userland/Libraries/LibWeb/CSS/StyleSheetList.h b/Userland/Libraries/LibWeb/CSS/StyleSheetList.h index 15e7e8b417..3aa0b63874 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleSheetList.h +++ b/Userland/Libraries/LibWeb/CSS/StyleSheetList.h @@ -28,7 +28,8 @@ public: void add_sheet(NonnullRefPtr); void remove_sheet(CSSStyleSheet&); - const NonnullRefPtrVector& sheets() const { return m_sheets; } + NonnullRefPtrVector const& sheets() const { return m_sheets; } + NonnullRefPtrVector& sheets() { return m_sheets; } RefPtr item(size_t index) const { diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index e575c64128..1e20c5b3e2 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -1156,6 +1156,11 @@ void Document::evaluate_media_queries_and_report_changes() media_query_list->dispatch_event(event); } } + + // Also not in the spec, but this is as good a place as any to evaluate @media rules! + for (auto& style_sheet : style_sheets().sheets()) { + style_sheet.evaluate_media_queries(window()); + } } } -- cgit v1.2.3