Quellcode durchsuchen

LibWeb: Correctly set timing function in AnimationEffect::update_timing

Also pulls out the parse_easing_string function out since it will be
needed elsewhere
Matthew Olsson vor 1 Jahr
Ursprung
Commit
62f62a0e52

+ 22 - 1
Userland/Libraries/LibWeb/Animations/AnimationEffect.cpp

@@ -9,6 +9,7 @@
 #include <LibWeb/Animations/AnimationEffect.h>
 #include <LibWeb/Animations/AnimationTimeline.h>
 #include <LibWeb/Bindings/Intrinsics.h>
+#include <LibWeb/CSS/Parser/Parser.h>
 #include <LibWeb/DOM/Element.h>
 #include <LibWeb/WebIDL/ExceptionOr.h>
 
@@ -181,8 +182,14 @@ WebIDL::ExceptionOr<void> AnimationEffect::update_timing(OptionalEffectTiming ti
         m_playback_direction = timing.direction.value();
 
     //    - easing → timing function
-    if (timing.easing.has_value())
+    if (timing.easing.has_value()) {
         m_easing_function = timing.easing.value();
+        if (auto timing_function = parse_easing_string(realm(), m_easing_function)) {
+            m_timing_function = TimingFunction::from_easing_style_value(timing_function->as_easing());
+        } else {
+            m_timing_function = Animations::linear_timing_function;
+        }
+    }
 
     if (auto animation = m_associated_animation)
         animation->effect_timing_changed({});
@@ -580,6 +587,20 @@ Optional<double> AnimationEffect::transformed_progress() const
     return m_timing_function(directed_progress.value(), before_flag);
 }
 
+RefPtr<CSS::StyleValue const> AnimationEffect::parse_easing_string(JS::Realm& realm, StringView value)
+{
+    auto maybe_parser = CSS::Parser::Parser::create(CSS::Parser::ParsingContext(realm), value);
+    if (maybe_parser.is_error())
+        return {};
+
+    if (auto style_value = maybe_parser.release_value().parse_as_css_value(CSS::PropertyID::AnimationTimingFunction)) {
+        if (style_value->is_easing())
+            return style_value;
+    }
+
+    return {};
+}
+
 AnimationEffect::AnimationEffect(JS::Realm& realm)
     : Bindings::PlatformObject(realm)
 {

+ 2 - 0
Userland/Libraries/LibWeb/Animations/AnimationEffect.h

@@ -65,6 +65,8 @@ class AnimationEffect : public Bindings::PlatformObject {
     JS_DECLARE_ALLOCATOR(AnimationEffect);
 
 public:
+    static RefPtr<CSS::StyleValue const> parse_easing_string(JS::Realm& realm, StringView value);
+
     static JS::NonnullGCPtr<AnimationEffect> create(JS::Realm&);
 
     EffectTiming get_timing() const;

+ 3 - 15
Userland/Libraries/LibWeb/Animations/KeyframeEffect.cpp

@@ -287,19 +287,6 @@ static WebIDL::ExceptionOr<Vector<BaseKeyframe>> process_a_keyframes_argument(JS
 {
     auto& vm = realm.vm();
 
-    auto parse_easing_string = [&](auto& value) -> RefPtr<CSS::StyleValue const> {
-        auto maybe_parser = CSS::Parser::Parser::create(CSS::Parser::ParsingContext(realm), value);
-        if (maybe_parser.is_error())
-            return {};
-
-        if (auto style_value = maybe_parser.release_value().parse_as_css_value(CSS::PropertyID::AnimationTimingFunction)) {
-            if (style_value->is_easing())
-                return style_value;
-        }
-
-        return {};
-    };
-
     // 1. If object is null, return an empty sequence of keyframes.
     if (!object)
         return Vector<BaseKeyframe> {};
@@ -525,7 +512,7 @@ static WebIDL::ExceptionOr<Vector<BaseKeyframe>> process_a_keyframes_argument(JS
         //
         //    If parsing the "easing" property fails, throw a TypeError and abort this procedure.
         auto easing_string = keyframe.easing.get<String>();
-        auto easing_value = parse_easing_string(easing_string);
+        auto easing_value = AnimationEffect::parse_easing_string(realm, easing_string);
 
         if (!easing_value)
             return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, MUST(String::formatted("Invalid animation easing value: \"{}\"", easing_string)) };
@@ -537,7 +524,7 @@ static WebIDL::ExceptionOr<Vector<BaseKeyframe>> process_a_keyframes_argument(JS
     //    interface, and if any of the values fail to parse, throw a TypeError and abort this procedure.
     for (auto& unused_easing : unused_easings) {
         auto easing_string = unused_easing.get<String>();
-        auto easing_value = parse_easing_string(easing_string);
+        auto easing_value = AnimationEffect::parse_easing_string(realm, easing_string);
         if (!easing_value)
             return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, MUST(String::formatted("Invalid animation easing value: \"{}\"", easing_string)) };
     }
@@ -729,6 +716,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<KeyframeEffect>> KeyframeEffect::construct_
 
     //     - timing function.
     effect->m_easing_function = source->m_easing_function;
+    effect->m_timing_function = source->m_timing_function;
 
     return effect;
 }