diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 8f520893cb..37a95d07d4 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -2394,8 +2394,7 @@ RefPtr Parser::parse_background_value(ParsingContext const& context, { RefPtr background_color; RefPtr background_image; - RefPtr repeat_x; - RefPtr repeat_y; + RefPtr background_repeat; RefPtr background_position; // FIXME: Implement background-size. RefPtr background_attachment; @@ -2463,30 +2462,14 @@ RefPtr Parser::parse_background_value(ParsingContext const& context, return nullptr; } if (property_accepts_value(PropertyID::BackgroundRepeat, *value)) { - if (repeat_x) + if (background_repeat) return nullptr; - - auto value_id = value->to_identifier(); - if (value_id == ValueID::RepeatX || value_id == ValueID::RepeatY) { - repeat_x = IdentifierStyleValue::create(value_id == ValueID::RepeatX ? ValueID::Repeat : ValueID::NoRepeat); - repeat_y = IdentifierStyleValue::create(value_id == ValueID::RepeatX ? ValueID::NoRepeat : ValueID::Repeat); + tokens.reconsume_current_input_token(); + if (auto maybe_repeat = parse_single_background_repeat_value(context, tokens)) { + background_repeat = maybe_repeat.release_nonnull(); continue; } - - // Check following value, if it's also a repeat, set both. - if (tokens.has_next_token()) { - auto next_value = parse_css_value(context, tokens.peek_token()); - if (next_value && property_accepts_value(PropertyID::BackgroundRepeat, *next_value)) { - tokens.next_token(); - repeat_x = value.release_nonnull(); - repeat_y = next_value.release_nonnull(); - continue; - } - } - auto repeat = value.release_nonnull(); - repeat_x = repeat; - repeat_y = repeat; - continue; + return nullptr; } return nullptr; @@ -2498,10 +2481,8 @@ RefPtr Parser::parse_background_value(ParsingContext const& context, background_image = property_initial_value(PropertyID::BackgroundImage); if (!background_position) background_position = property_initial_value(PropertyID::BackgroundPosition); - if (!repeat_x) - repeat_x = property_initial_value(PropertyID::BackgroundRepeatX); - if (!repeat_y) - repeat_y = property_initial_value(PropertyID::BackgroundRepeatY); + if (!background_repeat) + background_repeat = property_initial_value(PropertyID::BackgroundRepeat); if (!background_attachment) background_attachment = property_initial_value(PropertyID::BackgroundAttachment); @@ -2516,7 +2497,7 @@ RefPtr Parser::parse_background_value(ParsingContext const& context, background_color.release_nonnull(), background_image.release_nonnull(), background_position.release_nonnull(), - repeat_x.release_nonnull(), repeat_y.release_nonnull(), + background_repeat.release_nonnull(), background_attachment.release_nonnull(), background_origin.release_nonnull(), background_clip.release_nonnull()); @@ -2708,48 +2689,51 @@ RefPtr Parser::parse_background_position_value(ParsingContext const& return parse_single_background_position_value(context, tokens); } -RefPtr Parser::parse_background_repeat_value(ParsingContext const& context, Vector const& component_values) +RefPtr Parser::parse_single_background_repeat_value(ParsingContext const& context, TokenStream& tokens) { + auto start_position = tokens.position(); + auto error = [&]() { + tokens.rewind_to_position(start_position); + return nullptr; + }; + auto is_directional_repeat = [](StyleValue const& value) -> bool { auto value_id = value.to_identifier(); return value_id == ValueID::RepeatX || value_id == ValueID::RepeatY; }; - if (component_values.size() == 1) { - auto maybe_value = parse_css_value(context, component_values.first()); - if (!maybe_value) - return nullptr; - auto value = maybe_value.release_nonnull(); - if (!property_accepts_value(PropertyID::BackgroundRepeat, *value)) - return nullptr; + auto& token = tokens.next_token(); + auto maybe_x_value = parse_css_value(context, token); + if (!maybe_x_value || !property_accepts_value(PropertyID::BackgroundRepeat, *maybe_x_value)) + return error(); + auto x_value = maybe_x_value.release_nonnull(); - if (is_directional_repeat(value)) { - auto value_id = value->to_identifier(); - return BackgroundRepeatStyleValue::create( - IdentifierStyleValue::create(value_id == ValueID::RepeatX ? ValueID::Repeat : ValueID::NoRepeat), - IdentifierStyleValue::create(value_id == ValueID::RepeatX ? ValueID::NoRepeat : ValueID::Repeat)); - } - return BackgroundRepeatStyleValue::create(value, value); + if (is_directional_repeat(*x_value)) { + auto value_id = x_value->to_identifier(); + return BackgroundRepeatStyleValue::create( + IdentifierStyleValue::create(value_id == ValueID::RepeatX ? ValueID::Repeat : ValueID::NoRepeat), + IdentifierStyleValue::create(value_id == ValueID::RepeatX ? ValueID::NoRepeat : ValueID::Repeat)); } - if (component_values.size() == 2) { - auto maybe_x_value = parse_css_value(context, component_values[0]); - auto maybe_y_value = parse_css_value(context, component_values[1]); - if (!maybe_x_value || !maybe_y_value) - return nullptr; - - auto x_value = maybe_x_value.release_nonnull(); - auto y_value = maybe_y_value.release_nonnull(); - if (!property_accepts_value(PropertyID::BackgroundRepeat, x_value) || !property_accepts_value(PropertyID::BackgroundRepeat, y_value)) - return nullptr; - if (is_directional_repeat(x_value) || is_directional_repeat(y_value)) - return nullptr; - return BackgroundRepeatStyleValue::create(x_value, y_value); + // See if we have a second value for Y + auto& second_token = tokens.peek_token(); + auto maybe_y_value = parse_css_value(context, second_token); + if (!maybe_y_value || !property_accepts_value(PropertyID::BackgroundRepeat, *maybe_y_value)) { + // We don't have a second value, so use x for both + return BackgroundRepeatStyleValue::create(x_value, x_value); } + tokens.next_token(); + auto y_value = maybe_y_value.release_nonnull(); + if (is_directional_repeat(*y_value)) + return error(); + return BackgroundRepeatStyleValue::create(x_value, y_value); +} +RefPtr Parser::parse_background_repeat_value(ParsingContext const& context, Vector const& component_values) +{ + auto tokens = TokenStream { component_values }; // FIXME: Handle multiple sets of comma-separated values. - dbgln("CSS Parser does not yet support multiple comma-separated values for background-repeat."); - return nullptr; + return parse_single_background_repeat_value(context, tokens); } RefPtr Parser::parse_border_value(ParsingContext const& context, Vector const& component_values) diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index 4adb079b73..a79f704a3d 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -216,6 +216,7 @@ private: static RefPtr parse_background_image_value(ParsingContext const&, Vector const&); static RefPtr parse_single_background_position_value(ParsingContext const&, TokenStream&); static RefPtr parse_background_position_value(ParsingContext const&, Vector const&); + static RefPtr parse_single_background_repeat_value(ParsingContext const&, TokenStream&); static RefPtr parse_background_repeat_value(ParsingContext const&, Vector const&); static RefPtr parse_border_value(ParsingContext const&, Vector const&); static RefPtr parse_border_radius_value(ParsingContext const&, Vector const&); diff --git a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp index 97f0a8cf5d..e360550acd 100644 --- a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp +++ b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp @@ -673,8 +673,7 @@ RefPtr ResolvedCSSStyleDeclaration::style_value_for_property(Layout: auto maybe_background_color = property(CSS::PropertyID::BackgroundColor); auto maybe_background_image = property(CSS::PropertyID::BackgroundImage); auto maybe_background_position = property(CSS::PropertyID::BackgroundPosition); - auto maybe_background_repeat_x = property(CSS::PropertyID::BackgroundRepeatX); - auto maybe_background_repeat_y = property(CSS::PropertyID::BackgroundRepeatY); + auto maybe_background_repeat = property(CSS::PropertyID::BackgroundRepeat); auto maybe_background_attachment = property(CSS::PropertyID::BackgroundAttachment); auto maybe_background_origin = property(CSS::PropertyID::BackgroundOrigin); auto maybe_background_clip = property(CSS::PropertyID::BackgroundClip); @@ -683,8 +682,7 @@ RefPtr ResolvedCSSStyleDeclaration::style_value_for_property(Layout: value_or_default(maybe_background_color, InitialStyleValue::the()), value_or_default(maybe_background_image, IdentifierStyleValue::create(CSS::ValueID::None)), value_or_default(maybe_background_position, PositionStyleValue::create(PositionEdge::Left, Length::make_px(0), PositionEdge::Top, Length::make_px(0))), - value_or_default(maybe_background_repeat_x, IdentifierStyleValue::create(CSS::ValueID::RepeatX)), - value_or_default(maybe_background_repeat_y, IdentifierStyleValue::create(CSS::ValueID::RepeatX)), + value_or_default(maybe_background_repeat, BackgroundRepeatStyleValue::create(IdentifierStyleValue::create(CSS::ValueID::Repeat), IdentifierStyleValue::create(CSS::ValueID::Repeat))), value_or_default(maybe_background_attachment, IdentifierStyleValue::create(CSS::ValueID::Scroll)), value_or_default(maybe_background_origin, IdentifierStyleValue::create(CSS::ValueID::PaddingBox)), value_or_default(maybe_background_clip, IdentifierStyleValue::create(CSS::ValueID::BorderBox))); diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp index 1c3742fe2e..b2ab50f6bc 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -302,8 +302,7 @@ static void set_property_expanding_shorthands(StyleProperties& style, CSS::Prope set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundColor, background.color(), document); set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundImage, background.image(), document); set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundPosition, background.position(), document); - set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundRepeatX, background.repeat_x(), document, true); - set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundRepeatY, background.repeat_y(), document, true); + set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundRepeat, background.repeat(), document); set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundAttachment, background.attachment(), document); set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundOrigin, background.origin(), document); set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundClip, background.clip(), document); @@ -328,8 +327,7 @@ static void set_property_expanding_shorthands(StyleProperties& style, CSS::Prope set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundColor, value, document); set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundImage, value, document); set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundPosition, value, document); - set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundRepeatX, value, document, true); - set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundRepeatY, value, document, true); + set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundRepeat, value, document); set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundAttachment, value, document); set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundOrigin, value, document); set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundClip, value, document); diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValue.h index dac3f0a68d..fbf3d8f32f 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.h +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.h @@ -378,13 +378,12 @@ public: NonnullRefPtr color, NonnullRefPtr image, NonnullRefPtr position, - NonnullRefPtr repeat_x, - NonnullRefPtr repeat_y, + NonnullRefPtr repeat, NonnullRefPtr attachment, NonnullRefPtr origin, NonnullRefPtr clip) { - return adopt_ref(*new BackgroundStyleValue(color, image, position, repeat_x, repeat_y, attachment, origin, clip)); + return adopt_ref(*new BackgroundStyleValue(color, image, position, repeat, attachment, origin, clip)); } virtual ~BackgroundStyleValue() override { } @@ -394,12 +393,11 @@ public: NonnullRefPtr image() const { return m_image; } NonnullRefPtr origin() const { return m_origin; } NonnullRefPtr position() const { return m_position; } - NonnullRefPtr repeat_x() const { return m_repeat_x; } - NonnullRefPtr repeat_y() const { return m_repeat_y; } + NonnullRefPtr repeat() const { return m_repeat; } virtual String to_string() const override { - return String::formatted("{} {} {} {} {} {} {} {}", m_color->to_string(), m_image->to_string(), m_position->to_string(), m_repeat_x->to_string(), m_repeat_y->to_string(), m_attachment->to_string(), m_origin->to_string(), m_clip->to_string()); + return String::formatted("{} {} {} {} {} {} {}", m_color->to_string(), m_image->to_string(), m_position->to_string(), m_repeat->to_string(), m_attachment->to_string(), m_origin->to_string(), m_clip->to_string()); } private: @@ -407,8 +405,7 @@ private: NonnullRefPtr color, NonnullRefPtr image, NonnullRefPtr position, - NonnullRefPtr repeat_x, - NonnullRefPtr repeat_y, + NonnullRefPtr repeat, NonnullRefPtr attachment, NonnullRefPtr origin, NonnullRefPtr clip) @@ -416,8 +413,7 @@ private: , m_color(color) , m_image(image) , m_position(position) - , m_repeat_x(repeat_x) - , m_repeat_y(repeat_y) + , m_repeat(repeat) , m_attachment(attachment) , m_origin(origin) , m_clip(clip) @@ -427,8 +423,7 @@ private: NonnullRefPtr m_image; NonnullRefPtr m_position; // FIXME: background-size - NonnullRefPtr m_repeat_x; - NonnullRefPtr m_repeat_y; + NonnullRefPtr m_repeat; NonnullRefPtr m_attachment; NonnullRefPtr m_origin; NonnullRefPtr m_clip;