Title: [225917] trunk
Revision
225917
Author
[email protected]
Date
2017-12-14 12:08:21 -0800 (Thu, 14 Dec 2017)

Log Message

[Web Animations] Implement the finish() method on Animation
https://bugs.webkit.org/show_bug.cgi?id=180822
<rdar://problem/36053282>

Reviewed by Dean Jackson.

Source/WebCore:

We implement the finish() method on the Animation interface with full spec text defining
the normative behavior of those methods and code matching those steps. Implementing the
finish() method required implementing the notion of "silently setting the current time",
which the Web Animations spec defines as well.

* animation/WebAnimation.cpp:
(WebCore::WebAnimation::silentlySetCurrentTime):
(WebCore::WebAnimation::setCurrentTime):
(WebCore::WebAnimation::finish):
* animation/WebAnimation.h:
* animation/WebAnimation.idl:

LayoutTests:

Rebase some WPT expectations with progressions due to exposing the finish() method.
We're also removing a WebKit-only test that is no longer relevant and started failing
with compliant behavior.

* http/wpt/web-animations/interfaces/Animation/idlharness-expected.txt:
* http/wpt/web-animations/timing-model/animations/set-the-timeline-of-an-animation-expected.txt:
* http/wpt/wk-web-animations/timing-model/animation-playback-rate-expected.txt: Removed.
* http/wpt/wk-web-animations/timing-model/animation-playback-rate.html: Removed.

Modified Paths

Removed Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (225916 => 225917)


--- trunk/LayoutTests/ChangeLog	2017-12-14 19:55:01 UTC (rev 225916)
+++ trunk/LayoutTests/ChangeLog	2017-12-14 20:08:21 UTC (rev 225917)
@@ -1,3 +1,20 @@
+2017-12-14  Antoine Quint  <[email protected]>
+
+        [Web Animations] Implement the finish() method on Animation
+        https://bugs.webkit.org/show_bug.cgi?id=180822
+        <rdar://problem/36053282>
+
+        Reviewed by Dean Jackson.
+
+        Rebase some WPT expectations with progressions due to exposing the finish() method.
+        We're also removing a WebKit-only test that is no longer relevant and started failing
+        with compliant behavior.
+
+        * http/wpt/web-animations/interfaces/Animation/idlharness-expected.txt:
+        * http/wpt/web-animations/timing-model/animations/set-the-timeline-of-an-animation-expected.txt:
+        * http/wpt/wk-web-animations/timing-model/animation-playback-rate-expected.txt: Removed.
+        * http/wpt/wk-web-animations/timing-model/animation-playback-rate.html: Removed.
+
 2017-12-14  Chris Dumez  <[email protected]>
 
         Service worker script fetching currently always uses the network cache

Modified: trunk/LayoutTests/http/wpt/web-animations/interfaces/Animation/idlharness-expected.txt (225916 => 225917)


--- trunk/LayoutTests/http/wpt/web-animations/interfaces/Animation/idlharness-expected.txt	2017-12-14 19:55:01 UTC (rev 225916)
+++ trunk/LayoutTests/http/wpt/web-animations/interfaces/Animation/idlharness-expected.txt	2017-12-14 20:08:21 UTC (rev 225917)
@@ -17,7 +17,7 @@
 PASS Animation interface: attribute onfinish 
 FAIL Animation interface: attribute oncancel assert_true: The prototype object must have a property "oncancel" expected true got false
 FAIL Animation interface: operation cancel() assert_own_property: interface prototype object missing non-static operation expected property "cancel" missing
-FAIL Animation interface: operation finish() assert_own_property: interface prototype object missing non-static operation expected property "finish" missing
+PASS Animation interface: operation finish() 
 PASS Animation interface: operation play() 
 PASS Animation interface: operation pause() 
 FAIL Animation interface: operation reverse() assert_own_property: interface prototype object missing non-static operation expected property "reverse" missing
@@ -35,7 +35,7 @@
 PASS Animation interface: new Animation() must inherit property "onfinish" with the proper type 
 FAIL Animation interface: new Animation() must inherit property "oncancel" with the proper type assert_inherits: property "oncancel" not found in prototype chain
 FAIL Animation interface: new Animation() must inherit property "cancel()" with the proper type assert_inherits: property "cancel" not found in prototype chain
-FAIL Animation interface: new Animation() must inherit property "finish()" with the proper type assert_inherits: property "finish" not found in prototype chain
+PASS Animation interface: new Animation() must inherit property "finish()" with the proper type 
 PASS Animation interface: new Animation() must inherit property "play()" with the proper type 
 PASS Animation interface: new Animation() must inherit property "pause()" with the proper type 
 FAIL Animation interface: new Animation() must inherit property "reverse()" with the proper type assert_inherits: property "reverse" not found in prototype chain

Modified: trunk/LayoutTests/http/wpt/web-animations/timing-model/animations/set-the-timeline-of-an-animation-expected.txt (225916 => 225917)


--- trunk/LayoutTests/http/wpt/web-animations/timing-model/animations/set-the-timeline-of-an-animation-expected.txt	2017-12-14 19:55:01 UTC (rev 225916)
+++ trunk/LayoutTests/http/wpt/web-animations/timing-model/animations/set-the-timeline-of-an-animation-expected.txt	2017-12-14 20:08:21 UTC (rev 225917)
@@ -1,6 +1,6 @@
 
-FAIL After setting timeline on paused animation it is still paused assert_equals: expected "paused" but got "finished"
-FAIL After setting timeline on animation paused outside active interval it is still paused assert_equals: expected "paused" but got "finished"
+PASS After setting timeline on paused animation it is still paused 
+PASS After setting timeline on animation paused outside active interval it is still paused 
 PASS After setting timeline on an idle animation without a start time it is still idle 
 FAIL After setting timeline on an idle animation with a start time it is running assert_equals: expected "idle" but got "finished"
 FAIL After setting timeline on an idle animation with a sufficiently ancient start time it is finished assert_equals: expected "idle" but got "finished"
@@ -8,7 +8,7 @@
 FAIL After setting timeline on a play-pending animation it begins playing after pending assert_equals: expected "pending" but got "finished"
 FAIL After setting timeline on a pause-pending animation it is still pending assert_equals: expected "pending" but got "paused"
 FAIL After setting timeline on a pause-pending animation it becomes paused after pending assert_equals: expected "pending" but got "paused"
-FAIL After clearing timeline on paused animation it is still paused assert_equals: expected "paused" but got "finished"
+PASS After clearing timeline on paused animation it is still paused 
 PASS After clearing timeline on finished animation it is idle 
 FAIL After clearing timeline on running animation it is idle assert_equals: expected "running" but got "finished"
 PASS After clearing timeline on idle animation it is still idle 

Deleted: trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/animation-playback-rate-expected.txt (225916 => 225917)


--- trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/animation-playback-rate-expected.txt	2017-12-14 19:55:01 UTC (rev 225916)
+++ trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/animation-playback-rate-expected.txt	2017-12-14 20:08:21 UTC (rev 225917)
@@ -1,8 +0,0 @@
-
-PASS Playback rate defaults to 1 
-PASS Correctly compute the current time based on the playback rate 
-PASS Correctly compute the start time based on the playback rate when setting current time 
-PASS Correctly compute the start time based on a playback rate < 1 when setting current time 
-PASS Correctly compute the start time based on a playback rate < 0 
-PASS Correctly compute a current time of 0 when playback rate is 0 
-

Deleted: trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/animation-playback-rate.html (225916 => 225917)


--- trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/animation-playback-rate.html	2017-12-14 19:55:01 UTC (rev 225916)
+++ trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/animation-playback-rate.html	2017-12-14 20:08:21 UTC (rev 225917)
@@ -1,80 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Tests for playback rate</title>
-<link rel="help" href=""
-<script src=""
-<script src=""
-<body>
-<div id="log"></div>
-<script>
-'use strict';
-
-internals.pauseTimeline(document.timeline);
-
-test(t => {
-  const animation = new Animation;
-
-  assert_equals(animation.playbackRate, 1);
-}, 'Playback rate defaults to 1');
-
-test(t => {
-  const animation = new Animation;
-  animation.startTime = 1000;
-  animation.playbackRate = 2;
-  internals.setTimelineCurrentTime(document.timeline, 3000);
-
-  assert_equals(animation.startTime, 1000);
-  assert_equals(animation.currentTime, 4000);
-  assert_equals(animation.playbackRate, 2);
-}, 'Correctly compute the current time based on the playback rate');
-
-test(t => {
-  const animation = new Animation;
-  animation.startTime = 2000;
-  animation.playbackRate = 2;
-  internals.setTimelineCurrentTime(document.timeline, 4000);
-
-  animation.currentTime = 3000;
-
-  assert_equals(animation.startTime, 2500);
-  assert_equals(animation.currentTime, 3000);
-  assert_equals(animation.playbackRate, 2);
-}, 'Correctly compute the start time based on the playback rate when setting current time');
-
-test(t => {
-  const animation = new Animation;
-  animation.startTime = 2000;
-  animation.playbackRate = 0.5;
-  internals.setTimelineCurrentTime(document.timeline, 4000);
-
-  animation.currentTime = 1000;
-
-  assert_equals(animation.startTime, 2000);
-  assert_equals(animation.currentTime, 1000);
-  assert_equals(animation.playbackRate, 0.5);
-}, 'Correctly compute the start time based on a playback rate < 1 when setting current time');
-
-test(t => {
-  const animation = new Animation;
-  animation.currentTime = 1000;
-  animation.playbackRate = -1;
-  internals.setTimelineCurrentTime(document.timeline, 4000);
-
-  assert_equals(animation.startTime, 5000);
-  assert_equals(animation.currentTime, 1000);
-  assert_equals(animation.playbackRate, -1);
-}, 'Correctly compute the start time based on a playback rate < 0');
-
-test(t => {
-  const animation = new Animation;
-  animation.playbackRate = 0;
-  animation.startTime = 0;
-  internals.setTimelineCurrentTime(document.timeline, 1000);
-
-  assert_equals(animation.startTime, 0);
-  assert_equals(animation.currentTime, 0);
-  assert_equals(animation.playbackRate, 0);
-}, 'Correctly compute a current time of 0 when playback rate is 0');
-
-</script>
-</body>

Modified: trunk/Source/WebCore/ChangeLog (225916 => 225917)


--- trunk/Source/WebCore/ChangeLog	2017-12-14 19:55:01 UTC (rev 225916)
+++ trunk/Source/WebCore/ChangeLog	2017-12-14 20:08:21 UTC (rev 225917)
@@ -1,3 +1,23 @@
+2017-12-14  Antoine Quint  <[email protected]>
+
+        [Web Animations] Implement the finish() method on Animation
+        https://bugs.webkit.org/show_bug.cgi?id=180822
+        <rdar://problem/36053282>
+
+        Reviewed by Dean Jackson.
+
+        We implement the finish() method on the Animation interface with full spec text defining
+        the normative behavior of those methods and code matching those steps. Implementing the
+        finish() method required implementing the notion of "silently setting the current time",
+        which the Web Animations spec defines as well.
+
+        * animation/WebAnimation.cpp:
+        (WebCore::WebAnimation::silentlySetCurrentTime):
+        (WebCore::WebAnimation::setCurrentTime):
+        (WebCore::WebAnimation::finish):
+        * animation/WebAnimation.h:
+        * animation/WebAnimation.idl:
+
 2017-12-14  Chris Dumez  <[email protected]>
 
         Service worker script fetching currently always uses the network cache

Modified: trunk/Source/WebCore/animation/WebAnimation.cpp (225916 => 225917)


--- trunk/Source/WebCore/animation/WebAnimation.cpp	2017-12-14 19:55:01 UTC (rev 225916)
+++ trunk/Source/WebCore/animation/WebAnimation.cpp	2017-12-14 20:08:21 UTC (rev 225917)
@@ -203,23 +203,70 @@
     return (m_timeline->currentTime().value() - m_startTime.value()) * m_playbackRate;
 }
 
-void WebAnimation::setCurrentTime(std::optional<Seconds> seekTime)
+ExceptionOr<void> WebAnimation::silentlySetCurrentTime(std::optional<Seconds> seekTime)
 {
-    // FIXME: account for hold time when we support it (webkit.org/b/178932),
-    // including situations where playbackRate is 0.
+    // 3.4.5. Setting the current time of an animation
+    // https://drafts.csswg.org/web-animations-1/#setting-the-current-time-of-an-animation
 
-    if (!m_timeline) {
-        setStartTime(std::nullopt);
-        return;
+    // 1. If seek time is an unresolved time value, then perform the following steps.
+    if (!seekTime) {
+        // 1. If the current time is resolved, then throw a TypeError.
+        if (currentTime())
+            return Exception { TypeError };
+        // 2. Abort these steps.
+        return { };
     }
 
-    auto timelineTime = m_timeline->currentTime();
-    if (!timelineTime) {
+    // 2. Update either animation's hold time or start time as follows:
+    // If any of the following conditions are true:
+    //     - animation's hold time is resolved, or
+    //     - animation's start time is unresolved, or
+    //     - animation has no associated timeline or the associated timeline is inactive, or
+    //     - animation's playback rate is 0,
+    // Set animation's hold time to seek time.
+    // Otherwise, set animation's start time to the result of evaluating timeline time - (seek time / playback rate)
+    // where timeline time is the current time value of timeline associated with animation.
+    if (m_holdTime || !startTime() || !m_timeline || !m_timeline->currentTime() || !m_playbackRate)
+        m_holdTime = seekTime;
+    else
+        setStartTime(m_timeline->currentTime().value() - (seekTime.value() / m_playbackRate));
+
+    // 3. If animation has no associated timeline or the associated timeline is inactive, make animation's start time unresolved.
+    if (!m_timeline || !m_timeline->currentTime())
         setStartTime(std::nullopt);
-        return;
+
+    // 4. Make animation's previous current time unresolved.
+    m_previousCurrentTime = std::nullopt;
+
+    return { };
+}
+
+ExceptionOr<void> WebAnimation::setCurrentTime(std::optional<Seconds> seekTime)
+{
+    // 3.4.5. Setting the current time of an animation
+    // https://drafts.csswg.org/web-animations-1/#setting-the-current-time-of-an-animation
+
+    // 1. Run the steps to silently set the current time of animation to seek time.
+    auto silentResult = silentlySetCurrentTime(seekTime);
+    if (silentResult.hasException())
+        return silentResult.releaseException();
+
+    // 2. If animation has a pending pause task, synchronously complete the pause operation by performing the following steps:
+    if (hasPendingPauseTask()) {
+        // 1. Set animation's hold time to seek time.
+        m_holdTime = seekTime;
+        // 2. Make animation's start time unresolved.
+        setStartTime(std::nullopt);
+        // 3. Cancel the pending pause task.
+        setTimeToRunPendingPauseTask(TimeToRunPendingTask::NotScheduled);
+        // 4. Resolve animation's current ready promise with animation.
+        m_readyPromise.resolve(*this);
     }
 
-    setStartTime(timelineTime.value() - (seekTime.value() / m_playbackRate));
+    // 3. Run the procedure to update an animation's finished state for animation with the did seek flag set to true, and the synchronously notify flag set to false.
+    updateFinishedState(DidSeek::Yes, SynchronouslyNotify::No);
+
+    return { };
 }
 
 void WebAnimation::setPlaybackRate(double newPlaybackRate)
@@ -289,6 +336,52 @@
     }
 }
 
+ExceptionOr<void> WebAnimation::finish()
+{
+    // 3.4.15. Finishing an animation
+    // https://drafts.csswg.org/web-animations-1/#finishing-an-animation-section
+
+    // An animation can be advanced to the natural end of its current playback direction by using the procedure to finish an animation for animation defined below:
+    //
+    // 1. If animation playback rate is zero, or if animation playback rate > 0 and target effect end is infinity, throw an InvalidStateError and abort these steps.
+    if (!m_playbackRate || (m_playbackRate > 0 && effectEndTime() == Seconds::infinity()))
+        return Exception { InvalidStateError };
+
+    // 2. Set limit as follows:
+    // If animation playback rate > 0, let limit be target effect end.
+    // Otherwise, let limit be zero.
+    auto limit = m_playbackRate > 0 ? effectEndTime() : 0_s;
+
+    // 3. Silently set the current time to limit.
+    silentlySetCurrentTime(limit);
+
+    // 4. If animation's start time is unresolved and animation has an associated active timeline, let the start time be the result of
+    //    evaluating timeline time - (limit / playback rate) where timeline time is the current time value of the associated timeline.
+    if (!startTime() && m_timeline && m_timeline->currentTime())
+        setStartTime(m_timeline->currentTime().value() - (limit / m_playbackRate));
+
+    // 5. If there is a pending pause task and start time is resolved,
+    if (hasPendingPauseTask() && startTime()) {
+        // 1. Let the hold time be unresolved.
+        m_holdTime = std::nullopt;
+        // 2. Cancel the pending pause task.
+        setTimeToRunPendingPauseTask(TimeToRunPendingTask::NotScheduled);
+        // 3. Resolve the current ready promise of animation with animation.
+        m_readyPromise.resolve(*this);
+    }
+
+    // 6. If there is a pending play task and start time is resolved, cancel that task and resolve the current ready promise of animation with animation.
+    if (hasPendingPlayTask() && startTime()) {
+        setTimeToRunPendingPlayTask(TimeToRunPendingTask::NotScheduled);
+        m_readyPromise.resolve(*this);
+    }
+
+    // 7. Run the procedure to update an animation's finished state animation with the did seek flag set to true, and the synchronously notify flag set to true.
+    updateFinishedState(DidSeek::Yes, SynchronouslyNotify::Yes);
+
+    return { };
+}
+
 void WebAnimation::updateFinishedState(DidSeek didSeek, SynchronouslyNotify synchronouslyNotify)
 {
     // 3.4.14. Updating the finished state

Modified: trunk/Source/WebCore/animation/WebAnimation.h (225916 => 225917)


--- trunk/Source/WebCore/animation/WebAnimation.h	2017-12-14 19:55:01 UTC (rev 225916)
+++ trunk/Source/WebCore/animation/WebAnimation.h	2017-12-14 20:08:21 UTC (rev 225917)
@@ -62,7 +62,7 @@
     std::optional<double> bindingsCurrentTime() const;
     ExceptionOr<void> setBindingsCurrentTime(std::optional<double>);
     std::optional<Seconds> currentTime() const;
-    void setCurrentTime(std::optional<Seconds>);
+    ExceptionOr<void> setCurrentTime(std::optional<Seconds>);
 
     double playbackRate() const { return m_playbackRate; }
     void setPlaybackRate(double);
@@ -78,6 +78,7 @@
     using FinishedPromise = DOMPromiseProxyWithResolveCallback<IDLInterface<WebAnimation>>;
     FinishedPromise& finished() { return m_finishedPromise; }
 
+    ExceptionOr<void> finish();
     ExceptionOr<void> play();
     ExceptionOr<void> pause();
 
@@ -107,6 +108,7 @@
     WebAnimation& readyPromiseResolve();
     WebAnimation& finishedPromiseResolve();
     std::optional<Seconds> currentTime(RespectHoldTime) const;
+    ExceptionOr<void> silentlySetCurrentTime(std::optional<Seconds>);
     void finishNotificationSteps();
     void scheduleMicrotaskIfNeeded();
     void performMicrotask();

Modified: trunk/Source/WebCore/animation/WebAnimation.idl (225916 => 225917)


--- trunk/Source/WebCore/animation/WebAnimation.idl	2017-12-14 19:55:01 UTC (rev 225916)
+++ trunk/Source/WebCore/animation/WebAnimation.idl	2017-12-14 20:08:21 UTC (rev 225917)
@@ -48,6 +48,7 @@
     attribute EventHandler onfinish;
     readonly attribute Promise<WebAnimation> ready;
     readonly attribute Promise<WebAnimation> finished;
+    [MayThrowException] void finish();
     [MayThrowException] void play();
     [MayThrowException] void pause();
 };
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to