/* * 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 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(); 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(); template NonnullRefPtr parse_as_stylesheet(TokenStream&); // 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(); template NonnullRefPtrVector parse_as_list_of_rules(TokenStream&); // For use by the CSSStyleSheet#insertRule method, and similar functions which might exist, which parse text into a single rule. RefPtr parse_as_rule(); template RefPtr parse_as_rule(TokenStream&); // Used in @supports conditions. [CSS3-CONDITIONAL] Optional parse_as_declaration(); template Optional parse_as_declaration(TokenStream&); // For the contents of a style attribute, which parses text into the contents of a single style rule. RefPtr parse_as_list_of_declarations(); template RefPtr parse_as_list_of_declarations(TokenStream&); // For things that need to consume a single value, like the parsing rules for attr(). Optional parse_as_component_value(); template Optional parse_as_component_value(TokenStream&); // 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(); template Vector parse_as_list_of_component_values(TokenStream&); Vector> parse_as_comma_separated_list_of_component_values(); template Vector> parse_as_comma_separated_list_of_component_values(TokenStream&); template RefPtr parse_single_selector(TokenStream&, bool is_relative = false); Optional parse_nth_child_pattern(TokenStream&); // FIXME: https://www.w3.org/TR/selectors-4/ // Contrary to the name, these parse a comma-separated list of selectors, according to the spec. NonnullRefPtrVector parse_a_selector(); template NonnullRefPtrVector parse_a_selector(TokenStream&); NonnullRefPtrVector parse_a_relative_selector(); template NonnullRefPtrVector parse_a_relative_selector(TokenStream&); RefPtr parse_css_value(PropertyID, TokenStream&); static RefPtr parse_css_value(ParsingContext const&, PropertyID, StyleComponentValueRule const&); private: [[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 RefPtr parse_keyword_or_custom_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&); ParsingContext m_context; Tokenizer m_tokenizer; Vector m_tokens; TokenStream m_token_stream; }; }