summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorSam Atkins <atkinssj@serenityos.org>2021-10-08 20:21:46 +0100
committerAndreas Kling <kling@serenityos.org>2021-10-08 23:02:57 +0200
commit5098cd22a478b7264db9226c996f7fa229fcdb60 (patch)
tree8d4421c5db6bd8778e7101c75468c9466e44f3eb /Userland
parent57a25139a553d94d89f899eb93ca054301131be1 (diff)
downloadserenity-5098cd22a478b7264db9226c996f7fa229fcdb60.zip
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! :^)
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSGroupingRule.h1
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSMediaRule.h3
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp30
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSRuleList.h1
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp5
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h1
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleSheetList.h3
-rw-r--r--Userland/Libraries/LibWeb/DOM/Document.cpp5
8 files changed, 47 insertions, 2 deletions
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<MediaList> const& media() const { return m_media; }
+ bool evaluate(DOM::Window const& window) { return m_media->evaluate(window); }
+
private:
explicit CSSMediaRule(NonnullRefPtr<MediaList>&&, NonnullRefPtrVector<CSSRule>&&);
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<void(CSSImportRule&)
return false;
}
+void CSSRuleList::evaluate_media_queries(DOM::Window const& window)
+{
+ for (auto& rule : m_rules) {
+ switch (rule.type()) {
+ case CSSRule::Type::Style:
+ break;
+ case CSSRule::Type::Import: {
+ auto& import_rule = verify_cast<CSSImportRule>(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<CSSMediaRule>(rule);
+ if (media_rule.evaluate(window))
+ media_rule.css_rules().evaluate_media_queries(window);
+ break;
+ }
+ case CSSRule::Type::Supports: {
+ auto& supports_rule = verify_cast<CSSSupportsRule>(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<void(CSSStyleRule const&)> const& callback) const;
bool for_first_not_loaded_import_rule(Function<void(CSSImportRule&)> const& callback);
+ void evaluate_media_queries(DOM::Window const&);
private:
explicit CSSRuleList(NonnullRefPtrVector<CSSRule>&&);
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(Function<void(CSSImportRule
return m_rules->for_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<void(CSSStyleRule const&)> const& callback) const;
bool for_first_not_loaded_import_rule(Function<void(CSSImportRule&)> const& callback);
+ void evaluate_media_queries(DOM::Window const&);
private:
explicit CSSStyleSheet(NonnullRefPtrVector<CSSRule>);
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<CSSStyleSheet>);
void remove_sheet(CSSStyleSheet&);
- const NonnullRefPtrVector<CSSStyleSheet>& sheets() const { return m_sheets; }
+ NonnullRefPtrVector<CSSStyleSheet> const& sheets() const { return m_sheets; }
+ NonnullRefPtrVector<CSSStyleSheet>& sheets() { return m_sheets; }
RefPtr<CSSStyleSheet> 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());
+ }
}
}