[Web Animations] Update all DocumentTimeline objects when updating animations
authorgraouts@webkit.org <graouts@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 27 Jan 2020 12:01:21 +0000 (12:01 +0000)
committergraouts@webkit.org <graouts@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 27 Jan 2020 12:01:21 +0000 (12:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=206819

Reviewed by Antti Koivisto.

LayoutTests/imported/w3c:

Mark a single new WPT progression.

* web-platform-tests/web-animations/timing-model/timelines/update-and-send-events-replacement-expected.txt:

Source/WebCore:

Developers can create additional DocumentTimeline objects in JavaScript using that class's constructor, and an animation can be
assigned to that timeline after its creation. Until now we would only update an timeline created by a Document when that document's
animations were updated. Now we keep track of all DocumentTimeline objects that are created for a given Document as a vector of weak
references, and we update all of them when updating a document's animations.

* animation/DocumentTimeline.cpp:
(WebCore::DocumentTimeline::DocumentTimeline):
(WebCore::DocumentTimeline::~DocumentTimeline):
* animation/DocumentTimeline.h:
* dom/Document.cpp:
(WebCore::Document::updateAnimationsAndSendEvents):
(WebCore::Document::addTimeline):
(WebCore::Document::removeTimeline):
* dom/Document.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@255141 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/web-animations/timing-model/timelines/update-and-send-events-replacement-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/animation/DocumentTimeline.cpp
Source/WebCore/animation/DocumentTimeline.h
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h

index f80975c..48fe200 100644 (file)
@@ -1,3 +1,14 @@
+2020-01-26  Antoine Quint  <graouts@apple.com>
+
+        [Web Animations] Update all DocumentTimeline objects when updating animations
+        https://bugs.webkit.org/show_bug.cgi?id=206819
+
+        Reviewed by Antti Koivisto.
+
+        Mark a single new WPT progression.
+
+        * web-platform-tests/web-animations/timing-model/timelines/update-and-send-events-replacement-expected.txt:
+
 2020-01-27  Rob Buis  <rbuis@igalia.com>
 
         Re-sync web-platform-tests/fetch/api/policies from upstream
index d748b7c..94c660f 100644 (file)
@@ -38,7 +38,7 @@ PASS Does NOT remove an animation after making a redundant change to another ani
 PASS Does NOT remove an animation after making a redundant change to its timeline 
 PASS Does NOT remove an animation after making a redundant change to another animation's effect's properties 
 PASS Does NOT remove an animation after making a redundant change to its effect's properties 
-FAIL Updates ALL timelines before checking for replacement assert_equals: expected "removed" but got "active"
+PASS Updates ALL timelines before checking for replacement 
 PASS Dispatches remove events after finish events 
 PASS Fires remove event before requestAnimationFrame 
 PASS Queues all remove events before running them 
index 4275473..7a02e81 100644 (file)
@@ -1,3 +1,25 @@
+2020-01-26  Antoine Quint  <graouts@apple.com>
+
+        [Web Animations] Update all DocumentTimeline objects when updating animations
+        https://bugs.webkit.org/show_bug.cgi?id=206819
+
+        Reviewed by Antti Koivisto.
+
+        Developers can create additional DocumentTimeline objects in JavaScript using that class's constructor, and an animation can be
+        assigned to that timeline after its creation. Until now we would only update an timeline created by a Document when that document's
+        animations were updated. Now we keep track of all DocumentTimeline objects that are created for a given Document as a vector of weak
+        references, and we update all of them when updating a document's animations.
+
+        * animation/DocumentTimeline.cpp:
+        (WebCore::DocumentTimeline::DocumentTimeline):
+        (WebCore::DocumentTimeline::~DocumentTimeline):
+        * animation/DocumentTimeline.h:
+        * dom/Document.cpp:
+        (WebCore::Document::updateAnimationsAndSendEvents):
+        (WebCore::Document::addTimeline):
+        (WebCore::Document::removeTimeline):
+        * dom/Document.h:
+
 2020-01-26  Darin Adler  <darin@apple.com>
 
         Move DOMCacheEngine::errorToException back out of header and into .cpp file
index 2d5ae35..6be4e64 100644 (file)
@@ -62,11 +62,17 @@ DocumentTimeline::DocumentTimeline(Document& document, Seconds originTime)
     , m_document(&document)
     , m_originTime(originTime)
 {
+    if (m_document)
+        m_document->addTimeline(*this);
     if (m_document && m_document->page() && !m_document->page()->isVisible())
         suspendAnimations();
 }
 
-DocumentTimeline::~DocumentTimeline() = default;
+DocumentTimeline::~DocumentTimeline()
+{
+    if (m_document)
+        m_document->removeTimeline(*this);
+}
 
 void DocumentTimeline::detachFromDocument()
 {
index fcc3b03..2bb749e 100644 (file)
 #include "Timer.h"
 #include <wtf/Markable.h>
 #include <wtf/Ref.h>
+#include <wtf/WeakPtr.h>
 
 namespace WebCore {
 
 class AnimationPlaybackEvent;
 class RenderElement;
 
-class DocumentTimeline final : public AnimationTimeline
+class DocumentTimeline final : public AnimationTimeline, public CanMakeWeakPtr<DocumentTimeline>
 {
 public:
     static Ref<DocumentTimeline> create(Document&);
index 60f87d3..b4da24e 100644 (file)
@@ -6352,8 +6352,13 @@ void Document::resumeScriptedAnimationControllerCallbacks()
 
 void Document::updateAnimationsAndSendEvents(DOMHighResTimeStamp timestamp)
 {
-    if (m_timeline)
-        m_timeline->updateAnimationsAndSendEvents(timestamp);
+    ASSERT(!m_timelines.hasNullReferences());
+    // We need to copy m_timelines before iterating over its members since calling updateAnimationsAndSendEvents() may mutate m_timelines.
+    Vector<RefPtr<DocumentTimeline>> timelines;
+    for (auto& timeline : m_timelines)
+        timelines.append(&timeline);
+    for (auto& timeline : timelines)
+        timeline->updateAnimationsAndSendEvents(timestamp);
 }
 
 void Document::serviceRequestAnimationFrameCallbacks(DOMHighResTimeStamp timestamp)
@@ -8038,6 +8043,16 @@ void Document::setConsoleMessageListener(RefPtr<StringCallback>&& listener)
     m_consoleMessageListener = listener;
 }
 
+void Document::addTimeline(DocumentTimeline& timeline)
+{
+    m_timelines.add(timeline);
+}
+
+void Document::removeTimeline(DocumentTimeline& timeline)
+{
+    m_timelines.remove(timeline);
+}
+
 DocumentTimeline& Document::timeline()
 {
     if (!m_timeline)
index 3acb622..81ed93a 100644 (file)
@@ -1471,6 +1471,8 @@ public:
 
     WEBCORE_EXPORT void setConsoleMessageListener(RefPtr<StringCallback>&&); // For testing.
 
+    void addTimeline(DocumentTimeline&);
+    void removeTimeline(DocumentTimeline&);
     WEBCORE_EXPORT DocumentTimeline& timeline();
     DocumentTimeline* existingTimeline() const { return m_timeline.get(); }
     Vector<RefPtr<WebAnimation>> getAnimations();
@@ -2037,6 +2039,8 @@ private:
     static bool hasEverCreatedAnAXObjectCache;
 
     RefPtr<DocumentTimeline> m_timeline;
+    WeakHashSet<DocumentTimeline> m_timelines;
+
     DocumentIdentifier m_identifier;
 
     RefPtr<WindowEventLoop> m_eventLoop;