- Revision
- 261336
- Author
- grao...@webkit.org
- Date
- 2020-05-07 14:44:13 -0700 (Thu, 07 May 2020)
Log Message
[Web Animations] imported/w3c/web-platform-tests/web-animations/timing-model/timelines/update-and-send-events.html is a flaky failure
https://bugs.webkit.org/show_bug.cgi?id=211232
<rdar://problem/62650227>
Reviewed by Dean Jackson.
The flakiness came from this porting of the test:
animA.finished.then(() => { animB.cancel() });
animB.finished.then(() => { animA.cancel() });
Sometimes, animA and animB would finish in different frames even though they were designed to finish at the
same time. If this happened, animA.finished would resolve and trigger animB.cancel, which then rejected
animB.finished. This happened because animB was attached to a DocumentTimeline created by script which isn't
the main DocumenTimeline accessed via document.timeline. Some curious code would handle syncing of the
various timelines such that they would use a shared timebase. This was in DocumentTimeline::currentTime():
auto& mainDocumentTimeline = m_document->timeline();
if (&mainDocumentTimeline != this) {
if (auto mainDocumentTimelineCurrentTime = mainDocumentTimeline.currentTime())
return *mainDocumentTimelineCurrentTime - m_originTime;
return WTF::nullopt;
}
We now move the currentTime caching at the DocumentTimelinesController level which ensures all DocumentTimeline
objects attached to a given Document use the exact same currentTime(). This prompted some overdue refactoring
where also all the related animation suspension code is moved from DocumentTimeline up to DocumentTimelinesController.
* animation/DocumentTimeline.cpp:
(WebCore::DocumentTimeline::detachFromDocument):
(WebCore::DocumentTimeline::suspendAnimations):
(WebCore::DocumentTimeline::resumeAnimations):
(WebCore::DocumentTimeline::animationsAreSuspended const):
(WebCore::DocumentTimeline::currentTime):
(WebCore::DocumentTimeline::scheduleAnimationResolution):
(WebCore::DocumentTimeline::documentWillUpdateAnimationsAndSendEvents):
(WebCore::DocumentTimeline::animationsAreSuspended): Deleted.
(WebCore::DocumentTimeline::liveCurrentTime const): Deleted.
(WebCore::DocumentTimeline::cacheCurrentTime): Deleted.
(WebCore::DocumentTimeline::maybeClearCachedCurrentTime): Deleted.
* animation/DocumentTimeline.h:
* animation/DocumentTimelinesController.cpp:
(WebCore::DocumentTimelinesController::detachFromDocument):
(WebCore::DocumentTimelinesController::updateAnimationsAndSendEvents):
(WebCore::DocumentTimelinesController::suspendAnimations):
(WebCore::DocumentTimelinesController::resumeAnimations):
(WebCore::DocumentTimelinesController::animationsAreSuspended const):
(WebCore::DocumentTimelinesController::liveCurrentTime const):
(WebCore::DocumentTimelinesController::currentTime):
(WebCore::DocumentTimelinesController::cacheCurrentTime):
(WebCore::DocumentTimelinesController::maybeClearCachedCurrentTime):
* animation/DocumentTimelinesController.h:
* dom/Document.cpp:
(WebCore::Document::didBecomeCurrentDocumentInFrame):
(WebCore::Document::resume):
* dom/Document.h:
* page/Frame.cpp:
(WebCore::Frame::clearTimers):
(WebCore::Frame::resumeActiveDOMObjectsAndAnimations):
* page/Page.cpp:
(WebCore::Page::setIsVisibleInternal):
(WebCore::Page::hiddenPageCSSAnimationSuspensionStateChanged):
* testing/Internals.cpp:
(WebCore::Internals::animationsAreSuspended const):
(WebCore::Internals::suspendAnimations const):
(WebCore::Internals::resumeAnimations const):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (261335 => 261336)
--- trunk/Source/WebCore/ChangeLog 2020-05-07 21:39:20 UTC (rev 261335)
+++ trunk/Source/WebCore/ChangeLog 2020-05-07 21:44:13 UTC (rev 261336)
@@ -1,3 +1,72 @@
+2020-05-07 Antoine Quint <grao...@apple.com>
+
+ [Web Animations] imported/w3c/web-platform-tests/web-animations/timing-model/timelines/update-and-send-events.html is a flaky failure
+ https://bugs.webkit.org/show_bug.cgi?id=211232
+ <rdar://problem/62650227>
+
+ Reviewed by Dean Jackson.
+
+ The flakiness came from this porting of the test:
+
+ animA.finished.then(() => { animB.cancel() });
+ animB.finished.then(() => { animA.cancel() });
+
+ Sometimes, animA and animB would finish in different frames even though they were designed to finish at the
+ same time. If this happened, animA.finished would resolve and trigger animB.cancel, which then rejected
+ animB.finished. This happened because animB was attached to a DocumentTimeline created by script which isn't
+ the main DocumenTimeline accessed via document.timeline. Some curious code would handle syncing of the
+ various timelines such that they would use a shared timebase. This was in DocumentTimeline::currentTime():
+
+ auto& mainDocumentTimeline = m_document->timeline();
+ if (&mainDocumentTimeline != this) {
+ if (auto mainDocumentTimelineCurrentTime = mainDocumentTimeline.currentTime())
+ return *mainDocumentTimelineCurrentTime - m_originTime;
+ return WTF::nullopt;
+ }
+
+ We now move the currentTime caching at the DocumentTimelinesController level which ensures all DocumentTimeline
+ objects attached to a given Document use the exact same currentTime(). This prompted some overdue refactoring
+ where also all the related animation suspension code is moved from DocumentTimeline up to DocumentTimelinesController.
+
+ * animation/DocumentTimeline.cpp:
+ (WebCore::DocumentTimeline::detachFromDocument):
+ (WebCore::DocumentTimeline::suspendAnimations):
+ (WebCore::DocumentTimeline::resumeAnimations):
+ (WebCore::DocumentTimeline::animationsAreSuspended const):
+ (WebCore::DocumentTimeline::currentTime):
+ (WebCore::DocumentTimeline::scheduleAnimationResolution):
+ (WebCore::DocumentTimeline::documentWillUpdateAnimationsAndSendEvents):
+ (WebCore::DocumentTimeline::animationsAreSuspended): Deleted.
+ (WebCore::DocumentTimeline::liveCurrentTime const): Deleted.
+ (WebCore::DocumentTimeline::cacheCurrentTime): Deleted.
+ (WebCore::DocumentTimeline::maybeClearCachedCurrentTime): Deleted.
+ * animation/DocumentTimeline.h:
+ * animation/DocumentTimelinesController.cpp:
+ (WebCore::DocumentTimelinesController::detachFromDocument):
+ (WebCore::DocumentTimelinesController::updateAnimationsAndSendEvents):
+ (WebCore::DocumentTimelinesController::suspendAnimations):
+ (WebCore::DocumentTimelinesController::resumeAnimations):
+ (WebCore::DocumentTimelinesController::animationsAreSuspended const):
+ (WebCore::DocumentTimelinesController::liveCurrentTime const):
+ (WebCore::DocumentTimelinesController::currentTime):
+ (WebCore::DocumentTimelinesController::cacheCurrentTime):
+ (WebCore::DocumentTimelinesController::maybeClearCachedCurrentTime):
+ * animation/DocumentTimelinesController.h:
+ * dom/Document.cpp:
+ (WebCore::Document::didBecomeCurrentDocumentInFrame):
+ (WebCore::Document::resume):
+ * dom/Document.h:
+ * page/Frame.cpp:
+ (WebCore::Frame::clearTimers):
+ (WebCore::Frame::resumeActiveDOMObjectsAndAnimations):
+ * page/Page.cpp:
+ (WebCore::Page::setIsVisibleInternal):
+ (WebCore::Page::hiddenPageCSSAnimationSuspensionStateChanged):
+ * testing/Internals.cpp:
+ (WebCore::Internals::animationsAreSuspended const):
+ (WebCore::Internals::suspendAnimations const):
+ (WebCore::Internals::resumeAnimations const):
+
2020-05-07 Simon Fraser <simon.fra...@apple.com>
REGRESSION (r252161): Animation of box-shadow with border-radius set is flashy
Modified: trunk/Source/WebCore/animation/DocumentTimeline.cpp (261335 => 261336)
--- trunk/Source/WebCore/animation/DocumentTimeline.cpp 2020-05-07 21:39:20 UTC (rev 261335)
+++ trunk/Source/WebCore/animation/DocumentTimeline.cpp 2020-05-07 21:44:13 UTC (rev 261336)
@@ -29,7 +29,6 @@
#include "AnimationEventBase.h"
#include "CSSAnimation.h"
#include "CSSTransition.h"
-#include "DOMWindow.h"
#include "DeclarativeAnimation.h"
#include "Document.h"
#include "DocumentTimelinesController.h"
@@ -44,7 +43,6 @@
#include "RenderLayer.h"
#include "RenderLayerBacking.h"
#include "Settings.h"
-#include <_javascript_Core/VM.h>
namespace WebCore {
@@ -92,7 +90,6 @@
controller->removeTimeline(*this);
m_pendingAnimationEvents.clear();
- m_currentTimeClearingTaskQueue.close();
m_elementsWithRunningAcceleratedAnimations.clear();
auto& animationsToRemove = m_animations;
@@ -220,17 +217,9 @@
void DocumentTimeline::suspendAnimations()
{
- if (animationsAreSuspended())
- return;
-
- if (!m_cachedCurrentTime)
- m_cachedCurrentTime = liveCurrentTime();
-
for (const auto& animation : m_animations)
animation->setSuspended(true);
- m_isSuspended = true;
-
applyPendingAcceleratedAnimations();
clearTickScheduleTimer();
@@ -238,13 +227,6 @@
void DocumentTimeline::resumeAnimations()
{
- if (!animationsAreSuspended())
- return;
-
- m_cachedCurrentTime = WTF::nullopt;
-
- m_isSuspended = false;
-
for (const auto& animation : m_animations)
animation->setSuspended(false);
@@ -251,9 +233,9 @@
scheduleAnimationResolution();
}
-bool DocumentTimeline::animationsAreSuspended()
+bool DocumentTimeline::animationsAreSuspended() const
{
- return m_isSuspended;
+ return controller() && controller()->animationsAreSuspended();
}
unsigned DocumentTimeline::numberOfActiveAnimationsForTesting() const
@@ -266,56 +248,16 @@
return count;
}
-ReducedResolutionSeconds DocumentTimeline::liveCurrentTime() const
-{
- return m_document->domWindow()->nowTimestamp();
-}
-
Optional<Seconds> DocumentTimeline::currentTime()
{
- if (!m_document || !m_document->domWindow())
- return AnimationTimeline::currentTime();
-
- auto& mainDocumentTimeline = m_document->timeline();
- if (&mainDocumentTimeline != this) {
- if (auto mainDocumentTimelineCurrentTime = mainDocumentTimeline.currentTime())
- return *mainDocumentTimelineCurrentTime - m_originTime;
+ if (auto* controller = this->controller()) {
+ if (auto currentTime = controller->currentTime())
+ return *currentTime - m_originTime;
return WTF::nullopt;
}
-
- if (!m_cachedCurrentTime)
- cacheCurrentTime(liveCurrentTime());
-
- return m_cachedCurrentTime.value() - m_originTime;
+ return AnimationTimeline::currentTime();
}
-void DocumentTimeline::cacheCurrentTime(ReducedResolutionSeconds newCurrentTime)
-{
- ASSERT(m_document);
-
- m_cachedCurrentTime = newCurrentTime;
- // We want to be sure to keep this time cached until we've both finished running JS and finished updating
- // animations, so we schedule the invalidation task and register a whenIdle callback on the VM, which will
- // fire syncronously if no JS is running.
- m_waitingOnVMIdle = true;
- if (!m_currentTimeClearingTaskQueue.hasPendingTasks())
- m_currentTimeClearingTaskQueue.enqueueTask(std::bind(&DocumentTimeline::maybeClearCachedCurrentTime, this));
- m_document->vm().whenIdle([this, protectedThis = makeRefPtr(this)]() {
- m_waitingOnVMIdle = false;
- maybeClearCachedCurrentTime();
- });
-}
-
-void DocumentTimeline::maybeClearCachedCurrentTime()
-{
- // We want to make sure we only clear the cached current time if we're not currently running
- // JS or waiting on all current animation updating code to have completed. This is so that
- // we're guaranteed to have a consistent current time reported for all work happening in a given
- // JS frame or throughout updating animations in WebCore.
- if (!m_isSuspended && !m_waitingOnVMIdle && !m_currentTimeClearingTaskQueue.hasPendingTasks())
- m_cachedCurrentTime = WTF::nullopt;
-}
-
void DocumentTimeline::animationTimingDidChange(WebAnimation& animation)
{
AnimationTimeline::animationTimingDidChange(animation);
@@ -332,7 +274,7 @@
void DocumentTimeline::scheduleAnimationResolution()
{
- if (m_isSuspended || m_animationResolutionScheduled || !m_document || !m_document->page())
+ if (animationsAreSuspended() || m_animationResolutionScheduled || !m_document || !m_document->page())
return;
// We need some relevant animations or pending events to proceed.
@@ -353,19 +295,13 @@
return !m_animations.isEmpty() || !m_pendingAnimationEvents.isEmpty() || !m_acceleratedAnimationsPendingRunningStateChange.isEmpty();
}
-DocumentTimeline::ShouldUpdateAnimationsAndSendEvents DocumentTimeline::documentWillUpdateAnimationsAndSendEvents(ReducedResolutionSeconds timestamp)
+DocumentTimeline::ShouldUpdateAnimationsAndSendEvents DocumentTimeline::documentWillUpdateAnimationsAndSendEvents()
{
- // We need to freeze the current time even if no animation is running.
- // document.timeline.currentTime may be called from a rAF callback and
- // it has to match the rAF timestamp.
- if (!m_isSuspended || !shouldRunUpdateAnimationsAndSendEventsIgnoringSuspensionState())
- cacheCurrentTime(timestamp);
-
// Updating animations and sending events may invalidate the timing of some animations, so we must set the m_animationResolutionScheduled
// flag to false prior to running that procedure to allow animation with timing model updates to schedule updates.
bool wasAnimationResolutionScheduled = std::exchange(m_animationResolutionScheduled, false);
- if (!wasAnimationResolutionScheduled || m_isSuspended || !shouldRunUpdateAnimationsAndSendEventsIgnoringSuspensionState())
+ if (!wasAnimationResolutionScheduled || animationsAreSuspended() || !shouldRunUpdateAnimationsAndSendEventsIgnoringSuspensionState())
return DocumentTimeline::ShouldUpdateAnimationsAndSendEvents::No;
m_numberOfAnimationTimelineInvalidationsForTesting++;
Modified: trunk/Source/WebCore/animation/DocumentTimeline.h (261335 => 261336)
--- trunk/Source/WebCore/animation/DocumentTimeline.h 2020-05-07 21:39:20 UTC (rev 261335)
+++ trunk/Source/WebCore/animation/DocumentTimeline.h 2020-05-07 21:44:13 UTC (rev 261336)
@@ -27,10 +27,7 @@
#include "AnimationTimeline.h"
#include "DocumentTimelineOptions.h"
-#include "GenericTaskQueue.h"
-#include "ReducedResolutionSeconds.h"
#include "Timer.h"
-#include <wtf/Markable.h>
#include <wtf/Ref.h>
#include <wtf/WeakPtr.h>
@@ -75,15 +72,15 @@
void enqueueAnimationEvent(AnimationEventBase&);
enum class ShouldUpdateAnimationsAndSendEvents : uint8_t { Yes, No };
- ShouldUpdateAnimationsAndSendEvents documentWillUpdateAnimationsAndSendEvents(ReducedResolutionSeconds);
+ ShouldUpdateAnimationsAndSendEvents documentWillUpdateAnimationsAndSendEvents();
void removeReplacedAnimations();
AnimationEvents prepareForPendingAnimationEventsDispatch();
void documentDidUpdateAnimationsAndSendEvents();
WEBCORE_EXPORT Seconds animationInterval() const;
- WEBCORE_EXPORT void suspendAnimations();
- WEBCORE_EXPORT void resumeAnimations();
- WEBCORE_EXPORT bool animationsAreSuspended();
+ void suspendAnimations();
+ void resumeAnimations();
+ bool animationsAreSuspended() const;
WEBCORE_EXPORT unsigned numberOfActiveAnimationsForTesting() const;
WEBCORE_EXPORT Vector<std::pair<String, double>> acceleratedAnimationsForElement(Element&) const;
WEBCORE_EXPORT unsigned numberOfAnimationTimelineInvalidationsForTesting() const;
@@ -92,10 +89,7 @@
DocumentTimeline(Document&, Seconds);
DocumentTimelinesController* controller() const;
- ReducedResolutionSeconds liveCurrentTime() const;
void applyPendingAcceleratedAnimations();
- void cacheCurrentTime(ReducedResolutionSeconds);
- void maybeClearCachedCurrentTime();
void scheduleInvalidationTaskIfNeeded();
void scheduleAnimationResolution();
void clearTickScheduleTimer();
@@ -106,16 +100,12 @@
bool shouldRunUpdateAnimationsAndSendEventsIgnoringSuspensionState() const;
Timer m_tickScheduleTimer;
- GenericTaskQueue<Timer> m_currentTimeClearingTaskQueue;
HashSet<RefPtr<WebAnimation>> m_acceleratedAnimationsPendingRunningStateChange;
HashSet<Element*> m_elementsWithRunningAcceleratedAnimations;
AnimationEvents m_pendingAnimationEvents;
WeakPtr<Document> m_document;
- Markable<Seconds, Seconds::MarkableTraits> m_cachedCurrentTime;
Seconds m_originTime;
unsigned m_numberOfAnimationTimelineInvalidationsForTesting { 0 };
- bool m_isSuspended { false };
- bool m_waitingOnVMIdle { false };
bool m_animationResolutionScheduled { false };
bool m_shouldScheduleAnimationResolutionForNewPendingEvents { true };
};
Modified: trunk/Source/WebCore/animation/DocumentTimelinesController.cpp (261335 => 261336)
--- trunk/Source/WebCore/animation/DocumentTimelinesController.cpp 2020-05-07 21:39:20 UTC (rev 261335)
+++ trunk/Source/WebCore/animation/DocumentTimelinesController.cpp 2020-05-07 21:44:13 UTC (rev 261336)
@@ -28,11 +28,13 @@
#include "AnimationEventBase.h"
#include "CSSTransition.h"
+#include "DOMWindow.h"
#include "Document.h"
#include "DocumentTimeline.h"
#include "EventLoop.h"
#include "WebAnimation.h"
#include "WebAnimationTypes.h"
+#include <_javascript_Core/VM.h>
namespace WebCore {
@@ -57,6 +59,8 @@
void DocumentTimelinesController::detachFromDocument()
{
+ m_currentTimeClearingTaskQueue.close();
+
while (!m_timelines.computesEmpty())
m_timelines.begin()->detachFromDocument();
}
@@ -70,12 +74,18 @@
for (auto& timeline : m_timelines)
protectedTimelines.append(&timeline);
+ // We need to freeze the current time even if no animation is running.
+ // document.timeline.currentTime may be called from a rAF callback and
+ // it has to match the rAF timestamp.
+ if (!m_isSuspended)
+ cacheCurrentTime(timestamp);
+
// 1. Update the current time of all timelines associated with doc passing now as the timestamp.
Vector<DocumentTimeline*> timelinesToUpdate;
Vector<RefPtr<WebAnimation>> animationsToRemove;
Vector<RefPtr<CSSTransition>> completedTransitions;
for (auto& timeline : protectedTimelines) {
- auto shouldUpdateAnimationsAndSendEvents = timeline->documentWillUpdateAnimationsAndSendEvents(timestamp);
+ auto shouldUpdateAnimationsAndSendEvents = timeline->documentWillUpdateAnimationsAndSendEvents();
if (shouldUpdateAnimationsAndSendEvents == DocumentTimeline::ShouldUpdateAnimationsAndSendEvents::No)
continue;
@@ -156,5 +166,80 @@
timeline->documentDidUpdateAnimationsAndSendEvents();
}
+void DocumentTimelinesController::suspendAnimations()
+{
+ if (m_isSuspended)
+ return;
+
+ if (!m_cachedCurrentTime)
+ m_cachedCurrentTime = liveCurrentTime();
+
+ for (auto& timeline : m_timelines)
+ timeline.suspendAnimations();
+
+ m_isSuspended = true;
+}
+
+void DocumentTimelinesController::resumeAnimations()
+{
+ if (!m_isSuspended)
+ return;
+
+ m_cachedCurrentTime = WTF::nullopt;
+
+ m_isSuspended = false;
+
+ for (auto& timeline : m_timelines)
+ timeline.resumeAnimations();
+}
+
+bool DocumentTimelinesController::animationsAreSuspended() const
+{
+ return m_isSuspended;
+}
+
+ReducedResolutionSeconds DocumentTimelinesController::liveCurrentTime() const
+{
+ return m_document.domWindow()->nowTimestamp();
+}
+
+Optional<Seconds> DocumentTimelinesController::currentTime()
+{
+ if (!m_document.domWindow())
+ return WTF::nullopt;
+
+ if (!m_cachedCurrentTime)
+ cacheCurrentTime(liveCurrentTime());
+
+ return *m_cachedCurrentTime;
+}
+
+void DocumentTimelinesController::cacheCurrentTime(ReducedResolutionSeconds newCurrentTime)
+{
+ m_cachedCurrentTime = newCurrentTime;
+ // We want to be sure to keep this time cached until we've both finished running JS and finished updating
+ // animations, so we schedule the invalidation task and register a whenIdle callback on the VM, which will
+ // fire syncronously if no JS is running.
+ m_waitingOnVMIdle = true;
+ if (!m_currentTimeClearingTaskQueue.hasPendingTasks())
+ m_currentTimeClearingTaskQueue.enqueueTask(std::bind(&DocumentTimelinesController::maybeClearCachedCurrentTime, this));
+ // We extent the associated Document's lifecycle until the VM became idle since the DocumentTimelinesController
+ // is owned by the Document.
+ m_document.vm().whenIdle([this, protectedDocument = makeRefPtr(m_document)]() {
+ m_waitingOnVMIdle = false;
+ maybeClearCachedCurrentTime();
+ });
+}
+
+void DocumentTimelinesController::maybeClearCachedCurrentTime()
+{
+ // We want to make sure we only clear the cached current time if we're not currently running
+ // JS or waiting on all current animation updating code to have completed. This is so that
+ // we're guaranteed to have a consistent current time reported for all work happening in a given
+ // JS frame or throughout updating animations in WebCore.
+ if (!m_isSuspended && !m_waitingOnVMIdle && !m_currentTimeClearingTaskQueue.hasPendingTasks())
+ m_cachedCurrentTime = WTF::nullopt;
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/animation/DocumentTimelinesController.h (261335 => 261336)
--- trunk/Source/WebCore/animation/DocumentTimelinesController.h 2020-05-07 21:39:20 UTC (rev 261335)
+++ trunk/Source/WebCore/animation/DocumentTimelinesController.h 2020-05-07 21:44:13 UTC (rev 261336)
@@ -25,7 +25,11 @@
#pragma once
+#include "GenericTaskQueue.h"
#include "ReducedResolutionSeconds.h"
+#include "Timer.h"
+#include <wtf/Markable.h>
+#include <wtf/Seconds.h>
#include <wtf/WeakHashSet.h>
namespace WebCore {
@@ -46,6 +50,12 @@
void detachFromDocument();
void updateAnimationsAndSendEvents(ReducedResolutionSeconds);
+ Optional<Seconds> currentTime();
+
+ WEBCORE_EXPORT void suspendAnimations();
+ WEBCORE_EXPORT void resumeAnimations();
+ WEBCORE_EXPORT bool animationsAreSuspended() const;
+
private:
struct AnimationsToProcess {
Vector<RefPtr<WebAnimation>> animationsToRemove;
@@ -52,8 +62,16 @@
Vector<RefPtr<CSSTransition>> completedTransitions;
};
+ ReducedResolutionSeconds liveCurrentTime() const;
+ void cacheCurrentTime(ReducedResolutionSeconds);
+ void maybeClearCachedCurrentTime();
+
WeakHashSet<DocumentTimeline> m_timelines;
+ GenericTaskQueue<Timer> m_currentTimeClearingTaskQueue;
Document& m_document;
+ Markable<Seconds, Seconds::MarkableTraits> m_cachedCurrentTime;
+ bool m_isSuspended { false };
+ bool m_waitingOnVMIdle { false };
};
} // namespace WebCore
Modified: trunk/Source/WebCore/dom/Document.cpp (261335 => 261336)
--- trunk/Source/WebCore/dom/Document.cpp 2020-05-07 21:39:20 UTC (rev 261335)
+++ trunk/Source/WebCore/dom/Document.cpp 2020-05-07 21:44:13 UTC (rev 261336)
@@ -2403,8 +2403,8 @@
// back/forward cache, or simply newly created).
if (m_frame->activeDOMObjectsAndAnimationsSuspended()) {
if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
- if (auto* timeline = existingTimeline())
- timeline->suspendAnimations();
+ if (m_timelinesController)
+ m_timelinesController->suspendAnimations();
} else
m_frame->legacyAnimation().suspendAnimationsForDocument(this);
suspendScheduledTasks(ReasonForSuspension::PageWillBeSuspended);
@@ -2411,8 +2411,8 @@
} else {
resumeScheduledTasks(ReasonForSuspension::PageWillBeSuspended);
if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
- if (auto* timeline = existingTimeline())
- timeline->resumeAnimations();
+ if (m_timelinesController)
+ m_timelinesController->resumeAnimations();
} else
m_frame->legacyAnimation().resumeAnimationsForDocument(this);
}
@@ -5399,8 +5399,8 @@
m_frame->loader().client().dispatchDidBecomeFrameset(isFrameSet());
if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
- if (auto* timeline = existingTimeline())
- timeline->resumeAnimations();
+ if (m_timelinesController)
+ m_timelinesController->resumeAnimations();
} else
m_frame->legacyAnimation().resumeAnimationsForDocument(this);
Modified: trunk/Source/WebCore/dom/Document.h (261335 => 261336)
--- trunk/Source/WebCore/dom/Document.h 2020-05-07 21:39:20 UTC (rev 261335)
+++ trunk/Source/WebCore/dom/Document.h 2020-05-07 21:44:13 UTC (rev 261336)
@@ -1496,7 +1496,7 @@
Vector<RefPtr<WebAnimation>> getAnimations();
Vector<RefPtr<WebAnimation>> matchingAnimations(const WTF::Function<bool(Element&)>&);
DocumentTimelinesController* timelinesController() const { return m_timelinesController.get(); }
- DocumentTimelinesController& ensureTimelinesController();
+ WEBCORE_EXPORT DocumentTimelinesController& ensureTimelinesController();
#if ENABLE(ATTACHMENT_ELEMENT)
void registerAttachmentIdentifier(const String&);
Modified: trunk/Source/WebCore/page/Frame.cpp (261335 => 261336)
--- trunk/Source/WebCore/page/Frame.cpp 2020-05-07 21:39:20 UTC (rev 261335)
+++ trunk/Source/WebCore/page/Frame.cpp 2020-05-07 21:44:13 UTC (rev 261336)
@@ -718,8 +718,8 @@
if (view) {
view->layoutContext().unscheduleLayout();
if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
- if (auto* timeline = document->existingTimeline())
- timeline->suspendAnimations();
+ if (auto* timelines = document->timelinesController())
+ timelines->suspendAnimations();
} else
view->frame().legacyAnimation().suspendAnimationsForDocument(document);
view->frame().eventHandler().stopAutoscrollTimer();
@@ -1013,8 +1013,8 @@
// Frame::clearTimers() suspended animations and pending relayouts.
if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
- if (auto* timeline = m_doc->existingTimeline())
- timeline->resumeAnimations();
+ if (auto* timelines = m_doc->timelinesController())
+ timelines->resumeAnimations();
} else
legacyAnimation().resumeAnimationsForDocument(m_doc.get());
if (m_view)
Modified: trunk/Source/WebCore/page/Page.cpp (261335 => 261336)
--- trunk/Source/WebCore/page/Page.cpp 2020-05-07 21:39:20 UTC (rev 261335)
+++ trunk/Source/WebCore/page/Page.cpp 2020-05-07 21:44:13 UTC (rev 261336)
@@ -2052,8 +2052,8 @@
if (m_settings->hiddenPageCSSAnimationSuspensionEnabled()) {
if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
forEachDocument([] (Document& document) {
- if (auto* timeline = document.existingTimeline())
- timeline->resumeAnimations();
+ if (auto* timelines = document.timelinesController())
+ timelines->resumeAnimations();
});
} else
mainFrame().legacyAnimation().resumeAnimations();
@@ -2076,8 +2076,8 @@
if (m_settings->hiddenPageCSSAnimationSuspensionEnabled()) {
if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
forEachDocument([] (Document& document) {
- if (auto* timeline = document.existingTimeline())
- timeline->suspendAnimations();
+ if (auto* timelines = document.timelinesController())
+ timelines->suspendAnimations();
});
} else
mainFrame().legacyAnimation().suspendAnimations();
@@ -2427,11 +2427,11 @@
if (!isVisible()) {
if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
forEachDocument([&] (Document& document) {
- if (auto* timeline = document.existingTimeline()) {
+ if (auto* timelines = document.timelinesController()) {
if (m_settings->hiddenPageCSSAnimationSuspensionEnabled())
- timeline->suspendAnimations();
+ timelines->suspendAnimations();
else
- timeline->resumeAnimations();
+ timelines->resumeAnimations();
}
});
} else {
Modified: trunk/Source/WebCore/testing/Internals.cpp (261335 => 261336)
--- trunk/Source/WebCore/testing/Internals.cpp 2020-05-07 21:39:20 UTC (rev 261335)
+++ trunk/Source/WebCore/testing/Internals.cpp 2020-05-07 21:44:13 UTC (rev 261336)
@@ -1071,7 +1071,7 @@
return Exception { InvalidAccessError };
if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled())
- return document->timeline().animationsAreSuspended();
+ return document->ensureTimelinesController().animationsAreSuspended();
return document->frame()->legacyAnimation().animationsAreSuspendedForDocument(document);
}
@@ -1099,10 +1099,10 @@
return Exception { InvalidAccessError };
if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
- document->timeline().suspendAnimations();
+ document->ensureTimelinesController().suspendAnimations();
for (Frame* frame = document->frame(); frame; frame = frame->tree().traverseNext()) {
if (Document* document = frame->document())
- document->timeline().suspendAnimations();
+ document->ensureTimelinesController().suspendAnimations();
}
} else {
document->frame()->legacyAnimation().suspendAnimationsForDocument(document);
@@ -1123,10 +1123,10 @@
return Exception { InvalidAccessError };
if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
- document->timeline().resumeAnimations();
+ document->ensureTimelinesController().resumeAnimations();
for (Frame* frame = document->frame(); frame; frame = frame->tree().traverseNext()) {
if (Document* document = frame->document())
- document->timeline().resumeAnimations();
+ document->ensureTimelinesController().resumeAnimations();
}
} else {
document->frame()->legacyAnimation().resumeAnimationsForDocument(document);