Parcourir la source

LibWeb: Sketch out media-query parsing

This does everything except actually parse the individual media queries.
Sam Atkins il y a 3 ans
Parent
commit
5bbbdb81dc

+ 53 - 0
Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp

@@ -632,6 +632,47 @@ Result<Selector::SimpleSelector, Parser::ParsingResult> Parser::parse_simple_sel
     return ParsingResult::SyntaxError;
 }
 
+NonnullRefPtrVector<MediaQuery> Parser::parse_as_media_query_list()
+{
+    return parse_a_media_query_list(m_token_stream);
+}
+
+template<typename T>
+NonnullRefPtrVector<MediaQuery> Parser::parse_a_media_query_list(TokenStream<T>& tokens)
+{
+    // https://www.w3.org/TR/mediaqueries-4/#mq-list
+
+    auto comma_separated_lists = parse_a_comma_separated_list_of_component_values(tokens);
+
+    AK::NonnullRefPtrVector<MediaQuery> media_queries;
+    for (auto& media_query_parts : comma_separated_lists) {
+        auto stream = TokenStream(media_query_parts);
+        media_queries.append(parse_media_query(stream));
+    }
+
+    return media_queries;
+}
+
+RefPtr<MediaQuery> Parser::parse_as_media_query()
+{
+    // https://www.w3.org/TR/cssom-1/#parse-a-media-query
+    auto media_query_list = parse_as_media_query_list();
+    if (media_query_list.is_empty())
+        return MediaQuery::create_not_all();
+    if (media_query_list.size() == 1)
+        return media_query_list.first();
+    return nullptr;
+}
+
+NonnullRefPtr<MediaQuery> Parser::parse_media_query(TokenStream<StyleComponentValueRule>&)
+{
+    // "A media query that does not match the grammar in the previous section must be replaced by `not all`
+    // during parsing." - https://www.w3.org/TR/mediaqueries-5/#error-handling
+
+    // FIXME: Implement media queries!
+    return MediaQuery::create_not_all();
+}
+
 NonnullRefPtrVector<StyleRule> Parser::consume_a_list_of_rules(bool top_level)
 {
     return consume_a_list_of_rules(m_token_stream, top_level);
@@ -3310,6 +3351,18 @@ Optional<CSS::SelectorList> parse_selector(CSS::ParsingContext const& context, S
     return parser.parse_as_selector();
 }
 
+RefPtr<CSS::MediaQuery> parse_media_query(CSS::ParsingContext const& context, StringView const& string)
+{
+    CSS::Parser parser(context, string);
+    return parser.parse_as_media_query();
+}
+
+NonnullRefPtrVector<CSS::MediaQuery> parse_media_query_list(CSS::ParsingContext const& context, StringView const& string)
+{
+    CSS::Parser parser(context, string);
+    return parser.parse_as_media_query_list();
+}
+
 RefPtr<CSS::StyleValue> parse_html_length(DOM::Document const& document, StringView const& string)
 {
     auto integer = string.to_int();

+ 10 - 0
Userland/Libraries/LibWeb/CSS/Parser/Parser.h

@@ -12,6 +12,7 @@
 #include <AK/RefPtr.h>
 #include <AK/Result.h>
 #include <AK/Vector.h>
+#include <LibWeb/CSS/MediaQuery.h>
 #include <LibWeb/CSS/Parser/DeclarationOrAtRule.h>
 #include <LibWeb/CSS/Parser/StyleBlockRule.h>
 #include <LibWeb/CSS/Parser/StyleComponentValueRule.h>
@@ -97,6 +98,9 @@ public:
     Optional<SelectorList> parse_as_selector();
     Optional<SelectorList> parse_as_relative_selector();
 
+    NonnullRefPtrVector<MediaQuery> parse_as_media_query_list();
+    RefPtr<MediaQuery> parse_as_media_query();
+
     RefPtr<StyleValue> parse_as_css_value(PropertyID);
 
 private:
@@ -130,6 +134,8 @@ private:
     Result<SelectorList, ParsingResult> parse_a_selector_list(TokenStream<T>&);
     template<typename T>
     Result<SelectorList, ParsingResult> parse_a_relative_selector_list(TokenStream<T>&);
+    template<typename T>
+    NonnullRefPtrVector<MediaQuery> parse_a_media_query_list(TokenStream<T>&);
 
     Optional<Selector::SimpleSelector::ANPlusBPattern> parse_a_n_plus_b_pattern(TokenStream<StyleComponentValueRule>&);
 
@@ -218,6 +224,8 @@ private:
     Optional<Selector::Combinator> parse_selector_combinator(TokenStream<StyleComponentValueRule>&);
     Result<Selector::SimpleSelector, ParsingResult> parse_simple_selector(TokenStream<StyleComponentValueRule>&);
 
+    static NonnullRefPtr<MediaQuery> parse_media_query(TokenStream<StyleComponentValueRule>&);
+
     static bool has_ignored_vendor_prefix(StringView const&);
 
     ParsingContext m_context;
@@ -236,6 +244,8 @@ RefPtr<CSS::PropertyOwningCSSStyleDeclaration> parse_css_declaration(CSS::Parsin
 RefPtr<CSS::StyleValue> parse_css_value(CSS::ParsingContext const&, StringView const&, CSS::PropertyID property_id = CSS::PropertyID::Invalid);
 Optional<CSS::SelectorList> parse_selector(CSS::ParsingContext const&, StringView const&);
 RefPtr<CSS::CSSRule> parse_css_rule(CSS::ParsingContext const&, StringView);
+RefPtr<CSS::MediaQuery> parse_media_query(CSS::ParsingContext const&, StringView const&);
+NonnullRefPtrVector<CSS::MediaQuery> parse_media_query_list(CSS::ParsingContext const&, StringView const&);
 
 RefPtr<CSS::StyleValue> parse_html_length(DOM::Document const&, StringView const&);