Animations and Transitions should not start when globally suspended
authordino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 5 May 2013 04:43:05 +0000 (04:43 +0000)
committerdino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 5 May 2013 04:43:05 +0000 (04:43 +0000)
commit2312b45569799025b436e85c140d7409a5cd0bbb
treeb26b2ec1c29c0ff7772886cd3c6938f312b54e9a
parent7ae0ec3406d82f3a457e0b5c85ff3930e8c28b66
Animations and Transitions should not start when globally suspended
https://bugs.webkit.org/show_bug.cgi?id=114915

Reviewed by Sam Weinig.

.:

Export AnimationController::isSuspended().

* Source/autotools/symbols.filter:

Source/WebCore:

When the Document's AnimationController was suspended, we still
started new transitions and animations. Change this so that
animations enter a paused-but-new state, where they are frozen
until the AnimationController resumes. At that time, it is as
if they had just appeared: any delay counts down before
the animation starts.

For transitions, the change in value must still happen, but
it does so immediately. No transitionend event should be fired.
This produces a slightly confusing behaviour, because any
in-progress transitions are suspended, but any new style changes
happen instantly. This might sound contradictory, but in general
suspending the document is a rare (and dangerous) thing to do.

Previously, the Document would call resumeAnimations as it loaded,
effectively starting all the animations. This meant if you suspended
animations before loading a document, it was ignored as soon as the
load finished. Now there is a separate method startAnimationsIfNotSuspended
which checks to see if the document is suspended as it loads.

In order to handle this case, I added a new state to the Animation
machinery: AnimationStatePausedNew. This is an animation that was created
in the suspended state.

Tests: animations/added-while-suspended.html
       transitions/started-while-suspended.html

* WebCore.exp.in: Export AnimationController::isSuspended().

* dom/Document.cpp:
(WebCore::Document::implicitClose):
    resumeAnimationsForDocument() -> startAnimationsIfNotSuspended()

* page/animation/AnimationBase.cpp:
(WebCore::nameForState): New name for AnimationStatePausedNew.
(WebCore::AnimationBase::updateStateMachine): Handle new state AnimationStatePausedNew. The
    most important change is that when go from PausedNew to Running, we jump back into
    the New state and continue from there.
(WebCore::AnimationBase::updatePlayState): suspended -> isSuspended
* page/animation/AnimationBase.h: New state: AnimationStatePausedNew
(WebCore::AnimationBase::waitingToStart): Add AnimationStatePausedNew.
(WebCore::AnimationBase::paused): Add AnimationStatePausedNew.
(WebCore::AnimationBase::isNew): Add AnimationStatePausedNew.

* page/animation/AnimationController.cpp:
(WebCore::AnimationControllerPrivate::AnimationControllerPrivate): Initialise m_suspended.
(WebCore::AnimationControllerPrivate::clear): suspended -> isSuspended
(WebCore::AnimationControllerPrivate::updateAnimations): Ditto.
(WebCore::AnimationControllerPrivate::updateAnimationTimerForRenderer): Ditto.
(WebCore::AnimationControllerPrivate::suspendAnimations): Update m_suspended.
(WebCore::AnimationControllerPrivate::resumeAnimations): Ditto.
(WebCore::AnimationControllerPrivate::suspendAnimationsForDocument):
(WebCore::AnimationControllerPrivate::resumeAnimationsForDocument):
(WebCore::AnimationControllerPrivate::startAnimationsIfNotSuspended): New method that will
    only resume animations if we were not globally suspended.
(WebCore::AnimationController::isSuspended): New method.
(WebCore::AnimationController::suspendAnimations): Add logging.
(WebCore::AnimationController::resumeAnimations): Add logging.
(WebCore::AnimationController::suspendAnimationsForDocument): Add logging.
(WebCore::AnimationController::resumeAnimationsForDocument): Add logging.
(WebCore::AnimationController::startAnimationsIfNotSuspended): Calls private method.
* page/animation/AnimationController.h:
(AnimationController): Add isSuspended() and animationsForDocumentMayStart().
* page/animation/AnimationControllerPrivate.h:
(WebCore::AnimationControllerPrivate::isSuspended): New method.
(AnimationControllerPrivate): Add m_isSuspended member.

* page/animation/CompositeAnimation.cpp:
(WebCore::CompositeAnimation::CompositeAnimation): Moved from header - initialise m_isSuspended.
(WebCore::CompositeAnimation::updateTransitions): Do not create ImplicitAnimation if suspended.
(WebCore::CompositeAnimation::updateKeyframeAnimations): Move to AnimationStatePausedNew if suspended.
(WebCore::CompositeAnimation::suspendAnimations): m_suspended -> m_isSuspended
(WebCore::CompositeAnimation::resumeAnimations): Ditto.
* page/animation/CompositeAnimation.h:
(WebCore::CompositeAnimation::isSuspended): Renamed from suspended()

* page/animation/KeyframeAnimation.cpp:
(WebCore::KeyframeAnimation::animate): If we're in the AnimationStatePausedNew state, then
    we need to go to the first frame (to handle fill mode).

* testing/Internals.cpp:
(WebCore::Internals::animationsAreSuspended): New exposed method to reflect AnimationController.
* testing/Internals.h: Add animationsAreSuspended.
* testing/Internals.idl: Ditto.

Source/WebKit:

Export AnimationController::isSuspended

* WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in:

Source/WebKit/mac:

The WebView private API cssAnimationsSuspended did not necessarily
reflect the reality of the Frame's AnimationController value because it
was caching rather than asking directly. While the WebCore part of this
patch ensured loading the Document wouldn't resume all animations, it
is still better to ask directly.

* WebView/WebView.mm:
(-[WebView cssAnimationsSuspended]): Call into AnimationController.
(-[WebView setCSSAnimationsSuspended:]): Ditto.
* WebView/WebViewData.h: Remove cssAnimationsSuspended boolean.
* WebView/WebViewData.mm: Ditto.
(-[WebViewPrivate init]):

Source/WebKit/win:

Export AnimationController::isSuspended

* WebKit.vcproj/WebKitExports.def.in:

LayoutTests:

Two new tests. Add an animation or transition to
the document when the global animation controller is suspended.
In the animation case, nothing should happen until the
animations are resumed. In the transition case, the style
change should happen immediately and not fire any events.

* animations/added-while-suspended-expected.txt: Added.
* animations/added-while-suspended.html: Added.
* animations/suspend-transform-animation.html: Make sure to resume suspended animations
    before quitting the test.
* transitions/started-while-suspended-expected.txt: Added.
* transitions/started-while-suspended.html: Added.
* transitions/suspend-transform-transition.html: Make sure to resume suspended animations
    before quitting the test.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@149576 268f45cc-cd09-0410-ab3c-d52691b4dbfc
30 files changed:
ChangeLog
LayoutTests/ChangeLog
LayoutTests/animations/added-while-suspended-expected.txt [new file with mode: 0644]
LayoutTests/animations/added-while-suspended.html [new file with mode: 0644]
LayoutTests/animations/suspend-transform-animation.html
LayoutTests/transitions/started-while-suspended-expected.txt [new file with mode: 0644]
LayoutTests/transitions/started-while-suspended.html [new file with mode: 0644]
LayoutTests/transitions/suspend-transform-transition.html
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/dom/Document.cpp
Source/WebCore/page/animation/AnimationBase.cpp
Source/WebCore/page/animation/AnimationBase.h
Source/WebCore/page/animation/AnimationController.cpp
Source/WebCore/page/animation/AnimationController.h
Source/WebCore/page/animation/AnimationControllerPrivate.h
Source/WebCore/page/animation/CompositeAnimation.cpp
Source/WebCore/page/animation/CompositeAnimation.h
Source/WebCore/page/animation/KeyframeAnimation.cpp
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl
Source/WebKit/ChangeLog
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebView/WebView.mm
Source/WebKit/mac/WebView/WebViewData.h
Source/WebKit/mac/WebView/WebViewData.mm
Source/WebKit/win/ChangeLog
Source/WebKit/win/WebKit.vcproj/WebKitExports.def.in
Source/autotools/symbols.filter