@@ -581,7 +581,7 @@ static Optional<GridTrackSizeList> interpolate_grid_track_size_list(DOM::Element
581581 return result;
582582}
583583
584- ValueComparingRefPtr<StyleValue const > interpolate_property (DOM ::Element& element, PropertyID property_id, StyleValue const & a_from, StyleValue const & a_to, float delta, AllowDiscrete allow_discrete)
584+ ValueComparingRefPtr<StyleValue const > interpolate_property (DOM ::Element& element, PropertyID property_id, StyleValue const & a_from, StyleValue const & a_to, float delta, AllowDiscrete allow_discrete, ColorResolutionContext const * color_resolution_context )
585585{
586586 auto from = with_keyword_values_resolved (element, property_id, a_from);
587587 auto to = with_keyword_values_resolved (element, property_id, a_to);
@@ -591,11 +591,11 @@ ValueComparingRefPtr<StyleValue const> interpolate_property(DOM::Element& elemen
591591 auto animation_type = animation_type_from_longhand_property (property_id);
592592 switch (animation_type) {
593593 case AnimationType::ByComputedValue:
594- return interpolate_value (element, calculation_context, from, to, delta, allow_discrete);
594+ return interpolate_value (element, calculation_context, from, to, delta, allow_discrete, color_resolution_context );
595595 case AnimationType::None:
596596 return to;
597597 case AnimationType::RepeatableList:
598- return interpolate_repeatable_list (element, calculation_context, from, to, delta, allow_discrete);
598+ return interpolate_repeatable_list (element, calculation_context, from, to, delta, allow_discrete, color_resolution_context );
599599 case AnimationType::Custom: {
600600 if (property_id == PropertyID::Transform) {
601601 if (auto interpolated_transform = interpolate_transform (element, calculation_context, from, to, delta, allow_discrete))
@@ -617,7 +617,7 @@ ValueComparingRefPtr<StyleValue const> interpolate_property(DOM::Element& elemen
617617 static auto const & oblique_0deg_value = FontStyleStyleValue::create (FontStyleKeyword::Oblique, AngleStyleValue::create (Angle::make_degrees (0 ))).leak_ref ();
618618 auto from_value = from->as_font_style ().font_style () == FontStyleKeyword::Normal ? ValueComparingNonnullRefPtr<StyleValue const > { oblique_0deg_value } : from;
619619 auto to_value = to->as_font_style ().font_style () == FontStyleKeyword::Normal ? ValueComparingNonnullRefPtr<StyleValue const > { oblique_0deg_value } : to;
620- return interpolate_value (element, calculation_context, from_value, to_value, delta, allow_discrete);
620+ return interpolate_value (element, calculation_context, from_value, to_value, delta, allow_discrete, color_resolution_context );
621621 }
622622
623623 if (property_id == PropertyID::FontVariationSettings) {
@@ -632,7 +632,7 @@ ValueComparingRefPtr<StyleValue const> interpolate_property(DOM::Element& elemen
632632
633633 // The values in these lists have already been deduplicated and sorted at this point, so we can use
634634 // interpolate_value() to interpolate them pairwise.
635- return interpolate_value (element, calculation_context, from, to, delta, allow_discrete);
635+ return interpolate_value (element, calculation_context, from, to, delta, allow_discrete, color_resolution_context );
636636 }
637637
638638 // https://drafts.csswg.org/web-animations-1/#animating-visibility
@@ -754,7 +754,7 @@ ValueComparingRefPtr<StyleValue const> interpolate_property(DOM::Element& elemen
754754
755755 // Otherwise, repeat both dash patterns of start and end value list until the length of elements in
756756 // both value lists match. Each item is then combined by computed value.
757- if (auto result = interpolate_repeatable_list (element, calculation_context, from, to, delta, allow_discrete))
757+ if (auto result = interpolate_repeatable_list (element, calculation_context, from, to, delta, allow_discrete, color_resolution_context ))
758758 return result.release_nonnull ();
759759 return interpolate_discrete (from, to, delta, allow_discrete);
760760 }
@@ -1507,8 +1507,21 @@ static NonnullRefPtr<StyleValue const> length_percentage_or_auto_to_style_value(
15071507 VERIFY_NOT_REACHED ();
15081508}
15091509
1510- static RefPtr<StyleValue const > interpolate_value_impl (DOM ::Element& element, CalculationContext const & calculation_context, StyleValue const & from, StyleValue const & to, float delta, AllowDiscrete allow_discrete)
1510+ static RefPtr<StyleValue const > interpolate_value_impl (DOM ::Element& element, CalculationContext const & calculation_context, StyleValue const & from, StyleValue const & to, float delta, AllowDiscrete allow_discrete, ColorResolutionContext const * color_resolution_context )
15111511{
1512+ ColorResolutionContext fallback_color_resolution_context {};
1513+ if (from.has_color () && to.has_color ()) {
1514+ if (!color_resolution_context) {
1515+ if (auto * node = element.unsafe_layout_node ())
1516+ fallback_color_resolution_context = ColorResolutionContext::for_layout_node_with_style (*node);
1517+ color_resolution_context = &fallback_color_resolution_context;
1518+ }
1519+ if (auto interpolated = interpolate_color (from, to, delta, {}, *color_resolution_context))
1520+ return interpolated;
1521+ if (from.type () == StyleValue::Type::Color && to.type () == StyleValue::Type::Color)
1522+ return ColorStyleValue::create_from_color (Color::Black, ColorSyntax::Modern);
1523+ }
1524+
15121525 if (from.type () != to.type () || from.is_calculated () || to.is_calculated ()) {
15131526 // Handle mixed percentage and dimension types, as well as CalculatedStyleValues
15141527 // https://www.w3.org/TR/css-values-4/#mixed-percentages
@@ -1594,7 +1607,7 @@ static RefPtr<StyleValue const> interpolate_value_impl(DOM::Element& element, Ca
15941607 // If both shapes are the same type, that type is ellipse() or circle(), and the radiuses are specified
15951608 // as <length-percentage> (rather than keywords), interpolate between each value in the shape functions.
15961609 auto const & to_circle = to_shape.get <Circle>();
1597- auto interpolated_radius = interpolate_value_impl (element, basic_shape_calculation_context, from_circle.radius , to_circle.radius , delta, AllowDiscrete::No);
1610+ auto interpolated_radius = interpolate_value_impl (element, basic_shape_calculation_context, from_circle.radius , to_circle.radius , delta, AllowDiscrete::No, color_resolution_context );
15981611 auto interpolated_position = interpolate_optional_position (from_circle.position , to_circle.position );
15991612 if (!interpolated_radius || !interpolated_position.has_value ())
16001613 return {};
@@ -1603,7 +1616,7 @@ static RefPtr<StyleValue const> interpolate_value_impl(DOM::Element& element, Ca
16031616 },
16041617 [&](Ellipse const & from_ellipse) -> Optional<BasicShape> {
16051618 auto const & to_ellipse = to_shape.get <Ellipse>();
1606- auto interpolated_radius = interpolate_value_impl (element, basic_shape_calculation_context, from_ellipse.radius , to_ellipse.radius , delta, AllowDiscrete::No);
1619+ auto interpolated_radius = interpolate_value_impl (element, basic_shape_calculation_context, from_ellipse.radius , to_ellipse.radius , delta, AllowDiscrete::No, color_resolution_context );
16071620 auto interpolated_position = interpolate_optional_position (from_ellipse.position , to_ellipse.position );
16081621 if (!interpolated_radius || !interpolated_position.has_value ())
16091622 return {};
@@ -1646,8 +1659,8 @@ static RefPtr<StyleValue const> interpolate_value_impl(DOM::Element& element, Ca
16461659 auto const & to_horizontal_radius = to.as_border_radius ().horizontal_radius ();
16471660 auto const & from_vertical_radius = from.as_border_radius ().vertical_radius ();
16481661 auto const & to_vertical_radius = to.as_border_radius ().vertical_radius ();
1649- auto interpolated_horizontal_radius = interpolate_value_impl (element, calculation_context, from_horizontal_radius, to_horizontal_radius, delta, allow_discrete);
1650- auto interpolated_vertical_radius = interpolate_value_impl (element, calculation_context, from_vertical_radius, to_vertical_radius, delta, allow_discrete);
1662+ auto interpolated_horizontal_radius = interpolate_value_impl (element, calculation_context, from_horizontal_radius, to_horizontal_radius, delta, allow_discrete, color_resolution_context );
1663+ auto interpolated_vertical_radius = interpolate_value_impl (element, calculation_context, from_vertical_radius, to_vertical_radius, delta, allow_discrete, color_resolution_context );
16511664 if (!interpolated_horizontal_radius || !interpolated_vertical_radius)
16521665 return {};
16531666 return BorderRadiusStyleValue::create (interpolated_horizontal_radius.release_nonnull (), interpolated_vertical_radius.release_nonnull ());
@@ -1670,31 +1683,23 @@ static RefPtr<StyleValue const> interpolate_value_impl(DOM::Element& element, Ca
16701683 auto const & from_bottom_left = from.as_border_radius_rect ().bottom_left ();
16711684 auto const & to_bottom_left = to.as_border_radius_rect ().bottom_left ();
16721685
1673- auto interpolated_top_left = interpolate_value_impl (element, border_radius_rect_computation_context, from_top_left, to_top_left, delta, allow_discrete);
1674- auto interpolated_top_right = interpolate_value_impl (element, border_radius_rect_computation_context, from_top_right, to_top_right, delta, allow_discrete);
1675- auto interpolated_bottom_right = interpolate_value_impl (element, border_radius_rect_computation_context, from_bottom_right, to_bottom_right, delta, allow_discrete);
1676- auto interpolated_bottom_left = interpolate_value_impl (element, border_radius_rect_computation_context, from_bottom_left, to_bottom_left, delta, allow_discrete);
1686+ auto interpolated_top_left = interpolate_value_impl (element, border_radius_rect_computation_context, from_top_left, to_top_left, delta, allow_discrete, color_resolution_context );
1687+ auto interpolated_top_right = interpolate_value_impl (element, border_radius_rect_computation_context, from_top_right, to_top_right, delta, allow_discrete, color_resolution_context );
1688+ auto interpolated_bottom_right = interpolate_value_impl (element, border_radius_rect_computation_context, from_bottom_right, to_bottom_right, delta, allow_discrete, color_resolution_context );
1689+ auto interpolated_bottom_left = interpolate_value_impl (element, border_radius_rect_computation_context, from_bottom_left, to_bottom_left, delta, allow_discrete, color_resolution_context );
16771690
16781691 if (!interpolated_top_left || !interpolated_top_right || !interpolated_bottom_right || !interpolated_bottom_left)
16791692 return {};
16801693
16811694 return BorderRadiusRectStyleValue::create (interpolated_top_left.release_nonnull (), interpolated_top_right.release_nonnull (), interpolated_bottom_right.release_nonnull (), interpolated_bottom_left.release_nonnull ());
16821695 }
1683- case StyleValue::Type::Color: {
1684- // NB: Called during style interpolation.
1685- ColorResolutionContext color_resolution_context {};
1686- if (auto * node = element.unsafe_layout_node ())
1687- color_resolution_context = ColorResolutionContext::for_layout_node_with_style (*node);
1688-
1689- if (auto interpolated = interpolate_color (from, to, delta, {}, color_resolution_context))
1690- return interpolated;
1691- return ColorStyleValue::create_from_color (Color::Black, ColorSyntax::Modern);
1692- }
1696+ case StyleValue::Type::Color:
1697+ VERIFY_NOT_REACHED ();
16931698 case StyleValue::Type::Edge: {
16941699 auto const & from_offset = from.as_edge ().offset ();
16951700 auto const & to_offset = to.as_edge ().offset ();
16961701
1697- if (auto interpolated_value = interpolate_value_impl (element, calculation_context, from_offset, to_offset, delta, allow_discrete))
1702+ if (auto interpolated_value = interpolate_value_impl (element, calculation_context, from_offset, to_offset, delta, allow_discrete, color_resolution_context ))
16981703 return EdgeStyleValue::create ({}, interpolated_value);
16991704
17001705 return {};
@@ -1846,10 +1851,10 @@ static RefPtr<StyleValue const> interpolate_value_impl(DOM::Element& element, Ca
18461851 auto const & from_rect = from.as_rect ();
18471852 auto const & to_rect = to.as_rect ();
18481853
1849- auto interpolated_top = interpolate_value_impl (element, calculation_context, from_rect.top (), to_rect.top (), delta, allow_discrete);
1850- auto interpolated_right = interpolate_value_impl (element, calculation_context, from_rect.right (), to_rect.right (), delta, allow_discrete);
1851- auto interpolated_bottom = interpolate_value_impl (element, calculation_context, from_rect.bottom (), to_rect.bottom (), delta, allow_discrete);
1852- auto interpolated_left = interpolate_value_impl (element, calculation_context, from_rect.left (), to_rect.left (), delta, allow_discrete);
1854+ auto interpolated_top = interpolate_value_impl (element, calculation_context, from_rect.top (), to_rect.top (), delta, allow_discrete, color_resolution_context );
1855+ auto interpolated_right = interpolate_value_impl (element, calculation_context, from_rect.right (), to_rect.right (), delta, allow_discrete, color_resolution_context );
1856+ auto interpolated_bottom = interpolate_value_impl (element, calculation_context, from_rect.bottom (), to_rect.bottom (), delta, allow_discrete, color_resolution_context );
1857+ auto interpolated_left = interpolate_value_impl (element, calculation_context, from_rect.left (), to_rect.left (), delta, allow_discrete, color_resolution_context );
18531858
18541859 if (!interpolated_top || !interpolated_right || !interpolated_bottom || !interpolated_left)
18551860 return {};
@@ -1966,7 +1971,7 @@ static RefPtr<StyleValue const> interpolate_value_impl(DOM::Element& element, Ca
19661971 StyleValueVector interpolated_values;
19671972 interpolated_values.ensure_capacity (from_list.size ());
19681973 for (size_t i = 0 ; i < from_list.size (); ++i) {
1969- auto interpolated = interpolate_value (element, calculation_context, from_list.values ()[i], to_list.values ()[i], delta, AllowDiscrete::No);
1974+ auto interpolated = interpolate_value (element, calculation_context, from_list.values ()[i], to_list.values ()[i], delta, AllowDiscrete::No, color_resolution_context );
19701975 if (!interpolated)
19711976 return {};
19721977
@@ -1980,7 +1985,7 @@ static RefPtr<StyleValue const> interpolate_value_impl(DOM::Element& element, Ca
19801985 }
19811986}
19821987
1983- RefPtr<StyleValue const > interpolate_repeatable_list (DOM ::Element& element, CalculationContext const & calculation_context, StyleValue const & from, StyleValue const & to, float delta, AllowDiscrete allow_discrete)
1988+ RefPtr<StyleValue const > interpolate_repeatable_list (DOM ::Element& element, CalculationContext const & calculation_context, StyleValue const & from, StyleValue const & to, float delta, AllowDiscrete allow_discrete, ColorResolutionContext const * color_resolution_context )
19841989{
19851990 // https://www.w3.org/TR/web-animations/#repeatable-list
19861991 // Same as by computed value except that if the two lists have differing numbers of items, they are first repeated to the least common multiple number of items.
@@ -1993,7 +1998,7 @@ RefPtr<StyleValue const> interpolate_repeatable_list(DOM::Element& element, Calc
19931998 // then the property values combine as discrete
19941999 auto list_size = AK::lcm (from_list.size (), to_list.size ());
19952000 for (size_t i = 0 ; i < list_size; ++i) {
1996- auto value = interpolate_value (element, calculation_context, from_list.value_at (i, true ), to_list.value_at (i, true ), delta, AllowDiscrete::No);
2001+ auto value = interpolate_value (element, calculation_context, from_list.value_at (i, true ), to_list.value_at (i, true ), delta, AllowDiscrete::No, color_resolution_context );
19972002 if (!value)
19982003 return false ;
19992004 append_callback (*value);
@@ -2017,7 +2022,7 @@ RefPtr<StyleValue const> interpolate_repeatable_list(DOM::Element& element, Calc
20172022 else if (!to.is_value_list () && from.is_value_list ())
20182023 to_list = make_single_value_list (to, from.as_value_list ().size (), from.as_value_list ().separator ());
20192024 else if (!from.is_value_list () && !to.is_value_list ())
2020- return interpolate_value (element, calculation_context, from, to, delta, allow_discrete);
2025+ return interpolate_value (element, calculation_context, from, to, delta, allow_discrete, color_resolution_context );
20212026
20222027 StyleValueVector interpolated_values;
20232028 if (!make_repeatable_list (from_list->as_value_list (), to_list->as_value_list (), [&](auto const & value) { interpolated_values.append (value); }))
@@ -2153,9 +2158,9 @@ static StyleValueVector accumulate_filter_function(StyleValueList const& underly
21532158 return result;
21542159}
21552160
2156- RefPtr<StyleValue const > interpolate_value (DOM ::Element& element, CalculationContext const & calculation_context, StyleValue const & from, StyleValue const & to, float delta, AllowDiscrete allow_discrete)
2161+ RefPtr<StyleValue const > interpolate_value (DOM ::Element& element, CalculationContext const & calculation_context, StyleValue const & from, StyleValue const & to, float delta, AllowDiscrete allow_discrete, ColorResolutionContext const * color_resolution_context )
21572162{
2158- if (auto result = interpolate_value_impl (element, calculation_context, from, to, delta, allow_discrete))
2163+ if (auto result = interpolate_value_impl (element, calculation_context, from, to, delta, allow_discrete, color_resolution_context ))
21592164 return result;
21602165 return interpolate_discrete (from, to, delta, allow_discrete);
21612166}
0 commit comments