Title: [224705] trunk
Revision
224705
Author
[email protected]
Date
2017-11-10 14:12:08 -0800 (Fri, 10 Nov 2017)

Log Message

[Web Animations] Implement getAnimations()
https://bugs.webkit.org/show_bug.cgi?id=179535
<rdar://problem/34932475>

Reviewed by Simon Fraser.

Source/WebCore:

We now allow a list of animations for a document, with Document.getAnimations(), or for an
element, with Animatable.getAnimations(), to be returned. In order to support this, we maintain
a map on AnimationTimeline of all animations for a given element. This map is invalidated
when an animation's timeline changes and when an animation's effect changes. Note that the
Web Animations spec mandates that an AnimationEffect can only be a single animation's effect.

Additionally, we ensure that the Document-to-DocumentTimeline relationship is cleared when
is being prepared for teardown to avoid a ref-cycle.

Tests: http/wpt/wk-web-animations/interfaces/document-get-animations.html
       http/wpt/wk-web-animations/interfaces/element-get-animations.html
       http/wpt/wk-web-animations/timing-model/animation-effect-unique-relationship.html

* CMakeLists.txt: Add Animatable.idl.
* DerivedSources.make: Add Animatable.idl.
* WebCore.xcodeproj/project.pbxproj: Add Animatable.idl.
* animation/Animatable.idl: A new interface that Element implements and which currently only exposes
getAnimations(), the animate() method will be added later.
* animation/AnimationEffect.h: Add a new m_animation member to reference the animation using this
effect. This relationship is required so we guarantee that an effect is associated with a single
animation at most.
(WebCore::AnimationEffect::animation const):
(WebCore::AnimationEffect::setAnimation):
* animation/AnimationTimeline.cpp:
(WebCore::AnimationTimeline::animationWasAddedToElement): New method to notify the timeline that an
animation registered with this timeline has been associated with a new element through its effect.
(WebCore::AnimationTimeline::animationWasRemovedFromElement): New method to notify the timeline that an
animation registered with this timeline has been disassociated with an element through its effect.
(WebCore::AnimationTimeline::animationsForElement): New method returning all animations registered with
this timeline for a given element.
* animation/AnimationTimeline.h:
(WebCore::AnimationTimeline::animations const): All animations registered with this timeline.
* animation/DocumentTimeline.cpp:
(WebCore::DocumentTimeline::DocumentTimeline):
(WebCore::DocumentTimeline::detachFromDocument): Clear the reference between this timeline and its document.
* animation/DocumentTimeline.h:
* animation/WebAnimation.cpp:
(WebCore::WebAnimation::create):
(WebCore::WebAnimation::setEffect): As an animation's effect changes, we need to ensure that the old
effect no longer has an associated animation, and that the new effect is associated with this animation.
Additionally, we update the element-to-animations map on the animation's timeline.
(WebCore::WebAnimation::setTimeline): Update the element-to-animations map on the former and new timeline.
* dom/Document.cpp:
(WebCore::Document::prepareForDestruction): Clear the relationship between this document and its timeline.
(WebCore::Document::getAnimations): Obtain all animations associated with this document's timeline.
* dom/Document.h:
* dom/Document.idl:
* dom/Element.cpp:
(WebCore::Element::getAnimations): Obtain all animations associated with this element.
* dom/Element.h:
* dom/Element.idl:
* testing/Internals.cpp:

LayoutTests:

Update WPT expectations per new progressions and add three new tests that check the behavior of
Document.getAnimations(), Element.getAnimations() and the unique relationship between an Animation
and an AnimationEffect.

* http/wpt/web-animations/interfaces/Animatable/animate-expected.txt:
* http/wpt/web-animations/interfaces/Animatable/getAnimations-expected.txt:
* http/wpt/web-animations/interfaces/Document/getAnimations-expected.txt:
* http/wpt/wk-web-animations/interfaces/document-get-animations-expected.txt: Added.
* http/wpt/wk-web-animations/interfaces/document-get-animations.html: Added.
* http/wpt/wk-web-animations/interfaces/element-get-animations-expected.txt: Added.
* http/wpt/wk-web-animations/interfaces/element-get-animations.html: Added.
* http/wpt/wk-web-animations/timing-model/animation-effect-unique-relationship-expected.txt: Added.
* http/wpt/wk-web-animations/timing-model/animation-effect-unique-relationship.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (224704 => 224705)


--- trunk/LayoutTests/ChangeLog	2017-11-10 22:10:05 UTC (rev 224704)
+++ trunk/LayoutTests/ChangeLog	2017-11-10 22:12:08 UTC (rev 224705)
@@ -1,3 +1,25 @@
+2017-11-10  Antoine Quint  <[email protected]>
+
+        [Web Animations] Implement getAnimations()
+        https://bugs.webkit.org/show_bug.cgi?id=179535
+        <rdar://problem/34932475>
+
+        Reviewed by Simon Fraser.
+
+        Update WPT expectations per new progressions and add three new tests that check the behavior of
+        Document.getAnimations(), Element.getAnimations() and the unique relationship between an Animation
+        and an AnimationEffect.
+
+        * http/wpt/web-animations/interfaces/Animatable/animate-expected.txt:
+        * http/wpt/web-animations/interfaces/Animatable/getAnimations-expected.txt:
+        * http/wpt/web-animations/interfaces/Document/getAnimations-expected.txt:
+        * http/wpt/wk-web-animations/interfaces/document-get-animations-expected.txt: Added.
+        * http/wpt/wk-web-animations/interfaces/document-get-animations.html: Added.
+        * http/wpt/wk-web-animations/interfaces/element-get-animations-expected.txt: Added.
+        * http/wpt/wk-web-animations/interfaces/element-get-animations.html: Added.
+        * http/wpt/wk-web-animations/timing-model/animation-effect-unique-relationship-expected.txt: Added.
+        * http/wpt/wk-web-animations/timing-model/animation-effect-unique-relationship.html: Added.
+
 2017-11-10  Commit Queue  <[email protected]>
 
         Unreviewed, rolling out r224602 and r224697.

Modified: trunk/LayoutTests/http/wpt/web-animations/interfaces/Animatable/animate-expected.txt (224704 => 224705)


--- trunk/LayoutTests/http/wpt/web-animations/interfaces/Animatable/animate-expected.txt	2017-11-10 22:10:05 UTC (rev 224704)
+++ trunk/LayoutTests/http/wpt/web-animations/interfaces/Animatable/animate-expected.txt	2017-11-10 22:12:08 UTC (rev 224705)
@@ -91,6 +91,6 @@
 FAIL Element.animate() correctly sets the Animation's timeline div.animate is not a function. (In 'div.animate({ opacity: [ 0, 1 ] }, 2000)', 'div.animate' is undefined)
 FAIL Element.animate() correctly sets the Animation's timeline when triggered on an element in a different document div.animate is not a function. (In 'div.animate({ opacity: [ 0, 1 ] }, 2000)', 'div.animate' is undefined)
 FAIL Element.animate() calls play on the Animation div.animate is not a function. (In 'div.animate({ opacity: [ 0, 1 ] }, 2000)', 'div.animate' is undefined)
-FAIL CSSPseudoElement.animate() creates an Animation object document.getAnimations is not a function. (In 'document.getAnimations()', 'document.getAnimations' is undefined)
-FAIL CSSPseudoElement.animate() creates an Animation object targeting to the correct CSSPseudoElement object document.getAnimations is not a function. (In 'document.getAnimations()', 'document.getAnimations' is undefined)
+FAIL CSSPseudoElement.animate() creates an Animation object assert_true: expected true got false
+FAIL CSSPseudoElement.animate() creates an Animation object targeting to the correct CSSPseudoElement object assert_true: expected true got false
  

Modified: trunk/LayoutTests/http/wpt/web-animations/interfaces/Animatable/getAnimations-expected.txt (224704 => 224705)


--- trunk/LayoutTests/http/wpt/web-animations/interfaces/Animatable/getAnimations-expected.txt	2017-11-10 22:10:05 UTC (rev 224704)
+++ trunk/LayoutTests/http/wpt/web-animations/interfaces/Animatable/getAnimations-expected.txt	2017-11-10 22:12:08 UTC (rev 224705)
@@ -1,5 +1,5 @@
 
-FAIL Test getAnimations on element with no animations div.getAnimations is not a function. (In 'div.getAnimations()', 'div.getAnimations' is undefined)
+PASS Test getAnimations on element with no animations 
 FAIL Test getAnimations on element with two animations div.animate is not a function. (In 'div.animate(null, 100 * MS_PER_SEC)', 'div.animate' is undefined)
 FAIL Test getAnimations on separate elements with separate animations divA.animate is not a function. (In 'divA.animate(null, 100 * MS_PER_SEC)', 'divA.animate' is undefined)
 FAIL Test getAnimations on parent and child elements with separate animations divParent.animate is not a function. (In 'divParent.animate(null, 100 * MS_PER_SEC)', 'divParent.animate' is undefined)

Modified: trunk/LayoutTests/http/wpt/web-animations/interfaces/Document/getAnimations-expected.txt (224704 => 224705)


--- trunk/LayoutTests/http/wpt/web-animations/interfaces/Document/getAnimations-expected.txt	2017-11-10 22:10:05 UTC (rev 224704)
+++ trunk/LayoutTests/http/wpt/web-animations/interfaces/Document/getAnimations-expected.txt	2017-11-10 22:12:08 UTC (rev 224705)
@@ -1,5 +1,5 @@
 
-FAIL Test document.getAnimations for non-animated content document.getAnimations is not a function. (In 'document.getAnimations()', 'document.getAnimations' is undefined)
+PASS Test document.getAnimations for non-animated content 
 FAIL Test document.getAnimations for script-generated animations div.animate is not a function. (In 'div.animate(gKeyFrames, 100 * MS_PER_SEC)', 'div.animate' is undefined)
 FAIL Test the order of document.getAnimations with script generated animations div.animate is not a function. (In 'div.animate(gKeyFrames, 100 * MS_PER_SEC)', 'div.animate' is undefined)
 FAIL Test document.getAnimations with null target Can't find variable: KeyframeEffectReadOnly

Added: trunk/LayoutTests/http/wpt/wk-web-animations/interfaces/document-get-animations-expected.txt (0 => 224705)


--- trunk/LayoutTests/http/wpt/wk-web-animations/interfaces/document-get-animations-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/wk-web-animations/interfaces/document-get-animations-expected.txt	2017-11-10 22:12:08 UTC (rev 224705)
@@ -0,0 +1,7 @@
+
+PASS Document exposes the getAnimations method. 
+PASS Document.getAnimations() returns an empty array when no animations were added. 
+PASS Document.getAnimations() returns an array with the new animations contained. 
+PASS Setting timeline = null on an animation removes it from the array returned by Document.getAnimations(). 
+PASS Setting timeline = document.timeline on an animation adds it to the array returned by Document.getAnimations(). 
+

Added: trunk/LayoutTests/http/wpt/wk-web-animations/interfaces/document-get-animations.html (0 => 224705)


--- trunk/LayoutTests/http/wpt/wk-web-animations/interfaces/document-get-animations.html	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/wk-web-animations/interfaces/document-get-animations.html	2017-11-10 22:12:08 UTC (rev 224705)
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Document.getAnimations()</title>
+<script src=""
+<script src=""
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+let a, b, c;
+
+test(t => {
+    assert_true(typeof document.getAnimations === "function");
+}, "Document exposes the getAnimations method.");
+
+test(t => {
+    assert_array_equals(document.getAnimations(), []);
+}, "Document.getAnimations() returns an empty array when no animations were added.");
+
+test(t => {
+    a = new Animation;
+    b = new Animation;
+    c = new Animation;
+    const animations = document.getAnimations();
+    assert_equals(animations.length, 3);
+    assert_in_array(a, animations);
+    assert_in_array(b, animations);
+    assert_in_array(c, animations);
+}, "Document.getAnimations() returns an array with the new animations contained.");
+
+test(t => {
+    b.timeline = null;
+    const animations = document.getAnimations();
+    assert_equals(animations.length, 2);
+    assert_in_array(a, animations);
+    assert_in_array(c, animations);
+}, "Setting timeline = null on an animation removes it from the array returned by Document.getAnimations().");
+
+test(t => {
+    b.timeline = document.timeline;
+    const animations = document.getAnimations();
+    assert_equals(animations.length, 3);
+    assert_in_array(a, animations);
+    assert_in_array(b, animations);
+    assert_in_array(c, animations);
+}, "Setting timeline = document.timeline on an animation adds it to the array returned by Document.getAnimations().");
+
+</script>
+</body>

Added: trunk/LayoutTests/http/wpt/wk-web-animations/interfaces/element-get-animations-expected.txt (0 => 224705)


--- trunk/LayoutTests/http/wpt/wk-web-animations/interfaces/element-get-animations-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/wk-web-animations/interfaces/element-get-animations-expected.txt	2017-11-10 22:12:08 UTC (rev 224705)
@@ -0,0 +1,7 @@
+
+PASS Element exposes the getAnimations method. 
+PASS Element.getAnimations() returns an empty array when no animations were added. 
+PASS Element.getAnimations() returns an array with animations targetting that element. 
+PASS An effect can only be applied to a single animation and changing it changes the animations returned by Element.getAnimations(). 
+PASS Setting an animation's effect to null changes the animations returned by Element.getAnimations(). 
+

Added: trunk/LayoutTests/http/wpt/wk-web-animations/interfaces/element-get-animations.html (0 => 224705)


--- trunk/LayoutTests/http/wpt/wk-web-animations/interfaces/element-get-animations.html	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/wk-web-animations/interfaces/element-get-animations.html	2017-11-10 22:12:08 UTC (rev 224705)
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Element.getAnimations()</title>
+<script src=""
+<script src=""
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+let a, b, c;
+
+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);
+
+test(t => {
+    assert_true(typeof targetA.getAnimations === "function");
+}, "Element exposes the getAnimations method.");
+
+test(t => {
+    assert_array_equals(targetA.getAnimations(), []);
+    assert_array_equals(targetB.getAnimations(), []);
+}, "Element.getAnimations() returns an empty array when no animations were added.");
+
+test(t => {
+    a = new Animation(effectAa);
+    b = new Animation(effectAb);
+    c = new Animation(effectB);
+    assert_array_equals(targetA.getAnimations(), [a, b]);
+    assert_array_equals(targetB.getAnimations(), [c]);
+}, "Element.getAnimations() returns an array with animations targetting that element.");
+
+test(t => {
+    b.effect = effectB;
+    assert_array_equals(targetA.getAnimations(), [a]);
+    assert_array_equals(targetB.getAnimations(), [b]);
+}, "An effect can only be applied to a single animation and changing it changes the animations returned by Element.getAnimations().");
+
+test(t => {
+    a.effect = null;
+    b.effect = null;
+    c.effect = null;
+    assert_array_equals(targetA.getAnimations(), []);
+    assert_array_equals(targetB.getAnimations(), []);
+}, "Setting an animation's effect to null changes the animations returned by Element.getAnimations().");
+
+</script>
+</body>

Added: trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/animation-effect-unique-relationship-expected.txt (0 => 224705)


--- trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/animation-effect-unique-relationship-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/animation-effect-unique-relationship-expected.txt	2017-11-10 22:12:08 UTC (rev 224705)
@@ -0,0 +1,3 @@
+
+PASS Check that setting an animation's effect onto another animation sets effect to null. 
+

Added: trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/animation-effect-unique-relationship.html (0 => 224705)


--- trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/animation-effect-unique-relationship.html	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/wk-web-animations/timing-model/animation-effect-unique-relationship.html	2017-11-10 22:12:08 UTC (rev 224705)
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Check an AnimationEffect can only be used for one Animation</title>
+<script src=""
+<script src=""
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+test(t => {
+    const effectA = new KeyframeEffect(document.createElement("div"));
+    const effectB = new KeyframeEffect(document.createElement("div"));
+
+    const a = new Animation(effectA);
+    const b = new Animation(effectB);
+
+    assert_equals(a.effect, effectA);
+    assert_equals(b.effect, effectB);
+
+    b.effect = effectA;
+    assert_equals(a.effect, null);
+    assert_equals(b.effect, effectA);
+}, "Check that setting an animation's effect onto another animation sets effect to null.");
+
+</script>
+</body>

Modified: trunk/Source/WebCore/CMakeLists.txt (224704 => 224705)


--- trunk/Source/WebCore/CMakeLists.txt	2017-11-10 22:10:05 UTC (rev 224704)
+++ trunk/Source/WebCore/CMakeLists.txt	2017-11-10 22:12:08 UTC (rev 224705)
@@ -418,6 +418,7 @@
     Modules/webvr/VRPose.idl
     Modules/webvr/VRStageParameters.idl
 
+    animation/Animatable.idl
     animation/AnimationEffect.idl
     animation/AnimationEffectTiming.idl
     animation/AnimationTimeline.idl

Modified: trunk/Source/WebCore/ChangeLog (224704 => 224705)


--- trunk/Source/WebCore/ChangeLog	2017-11-10 22:10:05 UTC (rev 224704)
+++ trunk/Source/WebCore/ChangeLog	2017-11-10 22:12:08 UTC (rev 224705)
@@ -1,3 +1,64 @@
+2017-11-10  Antoine Quint  <[email protected]>
+
+        [Web Animations] Implement getAnimations()
+        https://bugs.webkit.org/show_bug.cgi?id=179535
+        <rdar://problem/34932475>
+
+        Reviewed by Simon Fraser.
+
+        We now allow a list of animations for a document, with Document.getAnimations(), or for an
+        element, with Animatable.getAnimations(), to be returned. In order to support this, we maintain
+        a map on AnimationTimeline of all animations for a given element. This map is invalidated
+        when an animation's timeline changes and when an animation's effect changes. Note that the
+        Web Animations spec mandates that an AnimationEffect can only be a single animation's effect.
+
+        Additionally, we ensure that the Document-to-DocumentTimeline relationship is cleared when
+        is being prepared for teardown to avoid a ref-cycle.
+
+        Tests: http/wpt/wk-web-animations/interfaces/document-get-animations.html
+               http/wpt/wk-web-animations/interfaces/element-get-animations.html
+               http/wpt/wk-web-animations/timing-model/animation-effect-unique-relationship.html
+
+        * CMakeLists.txt: Add Animatable.idl.
+        * DerivedSources.make: Add Animatable.idl.
+        * WebCore.xcodeproj/project.pbxproj: Add Animatable.idl.
+        * animation/Animatable.idl: A new interface that Element implements and which currently only exposes
+        getAnimations(), the animate() method will be added later.
+        * animation/AnimationEffect.h: Add a new m_animation member to reference the animation using this
+        effect. This relationship is required so we guarantee that an effect is associated with a single
+        animation at most.
+        (WebCore::AnimationEffect::animation const):
+        (WebCore::AnimationEffect::setAnimation):
+        * animation/AnimationTimeline.cpp:
+        (WebCore::AnimationTimeline::animationWasAddedToElement): New method to notify the timeline that an
+        animation registered with this timeline has been associated with a new element through its effect.
+        (WebCore::AnimationTimeline::animationWasRemovedFromElement): New method to notify the timeline that an
+        animation registered with this timeline has been disassociated with an element through its effect.
+        (WebCore::AnimationTimeline::animationsForElement): New method returning all animations registered with
+        this timeline for a given element.
+        * animation/AnimationTimeline.h:
+        (WebCore::AnimationTimeline::animations const): All animations registered with this timeline.
+        * animation/DocumentTimeline.cpp:
+        (WebCore::DocumentTimeline::DocumentTimeline):
+        (WebCore::DocumentTimeline::detachFromDocument): Clear the reference between this timeline and its document.
+        * animation/DocumentTimeline.h:
+        * animation/WebAnimation.cpp:
+        (WebCore::WebAnimation::create):
+        (WebCore::WebAnimation::setEffect): As an animation's effect changes, we need to ensure that the old
+        effect no longer has an associated animation, and that the new effect is associated with this animation.
+        Additionally, we update the element-to-animations map on the animation's timeline.
+        (WebCore::WebAnimation::setTimeline): Update the element-to-animations map on the former and new timeline.
+        * dom/Document.cpp:
+        (WebCore::Document::prepareForDestruction): Clear the relationship between this document and its timeline.
+        (WebCore::Document::getAnimations): Obtain all animations associated with this document's timeline.
+        * dom/Document.h:
+        * dom/Document.idl:
+        * dom/Element.cpp:
+        (WebCore::Element::getAnimations): Obtain all animations associated with this element.
+        * dom/Element.h:
+        * dom/Element.idl:
+        * testing/Internals.cpp:
+
 2017-11-10  Joseph Pecoraro  <[email protected]>
 
         Web Inspector: Make http status codes be "integer" instead of "number" in protocol

Modified: trunk/Source/WebCore/DerivedSources.make (224704 => 224705)


--- trunk/Source/WebCore/DerivedSources.make	2017-11-10 22:10:05 UTC (rev 224704)
+++ trunk/Source/WebCore/DerivedSources.make	2017-11-10 22:12:08 UTC (rev 224705)
@@ -343,6 +343,7 @@
     $(WebCore)/Modules/webvr/VRLayerInit.idl \
     $(WebCore)/Modules/webvr/VRPose.idl \
     $(WebCore)/Modules/webvr/VRStageParameters.idl \
+    $(WebCore)/animation/Animatable.idl \
     $(WebCore)/animation/AnimationEffect.idl \
     $(WebCore)/animation/AnimationEffectTiming.idl \
     $(WebCore)/animation/AnimationTimeline.idl \

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (224704 => 224705)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2017-11-10 22:10:05 UTC (rev 224704)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2017-11-10 22:12:08 UTC (rev 224705)
@@ -8684,6 +8684,7 @@
 		71A57DEF154BE25C0009D120 /* SVGPathUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGPathUtilities.cpp; sourceTree = "<group>"; };
 		71A57DF0154BE25C0009D120 /* SVGPathUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGPathUtilities.h; sourceTree = "<group>"; };
 		71B0460A1DD3C2EE00EE19CF /* status-support.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; path = "status-support.js"; sourceTree = "<group>"; };
+		71C5BB1B1FB611EA0007A2AE /* Animatable.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Animatable.idl; sourceTree = "<group>"; };
 		71C916071D1483A300ACA47D /* UserInterfaceLayoutDirection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserInterfaceLayoutDirection.h; sourceTree = "<group>"; };
 		71CC7A1F152A0BFE009EEAF9 /* SVGAnimatedEnumeration.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAnimatedEnumeration.cpp; sourceTree = "<group>"; };
 		71D02D901DB55C4E00DD5CF5 /* main.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; path = main.js; sourceTree = "<group>"; };
@@ -18603,6 +18604,7 @@
 		71025EC11F99F096004A250C /* animation */ = {
 			isa = PBXGroup;
 			children = (
+				71C5BB1B1FB611EA0007A2AE /* Animatable.idl */,
 				71556CB11F9F099F00E78D08 /* AnimationEffect.cpp */,
 				71556CAD1F9F099D00E78D08 /* AnimationEffect.h */,
 				71556CB01F9F099E00E78D08 /* AnimationEffect.idl */,

Copied: trunk/Source/WebCore/animation/Animatable.idl (from rev 224704, trunk/Source/WebCore/animation/AnimationEffect.h) (0 => 224705)


--- trunk/Source/WebCore/animation/Animatable.idl	                        (rev 0)
+++ trunk/Source/WebCore/animation/Animatable.idl	2017-11-10 22:12:08 UTC (rev 224705)
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+    EnabledAtRuntime=WebAnimations,
+    NoInterfaceObject
+] interface Animatable {
+    sequence<WebAnimation> getAnimations();
+};

Modified: trunk/Source/WebCore/animation/AnimationEffect.h (224704 => 224705)


--- trunk/Source/WebCore/animation/AnimationEffect.h	2017-11-10 22:10:05 UTC (rev 224704)
+++ trunk/Source/WebCore/animation/AnimationEffect.h	2017-11-10 22:12:08 UTC (rev 224705)
@@ -26,6 +26,7 @@
 #pragma once
 
 #include "AnimationEffectTiming.h"
+#include "WebAnimation.h"
 #include <wtf/Forward.h>
 #include <wtf/Ref.h>
 #include <wtf/RefCounted.h>
@@ -40,6 +41,9 @@
 
     virtual ~AnimationEffect() { }
 
+    WebAnimation* animation() const { return m_animation.get(); }
+    void setAnimation(RefPtr<WebAnimation>&& animation) { m_animation = animation; }
+
 protected:
     enum ClassType {
         KeyframeEffectClass
@@ -51,6 +55,7 @@
 
 private:
     ClassType m_classType;
+    RefPtr<WebAnimation> m_animation;
     RefPtr<AnimationEffectTiming> m_timing;
 };
 

Modified: trunk/Source/WebCore/animation/AnimationTimeline.cpp (224704 => 224705)


--- trunk/Source/WebCore/animation/AnimationTimeline.cpp	2017-11-10 22:10:05 UTC (rev 224704)
+++ trunk/Source/WebCore/animation/AnimationTimeline.cpp	2017-11-10 22:12:08 UTC (rev 224705)
@@ -68,6 +68,34 @@
     animationTimingModelDidChange();
 }
 
+void AnimationTimeline::animationWasAddedToElement(WebAnimation& animation, Element& element)
+{
+    auto result = m_elementToAnimationsMap.ensure(&element, [] {
+        return Vector<RefPtr<WebAnimation>>();
+    });
+    result.iterator->value.append(&animation);
+}
+
+void AnimationTimeline::animationWasRemovedFromElement(WebAnimation& animation, Element& element)
+{
+    auto iterator = m_elementToAnimationsMap.find(&element);
+    if (iterator == m_elementToAnimationsMap.end())
+        return;
+
+    auto& animations = iterator->value;
+    animations.removeFirst(&animation);
+    if (!animations.size())
+        m_elementToAnimationsMap.remove(iterator);
+}
+
+Vector<RefPtr<WebAnimation>> AnimationTimeline::animationsForElement(Element& element)
+{
+    Vector<RefPtr<WebAnimation>> animations;
+    if (m_elementToAnimationsMap.contains(&element))
+        animations = m_elementToAnimationsMap.get(&element);
+    return animations;
+}
+
 String AnimationTimeline::description()
 {
     TextStream stream;

Modified: trunk/Source/WebCore/animation/AnimationTimeline.h (224704 => 224705)


--- trunk/Source/WebCore/animation/AnimationTimeline.h	2017-11-10 22:10:05 UTC (rev 224704)
+++ trunk/Source/WebCore/animation/AnimationTimeline.h	2017-11-10 22:12:08 UTC (rev 224705)
@@ -28,6 +28,7 @@
 
 #include "WebAnimation.h"
 #include <wtf/Forward.h>
+#include <wtf/HashMap.h>
 #include <wtf/HashSet.h>
 #include <wtf/Optional.h>
 #include <wtf/Ref.h>
@@ -36,6 +37,8 @@
 
 namespace WebCore {
 
+class AnimationEffect;
+class Element;
 class WebAnimation;
 
 class AnimationTimeline : public RefCounted<AnimationTimeline> {
@@ -51,6 +54,11 @@
 
     virtual void animationTimingModelDidChange() { };
 
+    const HashSet<RefPtr<WebAnimation>>& animations() const { return m_animations; }
+    Vector<RefPtr<WebAnimation>> animationsForElement(Element&);
+    void animationWasAddedToElement(WebAnimation&, Element&);
+    void animationWasRemovedFromElement(WebAnimation&, Element&);
+
     virtual ~AnimationTimeline();
 
 protected:
@@ -60,13 +68,12 @@
 
     ClassType classType() const { return m_classType; }
 
-    HashSet<RefPtr<WebAnimation>> animations() const { return m_animations; }
-
     explicit AnimationTimeline(ClassType);
 
 private:
     ClassType m_classType;
     std::optional<Seconds> m_currentTime;
+    HashMap<RefPtr<Element>, Vector<RefPtr<WebAnimation>>> m_elementToAnimationsMap;
     HashSet<RefPtr<WebAnimation>> m_animations;
 };
 

Modified: trunk/Source/WebCore/animation/DocumentTimeline.cpp (224704 => 224705)


--- trunk/Source/WebCore/animation/DocumentTimeline.cpp	2017-11-10 22:10:05 UTC (rev 224704)
+++ trunk/Source/WebCore/animation/DocumentTimeline.cpp	2017-11-10 22:12:08 UTC (rev 224705)
@@ -45,7 +45,7 @@
 
 DocumentTimeline::DocumentTimeline(Document& document, PlatformDisplayID displayID)
     : AnimationTimeline(DocumentTimelineClass)
-    , m_document(document)
+    , m_document(&document)
     , m_animationScheduleTimer(*this, &DocumentTimeline::animationScheduleTimerFired)
 #if !USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
     , m_animationResolutionTimer(*this, &DocumentTimeline::animationResolutionTimerFired)
@@ -59,6 +59,11 @@
     m_invalidationTaskQueue.close();
 }
 
+void DocumentTimeline::detachFromDocument()
+{
+    m_document = nullptr;
+}
+
 std::optional<Seconds> DocumentTimeline::currentTime()
 {
     if (m_paused)

Modified: trunk/Source/WebCore/animation/DocumentTimeline.h (224704 => 224705)


--- trunk/Source/WebCore/animation/DocumentTimeline.h	2017-11-10 22:10:05 UTC (rev 224704)
+++ trunk/Source/WebCore/animation/DocumentTimeline.h	2017-11-10 22:12:08 UTC (rev 224705)
@@ -52,6 +52,8 @@
     void animationTimingModelDidChange() override;
     void windowScreenDidChange(PlatformDisplayID);
 
+    void detachFromDocument();
+
 private:
     DocumentTimeline(Document&, PlatformDisplayID);
 
@@ -62,7 +64,7 @@
     void scheduleAnimationResolution();
     void resolveAnimations();
 
-    Ref<Document> m_document;
+    RefPtr<Document> m_document;
     bool m_paused { false };
     std::optional<Seconds> m_cachedCurrentTime;
     GenericTaskQueue<Timer> m_invalidationTaskQueue;

Modified: trunk/Source/WebCore/animation/WebAnimation.cpp (224704 => 224705)


--- trunk/Source/WebCore/animation/WebAnimation.cpp	2017-11-10 22:10:05 UTC (rev 224704)
+++ trunk/Source/WebCore/animation/WebAnimation.cpp	2017-11-10 22:12:08 UTC (rev 224705)
@@ -29,6 +29,7 @@
 #include "AnimationEffect.h"
 #include "AnimationTimeline.h"
 #include "Document.h"
+#include "KeyframeEffect.h"
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
@@ -38,7 +39,7 @@
     auto result = adoptRef(*new WebAnimation());
 
     result->setEffect(effect);
-    
+
     // FIXME: the spec mandates distinguishing between an omitted timeline parameter
     // and an explicit null or undefined value (webkit.org/b/179065).
     result->setTimeline(timeline ? timeline : &document.timeline());
@@ -61,6 +62,33 @@
     if (effect == m_effect)
         return;
 
+    if (m_effect) {
+        m_effect->setAnimation(nullptr);
+
+        // Update the Element to Animation map.
+        if (m_timeline && m_effect->isKeyframeEffect()) {
+            auto* keyframeEffect = downcast<KeyframeEffect>(m_effect.get());
+            auto* target = keyframeEffect->target();
+            if (target)
+                m_timeline->animationWasRemovedFromElement(*this, *target);
+        }
+    }
+
+    if (effect) {
+        // An animation effect can only be associated with a single animation.
+        if (effect->animation())
+            effect->animation()->setEffect(nullptr);
+
+        effect->setAnimation(this);
+
+        if (m_timeline && effect->isKeyframeEffect()) {
+            auto* keyframeEffect = downcast<KeyframeEffect>(effect.get());
+            auto* target = keyframeEffect->target();
+            if (target)
+                m_timeline->animationWasAddedToElement(*this, *target);
+        }
+    }
+
     m_effect = WTFMove(effect);
 }
 
@@ -78,6 +106,17 @@
     if (timeline)
         timeline->addAnimation(*this);
 
+    if (m_effect && m_effect->isKeyframeEffect()) {
+        auto* keyframeEffect = downcast<KeyframeEffect>(m_effect.get());
+        auto* target = keyframeEffect->target();
+        if (target) {
+            if (m_timeline)
+                m_timeline->animationWasRemovedFromElement(*this, *target);
+            if (timeline)
+                timeline->animationWasAddedToElement(*this, *target);
+        }
+    }
+
     m_timeline = WTFMove(timeline);
 }
     

Modified: trunk/Source/WebCore/dom/Document.cpp (224704 => 224705)


--- trunk/Source/WebCore/dom/Document.cpp	2017-11-10 22:10:05 UTC (rev 224704)
+++ trunk/Source/WebCore/dom/Document.cpp	2017-11-10 22:12:08 UTC (rev 224705)
@@ -58,6 +58,7 @@
 #include "DocumentLoader.h"
 #include "DocumentMarkerController.h"
 #include "DocumentSharedObjectPool.h"
+#include "DocumentTimeline.h"
 #include "DocumentType.h"
 #include "Editing.h"
 #include "Editor.h"
@@ -194,6 +195,7 @@
 #include "ValidationMessageClient.h"
 #include "VisibilityChangeClient.h"
 #include "VisitedLinkState.h"
+#include "WebAnimation.h"
 #include "WheelEvent.h"
 #include "WindowFeatures.h"
 #include "XMLDocument.h"
@@ -2311,6 +2313,11 @@
     if (m_hasPreparedForDestruction)
         return;
 
+    if (m_timeline) {
+        m_timeline->detachFromDocument();
+        m_timeline = nullptr;
+    }
+
     if (m_frame)
         m_frame->animation().detachFromDocument(this);
 
@@ -7462,6 +7469,17 @@
     return *m_timeline;
 }
 
+Vector<RefPtr<WebAnimation>> Document::getAnimations()
+{
+    Vector<RefPtr<WebAnimation>> animations;
+    if (m_timeline) {
+        // FIXME: Filter and order the list as specified (webkit.org/b/179535).
+        for (auto& animation : m_timeline->animations())
+            animations.append(animation);
+    }
+    return animations;
+}
+
 static MessageSource messageSourceForWTFLogChannel(const WTFLogChannel& channel)
 {
     static const NeverDestroyed<String> mediaChannel = MAKE_STATIC_STRING_IMPL("media");

Modified: trunk/Source/WebCore/dom/Document.h (224704 => 224705)


--- trunk/Source/WebCore/dom/Document.h	2017-11-10 22:10:05 UTC (rev 224704)
+++ trunk/Source/WebCore/dom/Document.h	2017-11-10 22:12:08 UTC (rev 224705)
@@ -30,7 +30,6 @@
 #include "Color.h"
 #include "ContainerNode.h"
 #include "DocumentEventQueue.h"
-#include "DocumentTimeline.h"
 #include "DocumentTiming.h"
 #include "FocusDirection.h"
 #include "FontSelectorClient.h"
@@ -102,6 +101,7 @@
 class DocumentMarkerController;
 class DocumentParser;
 class DocumentSharedObjectPool;
+class DocumentTimeline;
 class DocumentType;
 class ExtensionStyleSheets;
 class FloatQuad;
@@ -173,6 +173,7 @@
 class TreeWalker;
 class VisibilityChangeClient;
 class VisitedLinkState;
+class WebAnimation;
 class WebGL2RenderingContext;
 class WebGLRenderingContext;
 class WebGPURenderingContext;
@@ -1372,6 +1373,7 @@
     WEBCORE_EXPORT void setConsoleMessageListener(RefPtr<StringCallback>&&); // For testing.
 
     DocumentTimeline& timeline();
+    Vector<RefPtr<WebAnimation>> getAnimations();
         
 protected:
     enum ConstructionFlags { Synthesized = 1, NonRenderedPlaceholder = 1 << 1 };

Modified: trunk/Source/WebCore/dom/Document.idl (224704 => 224705)


--- trunk/Source/WebCore/dom/Document.idl	2017-11-10 22:10:05 UTC (rev 224704)
+++ trunk/Source/WebCore/dom/Document.idl	2017-11-10 22:12:08 UTC (rev 224705)
@@ -212,6 +212,7 @@
     [Replaceable] readonly attribute HTMLAllCollection all; /* [SameObject] */
 
     [EnabledAtRuntime=WebAnimations] readonly attribute DocumentTimeline timeline;
+    [EnabledAtRuntime=WebAnimations] sequence<WebAnimation> getAnimations();
 };
 
 enum DocumentReadyState { "loading", "interactive", "complete" };

Modified: trunk/Source/WebCore/dom/Element.cpp (224704 => 224705)


--- trunk/Source/WebCore/dom/Element.cpp	2017-11-10 22:10:05 UTC (rev 224704)
+++ trunk/Source/WebCore/dom/Element.cpp	2017-11-10 22:12:08 UTC (rev 224705)
@@ -42,6 +42,7 @@
 #include "DOMRectList.h"
 #include "DOMTokenList.h"
 #include "DocumentSharedObjectPool.h"
+#include "DocumentTimeline.h"
 #include "Editing.h"
 #include "ElementIterator.h"
 #include "ElementRareData.h"
@@ -3700,4 +3701,10 @@
     return nullptr;
 }
 
+Vector<RefPtr<WebAnimation>> Element::getAnimations()
+{
+    // FIXME: Filter and order the list as specified (webkit.org/b/179535).
+    return document().timeline().animationsForElement(*this);
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/dom/Element.h (224704 => 224705)


--- trunk/Source/WebCore/dom/Element.h	2017-11-10 22:10:05 UTC (rev 224704)
+++ trunk/Source/WebCore/dom/Element.h	2017-11-10 22:12:08 UTC (rev 224705)
@@ -552,6 +552,8 @@
 
     Element* findAnchorElementForLink(String& outAnchorName);
 
+    Vector<RefPtr<WebAnimation>> getAnimations();
+
 protected:
     Element(const QualifiedName&, Document&, ConstructionType);
 

Modified: trunk/Source/WebCore/dom/Element.idl (224704 => 224705)


--- trunk/Source/WebCore/dom/Element.idl	2017-11-10 22:10:05 UTC (rev 224704)
+++ trunk/Source/WebCore/dom/Element.idl	2017-11-10 22:12:08 UTC (rev 224705)
@@ -146,6 +146,7 @@
     required ShadowRootMode mode;
 };
 
+Element implements Animatable;
 Element implements ChildNode;
 Element implements DocumentAndElementEventHandlers;
 Element implements NonDocumentTypeChildNode;

Modified: trunk/Source/WebCore/testing/Internals.cpp (224704 => 224705)


--- trunk/Source/WebCore/testing/Internals.cpp	2017-11-10 22:10:05 UTC (rev 224704)
+++ trunk/Source/WebCore/testing/Internals.cpp	2017-11-10 22:12:08 UTC (rev 224705)
@@ -29,6 +29,7 @@
 
 #include "AXObjectCache.h"
 #include "ActiveDOMCallbackMicrotask.h"
+#include "AnimationTimeline.h"
 #include "ApplicationCacheStorage.h"
 #include "AudioSession.h"
 #include "Autofill.h"
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to