diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 77b77e5eba0..a009ed42c72 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -2383,7 +2383,16 @@ RefPtr Parser::parse_simple_comma_separated_value_list(Vector Parser::parse_background_value(Vector const& component_values) { + NonnullRefPtrVector background_images; + NonnullRefPtrVector background_positions; + NonnullRefPtrVector background_sizes; + NonnullRefPtrVector background_repeats; + NonnullRefPtrVector background_attachments; + NonnullRefPtrVector background_clips; + NonnullRefPtrVector background_origins; RefPtr background_color; + + // Per-layer values RefPtr background_image; RefPtr background_position; RefPtr background_size; @@ -2392,14 +2401,54 @@ RefPtr Parser::parse_background_value(Vector background_clip; RefPtr background_origin; + bool has_multiple_layers = false; + + auto background_layer_is_valid = [&](bool allow_background_color) -> bool { + if (allow_background_color) { + if (background_color) + return true; + } else { + if (background_color) + return false; + } + return background_image || background_position || background_size || background_repeat || background_attachment || background_clip || background_origin; + }; + + auto complete_background_layer = [&]() { + background_images.append(background_image ? background_image.release_nonnull() : property_initial_value(PropertyID::BackgroundImage)); + background_positions.append(background_position ? background_position.release_nonnull() : property_initial_value(PropertyID::BackgroundPosition)); + background_sizes.append(background_size ? background_size.release_nonnull() : property_initial_value(PropertyID::BackgroundSize)); + background_repeats.append(background_repeat ? background_repeat.release_nonnull() : property_initial_value(PropertyID::BackgroundRepeat)); + background_attachments.append(background_attachment ? background_attachment.release_nonnull() : property_initial_value(PropertyID::BackgroundAttachment)); + + if (!background_origin && !background_clip) { + background_origin = property_initial_value(PropertyID::BackgroundOrigin); + background_clip = property_initial_value(PropertyID::BackgroundClip); + } else if (!background_clip) { + background_clip = background_origin; + } + background_origins.append(background_origin.release_nonnull()); + background_clips.append(background_clip.release_nonnull()); + + background_image = nullptr; + background_position = nullptr; + background_size = nullptr; + background_repeat = nullptr; + background_attachment = nullptr; + background_clip = nullptr; + background_origin = nullptr; + }; + auto tokens = TokenStream { component_values }; while (tokens.has_next_token()) { auto& part = tokens.next_token(); - // FIXME: Handle multiple backgrounds, by returning a List of BackgroundStyleValues. if (part.is(Token::Type::Comma)) { - dbgln("CSS Parser does not yet support multiple comma-separated values for background."); - break; + has_multiple_layers = true; + if (!background_layer_is_valid(false)) + return nullptr; + complete_background_layer(); + continue; } auto value = parse_css_value(part); @@ -2478,6 +2527,27 @@ RefPtr Parser::parse_background_value(Vector