/* * Copyright (c) 2020-2021, the SerenityOS developers. * Copyright (c) 2021, Sam Atkins * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Web::CSS { class CSSStyleSheet; class CSSRule; class CSSStyleRule; struct StyleProperty; enum class PropertyID; class ParsingContext { public: ParsingContext(); explicit ParsingContext(DOM::Document&); explicit ParsingContext(DOM::ParentNode&); bool in_quirks_mode() const; DOM::Document* document() const { return m_document; } URL complete_url(String const&) const; private: DOM::Document* m_document { nullptr }; }; template class TokenStream { public: explicit TokenStream(Vector const&); ~TokenStream(); bool has_next_token(); T const& next_token(); T const& peek_token(int offset = 0); T const& current_token(); void reconsume_current_input_token(); void skip_whitespace(); void dump_all_tokens(); private: Vector const& m_tokens; int m_iterator_offset { -1 }; T make_eof(); T m_eof; }; class Parser { public: Parser(ParsingContext const&, StringView const& input, String const& encoding = "utf-8"); ~Parser(); // The normal parser entry point, for parsing stylesheets. NonnullRefPtr parse_as_stylesheet(); // For the content of at-rules such as @media. It differs from "Parse a stylesheet" in the handling of and . NonnullRefPtrVector parse_as_list_of_rules(); // For use by the CSSStyleSheet#insertRule method, and similar functions which might exist, which parse text into a single rule. RefPtr parse_as_rule(); // Used in @supports conditions. [CSS3-CONDITIONAL] Optional parse_as_declaration(); // For the contents of a style attribute, which parses text into the contents of a single style rule. RefPtr parse_as_list_of_declarations(); // For things that need to consume a single value, like the parsing rules for attr(). Optional parse_as_component_value(); // For the contents of presentational attributes, which parse text into a single declaration’s value, or for parsing a stand-alone selector [SELECT] or list of Media Queries [MEDIAQ], as in Selectors API or the media HTML attribute. Vector parse_as_list_of_component_values(); Vector> parse_as_comma_separated_list_of_component_values(); // Contrary to the name, these parse a comma-separated list of selectors, according to the spec. Optional parse_as_selector(); Optional parse_as_relative_selector(); RefPtr parse_as_css_value(PropertyID); // FIXME: These want to be private, but StyleResolver still uses them for now. RefPtr parse_css_value(PropertyID, TokenStream&); static RefPtr parse_css_value(ParsingContext const&, PropertyID, StyleComponentValueRule const&); private: template NonnullRefPtr parse_a_stylesheet(TokenStream&); template NonnullRefPtrVector parse_a_list_of_rules(TokenStream&); template RefPtr parse_a_rule(TokenStream&); template Optional parse_a_declaration(TokenStream&); template RefPtr parse_a_list_of_declarations(TokenStream&); template Optional parse_a_component_value(TokenStream&); template Vector parse_a_list_of_component_values(TokenStream&); template Vector> parse_a_comma_separated_list_of_component_values(TokenStream&); template Optional parse_a_selector(TokenStream&); template Optional parse_a_relative_selector(TokenStream&); template Optional parse_a_selector_list(TokenStream&); template Optional parse_a_relative_selector_list(TokenStream&); Optional parse_a_n_plus_b_pattern(TokenStream&); [[nodiscard]] NonnullRefPtrVector consume_a_list_of_rules(bool top_level); template [[nodiscard]] NonnullRefPtrVector consume_a_list_of_rules(TokenStream&, bool top_level); [[nodiscard]] NonnullRefPtr consume_an_at_rule(); template [[nodiscard]] NonnullRefPtr consume_an_at_rule(TokenStream&); [[nodiscard]] RefPtr consume_a_qualified_rule(); template [[nodiscard]] RefPtr consume_a_qualified_rule(TokenStream&); [[nodiscard]] Vector consume_a_list_of_declarations(); template [[nodiscard]] Vector consume_a_list_of_declarations(TokenStream&); [[nodiscard]] Optional consume_a_declaration(); template [[nodiscard]] Optional consume_a_declaration(TokenStream&); [[nodiscard]] StyleComponentValueRule consume_a_component_value(); template [[nodiscard]] StyleComponentValueRule consume_a_component_value(TokenStream&); [[nodiscard]] NonnullRefPtr consume_a_simple_block(); template [[nodiscard]] NonnullRefPtr consume_a_simple_block(TokenStream&); [[nodiscard]] NonnullRefPtr consume_a_function(); template [[nodiscard]] NonnullRefPtr consume_a_function(TokenStream&); [[nodiscard]] RefPtr convert_to_rule(NonnullRefPtr); [[nodiscard]] RefPtr convert_to_declaration(NonnullRefPtr); [[nodiscard]] Optional convert_to_style_property(StyleDeclarationRule&); static Optional try_parse_float(StringView string); static Optional parse_color(ParsingContext const&, StyleComponentValueRule const&); static Optional parse_length(ParsingContext const&, StyleComponentValueRule const&); static Optional parse_url_function(ParsingContext const&, StyleComponentValueRule const&); static RefPtr parse_builtin_or_dynamic_value(ParsingContext const&, StyleComponentValueRule const&); static RefPtr parse_length_value(ParsingContext const&, StyleComponentValueRule const&); static RefPtr parse_numeric_value(ParsingContext const&, StyleComponentValueRule const&); static RefPtr parse_identifier_value(ParsingContext const&, StyleComponentValueRule const&); static RefPtr parse_color_value(ParsingContext const&, StyleComponentValueRule const&); static RefPtr parse_string_value(ParsingContext const&, StyleComponentValueRule const&); static RefPtr parse_image_value(ParsingContext const&, StyleComponentValueRule const&); static RefPtr parse_background_value(ParsingContext const&, Vector const&); static RefPtr parse_box_shadow_value(ParsingContext const&, Vector const&); static RefPtr parse_font_value(ParsingContext const&, Vector const&); static RefPtr parse_list_style_value(ParsingContext const&, Vector const&); // calc() parsing, according to https://www.w3.org/TR/css-values-3/#calc-syntax static OwnPtr parse_calc_sum(ParsingContext const&, TokenStream&); static OwnPtr parse_calc_product(ParsingContext const&, TokenStream&); static Optional parse_calc_value(ParsingContext const&, TokenStream&); static OwnPtr parse_calc_number_sum(ParsingContext const&, TokenStream&); static OwnPtr parse_calc_number_product(ParsingContext const&, TokenStream&); static Optional parse_calc_number_value(ParsingContext const&, TokenStream&); static OwnPtr parse_calc_product_part_with_operator(ParsingContext const&, TokenStream&); static OwnPtr parse_calc_sum_part_with_operator(ParsingContext const&, TokenStream&); static OwnPtr parse_calc_number_product_part_with_operator(ParsingContext const&, TokenStream& tokens); static OwnPtr parse_calc_number_sum_part_with_operator(ParsingContext const&, TokenStream&); static OwnPtr parse_calc_expression(ParsingContext const&, Vector const&); enum class SelectorParsingResult { Done, SyntaxError, }; RefPtr parse_complex_selector(TokenStream&, bool allow_starting_combinator); Result parse_compound_selector(TokenStream&); Optional parse_selector_combinator(TokenStream&); Result parse_simple_selector(TokenStream&); ParsingContext m_context; Tokenizer m_tokenizer; Vector m_tokens; TokenStream m_token_stream; }; } namespace Web { RefPtr parse_css(CSS::ParsingContext const&, StringView const&); RefPtr parse_css_declaration(CSS::ParsingContext const&, StringView const&); 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_html_length(DOM::Document const&, StringView const&); }