mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-28 05:07:35 +00:00
LibWeb: Update to_color
to take ColorResolutionContext
Using a generic context argument will allow us to resolve colors in places where we have all the required information but not in the form of a layout node as was expected previously.
This commit is contained in:
parent
b0508fb39a
commit
46153910ec
Notes:
github-actions[bot]
2025-08-04 10:30:51 +00:00
Author: https://github.com/Calme1709
Commit: 46153910ec
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5517
Reviewed-by: https://github.com/AtkinsSJ ✅
Reviewed-by: https://github.com/gmta
31 changed files with 129 additions and 127 deletions
|
@ -71,9 +71,20 @@
|
||||||
#include <LibWeb/CSS/StyleValues/URLStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/URLStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/UnicodeRangeStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/UnicodeRangeStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/UnresolvedStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/UnresolvedStyleValue.h>
|
||||||
|
#include <LibWeb/Layout/Node.h>
|
||||||
|
|
||||||
namespace Web::CSS {
|
namespace Web::CSS {
|
||||||
|
|
||||||
|
ColorResolutionContext ColorResolutionContext::for_layout_node_with_style(Layout::NodeWithStyle const& layout_node)
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
.color_scheme = layout_node.computed_values().color_scheme(),
|
||||||
|
.current_color = layout_node.computed_values().color(),
|
||||||
|
.document = layout_node.document(),
|
||||||
|
.calculation_resolution_context = { .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
CSSStyleValue::CSSStyleValue(Type type)
|
CSSStyleValue::CSSStyleValue(Type type)
|
||||||
: m_type(type)
|
: m_type(type)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <LibWeb/CSS/CalculationResolutionContext.h>
|
#include <LibWeb/CSS/CalculationResolutionContext.h>
|
||||||
#include <LibWeb/CSS/Keyword.h>
|
#include <LibWeb/CSS/Keyword.h>
|
||||||
#include <LibWeb/CSS/Length.h>
|
#include <LibWeb/CSS/Length.h>
|
||||||
|
#include <LibWeb/CSS/PreferredColorScheme.h>
|
||||||
#include <LibWeb/CSS/SerializationMode.h>
|
#include <LibWeb/CSS/SerializationMode.h>
|
||||||
#include <LibWeb/Forward.h>
|
#include <LibWeb/Forward.h>
|
||||||
|
|
||||||
|
@ -82,6 +83,15 @@ private:
|
||||||
|
|
||||||
using StyleValueVector = Vector<ValueComparingNonnullRefPtr<CSSStyleValue const>>;
|
using StyleValueVector = Vector<ValueComparingNonnullRefPtr<CSSStyleValue const>>;
|
||||||
|
|
||||||
|
struct ColorResolutionContext {
|
||||||
|
Optional<PreferredColorScheme> color_scheme;
|
||||||
|
Optional<Color> current_color;
|
||||||
|
GC::Ptr<DOM::Document const> document;
|
||||||
|
CalculationResolutionContext calculation_resolution_context;
|
||||||
|
|
||||||
|
[[nodiscard]] static ColorResolutionContext for_layout_node_with_style(Layout::NodeWithStyle const&);
|
||||||
|
};
|
||||||
|
|
||||||
// https://drafts.css-houdini.org/css-typed-om-1/#cssstylevalue
|
// https://drafts.css-houdini.org/css-typed-om-1/#cssstylevalue
|
||||||
class CSSStyleValue : public RefCounted<CSSStyleValue> {
|
class CSSStyleValue : public RefCounted<CSSStyleValue> {
|
||||||
public:
|
public:
|
||||||
|
@ -404,7 +414,7 @@ public:
|
||||||
|
|
||||||
virtual ValueComparingNonnullRefPtr<CSSStyleValue const> absolutized(CSSPixelRect const& viewport_rect, Length::FontMetrics const& font_metrics, Length::FontMetrics const& root_font_metrics) const;
|
virtual ValueComparingNonnullRefPtr<CSSStyleValue const> absolutized(CSSPixelRect const& viewport_rect, Length::FontMetrics const& font_metrics, Length::FontMetrics const& root_font_metrics) const;
|
||||||
|
|
||||||
virtual Optional<Color> to_color(Optional<Layout::NodeWithStyle const&>, CalculationResolutionContext const&) const { return {}; }
|
virtual Optional<Color> to_color(ColorResolutionContext) const { return {}; }
|
||||||
Keyword to_keyword() const;
|
Keyword to_keyword() const;
|
||||||
|
|
||||||
virtual String to_string(SerializationMode) const = 0;
|
virtual String to_string(SerializationMode) const = 0;
|
||||||
|
|
|
@ -229,7 +229,7 @@ Color ComputedProperties::color_or_fallback(PropertyID id, Layout::NodeWithStyle
|
||||||
auto const& value = property(id);
|
auto const& value = property(id);
|
||||||
if (!value.has_color())
|
if (!value.has_color())
|
||||||
return fallback;
|
return fallback;
|
||||||
return value.to_color(node, { .length_resolution_context = Length::ResolutionContext::for_layout_node(node) }).value();
|
return value.to_color(ColorResolutionContext::for_layout_node_with_style(node)).value();
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-color-adjust-1/#determine-the-used-color-scheme
|
// https://drafts.csswg.org/css-color-adjust-1/#determine-the-used-color-scheme
|
||||||
|
@ -450,7 +450,7 @@ Color ComputedProperties::flood_color(Layout::NodeWithStyle const& node) const
|
||||||
{
|
{
|
||||||
auto const& value = property(PropertyID::FloodColor);
|
auto const& value = property(PropertyID::FloodColor);
|
||||||
if (value.has_color()) {
|
if (value.has_color()) {
|
||||||
return value.to_color(node, { .length_resolution_context = Length::ResolutionContext::for_layout_node(node) }).value();
|
return value.to_color(ColorResolutionContext::for_layout_node_with_style(node)).value();
|
||||||
}
|
}
|
||||||
|
|
||||||
return InitialValues::flood_color();
|
return InitialValues::flood_color();
|
||||||
|
@ -689,7 +689,7 @@ Optional<Color> ComputedProperties::accent_color(Layout::NodeWithStyle const& no
|
||||||
{
|
{
|
||||||
auto const& value = property(PropertyID::AccentColor);
|
auto const& value = property(PropertyID::AccentColor);
|
||||||
if (value.has_color())
|
if (value.has_color())
|
||||||
return value.to_color(node, { .length_resolution_context = Length::ResolutionContext::for_layout_node(node) });
|
return value.to_color(ColorResolutionContext::for_layout_node_with_style(node));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -943,7 +943,7 @@ Color ComputedProperties::caret_color(Layout::NodeWithStyle const& node) const
|
||||||
return node.computed_values().color();
|
return node.computed_values().color();
|
||||||
|
|
||||||
if (value.has_color())
|
if (value.has_color())
|
||||||
return value.to_color(node, { .length_resolution_context = Length::ResolutionContext::for_layout_node(node) }).value();
|
return value.to_color(ColorResolutionContext::for_layout_node_with_style(node)).value();
|
||||||
|
|
||||||
return InitialValues::caret_color();
|
return InitialValues::caret_color();
|
||||||
}
|
}
|
||||||
|
@ -1203,7 +1203,7 @@ Vector<ShadowData> ComputedProperties::shadow(PropertyID property_id, Layout::No
|
||||||
maybe_offset_y.release_value(),
|
maybe_offset_y.release_value(),
|
||||||
maybe_blur_radius.release_value(),
|
maybe_blur_radius.release_value(),
|
||||||
maybe_spread_distance.release_value(),
|
maybe_spread_distance.release_value(),
|
||||||
value.color()->to_color(as<Layout::NodeWithStyle>(layout_node), { .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }).value(),
|
value.color()->to_color(ColorResolutionContext::for_layout_node_with_style(as<Layout::NodeWithStyle>(layout_node))).value(),
|
||||||
value.placement()
|
value.placement()
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -1826,7 +1826,7 @@ Color ComputedProperties::stop_color() const
|
||||||
// FIXME: This is used by the SVGStopElement, which does not participate in layout, so we can't pass a layout
|
// FIXME: This is used by the SVGStopElement, which does not participate in layout, so we can't pass a layout
|
||||||
// node or CalculationResolutionContext. This means we don't support all valid colors (e.g. palette
|
// node or CalculationResolutionContext. This means we don't support all valid colors (e.g. palette
|
||||||
// colors, calculated values which depend on length resolution, etc)
|
// colors, calculated values which depend on length resolution, etc)
|
||||||
return value->to_color({}, {}).value_or(Color::Black);
|
return value->to_color({}).value_or(Color::Black);
|
||||||
}
|
}
|
||||||
return Color::Black;
|
return Color::Black;
|
||||||
}
|
}
|
||||||
|
@ -1910,8 +1910,8 @@ ScrollbarColorData ComputedProperties::scrollbar_color(Layout::NodeWithStyle con
|
||||||
|
|
||||||
if (value.is_scrollbar_color()) {
|
if (value.is_scrollbar_color()) {
|
||||||
auto& scrollbar_color_value = value.as_scrollbar_color();
|
auto& scrollbar_color_value = value.as_scrollbar_color();
|
||||||
auto thumb_color = scrollbar_color_value.thumb_color()->to_color(layout_node, { .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }).value();
|
auto thumb_color = scrollbar_color_value.thumb_color()->to_color(ColorResolutionContext::for_layout_node_with_style(layout_node)).value();
|
||||||
auto track_color = scrollbar_color_value.track_color()->to_color(layout_node, { .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }).value();
|
auto track_color = scrollbar_color_value.track_color()->to_color(ColorResolutionContext::for_layout_node_with_style(layout_node)).value();
|
||||||
return { thumb_color, track_color };
|
return { thumb_color, track_color };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -957,11 +957,9 @@ RefPtr<CSSStyleValue const> interpolate_box_shadow(DOM::Element& element, Calcul
|
||||||
StyleValueVector result_shadows;
|
StyleValueVector result_shadows;
|
||||||
result_shadows.ensure_capacity(from_shadows.size());
|
result_shadows.ensure_capacity(from_shadows.size());
|
||||||
|
|
||||||
Optional<Layout::NodeWithStyle const&> layout_node;
|
ColorResolutionContext color_resolution_context {};
|
||||||
CalculationResolutionContext resolution_context;
|
|
||||||
if (auto node = element.layout_node()) {
|
if (auto node = element.layout_node()) {
|
||||||
layout_node = *node;
|
color_resolution_context = ColorResolutionContext::for_layout_node_with_style(*element.layout_node());
|
||||||
resolution_context.length_resolution_context = Length::ResolutionContext::for_layout_node(*node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < from_shadows.size(); i++) {
|
for (size_t i = 0; i < from_shadows.size(); i++) {
|
||||||
|
@ -982,8 +980,8 @@ RefPtr<CSSStyleValue const> interpolate_box_shadow(DOM::Element& element, Calcul
|
||||||
|
|
||||||
// FIXME: If we aren't able to resolve the colors here, we should postpone interpolation until we can (perhaps
|
// FIXME: If we aren't able to resolve the colors here, we should postpone interpolation until we can (perhaps
|
||||||
// by creating something similar to a ColorMixStyleValue).
|
// by creating something similar to a ColorMixStyleValue).
|
||||||
auto from_color = from_shadow.color()->to_color(layout_node, resolution_context);
|
auto from_color = from_shadow.color()->to_color(color_resolution_context);
|
||||||
auto to_color = to_shadow.color()->to_color(layout_node, resolution_context);
|
auto to_color = to_shadow.color()->to_color(color_resolution_context);
|
||||||
|
|
||||||
Color interpolated_color = Color::Black;
|
Color interpolated_color = Color::Black;
|
||||||
|
|
||||||
|
@ -1102,11 +1100,9 @@ static RefPtr<CSSStyleValue const> interpolate_value_impl(DOM::Element& element,
|
||||||
return BackgroundSizeStyleValue::create(*interpolated_x, *interpolated_y);
|
return BackgroundSizeStyleValue::create(*interpolated_x, *interpolated_y);
|
||||||
}
|
}
|
||||||
case CSSStyleValue::Type::Color: {
|
case CSSStyleValue::Type::Color: {
|
||||||
Optional<Layout::NodeWithStyle const&> layout_node;
|
ColorResolutionContext color_resolution_context {};
|
||||||
CalculationResolutionContext resolution_context {};
|
|
||||||
if (auto node = element.layout_node()) {
|
if (auto node = element.layout_node()) {
|
||||||
layout_node = *node;
|
color_resolution_context = ColorResolutionContext::for_layout_node_with_style(*element.layout_node());
|
||||||
resolution_context.length_resolution_context = Length::ResolutionContext::for_layout_node(*node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto color_syntax = ColorSyntax::Legacy;
|
auto color_syntax = ColorSyntax::Legacy;
|
||||||
|
@ -1117,8 +1113,8 @@ static RefPtr<CSSStyleValue const> interpolate_value_impl(DOM::Element& element,
|
||||||
|
|
||||||
// FIXME: If we aren't able to resolve the colors here, we should postpone interpolation until we can (perhaps
|
// FIXME: If we aren't able to resolve the colors here, we should postpone interpolation until we can (perhaps
|
||||||
// by creating something similar to a ColorMixStyleValue).
|
// by creating something similar to a ColorMixStyleValue).
|
||||||
auto from_color = from.to_color(layout_node, resolution_context);
|
auto from_color = from.to_color(color_resolution_context);
|
||||||
auto to_color = to.to_color(layout_node, resolution_context);
|
auto to_color = to.to_color(color_resolution_context);
|
||||||
|
|
||||||
Color interpolated_color = Color::Black;
|
Color interpolated_color = Color::Black;
|
||||||
|
|
||||||
|
|
|
@ -5119,7 +5119,7 @@ RefPtr<CSSStyleValue const> Parser::parse_filter_value_list_value(TokenStream<Co
|
||||||
Optional<Color> color = {};
|
Optional<Color> color = {};
|
||||||
if (maybe_color)
|
if (maybe_color)
|
||||||
// FIXME: We should support colors which require compute-time information (i.e. `em` and `vw` to `px` ratios).
|
// FIXME: We should support colors which require compute-time information (i.e. `em` and `vw` to `px` ratios).
|
||||||
color = maybe_color->to_color({}, {});
|
color = maybe_color->to_color({});
|
||||||
|
|
||||||
return if_no_more_tokens_return(FilterOperation::DropShadow { x_offset.value(), y_offset.value(), maybe_radius, color });
|
return if_no_more_tokens_return(FilterOperation::DropShadow { x_offset.value(), y_offset.value(), maybe_radius, color });
|
||||||
} else if (filter_token == FilterToken::HueRotate) {
|
} else if (filter_token == FilterToken::HueRotate) {
|
||||||
|
|
|
@ -12,12 +12,12 @@
|
||||||
|
|
||||||
namespace Web::CSS {
|
namespace Web::CSS {
|
||||||
|
|
||||||
Optional<Color> CSSHSL::to_color(Optional<Layout::NodeWithStyle const&>, CalculationResolutionContext const& resolution_context) const
|
Optional<Color> CSSHSL::to_color(ColorResolutionContext color_resolution_context) const
|
||||||
{
|
{
|
||||||
auto h_val = resolve_hue(m_properties.h, resolution_context);
|
auto h_val = resolve_hue(m_properties.h, color_resolution_context.calculation_resolution_context);
|
||||||
auto s_val = resolve_with_reference_value(m_properties.s, 100.0, resolution_context);
|
auto s_val = resolve_with_reference_value(m_properties.s, 100.0, color_resolution_context.calculation_resolution_context);
|
||||||
auto l_val = resolve_with_reference_value(m_properties.l, 100.0, resolution_context);
|
auto l_val = resolve_with_reference_value(m_properties.l, 100.0, color_resolution_context.calculation_resolution_context);
|
||||||
auto alpha_val = resolve_alpha(m_properties.alpha, resolution_context);
|
auto alpha_val = resolve_alpha(m_properties.alpha, color_resolution_context.calculation_resolution_context);
|
||||||
|
|
||||||
if (!h_val.has_value() || !s_val.has_value() || !l_val.has_value() || !alpha_val.has_value())
|
if (!h_val.has_value() || !s_val.has_value() || !l_val.has_value() || !alpha_val.has_value())
|
||||||
return {};
|
return {};
|
||||||
|
@ -39,7 +39,7 @@ bool CSSHSL::equals(CSSStyleValue const& other) const
|
||||||
// https://www.w3.org/TR/css-color-4/#serializing-sRGB-values
|
// https://www.w3.org/TR/css-color-4/#serializing-sRGB-values
|
||||||
String CSSHSL::to_string(SerializationMode mode) const
|
String CSSHSL::to_string(SerializationMode mode) const
|
||||||
{
|
{
|
||||||
if (auto color = to_color({}, {}); color.has_value())
|
if (auto color = to_color({}); color.has_value())
|
||||||
return serialize_a_srgb_value(color.value());
|
return serialize_a_srgb_value(color.value());
|
||||||
|
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
CSSStyleValue const& l() const { return *m_properties.l; }
|
CSSStyleValue const& l() const { return *m_properties.l; }
|
||||||
CSSStyleValue const& alpha() const { return *m_properties.alpha; }
|
CSSStyleValue const& alpha() const { return *m_properties.alpha; }
|
||||||
|
|
||||||
virtual Optional<Color> to_color(Optional<Layout::NodeWithStyle const&>, CalculationResolutionContext const&) const override;
|
virtual Optional<Color> to_color(ColorResolutionContext color_resolution_context) const override;
|
||||||
|
|
||||||
virtual String to_string(SerializationMode) const override;
|
virtual String to_string(SerializationMode) const override;
|
||||||
|
|
||||||
|
|
|
@ -12,12 +12,12 @@
|
||||||
|
|
||||||
namespace Web::CSS {
|
namespace Web::CSS {
|
||||||
|
|
||||||
Optional<Color> CSSHWB::to_color(Optional<Layout::NodeWithStyle const&>, CalculationResolutionContext const& resolution_context) const
|
Optional<Color> CSSHWB::to_color(ColorResolutionContext color_resolution_context) const
|
||||||
{
|
{
|
||||||
auto h_val = resolve_hue(m_properties.h, resolution_context);
|
auto h_val = resolve_hue(m_properties.h, color_resolution_context.calculation_resolution_context);
|
||||||
auto raw_w_value = resolve_with_reference_value(m_properties.w, 100.0, resolution_context);
|
auto raw_w_value = resolve_with_reference_value(m_properties.w, 100.0, color_resolution_context.calculation_resolution_context);
|
||||||
auto raw_b_value = resolve_with_reference_value(m_properties.b, 100.0, resolution_context);
|
auto raw_b_value = resolve_with_reference_value(m_properties.b, 100.0, color_resolution_context.calculation_resolution_context);
|
||||||
auto alpha_val = resolve_alpha(m_properties.alpha, resolution_context);
|
auto alpha_val = resolve_alpha(m_properties.alpha, color_resolution_context.calculation_resolution_context);
|
||||||
|
|
||||||
if (!h_val.has_value() || !raw_w_value.has_value() || !raw_b_value.has_value() || !alpha_val.has_value())
|
if (!h_val.has_value() || !raw_w_value.has_value() || !raw_b_value.has_value() || !alpha_val.has_value())
|
||||||
return {};
|
return {};
|
||||||
|
@ -52,7 +52,7 @@ bool CSSHWB::equals(CSSStyleValue const& other) const
|
||||||
// https://www.w3.org/TR/css-color-4/#serializing-sRGB-values
|
// https://www.w3.org/TR/css-color-4/#serializing-sRGB-values
|
||||||
String CSSHWB::to_string(SerializationMode mode) const
|
String CSSHWB::to_string(SerializationMode mode) const
|
||||||
{
|
{
|
||||||
if (auto color = to_color({}, {}); color.has_value())
|
if (auto color = to_color({}); color.has_value())
|
||||||
return serialize_a_srgb_value(color.value());
|
return serialize_a_srgb_value(color.value());
|
||||||
|
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
CSSStyleValue const& b() const { return *m_properties.b; }
|
CSSStyleValue const& b() const { return *m_properties.b; }
|
||||||
CSSStyleValue const& alpha() const { return *m_properties.alpha; }
|
CSSStyleValue const& alpha() const { return *m_properties.alpha; }
|
||||||
|
|
||||||
virtual Optional<Color> to_color(Optional<Layout::NodeWithStyle const&>, CalculationResolutionContext const&) const override;
|
virtual Optional<Color> to_color(ColorResolutionContext color_resolution_context) const override;
|
||||||
|
|
||||||
virtual String to_string(SerializationMode) const override;
|
virtual String to_string(SerializationMode) const override;
|
||||||
|
|
||||||
|
|
|
@ -135,18 +135,13 @@ bool CSSKeywordValue::has_color() const
|
||||||
return is_color(keyword());
|
return is_color(keyword());
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<Color> CSSKeywordValue::to_color(Optional<Layout::NodeWithStyle const&> node, CalculationResolutionContext const&) const
|
Optional<Color> CSSKeywordValue::to_color(ColorResolutionContext color_resolution_context) const
|
||||||
{
|
{
|
||||||
if (keyword() == Keyword::Currentcolor) {
|
if (keyword() == Keyword::Currentcolor) {
|
||||||
if (!node.has_value() || !node->has_style())
|
return color_resolution_context.current_color.value_or(Color::Black);
|
||||||
return Color::Black;
|
|
||||||
return node->computed_values().color();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PreferredColorScheme scheme = PreferredColorScheme::Light;
|
PreferredColorScheme scheme = color_resolution_context.color_scheme.value_or(PreferredColorScheme::Light);
|
||||||
if (node.has_value()) {
|
|
||||||
scheme = node->computed_values().color_scheme();
|
|
||||||
}
|
|
||||||
|
|
||||||
// First, handle <system-color>s, since they don't strictly require a node.
|
// First, handle <system-color>s, since they don't strictly require a node.
|
||||||
// https://www.w3.org/TR/css-color-4/#css-system-colors
|
// https://www.w3.org/TR/css-color-4/#css-system-colors
|
||||||
|
@ -215,26 +210,24 @@ Optional<Color> CSSKeywordValue::to_color(Optional<Layout::NodeWithStyle const&>
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!node.has_value()) {
|
if (!color_resolution_context.document) {
|
||||||
// FIXME: Can't resolve palette colors without layout node.
|
// FIXME: Can't resolve palette colors without a document.
|
||||||
return Color::Black;
|
return Color::Black;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const& document = node->document();
|
|
||||||
|
|
||||||
switch (keyword()) {
|
switch (keyword()) {
|
||||||
case Keyword::LibwebLink:
|
case Keyword::LibwebLink:
|
||||||
case Keyword::Linktext:
|
case Keyword::Linktext:
|
||||||
return document.normal_link_color().value_or(SystemColor::link_text(scheme));
|
return color_resolution_context.document->normal_link_color().value_or(SystemColor::link_text(scheme));
|
||||||
case Keyword::Visitedtext:
|
case Keyword::Visitedtext:
|
||||||
return document.visited_link_color().value_or(SystemColor::visited_text(scheme));
|
return color_resolution_context.document->visited_link_color().value_or(SystemColor::visited_text(scheme));
|
||||||
case Keyword::Activetext:
|
case Keyword::Activetext:
|
||||||
return document.active_link_color().value_or(SystemColor::active_text(scheme));
|
return color_resolution_context.document->active_link_color().value_or(SystemColor::active_text(scheme));
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto palette = document.page().palette();
|
auto palette = color_resolution_context.document->page().palette();
|
||||||
switch (keyword()) {
|
switch (keyword()) {
|
||||||
case Keyword::LibwebPaletteDesktopBackground:
|
case Keyword::LibwebPaletteDesktopBackground:
|
||||||
return palette.color(ColorRole::DesktopBackground);
|
return palette.color(ColorRole::DesktopBackground);
|
||||||
|
|
|
@ -51,7 +51,7 @@ public:
|
||||||
|
|
||||||
static bool is_color(Keyword);
|
static bool is_color(Keyword);
|
||||||
virtual bool has_color() const override;
|
virtual bool has_color() const override;
|
||||||
virtual Optional<Color> to_color(Optional<Layout::NodeWithStyle const&> node, CalculationResolutionContext const&) const override;
|
virtual Optional<Color> to_color(ColorResolutionContext) const override;
|
||||||
virtual String to_string(SerializationMode) const override;
|
virtual String to_string(SerializationMode) const override;
|
||||||
virtual Vector<Parser::ComponentValue> tokenize() const override;
|
virtual Vector<Parser::ComponentValue> tokenize() const override;
|
||||||
|
|
||||||
|
|
|
@ -27,12 +27,12 @@ bool CSSLCHLike::equals(CSSStyleValue const& other) const
|
||||||
return m_properties == other_oklch_like.m_properties;
|
return m_properties == other_oklch_like.m_properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<Color> CSSLCH::to_color(Optional<Layout::NodeWithStyle const&>, CalculationResolutionContext const& resolution_context) const
|
Optional<Color> CSSLCH::to_color(ColorResolutionContext color_resolution_context) const
|
||||||
{
|
{
|
||||||
auto raw_l_val = resolve_with_reference_value(m_properties.l, 100, resolution_context);
|
auto raw_l_val = resolve_with_reference_value(m_properties.l, 100, color_resolution_context.calculation_resolution_context);
|
||||||
auto c_val = resolve_with_reference_value(m_properties.c, 150, resolution_context);
|
auto c_val = resolve_with_reference_value(m_properties.c, 150, color_resolution_context.calculation_resolution_context);
|
||||||
auto raw_h_val = resolve_hue(m_properties.h, resolution_context);
|
auto raw_h_val = resolve_hue(m_properties.h, color_resolution_context.calculation_resolution_context);
|
||||||
auto alpha_val = resolve_alpha(m_properties.alpha, resolution_context);
|
auto alpha_val = resolve_alpha(m_properties.alpha, color_resolution_context.calculation_resolution_context);
|
||||||
|
|
||||||
if (!raw_l_val.has_value() || !c_val.has_value() || !raw_h_val.has_value() || !alpha_val.has_value())
|
if (!raw_l_val.has_value() || !c_val.has_value() || !raw_h_val.has_value() || !alpha_val.has_value())
|
||||||
return {};
|
return {};
|
||||||
|
@ -63,12 +63,12 @@ String CSSLCH::to_string(SerializationMode mode) const
|
||||||
return MUST(builder.to_string());
|
return MUST(builder.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<Color> CSSOKLCH::to_color(Optional<Layout::NodeWithStyle const&>, CalculationResolutionContext const& resolution_context) const
|
Optional<Color> CSSOKLCH::to_color(ColorResolutionContext color_resolution_context) const
|
||||||
{
|
{
|
||||||
auto raw_l_val = resolve_with_reference_value(m_properties.l, 1.0, resolution_context);
|
auto raw_l_val = resolve_with_reference_value(m_properties.l, 1.0, color_resolution_context.calculation_resolution_context);
|
||||||
auto raw_c_val = resolve_with_reference_value(m_properties.c, 0.4, resolution_context);
|
auto raw_c_val = resolve_with_reference_value(m_properties.c, 0.4, color_resolution_context.calculation_resolution_context);
|
||||||
auto raw_h_val = resolve_hue(m_properties.h, resolution_context);
|
auto raw_h_val = resolve_hue(m_properties.h, color_resolution_context.calculation_resolution_context);
|
||||||
auto alpha_val = resolve_alpha(m_properties.alpha, resolution_context);
|
auto alpha_val = resolve_alpha(m_properties.alpha, color_resolution_context.calculation_resolution_context);
|
||||||
|
|
||||||
if (!raw_l_val.has_value() || !raw_c_val.has_value() || !raw_h_val.has_value() || !alpha_val.has_value())
|
if (!raw_l_val.has_value() || !raw_c_val.has_value() || !raw_h_val.has_value() || !alpha_val.has_value())
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -56,7 +56,7 @@ public:
|
||||||
}
|
}
|
||||||
virtual ~CSSLCH() override = default;
|
virtual ~CSSLCH() override = default;
|
||||||
|
|
||||||
virtual Optional<Color> to_color(Optional<Layout::NodeWithStyle const&>, CalculationResolutionContext const&) const override;
|
virtual Optional<Color> to_color(ColorResolutionContext) const override;
|
||||||
|
|
||||||
virtual String to_string(SerializationMode) const override;
|
virtual String to_string(SerializationMode) const override;
|
||||||
};
|
};
|
||||||
|
@ -70,7 +70,7 @@ public:
|
||||||
}
|
}
|
||||||
virtual ~CSSOKLCH() override = default;
|
virtual ~CSSOKLCH() override = default;
|
||||||
|
|
||||||
virtual Optional<Color> to_color(Optional<Layout::NodeWithStyle const&>, CalculationResolutionContext const&) const override;
|
virtual Optional<Color> to_color(ColorResolutionContext) const override;
|
||||||
|
|
||||||
virtual String to_string(SerializationMode) const override;
|
virtual String to_string(SerializationMode) const override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,12 +26,12 @@ bool CSSLabLike::equals(CSSStyleValue const& other) const
|
||||||
return m_properties == other_lab_like.m_properties;
|
return m_properties == other_lab_like.m_properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<Color> CSSOKLab::to_color(Optional<Layout::NodeWithStyle const&>, CalculationResolutionContext const& resolution_context) const
|
Optional<Color> CSSOKLab::to_color(ColorResolutionContext color_resolution_context) const
|
||||||
{
|
{
|
||||||
auto const l_val = resolve_with_reference_value(m_properties.l, 1.0, resolution_context);
|
auto const l_val = resolve_with_reference_value(m_properties.l, 1.0, color_resolution_context.calculation_resolution_context);
|
||||||
auto const a_val = resolve_with_reference_value(m_properties.a, 0.4, resolution_context);
|
auto const a_val = resolve_with_reference_value(m_properties.a, 0.4, color_resolution_context.calculation_resolution_context);
|
||||||
auto const b_val = resolve_with_reference_value(m_properties.b, 0.4, resolution_context);
|
auto const b_val = resolve_with_reference_value(m_properties.b, 0.4, color_resolution_context.calculation_resolution_context);
|
||||||
auto const alpha_val = resolve_alpha(m_properties.alpha, resolution_context);
|
auto const alpha_val = resolve_alpha(m_properties.alpha, color_resolution_context.calculation_resolution_context);
|
||||||
|
|
||||||
if (!l_val.has_value() || !a_val.has_value() || !b_val.has_value() || !alpha_val.has_value())
|
if (!l_val.has_value() || !a_val.has_value() || !b_val.has_value() || !alpha_val.has_value())
|
||||||
return {};
|
return {};
|
||||||
|
@ -59,12 +59,12 @@ String CSSOKLab::to_string(SerializationMode mode) const
|
||||||
return MUST(builder.to_string());
|
return MUST(builder.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<Color> CSSLab::to_color(Optional<Layout::NodeWithStyle const&>, CalculationResolutionContext const& resolution_context) const
|
Optional<Color> CSSLab::to_color(ColorResolutionContext color_resolution_context) const
|
||||||
{
|
{
|
||||||
auto l_val = resolve_with_reference_value(m_properties.l, 100, resolution_context);
|
auto l_val = resolve_with_reference_value(m_properties.l, 100, color_resolution_context.calculation_resolution_context);
|
||||||
auto a_val = resolve_with_reference_value(m_properties.a, 125, resolution_context);
|
auto a_val = resolve_with_reference_value(m_properties.a, 125, color_resolution_context.calculation_resolution_context);
|
||||||
auto b_val = resolve_with_reference_value(m_properties.b, 125, resolution_context);
|
auto b_val = resolve_with_reference_value(m_properties.b, 125, color_resolution_context.calculation_resolution_context);
|
||||||
auto alpha_val = resolve_alpha(m_properties.alpha, resolution_context);
|
auto alpha_val = resolve_alpha(m_properties.alpha, color_resolution_context.calculation_resolution_context);
|
||||||
|
|
||||||
if (!l_val.has_value() || !a_val.has_value() || !b_val.has_value() || !alpha_val.has_value())
|
if (!l_val.has_value() || !a_val.has_value() || !b_val.has_value() || !alpha_val.has_value())
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -51,7 +51,7 @@ protected:
|
||||||
// https://drafts.css-houdini.org/css-typed-om-1/#cssoklab
|
// https://drafts.css-houdini.org/css-typed-om-1/#cssoklab
|
||||||
class CSSOKLab final : public CSSLabLike {
|
class CSSOKLab final : public CSSLabLike {
|
||||||
public:
|
public:
|
||||||
virtual Optional<Color> to_color(Optional<Layout::NodeWithStyle const&>, CalculationResolutionContext const&) const override;
|
virtual Optional<Color> to_color(ColorResolutionContext) const override;
|
||||||
virtual String to_string(SerializationMode) const override;
|
virtual String to_string(SerializationMode) const override;
|
||||||
|
|
||||||
CSSOKLab(Badge<CSSLabLike>, ValueComparingNonnullRefPtr<CSSStyleValue const> l, ValueComparingNonnullRefPtr<CSSStyleValue const> a, ValueComparingNonnullRefPtr<CSSStyleValue const> b, ValueComparingNonnullRefPtr<CSSStyleValue const> alpha)
|
CSSOKLab(Badge<CSSLabLike>, ValueComparingNonnullRefPtr<CSSStyleValue const> l, ValueComparingNonnullRefPtr<CSSStyleValue const> a, ValueComparingNonnullRefPtr<CSSStyleValue const> b, ValueComparingNonnullRefPtr<CSSStyleValue const> alpha)
|
||||||
|
@ -63,7 +63,7 @@ public:
|
||||||
// https://drafts.css-houdini.org/css-typed-om-1/#csslab
|
// https://drafts.css-houdini.org/css-typed-om-1/#csslab
|
||||||
class CSSLab final : public CSSLabLike {
|
class CSSLab final : public CSSLabLike {
|
||||||
public:
|
public:
|
||||||
virtual Optional<Color> to_color(Optional<Layout::NodeWithStyle const&>, CalculationResolutionContext const&) const override;
|
virtual Optional<Color> to_color(ColorResolutionContext) const override;
|
||||||
virtual String to_string(SerializationMode) const override;
|
virtual String to_string(SerializationMode) const override;
|
||||||
|
|
||||||
CSSLab(Badge<CSSLabLike>, ValueComparingNonnullRefPtr<CSSStyleValue const> l, ValueComparingNonnullRefPtr<CSSStyleValue const> a, ValueComparingNonnullRefPtr<CSSStyleValue const> b, ValueComparingNonnullRefPtr<CSSStyleValue const> alpha)
|
CSSLab(Badge<CSSLabLike>, ValueComparingNonnullRefPtr<CSSStyleValue const> l, ValueComparingNonnullRefPtr<CSSStyleValue const> a, ValueComparingNonnullRefPtr<CSSStyleValue const> b, ValueComparingNonnullRefPtr<CSSStyleValue const> alpha)
|
||||||
|
|
|
@ -9,12 +9,12 @@
|
||||||
|
|
||||||
namespace Web::CSS {
|
namespace Web::CSS {
|
||||||
|
|
||||||
Optional<Color> CSSLightDark::to_color(Optional<Layout::NodeWithStyle const&> node, CalculationResolutionContext const& resolution_context) const
|
Optional<Color> CSSLightDark::to_color(ColorResolutionContext color_resolution_context) const
|
||||||
{
|
{
|
||||||
if (node.has_value() && node.value().computed_values().color_scheme() == PreferredColorScheme::Dark)
|
if (color_resolution_context.color_scheme == PreferredColorScheme::Dark)
|
||||||
return m_properties.dark->to_color(node, resolution_context);
|
return m_properties.dark->to_color(color_resolution_context);
|
||||||
|
|
||||||
return m_properties.light->to_color(node, resolution_context);
|
return m_properties.light->to_color(color_resolution_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSSLightDark::equals(CSSStyleValue const& other) const
|
bool CSSLightDark::equals(CSSStyleValue const& other) const
|
||||||
|
|
|
@ -21,7 +21,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool equals(CSSStyleValue const&) const override;
|
virtual bool equals(CSSStyleValue const&) const override;
|
||||||
virtual Optional<Color> to_color(Optional<Layout::NodeWithStyle const&>, CalculationResolutionContext const&) const override;
|
virtual Optional<Color> to_color(ColorResolutionContext) const override;
|
||||||
virtual String to_string(SerializationMode) const override;
|
virtual String to_string(SerializationMode) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -14,9 +14,9 @@
|
||||||
|
|
||||||
namespace Web::CSS {
|
namespace Web::CSS {
|
||||||
|
|
||||||
Optional<Color> CSSRGB::to_color(Optional<Layout::NodeWithStyle const&>, CalculationResolutionContext const& resolution_context) const
|
Optional<Color> CSSRGB::to_color(ColorResolutionContext color_resolution_context) const
|
||||||
{
|
{
|
||||||
auto resolve_rgb_to_u8 = [&resolution_context](CSSStyleValue const& style_value) -> Optional<u8> {
|
auto resolve_rgb_to_u8 = [&color_resolution_context](CSSStyleValue const& style_value) -> Optional<u8> {
|
||||||
// <number> | <percentage> | none
|
// <number> | <percentage> | none
|
||||||
auto normalized = [](double number) {
|
auto normalized = [](double number) {
|
||||||
if (isnan(number))
|
if (isnan(number))
|
||||||
|
@ -33,7 +33,7 @@ Optional<Color> CSSRGB::to_color(Optional<Layout::NodeWithStyle const&>, Calcula
|
||||||
if (style_value.is_calculated()) {
|
if (style_value.is_calculated()) {
|
||||||
auto const& calculated = style_value.as_calculated();
|
auto const& calculated = style_value.as_calculated();
|
||||||
if (calculated.resolves_to_number()) {
|
if (calculated.resolves_to_number()) {
|
||||||
auto maybe_number = calculated.resolve_number(resolution_context);
|
auto maybe_number = calculated.resolve_number(color_resolution_context.calculation_resolution_context);
|
||||||
|
|
||||||
if (!maybe_number.has_value())
|
if (!maybe_number.has_value())
|
||||||
return {};
|
return {};
|
||||||
|
@ -42,7 +42,7 @@ Optional<Color> CSSRGB::to_color(Optional<Layout::NodeWithStyle const&>, Calcula
|
||||||
}
|
}
|
||||||
|
|
||||||
if (calculated.resolves_to_percentage()) {
|
if (calculated.resolves_to_percentage()) {
|
||||||
auto maybe_percentage = calculated.resolve_percentage(resolution_context);
|
auto maybe_percentage = calculated.resolve_percentage(color_resolution_context.calculation_resolution_context);
|
||||||
|
|
||||||
if (!maybe_percentage.has_value())
|
if (!maybe_percentage.has_value())
|
||||||
return {};
|
return {};
|
||||||
|
@ -54,8 +54,8 @@ Optional<Color> CSSRGB::to_color(Optional<Layout::NodeWithStyle const&>, Calcula
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto resolve_alpha_to_u8 = [&resolution_context](CSSStyleValue const& style_value) -> Optional<u8> {
|
auto resolve_alpha_to_u8 = [&color_resolution_context](CSSStyleValue const& style_value) -> Optional<u8> {
|
||||||
auto alpha_0_1 = resolve_alpha(style_value, resolution_context);
|
auto alpha_0_1 = resolve_alpha(style_value, color_resolution_context.calculation_resolution_context);
|
||||||
if (alpha_0_1.has_value())
|
if (alpha_0_1.has_value())
|
||||||
return llround(clamp(alpha_0_1.value() * 255.0f, 0.0f, 255.0f));
|
return llround(clamp(alpha_0_1.value() * 255.0f, 0.0f, 255.0f));
|
||||||
return {};
|
return {};
|
||||||
|
@ -89,7 +89,7 @@ String CSSRGB::to_string(SerializationMode mode) const
|
||||||
if (mode != SerializationMode::ResolvedValue && m_properties.name.has_value())
|
if (mode != SerializationMode::ResolvedValue && m_properties.name.has_value())
|
||||||
return m_properties.name.value().to_string().to_ascii_lowercase();
|
return m_properties.name.value().to_string().to_ascii_lowercase();
|
||||||
|
|
||||||
if (auto color = to_color({}, {}); color.has_value())
|
if (auto color = to_color({}); color.has_value())
|
||||||
return serialize_a_srgb_value(color.value());
|
return serialize_a_srgb_value(color.value());
|
||||||
|
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
CSSStyleValue const& b() const { return *m_properties.b; }
|
CSSStyleValue const& b() const { return *m_properties.b; }
|
||||||
CSSStyleValue const& alpha() const { return *m_properties.alpha; }
|
CSSStyleValue const& alpha() const { return *m_properties.alpha; }
|
||||||
|
|
||||||
virtual Optional<Color> to_color(Optional<Layout::NodeWithStyle const&>, CalculationResolutionContext const&) const override;
|
virtual Optional<Color> to_color(ColorResolutionContext) const override;
|
||||||
|
|
||||||
virtual String to_string(SerializationMode) const override;
|
virtual String to_string(SerializationMode) const override;
|
||||||
|
|
||||||
|
|
|
@ -153,9 +153,9 @@ String ColorFunctionStyleValue::to_string(SerializationMode mode) const
|
||||||
convert_percentage(m_properties.channels[2])->to_string(mode)));
|
convert_percentage(m_properties.channels[2])->to_string(mode)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<Color> ColorFunctionStyleValue::to_color(Optional<Layout::NodeWithStyle const&>, CalculationResolutionContext const& resolution_context) const
|
Optional<Color> ColorFunctionStyleValue::to_color(ColorResolutionContext color_resolution_context) const
|
||||||
{
|
{
|
||||||
auto properties = resolve_properties(resolution_context);
|
auto properties = resolve_properties(color_resolution_context.calculation_resolution_context);
|
||||||
|
|
||||||
if (!properties.has_value())
|
if (!properties.has_value())
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -18,7 +18,7 @@ public:
|
||||||
static ValueComparingNonnullRefPtr<ColorFunctionStyleValue const> create(StringView color_space, ValueComparingNonnullRefPtr<CSSStyleValue const> c1, ValueComparingNonnullRefPtr<CSSStyleValue const> c2, ValueComparingNonnullRefPtr<CSSStyleValue const> c3, ValueComparingRefPtr<CSSStyleValue const> alpha = {});
|
static ValueComparingNonnullRefPtr<ColorFunctionStyleValue const> create(StringView color_space, ValueComparingNonnullRefPtr<CSSStyleValue const> c1, ValueComparingNonnullRefPtr<CSSStyleValue const> c2, ValueComparingNonnullRefPtr<CSSStyleValue const> c3, ValueComparingRefPtr<CSSStyleValue const> alpha = {});
|
||||||
|
|
||||||
virtual bool equals(CSSStyleValue const&) const override;
|
virtual bool equals(CSSStyleValue const&) const override;
|
||||||
virtual Optional<Color> to_color(Optional<Layout::NodeWithStyle const&>, CalculationResolutionContext const& resolution_context) const override;
|
virtual Optional<Color> to_color(ColorResolutionContext) const override;
|
||||||
virtual String to_string(SerializationMode) const override;
|
virtual String to_string(SerializationMode) const override;
|
||||||
|
|
||||||
virtual bool is_color_function() const override { return true; }
|
virtual bool is_color_function() const override { return true; }
|
||||||
|
|
|
@ -175,13 +175,13 @@ ColorMixStyleValue::PercentageNormalizationResult ColorMixStyleValue::normalize_
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-color-5/#color-mix-result
|
// https://drafts.csswg.org/css-color-5/#color-mix-result
|
||||||
Optional<Color> ColorMixStyleValue::to_color(Optional<Layout::NodeWithStyle const&> node, CalculationResolutionContext const& resolution_context) const
|
Optional<Color> ColorMixStyleValue::to_color(ColorResolutionContext color_resolution_context) const
|
||||||
{
|
{
|
||||||
// FIXME: Take the color space and hue interpolation method into account.
|
// FIXME: Take the color space and hue interpolation method into account.
|
||||||
// The current implementation only uses oklab interpolation.
|
// The current implementation only uses oklab interpolation.
|
||||||
auto normalized_percentages = normalize_percentages();
|
auto normalized_percentages = normalize_percentages();
|
||||||
auto from_color = m_properties.first_component.color->to_color(node, resolution_context);
|
auto from_color = m_properties.first_component.color->to_color(color_resolution_context);
|
||||||
auto to_color = m_properties.second_component.color->to_color(node, resolution_context);
|
auto to_color = m_properties.second_component.color->to_color(color_resolution_context);
|
||||||
auto delta = normalized_percentages.p2.value() / 100;
|
auto delta = normalized_percentages.p2.value() / 100;
|
||||||
|
|
||||||
if (!from_color.has_value() || !to_color.has_value())
|
if (!from_color.has_value() || !to_color.has_value())
|
||||||
|
|
|
@ -30,7 +30,7 @@ public:
|
||||||
static ValueComparingNonnullRefPtr<ColorMixStyleValue const> create(ColorInterpolationMethod, ColorMixComponent first_component, ColorMixComponent second_component);
|
static ValueComparingNonnullRefPtr<ColorMixStyleValue const> create(ColorInterpolationMethod, ColorMixComponent first_component, ColorMixComponent second_component);
|
||||||
|
|
||||||
virtual bool equals(CSSStyleValue const&) const override;
|
virtual bool equals(CSSStyleValue const&) const override;
|
||||||
virtual Optional<Color> to_color(Optional<Layout::NodeWithStyle const&>, CalculationResolutionContext const&) const override;
|
virtual Optional<Color> to_color(ColorResolutionContext) const override;
|
||||||
virtual String to_string(SerializationMode) const override;
|
virtual String to_string(SerializationMode) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1653,14 +1653,12 @@ void Document::obtain_theme_color()
|
||||||
|
|
||||||
// 4. If color is not failure, then return color.
|
// 4. If color is not failure, then return color.
|
||||||
if (!css_value.is_null() && css_value->has_color()) {
|
if (!css_value.is_null() && css_value->has_color()) {
|
||||||
Optional<Layout::NodeWithStyle const&> root_node;
|
CSS::ColorResolutionContext color_resolution_context {};
|
||||||
CSS::CalculationResolutionContext resolution_context;
|
|
||||||
if (html_element() && html_element()->layout_node()) {
|
if (html_element() && html_element()->layout_node()) {
|
||||||
root_node = *html_element()->layout_node();
|
color_resolution_context = CSS::ColorResolutionContext::for_layout_node_with_style(*html_element()->layout_node());
|
||||||
resolution_context.length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*html_element()->layout_node());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
theme_color = css_value->to_color(root_node, resolution_context).value();
|
theme_color = css_value->to_color(color_resolution_context).value();
|
||||||
return TraversalDecision::Break;
|
return TraversalDecision::Break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1144,8 +1144,7 @@ Optional<Utf16String> effective_command_value(GC::Ptr<DOM::Node> node, FlyString
|
||||||
if (!background_color.has_value())
|
if (!background_color.has_value())
|
||||||
return NumericLimits<u8>::max();
|
return NumericLimits<u8>::max();
|
||||||
VERIFY(is<Layout::NodeWithStyle>(node->layout_node()));
|
VERIFY(is<Layout::NodeWithStyle>(node->layout_node()));
|
||||||
auto& layout_node = *static_cast<Layout::NodeWithStyle*>(node->layout_node());
|
return background_color.value()->to_color(CSS::ColorResolutionContext::for_layout_node_with_style(*static_cast<Layout::NodeWithStyle*>(node->layout_node()))).value().alpha();
|
||||||
return background_color.value()->to_color(layout_node, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(layout_node) }).value().alpha();
|
|
||||||
};
|
};
|
||||||
while (resolved_background_alpha() == 0 && node->parent() && is<DOM::Element>(*node->parent()))
|
while (resolved_background_alpha() == 0 && node->parent() && is<DOM::Element>(*node->parent()))
|
||||||
node = node->parent();
|
node = node->parent();
|
||||||
|
|
|
@ -45,14 +45,13 @@ public:
|
||||||
// https://drafts.csswg.org/css-color/#parse-a-css-color-value
|
// https://drafts.csswg.org/css-color/#parse-a-css-color-value
|
||||||
auto style_value = parse_css_value(CSS::Parser::ParsingParams(), string, CSS::PropertyID::Color);
|
auto style_value = parse_css_value(CSS::Parser::ParsingParams(), string, CSS::PropertyID::Color);
|
||||||
if (style_value && style_value->has_color()) {
|
if (style_value && style_value->has_color()) {
|
||||||
Optional<Layout::NodeWithStyle const&> layout_node;
|
CSS::ColorResolutionContext color_resolution_context {};
|
||||||
CSS::CalculationResolutionContext resolution_context {};
|
|
||||||
if (context && context->layout_node()) {
|
if (context && context->layout_node()) {
|
||||||
layout_node = *context->layout_node();
|
color_resolution_context = CSS::ColorResolutionContext::for_layout_node_with_style(*context->layout_node());
|
||||||
resolution_context.length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*context->layout_node());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto parsedValue = style_value->to_color(layout_node, resolution_context).value_or(Color::Black);
|
auto parsedValue = style_value->to_color(color_resolution_context).value_or(Color::Black);
|
||||||
|
|
||||||
// 4. Set this's fill style to parsedValue.
|
// 4. Set this's fill style to parsedValue.
|
||||||
my_drawing_state().fill_style = parsedValue;
|
my_drawing_state().fill_style = parsedValue;
|
||||||
|
@ -98,14 +97,13 @@ public:
|
||||||
// https://drafts.csswg.org/css-color/#parse-a-css-color-value
|
// https://drafts.csswg.org/css-color/#parse-a-css-color-value
|
||||||
auto style_value = parse_css_value(CSS::Parser::ParsingParams(), string, CSS::PropertyID::Color);
|
auto style_value = parse_css_value(CSS::Parser::ParsingParams(), string, CSS::PropertyID::Color);
|
||||||
if (style_value && style_value->has_color()) {
|
if (style_value && style_value->has_color()) {
|
||||||
Optional<Layout::NodeWithStyle const&> layout_node;
|
CSS::ColorResolutionContext color_resolution_context {};
|
||||||
CSS::CalculationResolutionContext resolution_context {};
|
|
||||||
if (context && context->layout_node()) {
|
if (context && context->layout_node()) {
|
||||||
layout_node = *context->layout_node();
|
color_resolution_context = CSS::ColorResolutionContext::for_layout_node_with_style(*context->layout_node());
|
||||||
resolution_context.length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*context->layout_node());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto parsedValue = style_value->to_color(layout_node, resolution_context).value_or(Color::Black);
|
auto parsedValue = style_value->to_color(color_resolution_context).value_or(Color::Black);
|
||||||
|
|
||||||
// 4. Set this's stroke style to parsedValue.
|
// 4. Set this's stroke style to parsedValue.
|
||||||
my_drawing_state().stroke_style = parsedValue;
|
my_drawing_state().stroke_style = parsedValue;
|
||||||
|
|
|
@ -945,15 +945,13 @@ void CanvasRenderingContext2D::set_shadow_color(String color)
|
||||||
// 2. Let parsedValue be the result of parsing the given value with context if non-null.
|
// 2. Let parsedValue be the result of parsing the given value with context if non-null.
|
||||||
auto style_value = parse_css_value(CSS::Parser::ParsingParams(), color, CSS::PropertyID::Color);
|
auto style_value = parse_css_value(CSS::Parser::ParsingParams(), color, CSS::PropertyID::Color);
|
||||||
if (style_value && style_value->has_color()) {
|
if (style_value && style_value->has_color()) {
|
||||||
Optional<Layout::NodeWithStyle const&> layout_node;
|
CSS::ColorResolutionContext color_resolution_context {};
|
||||||
CSS::CalculationResolutionContext resolution_context;
|
|
||||||
|
|
||||||
if (auto node = context.layout_node()) {
|
if (auto node = context.layout_node()) {
|
||||||
layout_node = *node;
|
color_resolution_context = CSS::ColorResolutionContext::for_layout_node_with_style(*context.layout_node());
|
||||||
resolution_context.length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto parsedValue = style_value->to_color(layout_node, resolution_context).value_or(Color::Black);
|
auto parsedValue = style_value->to_color(color_resolution_context).value_or(Color::Black);
|
||||||
|
|
||||||
// 4. Set this's shadow color to parsedValue.
|
// 4. Set this's shadow color to parsedValue.
|
||||||
drawing_state().shadow_color = parsedValue;
|
drawing_state().shadow_color = parsedValue;
|
||||||
|
|
|
@ -288,7 +288,7 @@ void OffscreenCanvasRenderingContext2D::set_shadow_color(String color)
|
||||||
// 2. Let parsedValue be the result of parsing the given value with context if non-null.
|
// 2. Let parsedValue be the result of parsing the given value with context if non-null.
|
||||||
auto style_value = parse_css_value(CSS::Parser::ParsingParams(), color, CSS::PropertyID::Color);
|
auto style_value = parse_css_value(CSS::Parser::ParsingParams(), color, CSS::PropertyID::Color);
|
||||||
if (style_value && style_value->has_color()) {
|
if (style_value && style_value->has_color()) {
|
||||||
auto parsedValue = style_value->to_color({}, {}).value_or(Color::Black);
|
auto parsedValue = style_value->to_color({}).value_or(Color::Black);
|
||||||
|
|
||||||
// 4. Set this's shadow color to parsedValue.
|
// 4. Set this's shadow color to parsedValue.
|
||||||
drawing_state().shadow_color = parsedValue;
|
drawing_state().shadow_color = parsedValue;
|
||||||
|
|
|
@ -838,7 +838,7 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style)
|
||||||
do_border_style(computed_values.border_bottom(), CSS::PropertyID::BorderBottomWidth, CSS::PropertyID::BorderBottomColor, CSS::PropertyID::BorderBottomStyle);
|
do_border_style(computed_values.border_bottom(), CSS::PropertyID::BorderBottomWidth, CSS::PropertyID::BorderBottomColor, CSS::PropertyID::BorderBottomStyle);
|
||||||
|
|
||||||
if (auto const& outline_color = computed_style.property(CSS::PropertyID::OutlineColor); outline_color.has_color())
|
if (auto const& outline_color = computed_style.property(CSS::PropertyID::OutlineColor); outline_color.has_color())
|
||||||
computed_values.set_outline_color(outline_color.to_color(*this, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*this) }).value());
|
computed_values.set_outline_color(outline_color.to_color(CSS::ColorResolutionContext::for_layout_node_with_style(*this)).value());
|
||||||
if (auto const& outline_offset = computed_style.property(CSS::PropertyID::OutlineOffset); outline_offset.is_length())
|
if (auto const& outline_offset = computed_style.property(CSS::PropertyID::OutlineOffset); outline_offset.is_length())
|
||||||
computed_values.set_outline_offset(outline_offset.as_length().length());
|
computed_values.set_outline_offset(outline_offset.as_length().length());
|
||||||
computed_values.set_outline_style(computed_style.outline_style());
|
computed_values.set_outline_style(computed_style.outline_style());
|
||||||
|
@ -878,16 +878,16 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style)
|
||||||
|
|
||||||
auto const& fill = computed_style.property(CSS::PropertyID::Fill);
|
auto const& fill = computed_style.property(CSS::PropertyID::Fill);
|
||||||
if (fill.has_color())
|
if (fill.has_color())
|
||||||
computed_values.set_fill(fill.to_color(*this, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*this) }).value());
|
computed_values.set_fill(fill.to_color(CSS::ColorResolutionContext::for_layout_node_with_style(*this)).value());
|
||||||
else if (fill.is_url())
|
else if (fill.is_url())
|
||||||
computed_values.set_fill(fill.as_url().url());
|
computed_values.set_fill(fill.as_url().url());
|
||||||
auto const& stroke = computed_style.property(CSS::PropertyID::Stroke);
|
auto const& stroke = computed_style.property(CSS::PropertyID::Stroke);
|
||||||
if (stroke.has_color())
|
if (stroke.has_color())
|
||||||
computed_values.set_stroke(stroke.to_color(*this, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*this) }).value());
|
computed_values.set_stroke(stroke.to_color(CSS::ColorResolutionContext::for_layout_node_with_style(*this)).value());
|
||||||
else if (stroke.is_url())
|
else if (stroke.is_url())
|
||||||
computed_values.set_stroke(stroke.as_url().url());
|
computed_values.set_stroke(stroke.as_url().url());
|
||||||
if (auto const& stop_color = computed_style.property(CSS::PropertyID::StopColor); stop_color.has_color())
|
if (auto const& stop_color = computed_style.property(CSS::PropertyID::StopColor); stop_color.has_color())
|
||||||
computed_values.set_stop_color(stop_color.to_color(*this, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*this) }).value());
|
computed_values.set_stop_color(stop_color.to_color(CSS::ColorResolutionContext::for_layout_node_with_style(*this)).value());
|
||||||
auto const& stroke_width = computed_style.property(CSS::PropertyID::StrokeWidth);
|
auto const& stroke_width = computed_style.property(CSS::PropertyID::StrokeWidth);
|
||||||
// FIXME: Converting to pixels isn't really correct - values should be in "user units"
|
// FIXME: Converting to pixels isn't really correct - values should be in "user units"
|
||||||
// https://svgwg.org/svg2-draft/coords.html#TermUserUnits
|
// https://svgwg.org/svg2-draft/coords.html#TermUserUnits
|
||||||
|
|
|
@ -584,8 +584,7 @@ Optional<BordersData> borders_data_for_outline(Layout::Node const& layout_node,
|
||||||
if (outline_style == CSS::OutlineStyle::Auto) {
|
if (outline_style == CSS::OutlineStyle::Auto) {
|
||||||
// `auto` lets us do whatever we want for the outline. 2px of the accent colour seems reasonable.
|
// `auto` lets us do whatever we want for the outline. 2px of the accent colour seems reasonable.
|
||||||
line_style = CSS::LineStyle::Solid;
|
line_style = CSS::LineStyle::Solid;
|
||||||
// NOTE: CalculationResolutionContext is not required here as Accentcolor keyword value is guaranteed to not rely on it to resolve.
|
outline_color = CSS::CSSKeywordValue::create(CSS::Keyword::Accentcolor)->to_color(CSS::ColorResolutionContext::for_layout_node_with_style(*static_cast<Layout::NodeWithStyle const*>(&layout_node))).value();
|
||||||
outline_color = CSS::CSSKeywordValue::create(CSS::Keyword::Accentcolor)->to_color(*static_cast<Layout::NodeWithStyle const*>(&layout_node), {}).value();
|
|
||||||
outline_width = 2;
|
outline_width = 2;
|
||||||
} else {
|
} else {
|
||||||
line_style = CSS::keyword_to_line_style(CSS::to_keyword(outline_style)).value_or(CSS::LineStyle::None);
|
line_style = CSS::keyword_to_line_style(CSS::to_keyword(outline_style)).value_or(CSS::LineStyle::None);
|
||||||
|
|
|
@ -30,7 +30,7 @@ static ColorStopData resolve_color_stop_positions(Layout::NodeWithStyle const& n
|
||||||
|
|
||||||
resolved_color_stops.ensure_capacity(expanded_size);
|
resolved_color_stops.ensure_capacity(expanded_size);
|
||||||
for (auto& stop : color_stop_list) {
|
for (auto& stop : color_stop_list) {
|
||||||
auto resolved_stop = Gfx::ColorStop { .color = stop.color_stop.color->to_color(node, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(node) }).value() };
|
auto resolved_stop = Gfx::ColorStop { .color = stop.color_stop.color->to_color(CSS::ColorResolutionContext::for_layout_node_with_style(node)).value() };
|
||||||
for (int i = 0; i < color_stop_length(stop); i++)
|
for (int i = 0; i < color_stop_length(stop); i++)
|
||||||
resolved_color_stops.append(resolved_stop);
|
resolved_color_stops.append(resolved_stop);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue