Title: [224897] trunk
Revision
224897
Author
grao...@webkit.org
Date
2017-11-15 13:35:38 -0800 (Wed, 15 Nov 2017)

Log Message

[Web Animations] Implement basic to-from animations
https://bugs.webkit.org/show_bug.cgi?id=179707
<rdar://problem/34932456>

Source/WebCore:

We can now actually perform an animation, in software only, when provided two keyframes on an AnimationEffect.
To parse a keyframes object from JS, we use the StyleResolver to create RenderStyle objects based on the strings
provided for the property names and values. Then, when the DocumentTimeline indicates that animations are ready
to be updated, we invalidate the style of elements with animations, so that during style resolution we can perform
blending between the RenderStyles for each keyframe.

Reviewed by Dean Jackson.

* animation/AnimationEffect.h:
(WebCore::AnimationEffect::~AnimationEffect): Deleted.
* animation/AnimationTimeline.h:
(WebCore::AnimationTimeline::elementToAnimationsMap const):
* animation/DocumentTimeline.cpp:
(WebCore::DocumentTimeline::animationResolutionTimerFired):
(WebCore::DocumentTimeline::updateAnimations): Renamed from resolveAnimations() since we're not
actually resolving animations, merely invalidating styles in preparation for resolution.
(WebCore::DocumentTimeline::resolveAnimations): Deleted.
* animation/DocumentTimeline.h:
* animation/KeyframeEffect.cpp:
(WebCore::KeyframeEffect::create): Pass the keyframes argument to setKeyframes() and forward the
exception in case one was raised in the setter.
(WebCore::KeyframeEffect::setKeyframes): Pass the keyframes argument to processKeyframes() and
forward the exception in case one was raised during processing.
(WebCore::KeyframeEffect::processKeyframes): Deal with exactly two keyframes, set at 0 and 1 offsets,
specified in array forms for the keyframes object. As we parse the content of the provided JS object,
we create RenderStyle objects using the element's StyleResolver from a CSS text string we create
based on the property and values as strings.
(WebCore::KeyframeEffect::applyAtLocalTime): Compute the progress based on the local time and duration,
using the existing CSSPropertyAnimation::blendProperties() mechanics to perform the blend between the
from and to keyframes.
* animation/KeyframeEffect.h:
* animation/KeyframeEffect.idl:
* animation/WebAnimation.cpp:
(WebCore::WebAnimation::resolve):
* animation/WebAnimation.h:
* bindings/IDLTypes.h:
(WebCore::IDLObject::nullValue): Make JSC::Strong an optional type.
* dom/Document.h:
(WebCore::Document::existingTimeline const): Provide an explicit method for call sites to check existence
of a timeline before forcing one to be created if missing by calling timeline().
* dom/Element.cpp:
(WebCore::Element::getAnimations): Do not force the creation of a timeline if one isn't already created.
* style/StyleTreeResolver.cpp:
(WebCore::Style::TreeResolver::createAnimatedElementUpdate): When applying styles, account for any Web
Animation applied to the provided element.

LayoutTests:

Reviewed by Dean Jackson.

Update existing tests to explicitly pass null for keyframes and update WPT expectations.

* http/wpt/web-animations/interfaces/AnimationTimeline/document-timeline-expected.txt:
* http/wpt/web-animations/interfaces/KeyframeEffect/constructor-expected.txt:
* http/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001-expected.txt:
* http/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-002-expected.txt:
* http/wpt/web-animations/interfaces/KeyframeEffect/setKeyframes-expected.txt:
* http/wpt/wk-web-animations/interfaces/element-get-animations.html:
* http/wpt/wk-web-animations/timing-model/animation-creation-basic.html:
* http/wpt/wk-web-animations/timing-model/animation-effect-unique-relationship.html:
* http/wpt/wk-web-animations/timing-model/animation-interface-effect-property.html:
* http/wpt/wk-web-animations/timing-model/keyframe-effect-expected.txt:
* http/wpt/wk-web-animations/timing-model/keyframe-effect-interface-timing-duration.html:
* http/wpt/wk-web-animations/timing-model/keyframe-effect.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (224896 => 224897)


--- trunk/LayoutTests/ChangeLog	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/LayoutTests/ChangeLog	2017-11-15 21:35:38 UTC (rev 224897)
@@ -1,3 +1,26 @@
+2017-11-15  Antoine Quint  <grao...@apple.com>
+
+        [Web Animations] Implement basic to-from animations
+        https://bugs.webkit.org/show_bug.cgi?id=179707
+        <rdar://problem/34932456>
+
+        Reviewed by Dean Jackson.
+
+        Update existing tests to explicitly pass null for keyframes and update WPT expectations.
+
+        * http/wpt/web-animations/interfaces/AnimationTimeline/document-timeline-expected.txt:
+        * http/wpt/web-animations/interfaces/KeyframeEffect/constructor-expected.txt:
+        * http/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001-expected.txt:
+        * http/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-002-expected.txt:
+        * http/wpt/web-animations/interfaces/KeyframeEffect/setKeyframes-expected.txt:
+        * http/wpt/wk-web-animations/interfaces/element-get-animations.html:
+        * http/wpt/wk-web-animations/timing-model/animation-creation-basic.html:
+        * http/wpt/wk-web-animations/timing-model/animation-effect-unique-relationship.html:
+        * http/wpt/wk-web-animations/timing-model/animation-interface-effect-property.html:
+        * http/wpt/wk-web-animations/timing-model/keyframe-effect-expected.txt:
+        * http/wpt/wk-web-animations/timing-model/keyframe-effect-interface-timing-duration.html:
+        * http/wpt/wk-web-animations/timing-model/keyframe-effect.html:
+
 2017-11-15  Frederic Wang  <fw...@igalia.com>
 
         ASSERTION FAILED: !renderer->needsLayout() in WebCore::RenderBlock::checkPositionedObjectsNeedLayout with MathML

Modified: trunk/LayoutTests/http/wpt/web-animations/interfaces/AnimationTimeline/document-timeline-expected.txt (224896 => 224897)


--- trunk/LayoutTests/http/wpt/web-animations/interfaces/AnimationTimeline/document-timeline-expected.txt	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/LayoutTests/http/wpt/web-animations/interfaces/AnimationTimeline/document-timeline-expected.txt	2017-11-15 21:35:38 UTC (rev 224897)
@@ -1,6 +1,6 @@
 
 PASS document.timeline identity tests 
-FAIL document.timeline.currentTime value tests assert_equals: document.timeline.currentTime matches requestAnimationFrame time expected 552.3000000000001 but got 0.5538000000000001
+FAIL document.timeline.currentTime value tests assert_equals: document.timeline.currentTime matches requestAnimationFrame time expected 852.9 but got 0.8540000000000001
 PASS document.timeline.currentTime liveness tests 
 PASS iframe document.timeline.currentTime liveness tests 
 PASS document.timeline.currentTime time should be the same for all RAF callbacks in a frame 

Modified: trunk/LayoutTests/http/wpt/web-animations/interfaces/KeyframeEffect/constructor-expected.txt (224896 => 224897)


--- trunk/LayoutTests/http/wpt/web-animations/interfaces/KeyframeEffect/constructor-expected.txt	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/LayoutTests/http/wpt/web-animations/interfaces/KeyframeEffect/constructor-expected.txt	2017-11-15 21:35:38 UTC (rev 224897)
@@ -199,5 +199,5 @@
 PASS KeyframeEffect constructor creates an AnimationEffectTiming timing object 
 FAIL KeyframeEffect constructor propagates exceptions generated by accessing the options object assert_throws: function "function () {
     new KeyframeEffect(target, { get left() { throw test_error }})
-  }" did not throw
+  }" threw object "TypeError: Type error" ("TypeError") expected object "[object Object]" ("test")
 

Modified: trunk/LayoutTests/http/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001-expected.txt (224896 => 224897)


--- trunk/LayoutTests/http/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001-expected.txt	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/LayoutTests/http/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001-expected.txt	2017-11-15 21:35:38 UTC (rev 224897)
@@ -55,5 +55,5 @@
 FAIL Only properties defined directly on keyframes are read effect.getKeyframes is not a function. (In 'effect.getKeyframes()', 'effect.getKeyframes' is undefined)
 FAIL Only enumerable properties on property-indexed keyframes are read effect.getKeyframes is not a function. (In 'effect.getKeyframes()', 'effect.getKeyframes' is undefined)
 FAIL Only properties defined directly on property-indexed keyframes are read effect.getKeyframes is not a function. (In 'effect.getKeyframes()', 'effect.getKeyframes' is undefined)
-FAIL Properties are read in ascending order by Unicode codepoint assert_array_equals: property access order lengths differ, expected 5 got 0
+FAIL Properties are read in ascending order by Unicode codepoint assert_array_equals: property access order property 0, expected "composite" but got "marginLeft"
 

Modified: trunk/LayoutTests/http/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-002-expected.txt (224896 => 224897)


--- trunk/LayoutTests/http/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-002-expected.txt	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/LayoutTests/http/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-002-expected.txt	2017-11-15 21:35:38 UTC (rev 224897)
@@ -1,15 +1,9 @@
 
-FAIL easing values are parsed correctly when set on a property-indexed keyframe effect.getKeyframes is not a function. (In 'effect.getKeyframes()', 'effect.getKeyframes' is undefined)
+FAIL easing values are parsed correctly when set on a property-indexed keyframe Type error
 FAIL easing values are parsed correctly when using a keyframe sequence effect.getKeyframes is not a function. (In 'effect.getKeyframes()', 'effect.getKeyframes' is undefined)
-FAIL Invalid easing values are correctly rejected when set on a property-indexed keyframe assert_throws: TypeError is thrown for easing '' function "() => {
-      new KeyframeEffect(target, { easing: invalidEasing });
-    }" did not throw
-FAIL Invalid easing values are correctly rejected when using a keyframe sequence assert_throws: TypeError is thrown for easing '' function "() => {
-      new KeyframeEffect(target, [{ easing: invalidEasing }]);
-    }" did not throw
-FAIL Errors from invalid easings on a property-indexed keyframe are thrown after reading all properties assert_throws: function "() => {
-    new KeyframeEffect(target, keyframe);
-  }" did not throw
+PASS Invalid easing values are correctly rejected when set on a property-indexed keyframe 
+PASS Invalid easing values are correctly rejected when using a keyframe sequence 
+FAIL Errors from invalid easings on a property-indexed keyframe are thrown after reading all properties assert_equals: All properties were read before throwing the easing error expected 2 but got 0
 FAIL Errors from invalid easings on a keyframe sequence are thrown after reading all properties assert_throws: function "() => {
     new KeyframeEffect(target, [ kf1, kf2 ]);
   }" did not throw

Modified: trunk/LayoutTests/http/wpt/web-animations/interfaces/KeyframeEffect/setKeyframes-expected.txt (224896 => 224897)


--- trunk/LayoutTests/http/wpt/web-animations/interfaces/KeyframeEffect/setKeyframes-expected.txt	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/LayoutTests/http/wpt/web-animations/interfaces/KeyframeEffect/setKeyframes-expected.txt	2017-11-15 21:35:38 UTC (rev 224897)
@@ -1,49 +1,49 @@
 
-FAIL Keyframes can be replaced with an empty keyframe effect.setKeyframes is not a function. (In 'effect.setKeyframes(frame)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a one property two value property-indexed keyframes specification effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a one shorthand property two value property-indexed keyframes specification effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a two property (one shorthand and one of its longhand components) two value property-indexed keyframes specification effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a two property two value property-indexed keyframes specification effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a two property property-indexed keyframes specification with different numbers of values effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a property-indexed keyframes specification with an invalid value effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a one property two value property-indexed keyframes specification that needs to stringify its values effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a property-indexed keyframes specification with a CSS variable reference effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a property-indexed keyframes specification with a CSS variable reference in a shorthand property effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a one property one value property-indexed keyframes specification effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a one property one non-array value property-indexed keyframes specification effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a one property two value property-indexed keyframes specification where the first value is invalid effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a one property two value property-indexed keyframes specification where the second value is invalid effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a one property one keyframe sequence effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a one property two keyframe sequence effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a two property two keyframe sequence effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a one shorthand property two keyframe sequence effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a two property (a shorthand and one of its component longhands) two keyframe sequence effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a keyframe sequence with duplicate values for a given interior offset effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a keyframe sequence with duplicate values for offsets 0 and 1 effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a two property four keyframe sequence effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a single keyframe sequence with omitted offset effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a single keyframe sequence with null offset effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a single keyframe sequence with string offset effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a one property keyframe sequence with some omitted offsets effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a one property keyframe sequence with some null offsets effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a two property keyframe sequence with some omitted offsets effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a one property keyframe sequence with all omitted offsets effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a keyframe sequence with different easing values, but the same easing value for a given offset effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a keyframe sequence with different composite values, but the same composite value for a given offset effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a one property two keyframe sequence that needs to stringify its values effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a keyframe sequence with a CSS variable reference effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a keyframe sequence with a CSS variable reference in a shorthand property effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a keyframe sequence where shorthand precedes longhand effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a keyframe sequence where longhand precedes shorthand effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a keyframe sequence where lesser shorthand precedes greater shorthand effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a keyframe sequence where greater shorthand precedes lesser shorthand effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a two property keyframe sequence where one property is missing from the first keyframe effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a two property keyframe sequence where one property is missing from the last keyframe effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-FAIL Keyframes can be replaced with a keyframe sequence with repeated values at offset 1 with different easings effect.setKeyframes is not a function. (In 'effect.setKeyframes(subtest.input)', 'effect.setKeyframes' is undefined)
-PASS KeyframeEffect constructor throws with keyframes with an out-of-bounded positive offset 
-PASS KeyframeEffect constructor throws with keyframes with an out-of-bounded negative offset 
-PASS KeyframeEffect constructor throws with keyframes not loosely sorted by offset 
-PASS KeyframeEffect constructor throws with property-indexed keyframes with an invalid easing value 
-PASS KeyframeEffect constructor throws with a keyframe sequence with an invalid easing value 
-PASS KeyframeEffect constructor throws with keyframes with an invalid composite value 
+FAIL Keyframes can be replaced with an empty keyframe Type error
+FAIL Keyframes can be replaced with a one property two value property-indexed keyframes specification Type error
+FAIL Keyframes can be replaced with a one shorthand property two value property-indexed keyframes specification Type error
+FAIL Keyframes can be replaced with a two property (one shorthand and one of its longhand components) two value property-indexed keyframes specification Type error
+FAIL Keyframes can be replaced with a two property two value property-indexed keyframes specification Type error
+FAIL Keyframes can be replaced with a two property property-indexed keyframes specification with different numbers of values Type error
+FAIL Keyframes can be replaced with a property-indexed keyframes specification with an invalid value Type error
+FAIL Keyframes can be replaced with a one property two value property-indexed keyframes specification that needs to stringify its values Type error
+FAIL Keyframes can be replaced with a property-indexed keyframes specification with a CSS variable reference Type error
+FAIL Keyframes can be replaced with a property-indexed keyframes specification with a CSS variable reference in a shorthand property Type error
+FAIL Keyframes can be replaced with a one property one value property-indexed keyframes specification Type error
+FAIL Keyframes can be replaced with a one property one non-array value property-indexed keyframes specification Type error
+FAIL Keyframes can be replaced with a one property two value property-indexed keyframes specification where the first value is invalid Type error
+FAIL Keyframes can be replaced with a one property two value property-indexed keyframes specification where the second value is invalid Type error
+FAIL Keyframes can be replaced with a one property one keyframe sequence Type error
+FAIL Keyframes can be replaced with a one property two keyframe sequence Type error
+FAIL Keyframes can be replaced with a two property two keyframe sequence Type error
+FAIL Keyframes can be replaced with a one shorthand property two keyframe sequence Type error
+FAIL Keyframes can be replaced with a two property (a shorthand and one of its component longhands) two keyframe sequence Type error
+FAIL Keyframes can be replaced with a keyframe sequence with duplicate values for a given interior offset Type error
+FAIL Keyframes can be replaced with a keyframe sequence with duplicate values for offsets 0 and 1 Type error
+FAIL Keyframes can be replaced with a two property four keyframe sequence Type error
+FAIL Keyframes can be replaced with a single keyframe sequence with omitted offset Type error
+FAIL Keyframes can be replaced with a single keyframe sequence with null offset Type error
+FAIL Keyframes can be replaced with a single keyframe sequence with string offset Type error
+FAIL Keyframes can be replaced with a one property keyframe sequence with some omitted offsets Type error
+FAIL Keyframes can be replaced with a one property keyframe sequence with some null offsets Type error
+FAIL Keyframes can be replaced with a two property keyframe sequence with some omitted offsets Type error
+FAIL Keyframes can be replaced with a one property keyframe sequence with all omitted offsets Type error
+FAIL Keyframes can be replaced with a keyframe sequence with different easing values, but the same easing value for a given offset Type error
+FAIL Keyframes can be replaced with a keyframe sequence with different composite values, but the same composite value for a given offset Type error
+FAIL Keyframes can be replaced with a one property two keyframe sequence that needs to stringify its values Type error
+FAIL Keyframes can be replaced with a keyframe sequence with a CSS variable reference Type error
+FAIL Keyframes can be replaced with a keyframe sequence with a CSS variable reference in a shorthand property Type error
+FAIL Keyframes can be replaced with a keyframe sequence where shorthand precedes longhand Type error
+FAIL Keyframes can be replaced with a keyframe sequence where longhand precedes shorthand Type error
+FAIL Keyframes can be replaced with a keyframe sequence where lesser shorthand precedes greater shorthand Type error
+FAIL Keyframes can be replaced with a keyframe sequence where greater shorthand precedes lesser shorthand Type error
+FAIL Keyframes can be replaced with a two property keyframe sequence where one property is missing from the first keyframe Type error
+FAIL Keyframes can be replaced with a two property keyframe sequence where one property is missing from the last keyframe Type error
+FAIL Keyframes can be replaced with a keyframe sequence with repeated values at offset 1 with different easings Type error
+FAIL KeyframeEffect constructor throws with keyframes with an out-of-bounded positive offset Type error
+FAIL KeyframeEffect constructor throws with keyframes with an out-of-bounded negative offset Type error
+FAIL KeyframeEffect constructor throws with keyframes not loosely sorted by offset Type error
+FAIL KeyframeEffect constructor throws with property-indexed keyframes with an invalid easing value Type error
+FAIL KeyframeEffect constructor throws with a keyframe sequence with an invalid easing value Type error
+FAIL KeyframeEffect constructor throws with keyframes with an invalid composite value Type error
 

Modified: trunk/LayoutTests/http/wpt/wk-web-animations/interfaces/element-get-animations.html (224896 => 224897)


--- trunk/LayoutTests/http/wpt/wk-web-animations/interfaces/element-get-animations.html	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/LayoutTests/http/wpt/wk-web-animations/interfaces/element-get-animations.html	2017-11-15 21:35:38 UTC (rev 224897)
@@ -13,9 +13,9 @@
 const targetA = document.createElement("a");
 const targetB = document.createElement("b");
 
-const effectAa = new KeyframeEffect(targetA);
-const effectAb = new KeyframeEffect(targetA);
-const effectB = new KeyframeEffect(targetB);
+const effectAa = new KeyframeEffect(targetA, null);
+const effectAb = new KeyframeEffect(targetA, null);
+const effectB = new KeyframeEffect(targetB, null);
 
 test(t => {
     assert_true(typeof targetA.getAnimations === "function");

Modified: trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/animation-creation-basic.html (224896 => 224897)


--- trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/animation-creation-basic.html	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/animation-creation-basic.html	2017-11-15 21:35:38 UTC (rev 224897)
@@ -33,7 +33,7 @@
 }, "Creating Animation with a null argument should have a null effect and the document timeline.");
 
 test(t => {
-    const effect = new KeyframeEffect(document.body);
+    const effect = new KeyframeEffect(document.body, null);
     const animation = new Animation(effect);
     assert_equals(animation.effect, effect);
     assert_equals(animation.timeline, document.timeline);

Modified: trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/animation-effect-unique-relationship.html (224896 => 224897)


--- trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/animation-effect-unique-relationship.html	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/animation-effect-unique-relationship.html	2017-11-15 21:35:38 UTC (rev 224897)
@@ -9,8 +9,8 @@
 'use strict';
 
 test(t => {
-    const effectA = new KeyframeEffect(document.createElement("div"));
-    const effectB = new KeyframeEffect(document.createElement("div"));
+    const effectA = new KeyframeEffect(document.createElement("div"), null);
+    const effectB = new KeyframeEffect(document.createElement("div"), null);
 
     const a = new Animation(effectA);
     const b = new Animation(effectB);

Modified: trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/animation-interface-effect-property.html (224896 => 224897)


--- trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/animation-interface-effect-property.html	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/animation-interface-effect-property.html	2017-11-15 21:35:38 UTC (rev 224897)
@@ -17,7 +17,7 @@
 
 test(t => {
     const animation = new Animation;
-    const effect = new KeyframeEffect(document.body);
+    const effect = new KeyframeEffect(document.body, null);
     animation.effect = effect;
     assert_equals(animation.effect, effect);
 }, "The animation.effect property can be set to a KeyframeEffect object.");
@@ -24,10 +24,10 @@
 
 test(t => {
     const animation = new Animation;
-    const effectA = new KeyframeEffect(document.body);
+    const effectA = new KeyframeEffect(document.body, null);
     animation.effect = effectA;
     assert_equals(animation.effect, effectA);
-    const effectB = new KeyframeEffect(document.body);
+    const effectB = new KeyframeEffect(document.body, null);
     animation.effect = effectB;
     assert_equals(animation.effect, effectB);
 }, "The animation.effect property can be set to another KeyframeEffect object.");
@@ -34,7 +34,7 @@
 
 test(t => {
     const animation = new Animation;
-    const effect = new KeyframeEffect(document.body);
+    const effect = new KeyframeEffect(document.body, null);
     animation.effect = effect;
     assert_equals(animation.effect, effect);
     animation.effect = null;

Modified: trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/keyframe-effect-expected.txt (224896 => 224897)


--- trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/keyframe-effect-expected.txt	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/keyframe-effect-expected.txt	2017-11-15 21:35:38 UTC (rev 224897)
@@ -1,7 +1,7 @@
 
 PASS The KeyframeEffect interface is defined. 
-PASS The KeyframeEffect interface cannot be constructed without parameters. 
-PASS The KeyframeEffect interface constructor throws if the parameter has the wrong type. 
+PASS The KeyframeEffect interface cannot be constructed without enough parameters. 
+PASS The KeyframeEffect interface constructor throws if the first parameter has the wrong type. 
 PASS The KeyframeEffect interface target is set to the provided Element. 
 PASS A KeyframeEffect object target is read-only. 
 

Modified: trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/keyframe-effect-interface-timing-duration.html (224896 => 224897)


--- trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/keyframe-effect-interface-timing-duration.html	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/keyframe-effect-interface-timing-duration.html	2017-11-15 21:35:38 UTC (rev 224897)
@@ -11,7 +11,7 @@
 internals.pauseTimeline(document.timeline);
 
 test(t => {
-    const keyframeEffect = new KeyframeEffect(document.body);
+    const keyframeEffect = new KeyframeEffect(document.body, null);
     assert_inherits(keyframeEffect, "timing");
     assert_inherits(keyframeEffect.timing, "duration");
     assert_equals(keyframeEffect.timing.duration, 0);
@@ -18,7 +18,7 @@
 }, "Check the default state of the timing and duration properties.");
 
 test(t => {
-    const keyframeEffect = new KeyframeEffect(document.body);
+    const keyframeEffect = new KeyframeEffect(document.body, null);
     keyframeEffect.timing.duration = 2;
     assert_equals(keyframeEffect.timing.duration, 2);
 }, "Check that we can update the timing duration.");

Modified: trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/keyframe-effect.html (224896 => 224897)


--- trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/keyframe-effect.html	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/keyframe-effect.html	2017-11-15 21:35:38 UTC (rev 224897)
@@ -16,22 +16,23 @@
 
 test(t => {
     assert_throws(new TypeError, () => new KeyframeEffect);
-}, "The KeyframeEffect interface cannot be constructed without parameters.");
+    assert_throws(new TypeError, () => new KeyframeEffect(document.createElement("div")));
+}, "The KeyframeEffect interface cannot be constructed without enough parameters.");
 
 test(t => {
-    assert_throws(new TypeError, () => new KeyframeEffect(0));
-    assert_throws(new TypeError, () => new KeyframeEffect({}));
-    assert_throws(new TypeError, () => new KeyframeEffect([]));
-    assert_throws(new TypeError, () => new KeyframeEffect(false));
-    assert_throws(new TypeError, () => new KeyframeEffect('element'));
-}, "The KeyframeEffect interface constructor throws if the parameter has the wrong type.");
+    assert_throws(new TypeError, () => new KeyframeEffect(0, null));
+    assert_throws(new TypeError, () => new KeyframeEffect({}, null));
+    assert_throws(new TypeError, () => new KeyframeEffect([], null));
+    assert_throws(new TypeError, () => new KeyframeEffect(false, null));
+    assert_throws(new TypeError, () => new KeyframeEffect('element', null));
+}, "The KeyframeEffect interface constructor throws if the first parameter has the wrong type.");
 
 test(t => {
-    assert_equals((new KeyframeEffect(document.body)).target, document.body);
+    assert_equals((new KeyframeEffect(document.body, null)).target, document.body);
 }, "The KeyframeEffect interface target is set to the provided Element.");
 
 test(t => {
-    const effect = new KeyframeEffect(document.body);
+    const effect = new KeyframeEffect(document.body, null);
     assert_readonly(effect, "target");
 }, "A KeyframeEffect object target is read-only.");
 

Modified: trunk/Source/WebCore/ChangeLog (224896 => 224897)


--- trunk/Source/WebCore/ChangeLog	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/Source/WebCore/ChangeLog	2017-11-15 21:35:38 UTC (rev 224897)
@@ -1,3 +1,55 @@
+2017-11-15  Antoine Quint  <grao...@apple.com>
+
+        [Web Animations] Implement basic to-from animations
+        https://bugs.webkit.org/show_bug.cgi?id=179707
+        <rdar://problem/34932456>
+
+        We can now actually perform an animation, in software only, when provided two keyframes on an AnimationEffect.
+        To parse a keyframes object from JS, we use the StyleResolver to create RenderStyle objects based on the strings
+        provided for the property names and values. Then, when the DocumentTimeline indicates that animations are ready
+        to be updated, we invalidate the style of elements with animations, so that during style resolution we can perform
+        blending between the RenderStyles for each keyframe.
+
+        Reviewed by Dean Jackson.
+
+        * animation/AnimationEffect.h:
+        (WebCore::AnimationEffect::~AnimationEffect): Deleted.
+        * animation/AnimationTimeline.h:
+        (WebCore::AnimationTimeline::elementToAnimationsMap const):
+        * animation/DocumentTimeline.cpp:
+        (WebCore::DocumentTimeline::animationResolutionTimerFired):
+        (WebCore::DocumentTimeline::updateAnimations): Renamed from resolveAnimations() since we're not
+        actually resolving animations, merely invalidating styles in preparation for resolution.
+        (WebCore::DocumentTimeline::resolveAnimations): Deleted.
+        * animation/DocumentTimeline.h:
+        * animation/KeyframeEffect.cpp:
+        (WebCore::KeyframeEffect::create): Pass the keyframes argument to setKeyframes() and forward the
+        exception in case one was raised in the setter.
+        (WebCore::KeyframeEffect::setKeyframes): Pass the keyframes argument to processKeyframes() and
+        forward the exception in case one was raised during processing.
+        (WebCore::KeyframeEffect::processKeyframes): Deal with exactly two keyframes, set at 0 and 1 offsets,
+        specified in array forms for the keyframes object. As we parse the content of the provided JS object,
+        we create RenderStyle objects using the element's StyleResolver from a CSS text string we create
+        based on the property and values as strings.
+        (WebCore::KeyframeEffect::applyAtLocalTime): Compute the progress based on the local time and duration,
+        using the existing CSSPropertyAnimation::blendProperties() mechanics to perform the blend between the
+        from and to keyframes.
+        * animation/KeyframeEffect.h:
+        * animation/KeyframeEffect.idl:
+        * animation/WebAnimation.cpp:
+        (WebCore::WebAnimation::resolve):
+        * animation/WebAnimation.h:
+        * bindings/IDLTypes.h:
+        (WebCore::IDLObject::nullValue): Make JSC::Strong an optional type.
+        * dom/Document.h:
+        (WebCore::Document::existingTimeline const): Provide an explicit method for call sites to check existence
+        of a timeline before forcing one to be created if missing by calling timeline().
+        * dom/Element.cpp:
+        (WebCore::Element::getAnimations): Do not force the creation of a timeline if one isn't already created.
+        * style/StyleTreeResolver.cpp:
+        (WebCore::Style::TreeResolver::createAnimatedElementUpdate): When applying styles, account for any Web
+        Animation applied to the provided element.
+
 2017-11-15  Frederic Wang  <fw...@igalia.com>
 
         ASSERTION FAILED: !renderer->needsLayout() in WebCore::RenderBlock::checkPositionedObjectsNeedLayout with MathML

Modified: trunk/Source/WebCore/animation/AnimationEffect.h (224896 => 224897)


--- trunk/Source/WebCore/animation/AnimationEffect.h	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/Source/WebCore/animation/AnimationEffect.h	2017-11-15 21:35:38 UTC (rev 224897)
@@ -36,11 +36,12 @@
 
 class AnimationEffect : public RefCounted<AnimationEffect> {
 public:
+    virtual ~AnimationEffect() = default;
+
     bool isKeyframeEffect() const { return m_classType == KeyframeEffectClass; }
     AnimationEffectTiming* timing() const { return m_timing.get(); }
+    virtual void applyAtLocalTime(Seconds, RenderStyle&) = 0;
 
-    virtual ~AnimationEffect() { }
-
     WebAnimation* animation() const { return m_animation.get(); }
     void setAnimation(RefPtr<WebAnimation>&& animation) { m_animation = animation; }
 

Modified: trunk/Source/WebCore/animation/AnimationTimeline.h (224896 => 224897)


--- trunk/Source/WebCore/animation/AnimationTimeline.h	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/Source/WebCore/animation/AnimationTimeline.h	2017-11-15 21:35:38 UTC (rev 224897)
@@ -70,6 +70,8 @@
 
     explicit AnimationTimeline(ClassType);
 
+    const HashMap<RefPtr<Element>, Vector<RefPtr<WebAnimation>>>& elementToAnimationsMap() { return m_elementToAnimationsMap; }
+
 private:
     ClassType m_classType;
     std::optional<Seconds> m_currentTime;

Modified: trunk/Source/WebCore/animation/DocumentTimeline.cpp (224896 => 224897)


--- trunk/Source/WebCore/animation/DocumentTimeline.cpp	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/Source/WebCore/animation/DocumentTimeline.cpp	2017-11-15 21:35:38 UTC (rev 224897)
@@ -154,11 +154,17 @@
 void DocumentTimeline::animationResolutionTimerFired()
 #endif
 {
-    resolveAnimations();
+    updateAnimations();
 }
 
-void DocumentTimeline::resolveAnimations()
+void DocumentTimeline::updateAnimations()
 {
+    if (m_document && !elementToAnimationsMap().isEmpty()) {
+        for (const auto& elementToAnimationsMapItem : elementToAnimationsMap())
+            elementToAnimationsMapItem.key->invalidateStyleAndLayerComposition();
+        m_document->updateStyleIfNeeded();
+    }
+
     // Time has advanced, the timing model requires invalidation now.
     animationTimingModelDidChange();
 }

Modified: trunk/Source/WebCore/animation/DocumentTimeline.h (224896 => 224897)


--- trunk/Source/WebCore/animation/DocumentTimeline.h	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/Source/WebCore/animation/DocumentTimeline.h	2017-11-15 21:35:38 UTC (rev 224897)
@@ -62,7 +62,7 @@
     void updateAnimationSchedule();
     void animationScheduleTimerFired();
     void scheduleAnimationResolution();
-    void resolveAnimations();
+    void updateAnimations();
 
     RefPtr<Document> m_document;
     bool m_paused { false };

Modified: trunk/Source/WebCore/animation/KeyframeEffect.cpp (224896 => 224897)


--- trunk/Source/WebCore/animation/KeyframeEffect.cpp	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/Source/WebCore/animation/KeyframeEffect.cpp	2017-11-15 21:35:38 UTC (rev 224897)
@@ -26,13 +26,24 @@
 #include "config.h"
 #include "KeyframeEffect.h"
 
+#include "CSSPropertyAnimation.h"
 #include "Element.h"
+#include "RenderStyle.h"
+#include "StyleProperties.h"
+#include "StyleResolver.h"
 
 namespace WebCore {
+using namespace JSC;
 
-Ref<KeyframeEffect> KeyframeEffect::create(Element* target)
+ExceptionOr<Ref<KeyframeEffect>> KeyframeEffect::create(ExecState& state, Element* target, Strong<JSObject>&& keyframes)
 {
-    return adoptRef(*new KeyframeEffect(target));
+    auto result = adoptRef(*new KeyframeEffect(target));
+
+    auto setKeyframesResult = result->setKeyframes(state, WTFMove(keyframes));
+    if (setKeyframesResult.hasException())
+        return setKeyframesResult.releaseException();
+
+    return WTFMove(result);
 }
 
 KeyframeEffect::KeyframeEffect(Element* target)
@@ -41,4 +52,93 @@
 {
 }
 
+ExceptionOr<void> KeyframeEffect::setKeyframes(ExecState& state, Strong<JSObject>&& keyframes)
+{
+    auto processKeyframesResult = processKeyframes(state, WTFMove(keyframes));
+    if (processKeyframesResult.hasException())
+        return processKeyframesResult.releaseException();
+    return { };
+}
+
+ExceptionOr<void> KeyframeEffect::processKeyframes(ExecState& state, Strong<JSObject>&& keyframes)
+{
+    // FIXME: We only have primitive to-from parsing, for full support see webkit.org/b/179708.
+    // Full specification is at https://w3c.github.io/web-animations/#processing-a-keyframes-argument.
+
+    if (!m_target || !keyframes)
+        return { };
+
+    if (!isJSArray(keyframes.get()))
+        return Exception { TypeError };
+
+    Vector<Keyframe> newKeyframes { };
+
+    VM& vm = state.vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    StyleResolver& styleResolver = m_target->styleResolver();
+    auto parserContext = CSSParserContext(HTMLStandardMode);
+
+    const auto* array = jsCast<const JSArray*>(keyframes.get());
+    auto length = array->length();
+    if (length != 2)
+        return Exception { TypeError };
+
+    for (unsigned i = 0; i < length; ++i) {
+        const JSValue value = array->getIndex(&state, i);
+        if (scope.exception() || !value || !value.isObject())
+            return Exception { TypeError };
+        JSObject* keyframe = value.toObject(&state);
+        PropertyNameArray ownPropertyNames(&vm, PropertyNameMode::Strings, PrivateSymbolMode::Exclude);
+        JSObject::getOwnPropertyNames(keyframe, &state, ownPropertyNames, EnumerationMode());
+        size_t numberOfProperties = ownPropertyNames.size();
+
+        StringBuilder cssText;
+        for (unsigned j = 0; j < numberOfProperties; ++j) {
+            cssText.append(ownPropertyNames[j].string());
+            cssText.appendLiteral(": ");
+            cssText.append(keyframe->get(&state, ownPropertyNames[j]).toWTFString(&state));
+            cssText.appendLiteral("; ");
+        }
+
+        auto renderStyle = RenderStyle::createPtr();
+        auto styleProperties = MutableStyleProperties::create();
+        styleProperties->parseDeclaration(cssText.toString(), parserContext);
+        unsigned numberOfCSSProperties = styleProperties->propertyCount();
+
+        Vector<CSSPropertyID> properties;
+        for (unsigned k = 0; k < numberOfCSSProperties; ++k) {
+            properties.append(styleProperties->propertyAt(k).id());
+            styleResolver.applyPropertyToStyle(styleProperties->propertyAt(k).id(), styleProperties->propertyAt(k).value(), WTFMove(renderStyle));
+            renderStyle = styleResolver.state().takeStyle();
+        }
+
+        newKeyframes.append({ RenderStyle::clone(*renderStyle), properties });
+    }
+
+    m_keyframes = WTFMove(newKeyframes);
+
+    return { };
+}
+
+void KeyframeEffect::applyAtLocalTime(Seconds localTime, RenderStyle& targetStyle)
+{
+    if (!m_target)
+        return;
+
+    // FIXME: Assume animations only apply in the range [0, duration[
+    // until we support fill modes, delays and iterations.
+    if (localTime < 0_s || localTime >= timing()->duration())
+        return;
+
+    if (!timing()->duration())
+        return;
+
+    float progress = localTime / timing()->duration();
+
+    // FIXME: This will crash if we attempt to animate properties that require an AnimationBase.
+    for (auto propertyId : m_keyframes[0].properties)
+        CSSPropertyAnimation::blendProperties(nullptr, propertyId, &targetStyle, &m_keyframes[0].style, &m_keyframes[1].style, progress);
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/animation/KeyframeEffect.h (224896 => 224897)


--- trunk/Source/WebCore/animation/KeyframeEffect.h	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/Source/WebCore/animation/KeyframeEffect.h	2017-11-15 21:35:38 UTC (rev 224897)
@@ -26,6 +26,7 @@
 #pragma once
 
 #include "AnimationEffect.h"
+#include "RenderStyle.h"
 #include <wtf/Ref.h>
 
 namespace WebCore {
@@ -32,16 +33,25 @@
 
 class Element;
 
+struct Keyframe {
+    RenderStyle style;
+    Vector<CSSPropertyID> properties;
+};
+
 class KeyframeEffect final : public AnimationEffect {
 public:
-    static Ref<KeyframeEffect> create(Element*);
+    static ExceptionOr<Ref<KeyframeEffect>> create(JSC::ExecState&, Element*, JSC::Strong<JSC::JSObject>&&);
     ~KeyframeEffect() { }
 
     Element* target() const { return m_target.get(); }
+    ExceptionOr<void> setKeyframes(JSC::ExecState&, JSC::Strong<JSC::JSObject>&&);
+    void applyAtLocalTime(Seconds, RenderStyle&) override;
 
 private:
     KeyframeEffect(Element*);
+    ExceptionOr<void> processKeyframes(JSC::ExecState&, JSC::Strong<JSC::JSObject>&&);
     RefPtr<Element> m_target;
+    Vector<Keyframe> m_keyframes;
 
 };
 

Modified: trunk/Source/WebCore/animation/KeyframeEffect.idl (224896 => 224897)


--- trunk/Source/WebCore/animation/KeyframeEffect.idl	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/Source/WebCore/animation/KeyframeEffect.idl	2017-11-15 21:35:38 UTC (rev 224897)
@@ -25,7 +25,10 @@
 
 [
     EnabledAtRuntime=WebAnimations,
-    Constructor(Element? target)
+    ConstructorMayThrowException,
+    ConstructorCallWith=ScriptState,
+    Constructor(Element? target, object? keyframes)
 ] interface KeyframeEffect : AnimationEffect {
     readonly attribute Element? target;
+    [MayThrowException, CallWith=ScriptState] void setKeyframes(object? keyframes);
 };

Modified: trunk/Source/WebCore/animation/WebAnimation.cpp (224896 => 224897)


--- trunk/Source/WebCore/animation/WebAnimation.cpp	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/Source/WebCore/animation/WebAnimation.cpp	2017-11-15 21:35:38 UTC (rev 224897)
@@ -237,6 +237,12 @@
     return Seconds::infinity();
 }
 
+void WebAnimation::resolve(RenderStyle& targetStyle)
+{
+    if (m_effect && currentTime())
+        m_effect->applyAtLocalTime(currentTime().value(), targetStyle);
+}
+
 String WebAnimation::description()
 {
     return "Animation";

Modified: trunk/Source/WebCore/animation/WebAnimation.h (224896 => 224897)


--- trunk/Source/WebCore/animation/WebAnimation.h	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/Source/WebCore/animation/WebAnimation.h	2017-11-15 21:35:38 UTC (rev 224897)
@@ -38,6 +38,7 @@
 class AnimationEffect;
 class AnimationTimeline;
 class Document;
+class RenderStyle;
 
 class WebAnimation final : public RefCounted<WebAnimation> {
 public:
@@ -63,6 +64,7 @@
     void setPlaybackRate(double);
 
     Seconds timeToNextRequiredTick(Seconds) const;
+    void resolve(RenderStyle&);
 
     String description();
 

Modified: trunk/Source/WebCore/bindings/IDLTypes.h (224896 => 224897)


--- trunk/Source/WebCore/bindings/IDLTypes.h	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/Source/WebCore/bindings/IDLTypes.h	2017-11-15 21:35:38 UTC (rev 224897)
@@ -27,6 +27,7 @@
 
 #include "StringAdaptors.h"
 #include <heap/HandleTypes.h>
+#include <heap/Strong.h>
 #include <wtf/Brigand.h>
 #include <wtf/HashMap.h>
 #include <wtf/StdLibExtras.h>
@@ -150,7 +151,7 @@
 struct IDLObject : IDLType<JSC::Strong<JSC::JSObject>> {
     using NullableType = JSC::Strong<JSC::JSObject>;
 
-    static inline std::nullptr_t nullValue() { return nullptr; }
+    static inline NullableType nullValue() { return { }; }
     template<typename U> static inline bool isNullValue(U&& value) { return !value; }
     template<typename U> static inline U&& extractValueFromNullable(U&& value) { return std::forward<U>(value); }
 };

Modified: trunk/Source/WebCore/dom/Document.h (224896 => 224897)


--- trunk/Source/WebCore/dom/Document.h	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/Source/WebCore/dom/Document.h	2017-11-15 21:35:38 UTC (rev 224897)
@@ -1377,6 +1377,7 @@
     WEBCORE_EXPORT void setConsoleMessageListener(RefPtr<StringCallback>&&); // For testing.
 
     DocumentTimeline& timeline();
+    DocumentTimeline* existingTimeline() const { return m_timeline.get(); }
     Vector<RefPtr<WebAnimation>> getAnimations();
         
 #if ENABLE(ATTACHMENT_ELEMENT)

Modified: trunk/Source/WebCore/dom/Element.cpp (224896 => 224897)


--- trunk/Source/WebCore/dom/Element.cpp	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/Source/WebCore/dom/Element.cpp	2017-11-15 21:35:38 UTC (rev 224897)
@@ -3706,7 +3706,9 @@
 Vector<RefPtr<WebAnimation>> Element::getAnimations()
 {
     // FIXME: Filter and order the list as specified (webkit.org/b/179535).
-    return document().timeline().animationsForElement(*this);
+    if (auto timeline = document().existingTimeline())
+        return timeline->animationsForElement(*this);
+    return Vector<RefPtr<WebAnimation>> { };
 }
 
 AccessibleNode* Element::accessibleNode()

Modified: trunk/Source/WebCore/style/StyleTreeResolver.cpp (224896 => 224897)


--- trunk/Source/WebCore/style/StyleTreeResolver.cpp	2017-11-15 21:28:15 UTC (rev 224896)
+++ trunk/Source/WebCore/style/StyleTreeResolver.cpp	2017-11-15 21:35:38 UTC (rev 224897)
@@ -30,6 +30,7 @@
 #include "CSSFontSelector.h"
 #include "ComposedTreeAncestorIterator.h"
 #include "ComposedTreeIterator.h"
+#include "DocumentTimeline.h"
 #include "ElementIterator.h"
 #include "HTMLBodyElement.h"
 #include "HTMLMeterElement.h"
@@ -274,9 +275,20 @@
 
 ElementUpdate TreeResolver::createAnimatedElementUpdate(std::unique_ptr<RenderStyle> newStyle, Element& element, Change parentChange)
 {
+    auto* oldStyle = renderOrDisplayContentsStyle(element);
+
+    if (auto timeline = element.document().existingTimeline()) {
+        auto webAnimations = timeline->animationsForElement(element);
+        if (!webAnimations.isEmpty()) {
+            auto animatedStyle = RenderStyle::clonePtr(*newStyle);
+            for (const auto& animation : webAnimations)
+                animation->resolve(*animatedStyle);
+            newStyle = WTFMove(animatedStyle);
+        }
+    }
+
     auto& animationController = m_document.frame()->animation();
 
-    auto* oldStyle = renderOrDisplayContentsStyle(element);
     auto animationUpdate = animationController.updateAnimations(element, *newStyle, oldStyle);
 
     if (animationUpdate.style)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to