Browse Source

LibWeb: Combine identical relative/regular selector parsing functions

Sam Atkins 3 years ago
parent
commit
174a25db5b

+ 10 - 33
Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp

@@ -181,7 +181,7 @@ NonnullRefPtr<CSSStyleSheet> Parser::parse_a_stylesheet(TokenStream<T>& tokens)
 
 
 Optional<SelectorList> Parser::parse_as_selector(SelectorParsingMode parsing_mode)
 Optional<SelectorList> 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())
     if (!selector_list.is_error())
         return selector_list.release_value();
         return selector_list.release_value();
 
 
@@ -190,7 +190,7 @@ Optional<SelectorList> Parser::parse_as_selector(SelectorParsingMode parsing_mod
 
 
 Optional<SelectorList> Parser::parse_as_relative_selector(SelectorParsingMode parsing_mode)
 Optional<SelectorList> 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())
     if (!selector_list.is_error())
         return selector_list.release_value();
         return selector_list.release_value();
 
 
@@ -198,14 +198,14 @@ Optional<SelectorList> Parser::parse_as_relative_selector(SelectorParsingMode pa
 }
 }
 
 
 template<typename T>
 template<typename T>
-Result<SelectorList, Parser::ParsingResult> Parser::parse_a_selector_list(TokenStream<T>& tokens, SelectorParsingMode parsing_mode)
+Result<SelectorList, Parser::ParsingResult> Parser::parse_a_selector_list(TokenStream<T>& tokens, SelectorType mode, SelectorParsingMode parsing_mode)
 {
 {
     auto comma_separated_lists = parse_a_comma_separated_list_of_component_values(tokens);
     auto comma_separated_lists = parse_a_comma_separated_list_of_component_values(tokens);
 
 
     NonnullRefPtrVector<Selector> selectors;
     NonnullRefPtrVector<Selector> selectors;
     for (auto& selector_parts : comma_separated_lists) {
     for (auto& selector_parts : comma_separated_lists) {
         auto stream = TokenStream(selector_parts);
         auto stream = TokenStream(selector_parts);
-        auto selector = parse_complex_selector(stream, false);
+        auto selector = parse_complex_selector(stream, mode);
         if (selector.is_error()) {
         if (selector.is_error()) {
             if (parsing_mode == SelectorParsingMode::Forgiving)
             if (parsing_mode == SelectorParsingMode::Forgiving)
                 continue;
                 continue;
@@ -220,37 +220,14 @@ Result<SelectorList, Parser::ParsingResult> Parser::parse_a_selector_list(TokenS
     return selectors;
     return selectors;
 }
 }
 
 
-template<typename T>
-Result<SelectorList, Parser::ParsingResult> Parser::parse_a_relative_selector_list(TokenStream<T>& tokens, SelectorParsingMode parsing_mode)
-{
-    auto comma_separated_lists = parse_a_comma_separated_list_of_component_values(tokens);
-
-    NonnullRefPtrVector<Selector> 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<NonnullRefPtr<Selector>, Parser::ParsingResult> Parser::parse_complex_selector(TokenStream<StyleComponentValueRule>& tokens, bool allow_starting_combinator)
+Result<NonnullRefPtr<Selector>, Parser::ParsingResult> Parser::parse_complex_selector(TokenStream<StyleComponentValueRule>& tokens, SelectorType mode)
 {
 {
     Vector<Selector::CompoundSelector> compound_selectors;
     Vector<Selector::CompoundSelector> compound_selectors;
 
 
     auto first_selector = parse_compound_selector(tokens);
     auto first_selector = parse_compound_selector(tokens);
     if (first_selector.is_error())
     if (first_selector.is_error())
         return first_selector.error();
         return first_selector.error();
-    if (!allow_starting_combinator) {
+    if (mode == SelectorType::Standalone) {
         if (first_selector.value().combinator != Selector::Combinator::Descendant)
         if (first_selector.value().combinator != Selector::Combinator::Descendant)
             return ParsingResult::SyntaxError;
             return ParsingResult::SyntaxError;
         first_selector.value().combinator = Selector::Combinator::None;
         first_selector.value().combinator = Selector::Combinator::None;
@@ -593,7 +570,7 @@ Result<Selector::SimpleSelector, Parser::ParsingResult> Parser::parse_simple_sel
                     return false;
                     return false;
 
 
                 function_values.skip_whitespace();
                 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())
                 if (selector_list.is_error())
                     return false;
                     return false;
 
 
@@ -613,14 +590,14 @@ Result<Selector::SimpleSelector, Parser::ParsingResult> Parser::parse_simple_sel
                     ? Selector::SimpleSelector::PseudoClass::Type::Is
                     ? Selector::SimpleSelector::PseudoClass::Type::Is
                     : Selector::SimpleSelector::PseudoClass::Type::Where;
                     : Selector::SimpleSelector::PseudoClass::Type::Where;
                 auto function_token_stream = TokenStream(pseudo_function.values());
                 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.
                 // NOTE: Because it's forgiving, even complete garbage will parse OK as an empty selector-list.
                 VERIFY(!argument_selector_list.is_error());
                 VERIFY(!argument_selector_list.is_error());
                 simple_selector.pseudo_class.argument_selector_list = argument_selector_list.release_value();
                 simple_selector.pseudo_class.argument_selector_list = argument_selector_list.release_value();
             } else if (pseudo_function.name().equals_ignoring_case("not"sv)) {
             } else if (pseudo_function.name().equals_ignoring_case("not"sv)) {
                 simple_selector.pseudo_class.type = Selector::SimpleSelector::PseudoClass::Type::Not;
                 simple_selector.pseudo_class.type = Selector::SimpleSelector::PseudoClass::Type::Not;
                 auto function_token_stream = TokenStream(pseudo_function.values());
                 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()) {
                 if (not_selector.is_error()) {
                     dbgln_if(CSS_PARSER_DEBUG, "Invalid selector in :not() clause");
                     dbgln_if(CSS_PARSER_DEBUG, "Invalid selector in :not() clause");
                     return ParsingResult::SyntaxError;
                     return ParsingResult::SyntaxError;
@@ -2114,7 +2091,7 @@ RefPtr<CSSRule> Parser::convert_to_rule(NonnullRefPtr<StyleRule> rule)
 
 
     } else {
     } else {
         auto prelude_stream = TokenStream(rule->m_prelude);
         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.is_error()) {
             if (selectors.error() != ParsingResult::IncludesIgnoredVendorPrefix) {
             if (selectors.error() != ParsingResult::IncludesIgnoredVendorPrefix) {

+ 8 - 4
Userland/Libraries/LibWeb/CSS/Parser/Parser.h

@@ -148,10 +148,14 @@ private:
     Vector<StyleComponentValueRule> parse_a_list_of_component_values(TokenStream<T>&);
     Vector<StyleComponentValueRule> parse_a_list_of_component_values(TokenStream<T>&);
     template<typename T>
     template<typename T>
     Vector<Vector<StyleComponentValueRule>> parse_a_comma_separated_list_of_component_values(TokenStream<T>&);
     Vector<Vector<StyleComponentValueRule>> parse_a_comma_separated_list_of_component_values(TokenStream<T>&);
+
+    enum class SelectorType {
+        Standalone,
+        Relative
+    };
     template<typename T>
     template<typename T>
-    Result<SelectorList, ParsingResult> parse_a_selector_list(TokenStream<T>&, SelectorParsingMode = SelectorParsingMode::Standard);
-    template<typename T>
-    Result<SelectorList, ParsingResult> parse_a_relative_selector_list(TokenStream<T>&, SelectorParsingMode = SelectorParsingMode::Standard);
+    Result<SelectorList, ParsingResult> parse_a_selector_list(TokenStream<T>&, SelectorType, SelectorParsingMode = SelectorParsingMode::Standard);
+
     template<typename T>
     template<typename T>
     NonnullRefPtrVector<MediaQuery> parse_a_media_query_list(TokenStream<T>&);
     NonnullRefPtrVector<MediaQuery> parse_a_media_query_list(TokenStream<T>&);
     template<typename T>
     template<typename T>
@@ -308,7 +312,7 @@ private:
     OwnPtr<CalculatedStyleValue::CalcNumberSumPartWithOperator> parse_calc_number_sum_part_with_operator(TokenStream<StyleComponentValueRule>&);
     OwnPtr<CalculatedStyleValue::CalcNumberSumPartWithOperator> parse_calc_number_sum_part_with_operator(TokenStream<StyleComponentValueRule>&);
     OwnPtr<CalculatedStyleValue::CalcSum> parse_calc_expression(Vector<StyleComponentValueRule> const&);
     OwnPtr<CalculatedStyleValue::CalcSum> parse_calc_expression(Vector<StyleComponentValueRule> const&);
 
 
-    Result<NonnullRefPtr<Selector>, ParsingResult> parse_complex_selector(TokenStream<StyleComponentValueRule>&, bool allow_starting_combinator);
+    Result<NonnullRefPtr<Selector>, ParsingResult> parse_complex_selector(TokenStream<StyleComponentValueRule>&, SelectorType);
     Result<Selector::CompoundSelector, ParsingResult> parse_compound_selector(TokenStream<StyleComponentValueRule>&);
     Result<Selector::CompoundSelector, ParsingResult> parse_compound_selector(TokenStream<StyleComponentValueRule>&);
     Optional<Selector::Combinator> parse_selector_combinator(TokenStream<StyleComponentValueRule>&);
     Optional<Selector::Combinator> parse_selector_combinator(TokenStream<StyleComponentValueRule>&);
     Result<Selector::SimpleSelector, ParsingResult> parse_simple_selector(TokenStream<StyleComponentValueRule>&);
     Result<Selector::SimpleSelector, ParsingResult> parse_simple_selector(TokenStream<StyleComponentValueRule>&);