diff --git a/Tests/LibWeb/Ref/css-gradient-currentcolor-ref.html b/Tests/LibWeb/Ref/css-gradient-currentcolor-ref.html
new file mode 100644
index 0000000000..1f0ebff8b2
--- /dev/null
+++ b/Tests/LibWeb/Ref/css-gradient-currentcolor-ref.html
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/Tests/LibWeb/Ref/css-gradient-currentcolor.html b/Tests/LibWeb/Ref/css-gradient-currentcolor.html
new file mode 100644
index 0000000000..e1be1ba6ff
--- /dev/null
+++ b/Tests/LibWeb/Ref/css-gradient-currentcolor.html
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/Tests/LibWeb/Ref/manifest.json b/Tests/LibWeb/Ref/manifest.json
index 9a65ccf16c..e47c0298fd 100644
--- a/Tests/LibWeb/Ref/manifest.json
+++ b/Tests/LibWeb/Ref/manifest.json
@@ -1,5 +1,6 @@
{
"square-flex.html": "square-ref.html",
"separate-borders-inline-table.html": "separate-borders-ref.html",
- "opacity-stacking.html": "opacity-stacking-ref.html"
+ "opacity-stacking.html": "opacity-stacking-ref.html",
+ "css-gradient-currentcolor.html": "css-gradient-currentcolor-ref.html"
}
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
index 4be5ec262f..f4b7460784 100644
--- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
+++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
@@ -2419,7 +2419,7 @@ static Optional> parse_color_stop_list(auto& tokens, auto is_po
return ElementType::Garbage;
auto const& token = tokens.next_token();
- Gfx::Color color;
+ RefPtr color;
Optional position;
Optional second_position;
auto dimension = parse_dimension(token);
@@ -2434,15 +2434,15 @@ static Optional> parse_color_stop_list(auto& tokens, auto is_po
}
//
auto maybe_color = parse_color(tokens.next_token());
- if (!maybe_color.has_value())
+ if (maybe_color.is_error())
return ElementType::Garbage;
- color = *maybe_color;
+ color = maybe_color.release_value();
} else {
// [ ?]
auto maybe_color = parse_color(token);
- if (!maybe_color.has_value())
+ if (maybe_color.is_error())
return ElementType::Garbage;
- color = *maybe_color;
+ color = maybe_color.release_value();
tokens.skip_whitespace();
// Allow up to [ ] (double-position color stops)
// Note: Double-position color stops only appear to be valid in this order.
@@ -2503,7 +2503,7 @@ Optional> Parser::parse_linear_color_stop_lis
tokens,
[](Dimension& dimension) { return dimension.is_length_percentage(); },
[](Dimension& dimension) { return dimension.length_percentage(); },
- [&](auto& token) { return parse_color(token); },
+ [&](auto& token) { return parse_color_value(token); },
[&](auto& token) { return parse_dimension(token); });
}
@@ -2515,7 +2515,7 @@ Optional> Parser::parse_angular_color_stop_l
tokens,
[](Dimension& dimension) { return dimension.is_angle_percentage(); },
[](Dimension& dimension) { return dimension.angle_percentage(); },
- [&](auto& token) { return parse_color(token); },
+ [&](auto& token) { return parse_color_value(token); },
[&](auto& token) { return parse_dimension(token); });
}
diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/AbstractImageStyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValues/AbstractImageStyleValue.h
index 692b822571..79777124cd 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleValues/AbstractImageStyleValue.h
+++ b/Userland/Libraries/LibWeb/CSS/StyleValues/AbstractImageStyleValue.h
@@ -24,7 +24,7 @@ public:
virtual Optional natural_height() const { return {}; }
virtual void load_any_resources(DOM::Document&) {};
- virtual void resolve_for_size(Layout::Node const&, CSSPixelSize) const {};
+ virtual void resolve_for_size(Layout::NodeWithStyleAndBoxModelMetrics const&, CSSPixelSize) const {};
virtual bool is_paintable() const = 0;
virtual void paint(PaintContext& context, DevicePixelRect const& dest_rect, ImageRendering) const = 0;
@@ -47,7 +47,7 @@ struct ColorStopListElement {
Optional transition_hint;
struct ColorStop {
- Color color;
+ RefPtr color;
Optional position;
Optional second_position = {};
inline bool operator==(ColorStop const&) const = default;
@@ -69,7 +69,7 @@ static ErrorOr serialize_color_stop_list(StringBuilder& builder, auto cons
if (element.transition_hint.has_value())
TRY(builder.try_appendff("{}, "sv, TRY(element.transition_hint->value.to_string())));
- TRY(serialize_a_srgb_value(builder, element.color_stop.color));
+ TRY(builder.try_append(TRY(element.color_stop.color->to_string())));
for (auto position : Array { &element.color_stop.position, &element.color_stop.second_position }) {
if (position->has_value())
TRY(builder.try_appendff(" {}"sv, TRY((*position)->to_string())));
diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.cpp
index 8b2d61be9c..a685a90f15 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.cpp
+++ b/Userland/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.cpp
@@ -8,6 +8,7 @@
*/
#include "ConicGradientStyleValue.h"
+#include
namespace Web::CSS {
@@ -34,7 +35,7 @@ ErrorOr ConicGradientStyleValue::to_string() const
return builder.to_string();
}
-void ConicGradientStyleValue::resolve_for_size(Layout::Node const& node, CSSPixelSize size) const
+void ConicGradientStyleValue::resolve_for_size(Layout::NodeWithStyleAndBoxModelMetrics const& node, CSSPixelSize size) const
{
if (!m_resolved.has_value())
m_resolved = ResolvedData { Painting::resolve_conic_gradient_data(node, *this), {} };
diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.h
index 7b40ffcae1..5603d0e517 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.h
+++ b/Userland/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.h
@@ -39,7 +39,7 @@ public:
bool is_paintable() const override { return true; }
- void resolve_for_size(Layout::Node const&, CSSPixelSize) const override;
+ void resolve_for_size(Layout::NodeWithStyleAndBoxModelMetrics const&, CSSPixelSize) const override;
virtual ~ConicGradientStyleValue() override = default;
diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/LinearGradientStyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValues/LinearGradientStyleValue.cpp
index 8119d6fb84..0a1b244988 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleValues/LinearGradientStyleValue.cpp
+++ b/Userland/Libraries/LibWeb/CSS/StyleValues/LinearGradientStyleValue.cpp
@@ -102,7 +102,7 @@ float LinearGradientStyleValue::angle_degrees(CSSPixelSize gradient_size) const
});
}
-void LinearGradientStyleValue::resolve_for_size(Layout::Node const& node, CSSPixelSize size) const
+void LinearGradientStyleValue::resolve_for_size(Layout::NodeWithStyleAndBoxModelMetrics const& node, CSSPixelSize size) const
{
if (m_resolved.has_value() && m_resolved->size == size)
return;
diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/LinearGradientStyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValues/LinearGradientStyleValue.h
index 4e1f2de70c..4c5e08a565 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleValues/LinearGradientStyleValue.h
+++ b/Userland/Libraries/LibWeb/CSS/StyleValues/LinearGradientStyleValue.h
@@ -57,7 +57,7 @@ public:
float angle_degrees(CSSPixelSize gradient_size) const;
- void resolve_for_size(Layout::Node const&, CSSPixelSize) const override;
+ void resolve_for_size(Layout::NodeWithStyleAndBoxModelMetrics const&, CSSPixelSize) const override;
bool is_paintable() const override { return true; }
void paint(PaintContext& context, DevicePixelRect const& dest_rect, CSS::ImageRendering image_rendering) const override;
diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/RadialGradientStyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValues/RadialGradientStyleValue.cpp
index f35d230677..ecae87b16e 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleValues/RadialGradientStyleValue.cpp
+++ b/Userland/Libraries/LibWeb/CSS/StyleValues/RadialGradientStyleValue.cpp
@@ -8,6 +8,7 @@
*/
#include "RadialGradientStyleValue.h"
+#include
namespace Web::CSS {
@@ -184,7 +185,7 @@ Gfx::FloatSize RadialGradientStyleValue::resolve_size(Layout::Node const& node,
return resolved_size;
}
-void RadialGradientStyleValue::resolve_for_size(Layout::Node const& node, CSSPixelSize paint_size) const
+void RadialGradientStyleValue::resolve_for_size(Layout::NodeWithStyleAndBoxModelMetrics const& node, CSSPixelSize paint_size) const
{
CSSPixelRect gradient_box { { 0, 0 }, paint_size };
auto center = m_properties.position.resolved(node, gradient_box).to_type();
diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/RadialGradientStyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValues/RadialGradientStyleValue.h
index 96aec112a1..7b1a0d1a54 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleValues/RadialGradientStyleValue.h
+++ b/Userland/Libraries/LibWeb/CSS/StyleValues/RadialGradientStyleValue.h
@@ -63,7 +63,7 @@ public:
bool is_paintable() const override { return true; }
- void resolve_for_size(Layout::Node const&, CSSPixelSize) const override;
+ void resolve_for_size(Layout::NodeWithStyleAndBoxModelMetrics const&, CSSPixelSize) const override;
Gfx::FloatSize resolve_size(Layout::Node const&, Gfx::FloatPoint, Gfx::FloatRect const&) const;
diff --git a/Userland/Libraries/LibWeb/Painting/GradientPainting.cpp b/Userland/Libraries/LibWeb/Painting/GradientPainting.cpp
index e9d639141c..b5fce68190 100644
--- a/Userland/Libraries/LibWeb/Painting/GradientPainting.cpp
+++ b/Userland/Libraries/LibWeb/Painting/GradientPainting.cpp
@@ -10,11 +10,12 @@
#include
#include
#include
+#include
#include
namespace Web::Painting {
-static ColorStopData resolve_color_stop_positions(auto const& color_stop_list, auto resolve_position_to_float, bool repeating)
+static ColorStopData resolve_color_stop_positions(Layout::NodeWithStyleAndBoxModelMetrics const& node, auto const& color_stop_list, auto resolve_position_to_float, bool repeating)
{
VERIFY(color_stop_list.size() >= 2);
ColorStopList resolved_color_stops;
@@ -29,7 +30,7 @@ static ColorStopData resolve_color_stop_positions(auto const& color_stop_list, a
resolved_color_stops.ensure_capacity(expanded_size);
for (auto& stop : color_stop_list) {
- auto resolved_stop = Gfx::ColorStop { .color = stop.color_stop.color };
+ auto resolved_stop = Gfx::ColorStop { .color = stop.color_stop.color->to_color(node) };
for (int i = 0; i < color_stop_length(stop); i++)
resolved_color_stops.append(resolved_stop);
}
@@ -109,13 +110,13 @@ static ColorStopData resolve_color_stop_positions(auto const& color_stop_list, a
return { resolved_color_stops, repeat_length };
}
-LinearGradientData resolve_linear_gradient_data(Layout::Node const& node, CSSPixelSize gradient_size, CSS::LinearGradientStyleValue const& linear_gradient)
+LinearGradientData resolve_linear_gradient_data(Layout::NodeWithStyleAndBoxModelMetrics const& node, CSSPixelSize gradient_size, CSS::LinearGradientStyleValue const& linear_gradient)
{
auto gradient_angle = linear_gradient.angle_degrees(gradient_size);
auto gradient_length_px = Gfx::calculate_gradient_length(gradient_size.to_type(), gradient_angle);
auto resolved_color_stops = resolve_color_stop_positions(
- linear_gradient.color_stop_list(), [&](auto const& length_percentage) {
+ node, linear_gradient.color_stop_list(), [&](auto const& length_percentage) {
return length_percentage.to_px(node, gradient_length_px).to_float() / static_cast(gradient_length_px);
},
linear_gradient.is_repeating());
@@ -123,22 +124,22 @@ LinearGradientData resolve_linear_gradient_data(Layout::Node const& node, CSSPix
return { gradient_angle, resolved_color_stops };
}
-ConicGradientData resolve_conic_gradient_data(Layout::Node const& node, CSS::ConicGradientStyleValue const& conic_gradient)
+ConicGradientData resolve_conic_gradient_data(Layout::NodeWithStyleAndBoxModelMetrics const& node, CSS::ConicGradientStyleValue const& conic_gradient)
{
CSS::Angle one_turn(360.0f, CSS::Angle::Type::Deg);
auto resolved_color_stops = resolve_color_stop_positions(
- conic_gradient.color_stop_list(), [&](auto const& angle_percentage) {
+ node, conic_gradient.color_stop_list(), [&](auto const& angle_percentage) {
return angle_percentage.resolved(node, one_turn).to_degrees() / one_turn.to_degrees();
},
conic_gradient.is_repeating());
return { conic_gradient.angle_degrees(), resolved_color_stops };
}
-RadialGradientData resolve_radial_gradient_data(Layout::Node const& node, CSSPixelSize gradient_size, CSS::RadialGradientStyleValue const& radial_gradient)
+RadialGradientData resolve_radial_gradient_data(Layout::NodeWithStyleAndBoxModelMetrics const& node, CSSPixelSize gradient_size, CSS::RadialGradientStyleValue const& radial_gradient)
{
// Start center, goes right to ending point, where the gradient line intersects the ending shape
auto resolved_color_stops = resolve_color_stop_positions(
- radial_gradient.color_stop_list(), [&](auto const& length_percentage) {
+ node, radial_gradient.color_stop_list(), [&](auto const& length_percentage) {
return (length_percentage.to_px(node, gradient_size.width()) / gradient_size.width()).to_float();
},
radial_gradient.is_repeating());
diff --git a/Userland/Libraries/LibWeb/Painting/GradientPainting.h b/Userland/Libraries/LibWeb/Painting/GradientPainting.h
index 5154da16d5..3ca5ea4c19 100644
--- a/Userland/Libraries/LibWeb/Painting/GradientPainting.h
+++ b/Userland/Libraries/LibWeb/Painting/GradientPainting.h
@@ -36,9 +36,9 @@ struct RadialGradientData {
ColorStopData color_stops;
};
-LinearGradientData resolve_linear_gradient_data(Layout::Node const&, CSSPixelSize, CSS::LinearGradientStyleValue const&);
-ConicGradientData resolve_conic_gradient_data(Layout::Node const&, CSS::ConicGradientStyleValue const&);
-RadialGradientData resolve_radial_gradient_data(Layout::Node const&, CSSPixelSize, CSS::RadialGradientStyleValue const&);
+LinearGradientData resolve_linear_gradient_data(Layout::NodeWithStyleAndBoxModelMetrics const&, CSSPixelSize, CSS::LinearGradientStyleValue const&);
+ConicGradientData resolve_conic_gradient_data(Layout::NodeWithStyleAndBoxModelMetrics const&, CSS::ConicGradientStyleValue const&);
+RadialGradientData resolve_radial_gradient_data(Layout::NodeWithStyleAndBoxModelMetrics const&, CSSPixelSize, CSS::RadialGradientStyleValue const&);
void paint_linear_gradient(PaintContext&, DevicePixelRect const&, LinearGradientData const&);
void paint_conic_gradient(PaintContext&, DevicePixelRect const&, ConicGradientData const&, DevicePixelPoint position);