diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 238eff596e..5dd5a1fee6 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -1347,8 +1347,8 @@ RefPtr Parser::parse_a_supports(TokenStream& tokens) OwnPtr Parser::parse_supports_condition(TokenStream& tokens) { + auto transaction = tokens.begin_transaction(); tokens.skip_whitespace(); - auto start_position = tokens.position(); auto& peeked_token = tokens.peek_token(); // `not ` @@ -1356,15 +1356,14 @@ OwnPtr Parser::parse_supports_condition(TokenStreamtype = Supports::Condition::Type::Not; - condition->children.append(child.release_value()); - return adopt_own(*condition); - } + if (!child.has_value()) + return {}; - tokens.rewind_to_position(start_position); - return {}; + transaction.commit(); + auto condition = make(); + condition->type = Supports::Condition::Type::Not; + condition->children.append(child.release_value()); + return condition; } // ` [ and ]* @@ -1382,20 +1381,16 @@ OwnPtr Parser::parse_supports_condition(TokenStream Parser::parse_supports_condition(TokenStreamtype = condition_type.value_or(Supports::Condition::Type::Or); - condition->children = move(children); - return adopt_own(*condition); - } + if (children.is_empty()) + return {}; - tokens.rewind_to_position(start_position); - return {}; + transaction.commit(); + auto condition = make(); + condition->type = condition_type.value_or(Supports::Condition::Type::Or); + condition->children = move(children); + return condition; } Optional Parser::parse_supports_in_parens(TokenStream& tokens) { - tokens.skip_whitespace(); - auto start_position = tokens.position(); - - auto& first_token = tokens.peek_token(); // `( )` + auto& first_token = tokens.peek_token(); if (first_token.is_block() && first_token.block().is_paren()) { + auto transaction = tokens.begin_transaction(); tokens.next_token(); tokens.skip_whitespace(); TokenStream child_tokens { first_token.block().values() }; if (auto condition = parse_supports_condition(child_tokens)) { - if (child_tokens.has_next_token()) { - tokens.rewind_to_position(start_position); + if (child_tokens.has_next_token()) return {}; - } + transaction.commit(); return Supports::InParens { .value = { condition.release_nonnull() } }; } - - tokens.rewind_to_position(start_position); } // `` @@ -1461,58 +1449,61 @@ Optional Parser::parse_supports_in_parens(TokenStream Parser::parse_supports_feature(TokenStream& tokens) { + auto transaction = tokens.begin_transaction(); tokens.skip_whitespace(); - auto start_position = tokens.position(); - auto& first_token = tokens.next_token(); + // `` if (first_token.is_block() && first_token.block().is_paren()) { TokenStream block_tokens { first_token.block().values() }; // FIXME: Parsing and then converting back to a string is weird. if (auto declaration = consume_a_declaration(block_tokens); declaration.has_value()) { + transaction.commit(); return Supports::Feature { Supports::Declaration { declaration->to_string() } }; } } + // `` if (first_token.is_function() && first_token.function().name().equals_ignoring_case("selector"sv)) { // FIXME: Parsing and then converting back to a string is weird. StringBuilder builder; for (auto const& item : first_token.function().values()) builder.append(item.to_string()); + transaction.commit(); return Supports::Feature { Supports::Selector { builder.to_string() } }; } - tokens.rewind_to_position(start_position); return {}; } // https://www.w3.org/TR/mediaqueries-4/#typedef-general-enclosed Optional Parser::parse_general_enclosed(TokenStream& tokens) { + auto transaction = tokens.begin_transaction(); tokens.skip_whitespace(); - auto start_position = tokens.position(); - auto& first_token = tokens.next_token(); // `[ ? ) ]` - if (first_token.is_function()) + if (first_token.is_function()) { + transaction.commit(); return GeneralEnclosed { first_token.to_string() }; + } // `( ? )` - if (first_token.is_block() && first_token.block().is_paren()) + if (first_token.is_block() && first_token.block().is_paren()) { + transaction.commit(); return GeneralEnclosed { first_token.to_string() }; + } - tokens.rewind_to_position(start_position); return {}; }