From ebad94658a91cf1774eea491ed8fabad37687f15 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Thu, 7 Dec 2023 12:35:03 +0000 Subject: [PATCH] LibWeb: Parse display property using TokenStream --- .../Libraries/LibWeb/CSS/Parser/Parser.cpp | 35 ++++++++++++------- Userland/Libraries/LibWeb/CSS/Parser/Parser.h | 2 +- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 8f862bd947..f67b983ba4 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -3499,15 +3499,19 @@ RefPtr Parser::parse_content_value(TokenStream& toke } // https://www.w3.org/TR/css-display-3/#the-display-properties -RefPtr Parser::parse_display_value(Vector const& component_values) +RefPtr Parser::parse_display_value(TokenStream& tokens) { - auto parse_single_component_display = [&](Vector const& component_values) -> Optional { - if (auto identifier_value = parse_identifier_value(component_values.first())) { + auto parse_single_component_display = [this](TokenStream& tokens) -> Optional { + auto transaction = tokens.begin_transaction(); + if (auto identifier_value = parse_identifier_value(tokens.next_token())) { auto identifier = identifier_value->to_identifier(); - if (identifier == ValueID::ListItem) + if (identifier == ValueID::ListItem) { + transaction.commit(); return Display::from_short(Display::Short::ListItem); + } if (auto display_outside = value_id_to_display_outside(identifier); display_outside.has_value()) { + transaction.commit(); switch (display_outside.value()) { case DisplayOutside::Block: return Display::from_short(Display::Short::Block); @@ -3519,6 +3523,7 @@ RefPtr Parser::parse_display_value(Vector const& com } if (auto display_inside = value_id_to_display_inside(identifier); display_inside.has_value()) { + transaction.commit(); switch (display_inside.value()) { case DisplayInside::Flow: return Display::from_short(Display::Short::Flow); @@ -3538,10 +3543,12 @@ RefPtr Parser::parse_display_value(Vector const& com } if (auto display_internal = value_id_to_display_internal(identifier); display_internal.has_value()) { + transaction.commit(); return Display { display_internal.value() }; } if (auto display_box = value_id_to_display_box(identifier); display_box.has_value()) { + transaction.commit(); switch (display_box.value()) { case DisplayBox::Contents: return Display::from_short(Display::Short::Contents); @@ -3551,6 +3558,7 @@ RefPtr Parser::parse_display_value(Vector const& com } if (auto display_legacy = value_id_to_display_legacy(identifier); display_legacy.has_value()) { + transaction.commit(); switch (display_legacy.value()) { case DisplayLegacy::InlineBlock: return Display::from_short(Display::Short::InlineBlock); @@ -3566,13 +3574,15 @@ RefPtr Parser::parse_display_value(Vector const& com return OptionalNone {}; }; - auto parse_multi_component_display = [&](Vector const& component_values) -> Optional { + auto parse_multi_component_display = [this](TokenStream& tokens) -> Optional { auto list_item = Display::ListItem::No; Optional inside; Optional outside; - for (size_t i = 0; i < component_values.size(); ++i) { - if (auto value = parse_identifier_value(component_values[i])) { + auto transaction = tokens.begin_transaction(); + while (tokens.has_next_token()) { + auto& token = tokens.next_token(); + if (auto value = parse_identifier_value(token)) { auto identifier = value->to_identifier(); if (identifier == ValueID::ListItem) { if (list_item == Display::ListItem::Yes) @@ -3595,7 +3605,7 @@ RefPtr Parser::parse_display_value(Vector const& com } // Not a display value, abort. - dbgln_if(CSS_PARSER_DEBUG, "Unrecognized display value: `{}`", component_values[i].to_string()); + dbgln_if(CSS_PARSER_DEBUG, "Unrecognized display value: `{}`", token.to_string()); return {}; } @@ -3604,14 +3614,15 @@ RefPtr Parser::parse_display_value(Vector const& com if (list_item == Display::ListItem::Yes && inside.has_value() && inside != DisplayInside::Flow && inside != DisplayInside::FlowRoot) return {}; + transaction.commit(); return Display { outside.value_or(DisplayOutside::Block), inside.value_or(DisplayInside::Flow), list_item }; }; Optional display; - if (component_values.size() == 1) - display = parse_single_component_display(component_values); + if (tokens.remaining_token_count() == 1) + display = parse_single_component_display(tokens); else - display = parse_multi_component_display(component_values); + display = parse_multi_component_display(tokens); if (display.has_value()) return DisplayStyleValue::create(display.value()); @@ -5777,7 +5788,7 @@ Parser::ParseErrorOr> Parser::parse_css_value(Property return parsed_value.release_nonnull(); return ParseError::SyntaxError; case PropertyID::Display: - if (auto parsed_value = parse_display_value(component_values)) + if (auto parsed_value = parse_display_value(tokens); parsed_value && !tokens.has_next_token()) return parsed_value.release_nonnull(); return ParseError::SyntaxError; case PropertyID::Flex: diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index 925421f5ba..22fb1b3504 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -234,7 +234,7 @@ private: RefPtr parse_border_radius_value(TokenStream&); RefPtr parse_border_radius_shorthand_value(TokenStream&); RefPtr parse_content_value(TokenStream&); - RefPtr parse_display_value(Vector const&); + RefPtr parse_display_value(TokenStream&); RefPtr parse_flex_value(Vector const&); RefPtr parse_flex_flow_value(Vector const&); RefPtr parse_font_value(Vector const&);