Changeset 149576 in webkit


Ignore:
Timestamp:
May 4, 2013 9:43:05 PM (11 years ago)
Author:
dino@apple.com
Message:

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.

Location:
trunk
Files:
4 added
26 edited

Legend:

Unmodified
Added
Removed
  • trunk/ChangeLog

    r149451 r149576  
     12013-04-30  Dean Jackson  <dino@apple.com>
     2
     3        Animations and Transitions should not start when globally suspended
     4        https://bugs.webkit.org/show_bug.cgi?id=114915
     5
     6        Reviewed by Sam Weinig.
     7
     8        Export AnimationController::isSuspended().
     9
     10        * Source/autotools/symbols.filter:
     11
    1122013-05-01  Benjamin Poulain  <benjamin@webkit.org>
    213
  • trunk/LayoutTests/ChangeLog

    r149553 r149576  
     12013-04-30  Dean Jackson  <dino@apple.com>
     2
     3        Animations and Transitions should not start when globally suspended
     4        https://bugs.webkit.org/show_bug.cgi?id=114915
     5
     6        Reviewed by Sam Weinig.
     7
     8        Two new tests. Add an animation or transition to
     9        the document when the global animation controller is suspended.
     10        In the animation case, nothing should happen until the
     11        animations are resumed. In the transition case, the style
     12        change should happen immediately and not fire any events.
     13
     14        * animations/added-while-suspended-expected.txt: Added.
     15        * animations/added-while-suspended.html: Added.
     16        * animations/suspend-transform-animation.html: Make sure to resume suspended animations
     17            before quitting the test.
     18        * transitions/started-while-suspended-expected.txt: Added.
     19        * transitions/started-while-suspended.html: Added.
     20        * transitions/suspend-transform-transition.html: Make sure to resume suspended animations
     21            before quitting the test.
     22
    1232013-04-30  Robert Hogan  <robert@webkit.org>
    224
  • trunk/LayoutTests/animations/suspend-transform-animation.html

    r119985 r149576  
    4343
    4444        window.setTimeout(function() {
    45             if (window.testRunner)
     45            if (window.testRunner) {
     46                internals.resumeAnimations(document);
    4647                testRunner.notifyDone();
     48            }
    4749        }, 250);
    4850    }
  • trunk/LayoutTests/transitions/suspend-transform-transition.html

    r120521 r149576  
    3838
    3939        window.setTimeout(function() {
    40             if (window.testRunner)
     40            if (window.testRunner) {
     41                internals.resumeAnimations(document);
    4142                testRunner.notifyDone();
     43            }
    4244        }, 250);
    4345    }
  • trunk/Source/WebCore/ChangeLog

    r149574 r149576  
     12013-04-30  Dean Jackson  <dino@apple.com>
     2
     3        Animations and Transitions should not start when globally suspended
     4        https://bugs.webkit.org/show_bug.cgi?id=114915
     5
     6        Reviewed by Sam Weinig.
     7
     8        When the Document's AnimationController was suspended, we still
     9        started new transitions and animations. Change this so that
     10        animations enter a paused-but-new state, where they are frozen
     11        until the AnimationController resumes. At that time, it is as
     12        if they had just appeared: any delay counts down before
     13        the animation starts.
     14
     15        For transitions, the change in value must still happen, but
     16        it does so immediately. No transitionend event should be fired.
     17        This produces a slightly confusing behaviour, because any
     18        in-progress transitions are suspended, but any new style changes
     19        happen instantly. This might sound contradictory, but in general
     20        suspending the document is a rare (and dangerous) thing to do.
     21
     22        Previously, the Document would call resumeAnimations as it loaded,
     23        effectively starting all the animations. This meant if you suspended
     24        animations before loading a document, it was ignored as soon as the
     25        load finished. Now there is a separate method startAnimationsIfNotSuspended
     26        which checks to see if the document is suspended as it loads.
     27
     28        In order to handle this case, I added a new state to the Animation
     29        machinery: AnimationStatePausedNew. This is an animation that was created
     30        in the suspended state.
     31
     32        Tests: animations/added-while-suspended.html
     33               transitions/started-while-suspended.html
     34
     35        * WebCore.exp.in: Export AnimationController::isSuspended().
     36
     37        * dom/Document.cpp:
     38        (WebCore::Document::implicitClose):
     39            resumeAnimationsForDocument() -> startAnimationsIfNotSuspended()
     40
     41        * page/animation/AnimationBase.cpp:
     42        (WebCore::nameForState): New name for AnimationStatePausedNew.
     43        (WebCore::AnimationBase::updateStateMachine): Handle new state AnimationStatePausedNew. The
     44            most important change is that when go from PausedNew to Running, we jump back into
     45            the New state and continue from there.
     46        (WebCore::AnimationBase::updatePlayState): suspended -> isSuspended
     47        * page/animation/AnimationBase.h: New state: AnimationStatePausedNew
     48        (WebCore::AnimationBase::waitingToStart): Add AnimationStatePausedNew.
     49        (WebCore::AnimationBase::paused): Add AnimationStatePausedNew.
     50        (WebCore::AnimationBase::isNew): Add AnimationStatePausedNew.
     51
     52        * page/animation/AnimationController.cpp:
     53        (WebCore::AnimationControllerPrivate::AnimationControllerPrivate): Initialise m_suspended.
     54        (WebCore::AnimationControllerPrivate::clear): suspended -> isSuspended
     55        (WebCore::AnimationControllerPrivate::updateAnimations): Ditto.
     56        (WebCore::AnimationControllerPrivate::updateAnimationTimerForRenderer): Ditto.
     57        (WebCore::AnimationControllerPrivate::suspendAnimations): Update m_suspended.
     58        (WebCore::AnimationControllerPrivate::resumeAnimations): Ditto.
     59        (WebCore::AnimationControllerPrivate::suspendAnimationsForDocument):
     60        (WebCore::AnimationControllerPrivate::resumeAnimationsForDocument):
     61        (WebCore::AnimationControllerPrivate::startAnimationsIfNotSuspended): New method that will
     62            only resume animations if we were not globally suspended.
     63        (WebCore::AnimationController::isSuspended): New method.
     64        (WebCore::AnimationController::suspendAnimations): Add logging.
     65        (WebCore::AnimationController::resumeAnimations): Add logging.
     66        (WebCore::AnimationController::suspendAnimationsForDocument): Add logging.
     67        (WebCore::AnimationController::resumeAnimationsForDocument): Add logging.
     68        (WebCore::AnimationController::startAnimationsIfNotSuspended): Calls private method.
     69        * page/animation/AnimationController.h:
     70        (AnimationController): Add isSuspended() and animationsForDocumentMayStart().
     71        * page/animation/AnimationControllerPrivate.h:
     72        (WebCore::AnimationControllerPrivate::isSuspended): New method.
     73        (AnimationControllerPrivate): Add m_isSuspended member.
     74
     75        * page/animation/CompositeAnimation.cpp:
     76        (WebCore::CompositeAnimation::CompositeAnimation): Moved from header - initialise m_isSuspended.
     77        (WebCore::CompositeAnimation::updateTransitions): Do not create ImplicitAnimation if suspended.
     78        (WebCore::CompositeAnimation::updateKeyframeAnimations): Move to AnimationStatePausedNew if suspended.
     79        (WebCore::CompositeAnimation::suspendAnimations): m_suspended -> m_isSuspended
     80        (WebCore::CompositeAnimation::resumeAnimations): Ditto.
     81        * page/animation/CompositeAnimation.h:
     82        (WebCore::CompositeAnimation::isSuspended): Renamed from suspended()
     83
     84        * page/animation/KeyframeAnimation.cpp:
     85        (WebCore::KeyframeAnimation::animate): If we're in the AnimationStatePausedNew state, then
     86            we need to go to the first frame (to handle fill mode).
     87
     88        * testing/Internals.cpp:
     89        (WebCore::Internals::animationsAreSuspended): New exposed method to reflect AnimationController.
     90        * testing/Internals.h: Add animationsAreSuspended.
     91        * testing/Internals.idl: Ditto.
     92
    1932013-05-04  Sam Weinig  <sam@webkit.org>
    294
  • trunk/Source/WebCore/WebCore.exp.in

    r149574 r149576  
    603603__ZN7WebCore18pluginScriptObjectEPN3JSC9ExecStateEPNS_13JSHTMLElementE
    604604__ZN7WebCore18proxyServersForURLERKNS_4KURLEPKNS_17NetworkingContextE
     605__ZNK7WebCore19AnimationController11isSuspendedEv
    605606__ZN7WebCore19AnimationController16resumeAnimationsEv
    606607__ZN7WebCore19AnimationController17suspendAnimationsEv
  • trunk/Source/WebCore/dom/Document.cpp

    r149549 r149576  
    23972397    if (f) {
    23982398        f->loader()->icon()->startLoader();
    2399         f->animation()->resumeAnimationsForDocument(this);
     2399        f->animation()->startAnimationsIfNotSuspended(this);
    24002400    }
    24012401
  • trunk/Source/WebCore/page/animation/AnimationBase.cpp

    r148145 r149576  
    123123    case AnimationBase::AnimationStateLooping: return "Looping";
    124124    case AnimationBase::AnimationStateEnding: return "Ending";
     125    case AnimationBase::AnimationStatePausedNew: return "PausedNew";
    125126    case AnimationBase::AnimationStatePausedWaitTimer: return "PausedWaitTimer";
    126127    case AnimationBase::AnimationStatePausedWaitStyleAvailable: return "PausedWaitStyleAvailable";
     
    204205                LOG(Animations, "%p AnimationState %s -> StartWaitTimer", this, nameForState(m_animState));
    205206                m_animState = AnimationStateStartWaitTimer;
     207            } else {
     208                // We are pausing before we even started.
     209                LOG(Animations, "%p AnimationState %s -> AnimationStatePausedNew", this, nameForState(m_animState));
     210                m_animState = AnimationStatePausedNew;
    206211            }
    207212            break;
     
    356361            updateStateMachine(AnimationStateInputStartAnimation, 0);
    357362            break;
     363        case AnimationStatePausedNew:
    358364        case AnimationStatePausedWaitResponse:
    359365        case AnimationStatePausedWaitStyleAvailable:
     
    363369            // When the AnimationStateInputStartTimeSet comes in and we were in AnimationStatePausedRun, we will notice
    364370            // that we have already set the startTime and will ignore it.
    365             ASSERT(input == AnimationStateInputPlayStateRunning || input == AnimationStateInputStartTimeSet || input == AnimationStateInputStyleAvailable);
     371            ASSERT(input == AnimationStateInputPlayStateRunning || input == AnimationStateInputStartTimeSet || input == AnimationStateInputStyleAvailable || input == AnimationStateInputStartAnimation);
    366372            ASSERT(paused());
    367            
     373
    368374            if (input == AnimationStateInputPlayStateRunning) {
     375                if (m_animState == AnimationStatePausedNew) {
     376                    // We were paused before we even started, and now we're supposed
     377                    // to start, so jump back to the New state and reset.
     378                    LOG(Animations, "%p AnimationState %s -> AnimationStateNew", this, nameForState(m_animState));
     379                    m_animState = AnimationStateNew;
     380                    updateStateMachine(input, param);
     381                    break;
     382                }
     383
    369384                // Update the times
    370385                if (m_animState == AnimationStatePausedRun)
     
    411426                break;
    412427            }
    413            
     428
    414429            ASSERT(m_animState == AnimationStatePausedWaitStyleAvailable);
    415430            // We are paused but we got the callback that notifies us that style has been updated.
     
    492507    // The state machine can be in one of two states: running, paused.
    493508    // Set the state machine to the desired state.
    494     bool pause = playState == AnimPlayStatePaused || m_compAnim->suspended();
    495    
     509    bool pause = playState == AnimPlayStatePaused || m_compAnim->isSuspended();
     510
    496511    if (pause == paused() && !isNew())
    497512        return;
    498    
     513
    499514    updateStateMachine(pause ?  AnimationStateInputPlayStatePaused : AnimationStateInputPlayStateRunning, -1);
    500515}
  • trunk/Source/WebCore/page/animation/AnimationBase.h

    r141314 r149576  
    7979        AnimationStateLooping,              // response received, animation running, loop timer running, waiting for fire
    8080        AnimationStateEnding,               // received, animation running, end timer running, waiting for fire
     81        AnimationStatePausedNew,            // in pause mode when animation was created
    8182        AnimationStatePausedWaitTimer,      // in pause mode when animation started
    8283        AnimationStatePausedWaitStyleAvailable, // in pause mode when waiting for style setup
     
    116117    bool playStatePlaying() const;
    117118
    118     bool waitingToStart() const { return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer; }
     119    bool waitingToStart() const { return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer || m_animState == AnimationStatePausedNew; }
    119120    bool preActive() const
    120121    {
     
    125126    bool active() const { return !postActive() && !preActive(); }
    126127    bool running() const { return !isNew() && !postActive(); }
    127     bool paused() const { return m_pauseTime >= 0; }
    128     bool isNew() const { return m_animState == AnimationStateNew; }
     128    bool paused() const { return m_pauseTime >= 0 || m_animState == AnimationStatePausedNew; }
     129    bool isNew() const { return m_animState == AnimationStateNew || m_animState == AnimationStatePausedNew; }
    129130    bool waitingForStartTime() const { return m_animState == AnimationStateStartWaitResponse; }
    130131    bool waitingForStyleAvailable() const { return m_animState == AnimationStateStartWaitStyleAvailable; }
  • trunk/Source/WebCore/page/animation/AnimationController.cpp

    r148155 r149576  
    6060    , m_animationsWaitingForStartTimeResponse()
    6161    , m_waitingForAsyncStartNotification(false)
     62    , m_isSuspended(false)
    6263{
    6364}
     
    8586        return false;
    8687    animation->clearRenderer();
    87     return animation->suspended();
     88    return animation->isSuspended();
    8889}
    8990
     
    9697    for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) {
    9798        CompositeAnimation* compAnim = it->value.get();
    98         if (!compAnim->suspended() && compAnim->hasAnimations()) {
     99        if (!compAnim->isSuspended() && compAnim->hasAnimations()) {
    99100            double t = compAnim->timeToNextService();
    100101            if (t != -1 && (t < timeToNextService || timeToNextService == -1))
     
    124125
    125126    RefPtr<CompositeAnimation> compAnim = m_compositeAnimations.get(renderer);
    126     if (!compAnim->suspended() && compAnim->hasAnimations())
     127    if (!compAnim->isSuspended() && compAnim->hasAnimations())
    127128        timeToNextService = compAnim->timeToNextService();
    128129
     
    265266void AnimationControllerPrivate::suspendAnimations()
    266267{
     268    if (isSuspended())
     269        return;
     270
    267271    suspendAnimationsForDocument(m_frame->document());
    268    
     272
    269273    // Traverse subframes
    270274    for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling())
    271275        child->animation()->suspendAnimations();
     276
     277    m_isSuspended = true;
    272278}
    273279
    274280void AnimationControllerPrivate::resumeAnimations()
    275281{
     282    if (!isSuspended())
     283        return;
     284
    276285    resumeAnimationsForDocument(m_frame->document());
    277    
     286
    278287    // Traverse subframes
    279288    for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling())
    280289        child->animation()->resumeAnimations();
     290
     291    m_isSuspended = false;
    281292}
    282293
    283294void AnimationControllerPrivate::suspendAnimationsForDocument(Document* document)
    284295{
     296    if (isSuspended())
     297        return;
     298
    285299    setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet);
    286    
     300
    287301    RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end();
    288302    for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) {
     
    293307        }
    294308    }
    295    
     309
    296310    updateAnimationTimer();
    297311}
     
    299313void AnimationControllerPrivate::resumeAnimationsForDocument(Document* document)
    300314{
     315    if (!isSuspended())
     316        return;
     317
    301318    setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet);
    302    
     319
    303320    RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end();
    304321    for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) {
     
    309326        }
    310327    }
    311    
     328
    312329    updateAnimationTimer();
     330}
     331
     332void AnimationControllerPrivate::startAnimationsIfNotSuspended(Document* document)
     333{
     334    if (!isSuspended())
     335        resumeAnimationsForDocument(document);
    313336}
    314337
     
    579602}
    580603
     604bool AnimationController::isSuspended() const
     605{
     606    return m_data->isSuspended();
     607}
     608
    581609void AnimationController::suspendAnimations()
    582610{
     611    LOG(Animations, "controller is suspending animations");
    583612    m_data->suspendAnimations();
    584613}
     
    586615void AnimationController::resumeAnimations()
    587616{
     617    LOG(Animations, "controller is resuming animations");
    588618    m_data->resumeAnimations();
    589619}
     
    598628void AnimationController::suspendAnimationsForDocument(Document* document)
    599629{
     630    LOG(Animations, "suspending animations for document %p", document);
    600631    m_data->suspendAnimationsForDocument(document);
    601632}
     
    603634void AnimationController::resumeAnimationsForDocument(Document* document)
    604635{
     636    LOG(Animations, "resuming animations for document %p", document);
    605637    m_data->resumeAnimationsForDocument(document);
     638}
     639
     640void AnimationController::startAnimationsIfNotSuspended(Document* document)
     641{
     642    LOG(Animations, "animations may start for document %p", document);
     643    m_data->startAnimationsIfNotSuspended(document);
    606644}
    607645
  • trunk/Source/WebCore/page/animation/AnimationController.h

    r141656 r149576  
    6464    bool isRunningAcceleratedAnimationOnRenderer(RenderObject*, CSSPropertyID, bool isRunningNow = true) const;
    6565
     66    bool isSuspended() const;
    6667    void suspendAnimations();
    6768    void resumeAnimations();
     
    7273    void suspendAnimationsForDocument(Document*);
    7374    void resumeAnimationsForDocument(Document*);
     75    void startAnimationsIfNotSuspended(Document*);
    7476
    7577    void beginAnimationUpdate();
  • trunk/Source/WebCore/page/animation/AnimationControllerPrivate.h

    r144935 r149576  
    7676    bool hasAnimations() const { return !m_compositeAnimations.isEmpty(); }
    7777
     78    bool isSuspended() const { return m_isSuspended; }
    7879    void suspendAnimations();
    7980    void resumeAnimations();
     
    8485    void suspendAnimationsForDocument(Document*);
    8586    void resumeAnimationsForDocument(Document*);
     87    void startAnimationsIfNotSuspended(Document*);
    8688
    8789    bool isRunningAnimationOnRenderer(RenderObject*, CSSPropertyID, bool isRunningNow) const;
     
    140142    WaitingAnimationsSet m_animationsWaitingForStartTimeResponse;
    141143    bool m_waitingForAsyncStartNotification;
     144    bool m_isSuspended;
    142145};
    143146
  • trunk/Source/WebCore/page/animation/CompositeAnimation.cpp

    r148925 r149576  
    4242namespace WebCore {
    4343
     44CompositeAnimation::CompositeAnimation(AnimationControllerPrivate* animationController)
     45    : m_animationController(animationController)
     46{
     47    m_suspended = animationController->isSuspended();
     48}
     49
    4450CompositeAnimation::~CompositeAnimation()
    4551{
     
    9399        for (size_t i = 0; i < targetStyle->transitions()->size(); ++i) {
    94100            const Animation* anim = targetStyle->transitions()->animation(i);
    95             bool isActiveTransition = anim->duration() || anim->delay() > 0;
     101            bool isActiveTransition = !m_suspended && (anim->duration() || anim->delay() > 0);
    96102
    97103            Animation::AnimationMode mode = anim->animationMode();
     
    253259                } else if ((anim->duration() || anim->delay()) && anim->iterationCount() && animationName != none) {
    254260                    keyframeAnim = KeyframeAnimation::create(const_cast<Animation*>(anim), renderer, i, this, targetStyle);
    255                     LOG(Animations, "Creating KeyframeAnimation %p with keyframes %s duration %.2f delay %.2f, iterations %.2f", keyframeAnim.get(), anim->name().utf8().data(), anim->duration(), anim->delay(), anim->iterationCount());
     261                    LOG(Animations, "Creating KeyframeAnimation %p with keyframes %s, duration %.2f, delay %.2f, iterations %.2f", keyframeAnim.get(), anim->name().utf8().data(), anim->duration(), anim->delay(), anim->iterationCount());
     262                    if (m_suspended) {
     263                        keyframeAnim->updatePlayState(AnimPlayStatePaused);
     264                        LOG(Animations, "  (created in suspended/paused state)");
     265                    }
    256266#if !LOG_DISABLED
    257267                    HashSet<CSSPropertyID>::const_iterator endProperties = keyframeAnim->keyframes().endProperties();
  • trunk/Source/WebCore/page/animation/CompositeAnimation.h

    r141314 r149576  
    6565    void suspendAnimations();
    6666    void resumeAnimations();
    67     bool suspended() const { return m_suspended; }
     67    bool isSuspended() const { return m_suspended; }
    6868   
    6969    bool hasAnimations() const  { return !m_transitions.isEmpty() || !m_keyframeAnimations.isEmpty(); }
     
    8181
    8282private:
    83     CompositeAnimation(AnimationControllerPrivate* animationController)
    84         : m_animationController(animationController)
    85         , m_suspended(false)
    86     {
    87     }
     83    CompositeAnimation(AnimationControllerPrivate*);
    8884
    8985    void updateTransitions(RenderObject*, RenderStyle* currentStyle, RenderStyle* targetStyle);
  • trunk/Source/WebCore/page/animation/KeyframeAnimation.cpp

    r149392 r149576  
    141141}
    142142
    143 void KeyframeAnimation::animate(CompositeAnimation*, RenderObject*, const RenderStyle*, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle)
     143void KeyframeAnimation::animate(CompositeAnimation* compositeAnimation, RenderObject*, const RenderStyle*, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle)
    144144{
    145145    // Fire the start timeout if needed
     
    147147   
    148148    // If we have not yet started, we will not have a valid start time, so just start the animation if needed.
    149     if (isNew() && m_animation->playState() == AnimPlayStatePlaying)
     149    if (isNew() && m_animation->playState() == AnimPlayStatePlaying && !compositeAnimation->isSuspended())
    150150        updateStateMachine(AnimationStateInputStartAnimation, -1);
    151151
  • trunk/Source/WebCore/testing/Internals.cpp

    r149549 r149576  
    468468}
    469469
     470bool Internals::animationsAreSuspended(Document* document, ExceptionCode& ec) const
     471{
     472    if (!document || !document->frame()) {
     473        ec = INVALID_ACCESS_ERR;
     474        return false;
     475    }
     476
     477    AnimationController* controller = document->frame()->animation();
     478    if (!controller)
     479        return false;
     480
     481    return controller->isSuspended();
     482}
     483
    470484void Internals::suspendAnimations(Document* document, ExceptionCode& ec) const
    471485{
  • trunk/Source/WebCore/testing/Internals.h

    r149549 r149576  
    100100    // CSS Animation testing.
    101101    unsigned numberOfActiveAnimations() const;
     102    bool animationsAreSuspended(Document*, ExceptionCode&) const;
    102103    void suspendAnimations(Document*, ExceptionCode&) const;
    103104    void resumeAnimations(Document*, ExceptionCode&) const;
  • trunk/Source/WebCore/testing/Internals.idl

    r149549 r149576  
    6666    void suspendAnimations(Document document) raises (DOMException);
    6767    void resumeAnimations(Document document) raises (DOMException);
     68    boolean animationsAreSuspended(in Document document) raises (DOMException);
    6869    boolean pauseAnimationAtTimeOnElement(DOMString animationName, double pauseTime, Element element) raises (DOMException);
    6970    boolean pauseAnimationAtTimeOnPseudoElement(DOMString animationName, double pauseTime, Element element, DOMString pseudoId) raises (DOMException);
  • trunk/Source/WebKit/ChangeLog

    r149574 r149576  
     12013-05-04  Dean Jackson  <dino@apple.com>
     2
     3        Animations and Transitions should not start when globally suspended
     4        https://bugs.webkit.org/show_bug.cgi?id=114915
     5
     6        Reviewed by Sam Weinig.
     7
     8        Export AnimationController::isSuspended
     9
     10        * WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in:
     11
    1122013-05-04  Sam Weinig  <sam@webkit.org>
    213
  • trunk/Source/WebKit/mac/ChangeLog

    r149574 r149576  
     12013-05-04  Dean Jackson  <dino@apple.com>
     2
     3        Animations and Transitions should not start when globally suspended
     4        https://bugs.webkit.org/show_bug.cgi?id=114915
     5
     6        Reviewed by Sam Weinig.
     7
     8        The WebView private API cssAnimationsSuspended did not necessarily
     9        reflect the reality of the Frame's AnimationController value because it
     10        was caching rather than asking directly. While the WebCore part of this
     11        patch ensured loading the Document wouldn't resume all animations, it
     12        is still better to ask directly.
     13
     14        * WebView/WebView.mm:
     15        (-[WebView cssAnimationsSuspended]): Call into AnimationController.
     16        (-[WebView setCSSAnimationsSuspended:]): Ditto.
     17        * WebView/WebViewData.h: Remove cssAnimationsSuspended boolean.
     18        * WebView/WebViewData.mm: Ditto.
     19        (-[WebViewPrivate init]):
     20
    1212013-05-04  Sam Weinig  <sam@webkit.org>
    222
  • trunk/Source/WebKit/mac/WebView/WebView.mm

    r149476 r149576  
    27702770- (BOOL)cssAnimationsSuspended
    27712771{
    2772     return _private->cssAnimationsSuspended;
     2772    // should ask the page!
     2773    Frame* frame = core([self mainFrame]);
     2774    if (frame)
     2775        return frame->animation()->isSuspended();
     2776
     2777    return false;
    27732778}
    27742779
    27752780- (void)setCSSAnimationsSuspended:(BOOL)suspended
    27762781{
    2777     if (suspended == _private->cssAnimationsSuspended)
     2782    Frame* frame = core([self mainFrame]);
     2783    if (suspended == frame->animation()->isSuspended())
    27782784        return;
    27792785       
    2780     _private->cssAnimationsSuspended = suspended;
    2781    
    2782     Frame* frame = core([self mainFrame]);
    27832786    if (suspended)
    27842787        frame->animation()->suspendAnimations();
  • trunk/Source/WebKit/mac/WebView/WebViewData.h

    r145849 r149576  
    138138    BOOL becomingFirstResponderFromOutside;
    139139    BOOL usesPageCache;
    140     BOOL cssAnimationsSuspended;
    141140
    142141    NSColor *backgroundColor;
  • trunk/Source/WebKit/mac/WebView/WebViewData.mm

    r145849 r149576  
    8181    usesPageCache = YES;
    8282    shouldUpdateWhileOffscreen = YES;
    83     cssAnimationsSuspended = NO;
    8483
    8584    zoomMultiplier = 1;
  • trunk/Source/WebKit/win/ChangeLog

    r149432 r149576  
     12013-05-04  Dean Jackson  <dino@apple.com>
     2
     3        Animations and Transitions should not start when globally suspended
     4        https://bugs.webkit.org/show_bug.cgi?id=114915
     5
     6        Reviewed by Sam Weinig.
     7
     8        Export AnimationController::isSuspended
     9
     10        * WebKit.vcproj/WebKitExports.def.in:
     11
    1122013-05-01  Sergio Villar Senin  <svillar@igalia.com>
    213
  • trunk/Source/WebKit/win/WebKit.vcproj/WebKitExports.def.in

    r149432 r149576  
    334334        ?isPageBoxVisible@Document@WebCore@@QAE_NH@Z
    335335        ?isActive@InsertionPoint@WebCore@@QBE_NXZ
     336        ?isSuspended@AnimationController@WebCore@@QBE_NXZ
    336337        ?suspendAnimations@AnimationController@WebCore@@QAEXXZ
    337338        ?resumeAnimations@AnimationController@WebCore@@QAEXXZ
  • trunk/Source/autotools/symbols.filter

    r149432 r149576  
    185185_ZN7WebCore8Document16isPageBoxVisibleEi;
    186186_ZN7WebCore18ContentDistributor22ensureSelectFeatureSetEPNS_13ElementShadowE;
     187_ZNK7WebCore19AnimationController11isSuspendedEv;
    187188_ZN7WebCore19AnimationController17suspendAnimationsEv;
    188189_ZN7WebCore19AnimationController16resumeAnimationsEv;
Note: See TracChangeset for help on using the changeset viewer.