diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index fec89e8252..7dce78e7a4 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -181,7 +181,7 @@ NonnullRefPtr Parser::parse_a_stylesheet(TokenStream& tokens) Optional Parser::parse_as_selector(SelectorParsingMode parsing_mode) { - auto selector_list = parse_a_selector_list(m_token_stream, parsing_mode); + auto selector_list = parse_a_selector_list(m_token_stream, SelectorType::Standalone, parsing_mode); if (!selector_list.is_error()) return selector_list.release_value(); @@ -190,7 +190,7 @@ Optional Parser::parse_as_selector(SelectorParsingMode parsing_mod Optional Parser::parse_as_relative_selector(SelectorParsingMode parsing_mode) { - auto selector_list = parse_a_relative_selector_list(m_token_stream, parsing_mode); + auto selector_list = parse_a_selector_list(m_token_stream, SelectorType::Relative, parsing_mode); if (!selector_list.is_error()) return selector_list.release_value(); @@ -198,14 +198,14 @@ Optional Parser::parse_as_relative_selector(SelectorParsingMode pa } template -Result Parser::parse_a_selector_list(TokenStream& tokens, SelectorParsingMode parsing_mode) +Result Parser::parse_a_selector_list(TokenStream& tokens, SelectorType mode, SelectorParsingMode parsing_mode) { auto comma_separated_lists = parse_a_comma_separated_list_of_component_values(tokens); NonnullRefPtrVector selectors; for (auto& selector_parts : comma_separated_lists) { auto stream = TokenStream(selector_parts); - auto selector = parse_complex_selector(stream, false); + auto selector = parse_complex_selector(stream, mode); if (selector.is_error()) { if (parsing_mode == SelectorParsingMode::Forgiving) continue; @@ -220,37 +220,14 @@ Result Parser::parse_a_selector_list(TokenS return selectors; } -template -Result Parser::parse_a_relative_selector_list(TokenStream& tokens, SelectorParsingMode parsing_mode) -{ - auto comma_separated_lists = parse_a_comma_separated_list_of_component_values(tokens); - - NonnullRefPtrVector selectors; - for (auto& selector_parts : comma_separated_lists) { - auto stream = TokenStream(selector_parts); - auto selector = parse_complex_selector(stream, true); - if (selector.is_error()) { - if (parsing_mode == SelectorParsingMode::Forgiving) - continue; - return selector.error(); - } - selectors.append(selector.release_value()); - } - - if (selectors.is_empty() && parsing_mode != SelectorParsingMode::Forgiving) - return ParsingResult::SyntaxError; - - return selectors; -} - -Result, Parser::ParsingResult> Parser::parse_complex_selector(TokenStream& tokens, bool allow_starting_combinator) +Result, Parser::ParsingResult> Parser::parse_complex_selector(TokenStream& tokens, SelectorType mode) { Vector compound_selectors; auto first_selector = parse_compound_selector(tokens); if (first_selector.is_error()) return first_selector.error(); - if (!allow_starting_combinator) { + if (mode == SelectorType::Standalone) { if (first_selector.value().combinator != Selector::Combinator::Descendant) return ParsingResult::SyntaxError; first_selector.value().combinator = Selector::Combinator::None; @@ -593,7 +570,7 @@ Result Parser::parse_simple_sel return false; function_values.skip_whitespace(); - auto selector_list = parse_a_selector_list(function_values); + auto selector_list = parse_a_selector_list(function_values, SelectorType::Standalone); if (selector_list.is_error()) return false; @@ -613,14 +590,14 @@ Result Parser::parse_simple_sel ? Selector::SimpleSelector::PseudoClass::Type::Is : Selector::SimpleSelector::PseudoClass::Type::Where; auto function_token_stream = TokenStream(pseudo_function.values()); - auto argument_selector_list = parse_a_selector_list(function_token_stream, SelectorParsingMode::Forgiving); + auto argument_selector_list = parse_a_selector_list(function_token_stream, SelectorType::Standalone, SelectorParsingMode::Forgiving); // NOTE: Because it's forgiving, even complete garbage will parse OK as an empty selector-list. VERIFY(!argument_selector_list.is_error()); simple_selector.pseudo_class.argument_selector_list = argument_selector_list.release_value(); } else if (pseudo_function.name().equals_ignoring_case("not"sv)) { simple_selector.pseudo_class.type = Selector::SimpleSelector::PseudoClass::Type::Not; auto function_token_stream = TokenStream(pseudo_function.values()); - auto not_selector = parse_a_selector_list(function_token_stream); + auto not_selector = parse_a_selector_list(function_token_stream, SelectorType::Standalone); if (not_selector.is_error()) { dbgln_if(CSS_PARSER_DEBUG, "Invalid selector in :not() clause"); return ParsingResult::SyntaxError; @@ -2114,7 +2091,7 @@ RefPtr Parser::convert_to_rule(NonnullRefPtr rule) } else { auto prelude_stream = TokenStream(rule->m_prelude); - auto selectors = parse_a_selector_list(prelude_stream); + auto selectors = parse_a_selector_list(prelude_stream, SelectorType::Standalone); if (selectors.is_error()) { if (selectors.error() != ParsingResult::IncludesIgnoredVendorPrefix) { diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index 12e5fd0f8c..5bde43a289 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -148,10 +148,14 @@ private: Vector parse_a_list_of_component_values(TokenStream&); template Vector> parse_a_comma_separated_list_of_component_values(TokenStream&); + + enum class SelectorType { + Standalone, + Relative + }; template - Result parse_a_selector_list(TokenStream&, SelectorParsingMode = SelectorParsingMode::Standard); - template - Result parse_a_relative_selector_list(TokenStream&, SelectorParsingMode = SelectorParsingMode::Standard); + Result parse_a_selector_list(TokenStream&, SelectorType, SelectorParsingMode = SelectorParsingMode::Standard); + template NonnullRefPtrVector parse_a_media_query_list(TokenStream&); template @@ -308,7 +312,7 @@ private: OwnPtr parse_calc_number_sum_part_with_operator(TokenStream&); OwnPtr parse_calc_expression(Vector const&); - Result, ParsingResult> parse_complex_selector(TokenStream&, bool allow_starting_combinator); + Result, ParsingResult> parse_complex_selector(TokenStream&, SelectorType); Result parse_compound_selector(TokenStream&); Optional parse_selector_combinator(TokenStream&); Result parse_simple_selector(TokenStream&);