From 18477b0d84879d134221f706ea6466a546f0a84e Mon Sep 17 00:00:00 2001 From: Callum Law Date: Sun, 26 Oct 2025 17:39:01 +1300 Subject: [PATCH] LibWeb: Promote `animation-composition` values to enum This brings us in line with the other `animation-*` enum properties (`animation-play-state` and `animation-fill-mode`) --- Libraries/LibWeb/Animations/KeyframeEffect.cpp | 14 ++++++++++++++ Libraries/LibWeb/Animations/KeyframeEffect.h | 2 ++ Libraries/LibWeb/CSS/Enums.json | 5 +++++ Libraries/LibWeb/CSS/Properties.json | 6 ++---- Libraries/LibWeb/CSS/StyleComputer.cpp | 16 ++++------------ 5 files changed, 27 insertions(+), 16 deletions(-) diff --git a/Libraries/LibWeb/Animations/KeyframeEffect.cpp b/Libraries/LibWeb/Animations/KeyframeEffect.cpp index 02ed7876607..47af1ee7aa8 100644 --- a/Libraries/LibWeb/Animations/KeyframeEffect.cpp +++ b/Libraries/LibWeb/Animations/KeyframeEffect.cpp @@ -936,4 +936,18 @@ void KeyframeEffect::update_computed_properties(AnimationUpdateContext& context) target->document().style_computer().collect_animation_into(abstract_element, *this, *computed_properties); } +Bindings::CompositeOperation css_animation_composition_to_bindings_composite_operation(CSS::AnimationComposition composition) +{ + switch (composition) { + case CSS::AnimationComposition::Accumulate: + return Bindings::CompositeOperation::Accumulate; + case CSS::AnimationComposition::Add: + return Bindings::CompositeOperation::Add; + case CSS::AnimationComposition::Replace: + return Bindings::CompositeOperation::Replace; + default: + VERIFY_NOT_REACHED(); + } +} + } diff --git a/Libraries/LibWeb/Animations/KeyframeEffect.h b/Libraries/LibWeb/Animations/KeyframeEffect.h index 037b5aab074..f3dabd19cd1 100644 --- a/Libraries/LibWeb/Animations/KeyframeEffect.h +++ b/Libraries/LibWeb/Animations/KeyframeEffect.h @@ -25,6 +25,8 @@ struct KeyframeEffectOptions : public EffectTiming { Optional pseudo_element {}; }; +Bindings::CompositeOperation css_animation_composition_to_bindings_composite_operation(CSS::AnimationComposition composition); + // https://www.w3.org/TR/web-animations-1/#dictdef-basepropertyindexedkeyframe // Note: This is an intermediate structure used only when parsing Keyframes provided by the caller in a slightly // different format. It is converted to BaseKeyframe, which is why it doesn't need to store the parsed properties diff --git a/Libraries/LibWeb/CSS/Enums.json b/Libraries/LibWeb/CSS/Enums.json index 22a89dd5218..32909689b85 100644 --- a/Libraries/LibWeb/CSS/Enums.json +++ b/Libraries/LibWeb/CSS/Enums.json @@ -71,6 +71,11 @@ "self-inline", "width" ], + "animation-composition": [ + "replace", + "add", + "accumulate" + ], "animation-direction": [ "alternate", "alternate-reverse", diff --git a/Libraries/LibWeb/CSS/Properties.json b/Libraries/LibWeb/CSS/Properties.json index 15ee83502ff..227467c7b75 100644 --- a/Libraries/LibWeb/CSS/Properties.json +++ b/Libraries/LibWeb/CSS/Properties.json @@ -237,10 +237,8 @@ "animation-type": "none", "inherited": false, "initial": "replace", - "valid-identifiers": [ - "replace", - "add", - "accumulate" + "valid-types": [ + "animation-composition" ] }, "animation-delay": { diff --git a/Libraries/LibWeb/CSS/StyleComputer.cpp b/Libraries/LibWeb/CSS/StyleComputer.cpp index a999e9ad95d..1e0563d3a5a 100644 --- a/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -1247,18 +1247,10 @@ static void apply_animation_properties(DOM::Document& document, CascadedProperti if (auto timing_property = cascaded_properties.property(PropertyID::AnimationTimingFunction); timing_property && (timing_property->is_easing() || (timing_property->is_keyword() && !timing_property->is_css_wide_keyword()))) timing_function = EasingFunction::from_style_value(timing_property.release_nonnull()); - Bindings::CompositeOperation composite_operation { Bindings::CompositeOperation::Replace }; + AnimationComposition animation_composition { AnimationComposition::Replace }; if (auto composite_property = cascaded_properties.property(PropertyID::AnimationComposition); composite_property) { - switch (composite_property->to_keyword()) { - case Keyword::Add: - composite_operation = Bindings::CompositeOperation::Add; - break; - case Keyword::Accumulate: - composite_operation = Bindings::CompositeOperation::Accumulate; - break; - default: - break; - } + if (auto animation_composition_value = keyword_to_animation_composition(composite_property->to_keyword()); animation_composition_value.has_value()) + animation_composition = *animation_composition_value; } auto iteration_duration = duration.has_value() @@ -1270,7 +1262,7 @@ static void apply_animation_properties(DOM::Document& document, CascadedProperti effect.set_timing_function(move(timing_function)); effect.set_fill_mode(Animations::css_fill_mode_to_bindings_fill_mode(fill_mode)); effect.set_playback_direction(Animations::css_animation_direction_to_bindings_playback_direction(direction)); - effect.set_composite(composite_operation); + effect.set_composite(Animations::css_animation_composition_to_bindings_composite_operation(animation_composition)); if (play_state != effect.last_css_animation_play_state()) { if (play_state == CSS::AnimationPlayState::Running && animation.play_state() != Bindings::AnimationPlayState::Running) {