diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 9f4e511708..77b77e5eba 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -2345,6 +2345,42 @@ RefPtr Parser::parse_image_value(StyleComponentValueRule const& comp return {}; } +template +RefPtr Parser::parse_comma_separated_value_list(Vector const& component_values, ParseFunction parse_one_value) +{ + auto tokens = TokenStream { component_values }; + auto first = parse_one_value(tokens); + if (!first || !tokens.has_next_token()) + return first; + + NonnullRefPtrVector values; + values.append(first.release_nonnull()); + + while (tokens.has_next_token()) { + if (!tokens.next_token().is(Token::Type::Comma)) + return {}; + + if (auto maybe_value = parse_one_value(tokens)) { + values.append(maybe_value.release_nonnull()); + continue; + } + return {}; + } + + return StyleValueList::create(move(values)); +} + +RefPtr Parser::parse_simple_comma_separated_value_list(Vector const& component_values) +{ + return parse_comma_separated_value_list(component_values, [=, this](auto& tokens) -> RefPtr { + auto& token = tokens.next_token(); + if (auto value = parse_css_value(token); value && property_accepts_value(m_context.current_property_id(), *value)) + return value; + tokens.reconsume_current_input_token(); + return nullptr; + }); +} + RefPtr Parser::parse_background_value(Vector const& component_values) { RefPtr background_color; @@ -2473,23 +2509,6 @@ RefPtr Parser::parse_background_value(Vector Parser::parse_background_image_value(Vector const& component_values) -{ - if (component_values.size() == 1) { - auto maybe_value = parse_css_value(component_values.first()); - if (!maybe_value) - return nullptr; - auto value = maybe_value.release_nonnull(); - if (property_accepts_value(PropertyID::BackgroundImage, *value)) - return value; - return nullptr; - } - - // FIXME: Handle multiple sets of comma-separated values. - dbgln("CSS Parser does not yet support multiple comma-separated values for background-image."); - return nullptr; -} - RefPtr Parser::parse_single_background_position_value(TokenStream& tokens) { // NOTE: This *looks* like it parses a , but it doesn't. From the spec: @@ -2652,13 +2671,6 @@ RefPtr Parser::parse_single_background_position_value(TokenStreamedge, vertical->offset); } -RefPtr Parser::parse_background_position_value(Vector const& component_values) -{ - auto tokens = TokenStream { component_values }; - // FIXME: Handle multiple sets of comma-separated values. - return parse_single_background_position_value(tokens); -} - RefPtr Parser::parse_single_background_repeat_value(TokenStream& tokens) { auto start_position = tokens.position(); @@ -2714,13 +2726,6 @@ RefPtr Parser::parse_single_background_repeat_value(TokenStreamto_identifier()), as_repeat(y_value->to_identifier())); } -RefPtr Parser::parse_background_repeat_value(Vector const& component_values) -{ - auto tokens = TokenStream { component_values }; - // FIXME: Handle multiple sets of comma-separated values. - return parse_single_background_repeat_value(tokens); -} - RefPtr Parser::parse_single_background_size_value(TokenStream& tokens) { auto start_position = tokens.position(); @@ -2749,13 +2754,6 @@ RefPtr Parser::parse_single_background_size_value(TokenStream Parser::parse_background_size_value(Vector const& component_values) -{ - auto tokens = TokenStream { component_values }; - // FIXME: Handle multiple sets of comma-separated values. - return parse_single_background_size_value(tokens); -} - RefPtr Parser::parse_border_value(Vector const& component_values) { if (component_values.size() > 3) @@ -3472,20 +3470,23 @@ Result, Parser::ParsingResult> Parser::parse_css_value if (auto parsed_value = parse_background_value(component_values)) return parsed_value.release_nonnull(); return ParsingResult::SyntaxError; + case PropertyID::BackgroundAttachment: + case PropertyID::BackgroundClip: case PropertyID::BackgroundImage: - if (auto parsed_value = parse_background_image_value(component_values)) + case PropertyID::BackgroundOrigin: + if (auto parsed_value = parse_simple_comma_separated_value_list(component_values)) return parsed_value.release_nonnull(); return ParsingResult::SyntaxError; case PropertyID::BackgroundPosition: - if (auto parsed_value = parse_background_position_value(component_values)) + if (auto parsed_value = parse_comma_separated_value_list(component_values, [this](auto& tokens) { return parse_single_background_position_value(tokens); })) return parsed_value.release_nonnull(); return ParsingResult::SyntaxError; case PropertyID::BackgroundRepeat: - if (auto parsed_value = parse_background_repeat_value(component_values)) + if (auto parsed_value = parse_comma_separated_value_list(component_values, [this](auto& tokens) { return parse_single_background_repeat_value(tokens); })) return parsed_value.release_nonnull(); return ParsingResult::SyntaxError; case PropertyID::BackgroundSize: - if (auto parsed_value = parse_background_size_value(component_values)) + if (auto parsed_value = parse_comma_separated_value_list(component_values, [this](auto& tokens) { return parse_single_background_size_value(tokens); })) return parsed_value.release_nonnull(); return ParsingResult::SyntaxError; case PropertyID::Border: diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index 1d2225f601..578b2e56ac 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -198,14 +198,14 @@ private: RefPtr parse_color_value(StyleComponentValueRule const&); RefPtr parse_string_value(StyleComponentValueRule const&); RefPtr parse_image_value(StyleComponentValueRule const&); + template + RefPtr parse_comma_separated_value_list(Vector const&, ParseFunction); + RefPtr parse_simple_comma_separated_value_list(Vector const&); + RefPtr parse_background_value(Vector const&); - RefPtr parse_background_image_value(Vector const&); RefPtr parse_single_background_position_value(TokenStream&); - RefPtr parse_background_position_value(Vector const&); RefPtr parse_single_background_repeat_value(TokenStream&); - RefPtr parse_background_repeat_value(Vector const&); RefPtr parse_single_background_size_value(TokenStream&); - RefPtr parse_background_size_value(Vector const&); RefPtr parse_border_value(Vector const&); RefPtr parse_border_radius_value(Vector const&); RefPtr parse_border_radius_shorthand_value(Vector const&);