Diff
Modified: trunk/LayoutTests/ChangeLog (224759 => 224760)
--- trunk/LayoutTests/ChangeLog 2017-11-13 18:55:20 UTC (rev 224759)
+++ trunk/LayoutTests/ChangeLog 2017-11-13 19:14:47 UTC (rev 224760)
@@ -1,3 +1,25 @@
+2017-11-13 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-13 Per Arne Vollan <[email protected]>
Mark editing/execCommand/underline-selection-containing-image.html as failing on Windows.
Modified: trunk/LayoutTests/http/wpt/web-animations/interfaces/Animatable/animate-expected.txt (224759 => 224760)
--- trunk/LayoutTests/http/wpt/web-animations/interfaces/Animatable/animate-expected.txt 2017-11-13 18:55:20 UTC (rev 224759)
+++ trunk/LayoutTests/http/wpt/web-animations/interfaces/Animatable/animate-expected.txt 2017-11-13 19:14:47 UTC (rev 224760)
@@ -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 (224759 => 224760)
--- trunk/LayoutTests/http/wpt/web-animations/interfaces/Animatable/getAnimations-expected.txt 2017-11-13 18:55:20 UTC (rev 224759)
+++ trunk/LayoutTests/http/wpt/web-animations/interfaces/Animatable/getAnimations-expected.txt 2017-11-13 19:14:47 UTC (rev 224760)
@@ -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 (224759 => 224760)
--- trunk/LayoutTests/http/wpt/web-animations/interfaces/Document/getAnimations-expected.txt 2017-11-13 18:55:20 UTC (rev 224759)
+++ trunk/LayoutTests/http/wpt/web-animations/interfaces/Document/getAnimations-expected.txt 2017-11-13 19:14:47 UTC (rev 224760)
@@ -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 => 224760)
--- 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-13 19:14:47 UTC (rev 224760)
@@ -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 => 224760)
--- 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-13 19:14:47 UTC (rev 224760)
@@ -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 => 224760)
--- 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-13 19:14:47 UTC (rev 224760)
@@ -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 => 224760)
--- 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-13 19:14:47 UTC (rev 224760)
@@ -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 => 224760)
--- 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-13 19:14:47 UTC (rev 224760)
@@ -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 => 224760)
--- 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-13 19:14:47 UTC (rev 224760)
@@ -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 (224759 => 224760)
--- trunk/Source/WebCore/CMakeLists.txt 2017-11-13 18:55:20 UTC (rev 224759)
+++ trunk/Source/WebCore/CMakeLists.txt 2017-11-13 19:14:47 UTC (rev 224760)
@@ -419,6 +419,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 (224759 => 224760)
--- trunk/Source/WebCore/ChangeLog 2017-11-13 18:55:20 UTC (rev 224759)
+++ trunk/Source/WebCore/ChangeLog 2017-11-13 19:14:47 UTC (rev 224760)
@@ -1,3 +1,97 @@
+2017-11-13 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.
+
+ 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.
+ (WebCore::DocumentTimeline::currentTime): Protect against a null Document reference.
+ (WebCore::DocumentTimeline::createDisplayRefreshMonitor const): Protect against a null Document reference.
+ * 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:
+
+ * CMakeLists.txt:
+ * DerivedSources.make:
+ * WebCore.xcodeproj/project.pbxproj:
+ * animation/Animatable.idl:
+ * animation/AnimationEffect.h:
+ (WebCore::AnimationEffect::animation const):
+ (WebCore::AnimationEffect::setAnimation):
+ * animation/AnimationTimeline.cpp:
+ (WebCore::AnimationTimeline::animationWasAddedToElement):
+ (WebCore::AnimationTimeline::animationWasRemovedFromElement):
+ (WebCore::AnimationTimeline::animationsForElement):
+ * animation/AnimationTimeline.h:
+ (WebCore::AnimationTimeline::animations const):
+ * animation/DocumentTimeline.cpp:
+ (WebCore::DocumentTimeline::DocumentTimeline):
+ (WebCore::DocumentTimeline::detachFromDocument):
+ (WebCore::DocumentTimeline::currentTime):
+ (WebCore::DocumentTimeline::createDisplayRefreshMonitor const):
+ * animation/DocumentTimeline.h:
+ * animation/WebAnimation.cpp:
+ (WebCore::WebAnimation::create):
+ (WebCore::WebAnimation::setEffect):
+ (WebCore::WebAnimation::setTimeline):
+ * dom/Document.cpp:
+ (WebCore::Document::prepareForDestruction):
+ (WebCore::Document::getAnimations):
+ * dom/Document.h:
+ * dom/Document.idl:
+ * dom/Element.cpp:
+ (WebCore::Element::getAnimations):
+ * dom/Element.h:
+ * dom/Element.idl:
+ * testing/Internals.cpp:
+
2017-11-13 Alex Christensen <[email protected]>
Make DocumentLoader::willSendRequest asynchronous
Modified: trunk/Source/WebCore/DerivedSources.make (224759 => 224760)
--- trunk/Source/WebCore/DerivedSources.make 2017-11-13 18:55:20 UTC (rev 224759)
+++ trunk/Source/WebCore/DerivedSources.make 2017-11-13 19:14:47 UTC (rev 224760)
@@ -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 (224759 => 224760)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-11-13 18:55:20 UTC (rev 224759)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-11-13 19:14:47 UTC (rev 224760)
@@ -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>"; };
@@ -18622,6 +18623,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 224759, trunk/Source/WebCore/animation/AnimationEffect.h) (0 => 224760)
--- trunk/Source/WebCore/animation/Animatable.idl (rev 0)
+++ trunk/Source/WebCore/animation/Animatable.idl 2017-11-13 19:14:47 UTC (rev 224760)
@@ -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 (224759 => 224760)
--- trunk/Source/WebCore/animation/AnimationEffect.h 2017-11-13 18:55:20 UTC (rev 224759)
+++ trunk/Source/WebCore/animation/AnimationEffect.h 2017-11-13 19:14:47 UTC (rev 224760)
@@ -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 (224759 => 224760)
--- trunk/Source/WebCore/animation/AnimationTimeline.cpp 2017-11-13 18:55:20 UTC (rev 224759)
+++ trunk/Source/WebCore/animation/AnimationTimeline.cpp 2017-11-13 19:14:47 UTC (rev 224760)
@@ -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 (224759 => 224760)
--- trunk/Source/WebCore/animation/AnimationTimeline.h 2017-11-13 18:55:20 UTC (rev 224759)
+++ trunk/Source/WebCore/animation/AnimationTimeline.h 2017-11-13 19:14:47 UTC (rev 224760)
@@ -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 (224759 => 224760)
--- trunk/Source/WebCore/animation/DocumentTimeline.cpp 2017-11-13 18:55:20 UTC (rev 224759)
+++ trunk/Source/WebCore/animation/DocumentTimeline.cpp 2017-11-13 19:14:47 UTC (rev 224760)
@@ -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,9 +59,14 @@
m_invalidationTaskQueue.close();
}
+void DocumentTimeline::detachFromDocument()
+{
+ m_document = nullptr;
+}
+
std::optional<Seconds> DocumentTimeline::currentTime()
{
- if (m_paused)
+ if (m_paused || !m_document)
return AnimationTimeline::currentTime();
if (!m_cachedCurrentTime) {
@@ -170,7 +175,7 @@
#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
RefPtr<DisplayRefreshMonitor> DocumentTimeline::createDisplayRefreshMonitor(PlatformDisplayID displayID) const
{
- if (!m_document->page())
+ if (!m_document || !m_document->page())
return nullptr;
if (auto monitor = m_document->page()->chrome().client().createDisplayRefreshMonitor(displayID))
Modified: trunk/Source/WebCore/animation/DocumentTimeline.h (224759 => 224760)
--- trunk/Source/WebCore/animation/DocumentTimeline.h 2017-11-13 18:55:20 UTC (rev 224759)
+++ trunk/Source/WebCore/animation/DocumentTimeline.h 2017-11-13 19:14:47 UTC (rev 224760)
@@ -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 (224759 => 224760)
--- trunk/Source/WebCore/animation/WebAnimation.cpp 2017-11-13 18:55:20 UTC (rev 224759)
+++ trunk/Source/WebCore/animation/WebAnimation.cpp 2017-11-13 19:14:47 UTC (rev 224760)
@@ -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 (224759 => 224760)
--- trunk/Source/WebCore/dom/Document.cpp 2017-11-13 18:55:20 UTC (rev 224759)
+++ trunk/Source/WebCore/dom/Document.cpp 2017-11-13 19:14:47 UTC (rev 224760)
@@ -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"
@@ -195,6 +196,7 @@
#include "ValidationMessageClient.h"
#include "VisibilityChangeClient.h"
#include "VisitedLinkState.h"
+#include "WebAnimation.h"
#include "WheelEvent.h"
#include "WindowFeatures.h"
#include "XMLDocument.h"
@@ -2312,6 +2314,11 @@
if (m_hasPreparedForDestruction)
return;
+ if (m_timeline) {
+ m_timeline->detachFromDocument();
+ m_timeline = nullptr;
+ }
+
if (m_frame)
m_frame->animation().detachFromDocument(this);
@@ -7463,6 +7470,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;
+}
+
#if ENABLE(ATTACHMENT_ELEMENT)
void Document::didInsertAttachmentElement(HTMLAttachmentElement& attachment)
Modified: trunk/Source/WebCore/dom/Document.h (224759 => 224760)
--- trunk/Source/WebCore/dom/Document.h 2017-11-13 18:55:20 UTC (rev 224759)
+++ trunk/Source/WebCore/dom/Document.h 2017-11-13 19:14:47 UTC (rev 224760)
@@ -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;
@@ -1376,6 +1377,7 @@
WEBCORE_EXPORT void setConsoleMessageListener(RefPtr<StringCallback>&&); // For testing.
DocumentTimeline& timeline();
+ Vector<RefPtr<WebAnimation>> getAnimations();
#if ENABLE(ATTACHMENT_ELEMENT)
void didInsertAttachmentElement(HTMLAttachmentElement&);
Modified: trunk/Source/WebCore/dom/Document.idl (224759 => 224760)
--- trunk/Source/WebCore/dom/Document.idl 2017-11-13 18:55:20 UTC (rev 224759)
+++ trunk/Source/WebCore/dom/Document.idl 2017-11-13 19:14:47 UTC (rev 224760)
@@ -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 (224759 => 224760)
--- trunk/Source/WebCore/dom/Element.cpp 2017-11-13 18:55:20 UTC (rev 224759)
+++ trunk/Source/WebCore/dom/Element.cpp 2017-11-13 19:14:47 UTC (rev 224760)
@@ -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 (224759 => 224760)
--- trunk/Source/WebCore/dom/Element.h 2017-11-13 18:55:20 UTC (rev 224759)
+++ trunk/Source/WebCore/dom/Element.h 2017-11-13 19:14:47 UTC (rev 224760)
@@ -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 (224759 => 224760)
--- trunk/Source/WebCore/dom/Element.idl 2017-11-13 18:55:20 UTC (rev 224759)
+++ trunk/Source/WebCore/dom/Element.idl 2017-11-13 19:14:47 UTC (rev 224760)
@@ -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 (224759 => 224760)
--- trunk/Source/WebCore/testing/Internals.cpp 2017-11-13 18:55:20 UTC (rev 224759)
+++ trunk/Source/WebCore/testing/Internals.cpp 2017-11-13 19:14:47 UTC (rev 224760)
@@ -29,6 +29,7 @@
#include "AXObjectCache.h"
#include "ActiveDOMCallbackMicrotask.h"
+#include "AnimationTimeline.h"
#include "ApplicationCacheStorage.h"
#include "AudioSession.h"
#include "Autofill.h"