diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 7aa1ff4ab7..9bd1354946 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -2362,16 +2362,33 @@ Optional Parser::parse_url_function(ComponentValue const& component_val RefPtr Parser::parse_linear_gradient_function(ComponentValue const& component_value) { using GradientType = LinearGradientStyleValue::GradientType; + using Repeating = LinearGradientStyleValue::Repeating; if (!component_value.is_function()) return {}; + auto consume_if_starts_with = [](StringView str, StringView start, auto found_callback) { + if (str.starts_with(start, CaseSensitivity::CaseInsensitive)) { + found_callback(); + return str.substring_view(start.length()); + } + return str; + }; + + Repeating repeating_gradient = Repeating::No; + GradientType gradient_type { GradientType::Standard }; + auto function_name = component_value.function().name(); - GradientType gradient_type { GradientType::Standard }; - if (function_name.equals_ignoring_case("-webkit-linear-gradient"sv)) + function_name = consume_if_starts_with(function_name, "-webkit-"sv, [&] { gradient_type = GradientType::WebKit; - else if (!function_name.equals_ignoring_case("linear-gradient"sv)) + }); + + function_name = consume_if_starts_with(function_name, "repeating-"sv, [&] { + repeating_gradient = Repeating::Yes; + }); + + if (!function_name.equals_ignoring_case("linear-gradient"sv)) return {}; // linear-gradient() = linear-gradient([ | to ]?, ) @@ -2558,7 +2575,7 @@ RefPtr Parser::parse_linear_gradient_function(ComponentValue const& color_stops.append(list_element); } - return LinearGradientStyleValue::create(gradient_direction, move(color_stops), gradient_type); + return LinearGradientStyleValue::create(gradient_direction, move(color_stops), gradient_type, repeating_gradient); } RefPtr Parser::convert_to_rule(NonnullRefPtr rule) diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp index e2c42a3aec..daa59d3920 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp @@ -1491,6 +1491,8 @@ String LinearGradientStyleValue::to_string() const if (m_gradient_type == GradientType::WebKit) builder.append("-webkit-"sv); + if (m_repeating == Repeating::Yes) + builder.append("repeating-"sv); builder.append("linear-gradient("sv); m_direction.visit( [&](SideOrCorner side_or_corner) { diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValue.h index 5f757f6567..89ed09e583 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.h +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.h @@ -978,10 +978,15 @@ public: WebKit }; - static NonnullRefPtr create(GradientDirection direction, Vector color_stop_list, GradientType type) + enum class Repeating { + Yes, + No + }; + + static NonnullRefPtr create(GradientDirection direction, Vector color_stop_list, GradientType type, Repeating repeating) { VERIFY(color_stop_list.size() >= 2); - return adopt_ref(*new LinearGradientStyleValue(direction, move(color_stop_list), type)); + return adopt_ref(*new LinearGradientStyleValue(direction, move(color_stop_list), type, repeating)); } virtual String to_string() const override; @@ -993,6 +998,8 @@ public: return m_color_stop_list; } + bool is_repeating() const { return m_repeating == Repeating::Yes; } + float angle_degrees(Gfx::FloatSize const& gradient_size) const; void resolve_for_size(Layout::Node const&, Gfx::FloatSize const&) const override; @@ -1001,17 +1008,19 @@ public: void paint(PaintContext& context, Gfx::IntRect const& dest_rect, CSS::ImageRendering image_rendering) const override; private: - LinearGradientStyleValue(GradientDirection direction, Vector color_stop_list, GradientType type) + LinearGradientStyleValue(GradientDirection direction, Vector color_stop_list, GradientType type, Repeating repeating) : AbstractImageStyleValue(Type::LinearGradient) , m_direction(direction) , m_color_stop_list(move(color_stop_list)) , m_gradient_type(type) + , m_repeating(repeating) { } GradientDirection m_direction; Vector m_color_stop_list; GradientType m_gradient_type; + Repeating m_repeating; mutable Optional m_resolved_data; };