Pārlūkot izejas kodu

LibWeb: Make empty media query lists evaluate to true

Gingeh 10 mēneši atpakaļ
vecāks
revīzija
16f2f6aa42

+ 26 - 0
Tests/LibWeb/Layout/expected/media-query-empty.txt

@@ -0,0 +1,26 @@
+Viewport <#document> at (0,0) content-size 800x600 children: not-inline
+  BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
+    BlockContainer <body> at (8,8) content-size 784x34 children: not-inline
+      BlockContainer <div.first> at (8,8) content-size 784x17 children: inline
+        frag 0 from TextNode start: 0, length: 5, rect: [8,8 42.140625x17] baseline: 13.296875
+            "First"
+        TextNode <#text>
+      BlockContainer <(anonymous)> at (8,25) content-size 784x0 children: inline
+        TextNode <#text>
+      BlockContainer <div.second> at (8,25) content-size 784x17 children: inline
+        frag 0 from TextNode start: 0, length: 6, rect: [8,25 57.40625x17] baseline: 13.296875
+            "Second"
+        TextNode <#text>
+      BlockContainer <(anonymous)> at (8,42) content-size 784x0 children: inline
+        TextNode <#text>
+        TextNode <#text>
+
+ViewportPaintable (Viewport<#document>) [0,0 800x600]
+  PaintableWithLines (BlockContainer<HTML>) [0,0 800x600]
+    PaintableWithLines (BlockContainer<BODY>) [8,8 784x34]
+      PaintableWithLines (BlockContainer<DIV>.first) [8,8 784x17]
+        TextPaintable (TextNode<#text>)
+      PaintableWithLines (BlockContainer(anonymous)) [8,25 784x0]
+      PaintableWithLines (BlockContainer<DIV>.second) [8,25 784x17]
+        TextPaintable (TextNode<#text>)
+      PaintableWithLines (BlockContainer(anonymous)) [8,42 784x0]

+ 15 - 0
Tests/LibWeb/Layout/input/media-query-empty.html

@@ -0,0 +1,15 @@
+<style>
+div { display: none; }
+@media {
+    div.first { display: block; }
+}
+@media{
+    div.second { display: block; }
+}
+@media ,, {
+    div.invalid { display: block; }
+}
+</style>
+<div class="first">First</div>
+<div class="second">Second</div>
+<div class="invalid">Invalid</div>

+ 1 - 2
Userland/Libraries/LibWeb/CSS/MediaList.cpp

@@ -100,9 +100,8 @@ bool MediaList::evaluate(HTML::Window const& window)
 
 bool MediaList::matches() const
 {
-    if (m_media.is_empty()) {
+    if (m_media.is_empty())
         return true;
-    }
 
     for (auto& media : m_media) {
         if (media->matches())

+ 7 - 0
Userland/Libraries/LibWeb/CSS/MediaQueryList.cpp

@@ -51,10 +51,14 @@ String MediaQueryList::media() const
 // https://drafts.csswg.org/cssom-view/#dom-mediaquerylist-matches
 bool MediaQueryList::matches() const
 {
+    if (m_media.is_empty())
+        return true;
+
     for (auto& media : m_media) {
         if (media->matches())
             return true;
     }
+
     return false;
 }
 
@@ -64,6 +68,9 @@ bool MediaQueryList::evaluate()
     if (!window)
         return false;
 
+    if (m_media.is_empty())
+        return true;
+
     bool now_matches = false;
     for (auto& media : m_media) {
         now_matches = now_matches || media->evaluate(*window);

+ 6 - 7
Userland/Libraries/LibWeb/CSS/Parser/MediaParsing.cpp

@@ -27,6 +27,12 @@ Vector<NonnullRefPtr<MediaQuery>> Parser::parse_a_media_query_list(TokenStream<T
 {
     // https://www.w3.org/TR/mediaqueries-4/#mq-list
 
+    // AD-HOC: Ignore whitespace-only queries
+    // to make `@media {..}` equivalent to `@media all {..}`
+    tokens.skip_whitespace();
+    if (!tokens.has_next_token())
+        return {};
+
     auto comma_separated_lists = parse_a_comma_separated_list_of_component_values(tokens);
 
     AK::Vector<NonnullRefPtr<MediaQuery>> media_queries;
@@ -616,11 +622,6 @@ Optional<MediaFeatureValue> Parser::parse_media_feature_value(MediaFeatureID med
 
 JS::GCPtr<CSSMediaRule> Parser::convert_to_media_rule(Rule& rule)
 {
-    if (rule.prelude().is_empty()) {
-        dbgln_if(CSS_PARSER_DEBUG, "Failed to parse @media rule: Empty prelude.");
-        return {};
-    }
-
     if (!rule.block()) {
         dbgln_if(CSS_PARSER_DEBUG, "Failed to parse @media rule: No block.");
         return {};
@@ -628,8 +629,6 @@ JS::GCPtr<CSSMediaRule> Parser::convert_to_media_rule(Rule& rule)
 
     auto media_query_tokens = TokenStream { rule.prelude() };
     auto media_query_list = parse_a_media_query_list(media_query_tokens);
-    if (media_query_list.is_empty())
-        return {};
 
     auto child_tokens = TokenStream { rule.block()->values() };
     auto parser_rules = parse_a_list_of_rules(child_tokens);