diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 52193d3b44..f6beda5ad6 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -632,6 +632,47 @@ Result Parser::parse_simple_sel return ParsingResult::SyntaxError; } +NonnullRefPtrVector Parser::parse_as_media_query_list() +{ + return parse_a_media_query_list(m_token_stream); +} + +template +NonnullRefPtrVector Parser::parse_a_media_query_list(TokenStream& 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 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 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 Parser::parse_media_query(TokenStream&) +{ + // "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 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 parse_selector(CSS::ParsingContext const& context, S return parser.parse_as_selector(); } +RefPtr parse_media_query(CSS::ParsingContext const& context, StringView const& string) +{ + CSS::Parser parser(context, string); + return parser.parse_as_media_query(); +} + +NonnullRefPtrVector parse_media_query_list(CSS::ParsingContext const& context, StringView const& string) +{ + CSS::Parser parser(context, string); + return parser.parse_as_media_query_list(); +} + RefPtr parse_html_length(DOM::Document const& document, StringView const& string) { auto integer = string.to_int(); diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index 0e5823caa6..fabe517920 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -97,6 +98,9 @@ public: Optional parse_as_selector(); Optional parse_as_relative_selector(); + NonnullRefPtrVector parse_as_media_query_list(); + RefPtr parse_as_media_query(); + RefPtr parse_as_css_value(PropertyID); private: @@ -130,6 +134,8 @@ private: Result parse_a_selector_list(TokenStream&); template Result parse_a_relative_selector_list(TokenStream&); + template + NonnullRefPtrVector parse_a_media_query_list(TokenStream&); Optional parse_a_n_plus_b_pattern(TokenStream&); @@ -218,6 +224,8 @@ private: Optional parse_selector_combinator(TokenStream&); Result parse_simple_selector(TokenStream&); + static NonnullRefPtr parse_media_query(TokenStream&); + static bool has_ignored_vendor_prefix(StringView const&); ParsingContext m_context; @@ -236,6 +244,8 @@ RefPtr parse_css_declaration(CSS::Parsin RefPtr parse_css_value(CSS::ParsingContext const&, StringView const&, CSS::PropertyID property_id = CSS::PropertyID::Invalid); Optional parse_selector(CSS::ParsingContext const&, StringView const&); RefPtr parse_css_rule(CSS::ParsingContext const&, StringView); +RefPtr parse_media_query(CSS::ParsingContext const&, StringView const&); +NonnullRefPtrVector parse_media_query_list(CSS::ParsingContext const&, StringView const&); RefPtr parse_html_length(DOM::Document const&, StringView const&);