Changeset 217997 in webkit


Ignore:
Timestamp:
Jun 9, 2017 10:52:42 AM (7 years ago)
Author:
Chris Dumez
Message:

CSS transitions added while page is not visible do not start when the page becomes visible
https://bugs.webkit.org/show_bug.cgi?id=173166
<rdar://problem/32250351>

Reviewed by Darin Adler.

Source/WebCore:

CSS transitions added while page is not visible would not start when the page becomes
visible. The issue was that when CompositeAnimation::updateTransitions() was called
while the page is hidden (and animations are therefore suspended), it would not
populate m_transations with ImplicitAnimation objects. We would therefore have later
no transitions to resume when the page becomes visible later on. This patch updates
CompositeAnimation::updateTransitions() to properly populate m_transitions and instead
pause the ImplicitAnimation it creates if animations are currently suspended. This
behavior is more consistent with the one of CompositeAnimation::updateKeyframeAnimations().

I also needed to update ImplicitAnimation::animate() to not restart a paused animation
if the animation is currently paused. This is similar to what is done in
KeyframeAnimation::animate(). Without this, the paused ImplicitAnimation we add to
m_transition would incorrectly get unpaused while the page is still hidden and the
animations are still supposed to be suspended. This issue was showing when running the
test I am adding in this patch.

Test: fast/animation/css-animation-resuming-when-visible.html

  • page/animation/CompositeAnimation.cpp:

(WebCore::CompositeAnimation::updateTransitions):

  • page/animation/ImplicitAnimation.cpp:

(WebCore::ImplicitAnimation::animate):
(WebCore::ImplicitAnimation::reset):

  • page/animation/ImplicitAnimation.h:

LayoutTests:

Add layout test coverage.

  • fast/animation/css-animation-resuming-when-visible-expected.txt: Added.
  • fast/animation/css-animation-resuming-when-visible.html: Added.
Location:
trunk
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r217985 r217997  
     12017-06-09  Chris Dumez  <cdumez@apple.com>
     2
     3        CSS transitions added while page is not visible do not start when the page becomes visible
     4        https://bugs.webkit.org/show_bug.cgi?id=173166
     5        <rdar://problem/32250351>
     6
     7        Reviewed by Darin Adler.
     8
     9        Add layout test coverage.
     10
     11        * fast/animation/css-animation-resuming-when-visible-expected.txt: Added.
     12        * fast/animation/css-animation-resuming-when-visible.html: Added.
     13
    1142017-06-09  Eric Carlson  <eric.carlson@apple.com>
    215
  • trunk/Source/WebCore/ChangeLog

    r217994 r217997  
     12017-06-09  Chris Dumez  <cdumez@apple.com>
     2
     3        CSS transitions added while page is not visible do not start when the page becomes visible
     4        https://bugs.webkit.org/show_bug.cgi?id=173166
     5        <rdar://problem/32250351>
     6
     7        Reviewed by Darin Adler.
     8
     9        CSS transitions added while page is not visible would not start when the page becomes
     10        visible. The issue was that when CompositeAnimation::updateTransitions() was called
     11        while the page is hidden (and animations are therefore suspended), it would not
     12        populate m_transations with ImplicitAnimation objects. We would therefore have later
     13        no transitions to resume when the page becomes visible later on. This patch updates
     14        CompositeAnimation::updateTransitions() to properly populate m_transitions and instead
     15        pause the ImplicitAnimation it creates if animations are currently suspended. This
     16        behavior is more consistent with the one of CompositeAnimation::updateKeyframeAnimations().
     17
     18        I also needed to update ImplicitAnimation::animate() to not restart a paused animation
     19        if the animation is currently paused. This is similar to what is done in
     20        KeyframeAnimation::animate(). Without this, the paused ImplicitAnimation we add to
     21        m_transition would incorrectly get unpaused while the page is still hidden and the
     22        animations are still supposed to be suspended. This issue was showing when running the
     23        test I am adding in this patch.
     24
     25        Test: fast/animation/css-animation-resuming-when-visible.html
     26
     27        * page/animation/CompositeAnimation.cpp:
     28        (WebCore::CompositeAnimation::updateTransitions):
     29        * page/animation/ImplicitAnimation.cpp:
     30        (WebCore::ImplicitAnimation::animate):
     31        (WebCore::ImplicitAnimation::reset):
     32        * page/animation/ImplicitAnimation.h:
     33
    1342017-06-09  Yusuke Suzuki  <utatane.tea@gmail.com>
    235
  • trunk/Source/WebCore/page/animation/AnimationBase.h

    r215352 r217997  
    135135
    136136    // Returns true if the animation state changed.
    137     virtual bool animate(CompositeAnimation*, RenderElement*, const RenderStyle* /*currentStyle*/, const RenderStyle* /*targetStyle*/, std::unique_ptr<RenderStyle>& /*animatedStyle*/, bool& didBlendStyle) = 0;
     137    virtual bool animate(CompositeAnimation&, RenderElement*, const RenderStyle* /*currentStyle*/, const RenderStyle& /*targetStyle*/, std::unique_ptr<RenderStyle>& /*animatedStyle*/, bool& didBlendStyle) = 0;
    138138    virtual void getAnimatedStyle(std::unique_ptr<RenderStyle>& /*animatedStyle*/) = 0;
    139139
  • trunk/Source/WebCore/page/animation/CompositeAnimation.cpp

    r217075 r217997  
    9595        for (size_t i = 0; i < targetStyle->transitions()->size(); ++i) {
    9696            auto& animation = targetStyle->transitions()->animation(i);
    97             bool isActiveTransition = !m_suspended && (animation.duration() || animation.delay() > 0);
     97            bool isActiveTransition = animation.duration() || animation.delay() > 0;
    9898
    9999            Animation::AnimationMode mode = animation.animationMode();
     
    170170                    // Add the new transition
    171171                    auto implicitAnimation = ImplicitAnimation::create(animation, prop, renderer, this, modifiedCurrentStyle ? modifiedCurrentStyle.get() : fromStyle);
     172                    if (m_suspended && implicitAnimation->hasStyle())
     173                        implicitAnimation->updatePlayState(AnimPlayStatePaused);
     174
    172175                    LOG(Animations, "Created ImplicitAnimation %p on renderer %p for property %s duration %.2f delay %.2f", implicitAnimation.ptr(), renderer, getPropertyName(prop), animation.duration(), animation.delay());
    173176                    m_transitions.set(prop, WTFMove(implicitAnimation));
     
    301304        for (auto& transition : m_transitions.values()) {
    302305            bool didBlendStyle = false;
    303             if (transition->animate(this, &renderer, currentStyle, &targetStyle, blendedStyle, didBlendStyle))
     306            if (transition->animate(*this, &renderer, currentStyle, targetStyle, blendedStyle, didBlendStyle))
    304307                animationStateChanged = true;
    305308
     
    331334        if (keyframeAnim) {
    332335            bool didBlendStyle = false;
    333             if (keyframeAnim->animate(this, &renderer, currentStyle, &targetStyle, blendedStyle, didBlendStyle))
     336            if (keyframeAnim->animate(*this, &renderer, currentStyle, targetStyle, blendedStyle, didBlendStyle))
    334337                animationStateChanged = true;
    335338
  • trunk/Source/WebCore/page/animation/ImplicitAnimation.cpp

    r215143 r217997  
    6262}
    6363
    64 bool ImplicitAnimation::animate(CompositeAnimation*, RenderElement*, const RenderStyle*, const RenderStyle* targetStyle, std::unique_ptr<RenderStyle>& animatedStyle, bool& didBlendStyle)
     64bool ImplicitAnimation::animate(CompositeAnimation& compositeAnimation, RenderElement*, const RenderStyle*, const RenderStyle& targetStyle, std::unique_ptr<RenderStyle>& animatedStyle, bool& didBlendStyle)
    6565{
    6666    // If we get this far and the animation is done, it means we are cleaning up a just finished animation.
     
    7373    // Reset to start the transition if we are new
    7474    if (isNew())
    75         reset(targetStyle);
     75        reset(targetStyle, compositeAnimation);
    7676
    7777    // Run a cycle of animation.
    7878    // We know we will need a new render style, so make one if needed
    7979    if (!animatedStyle)
    80         animatedStyle = RenderStyle::clonePtr(*targetStyle);
     80        animatedStyle = RenderStyle::clonePtr(targetStyle);
    8181
    8282    CSSPropertyAnimation::blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress());
     
    200200}
    201201
    202 void ImplicitAnimation::reset(const RenderStyle* to)
    203 {
    204     ASSERT(to);
     202void ImplicitAnimation::reset(const RenderStyle& to, CompositeAnimation& compositeAnimation)
     203{
    205204    ASSERT(m_fromStyle);
    206205
    207     m_toStyle = RenderStyle::clonePtr(*to);
     206    m_toStyle = RenderStyle::clonePtr(to);
    208207
    209208    if (m_object && m_object->element())
     
    212211    // Restart the transition
    213212    if (m_fromStyle && m_toStyle)
    214         updateStateMachine(AnimationStateInput::RestartAnimation, -1);
     213        updateStateMachine(compositeAnimation.isSuspended() ? AnimationStateInput::PlayStatePaused : AnimationStateInput::RestartAnimation, -1);
    215214       
    216215    // set the transform animation list
  • trunk/Source/WebCore/page/animation/ImplicitAnimation.h

    r215143 r217997  
    5454    void endAnimation() override;
    5555
    56     bool animate(CompositeAnimation*, RenderElement*, const RenderStyle* currentStyle, const RenderStyle* targetStyle, std::unique_ptr<RenderStyle>& animatedStyle, bool& didBlendStyle) override;
     56    bool animate(CompositeAnimation&, RenderElement*, const RenderStyle* currentStyle, const RenderStyle& targetStyle, std::unique_ptr<RenderStyle>& animatedStyle, bool& didBlendStyle) override;
    5757    void getAnimatedStyle(std::unique_ptr<RenderStyle>& animatedStyle) override;
    58     void reset(const RenderStyle* to);
     58    void reset(const RenderStyle& to, CompositeAnimation&);
    5959
    6060    bool computeExtentOfTransformAnimation(LayoutRect&) const override;
  • trunk/Source/WebCore/page/animation/KeyframeAnimation.cpp

    r217075 r217997  
    155155}
    156156
    157 bool KeyframeAnimation::animate(CompositeAnimation* compositeAnimation, RenderElement*, const RenderStyle*, const RenderStyle* targetStyle, std::unique_ptr<RenderStyle>& animatedStyle, bool& didBlendStyle)
     157bool KeyframeAnimation::animate(CompositeAnimation& compositeAnimation, RenderElement*, const RenderStyle*, const RenderStyle& targetStyle, std::unique_ptr<RenderStyle>& animatedStyle, bool& didBlendStyle)
    158158{
    159159    // Fire the start timeout if needed
     
    162162    // If we have not yet started, we will not have a valid start time, so just start the animation if needed.
    163163    if (isNew()) {
    164         if (m_animation->playState() == AnimPlayStatePlaying && !compositeAnimation->isSuspended())
     164        if (m_animation->playState() == AnimPlayStatePlaying && !compositeAnimation.isSuspended())
    165165            updateStateMachine(AnimationStateInput::StartAnimation, -1);
    166166        else if (m_animation->playState() == AnimPlayStatePaused)
     
    172172    if (postActive()) {
    173173        if (!animatedStyle)
    174             animatedStyle = RenderStyle::clonePtr(*targetStyle);
     174            animatedStyle = RenderStyle::clonePtr(targetStyle);
    175175        return false;
    176176    }
     
    196196    // We know we will need a new render style, so make one if needed.
    197197    if (!animatedStyle)
    198         animatedStyle = RenderStyle::clonePtr(*targetStyle);
     198        animatedStyle = RenderStyle::clonePtr(targetStyle);
    199199
    200200    // FIXME: we need to be more efficient about determining which keyframes we are animating between.
  • trunk/Source/WebCore/page/animation/KeyframeAnimation.h

    r217075 r217997  
    4545    }
    4646
    47     bool animate(CompositeAnimation*, RenderElement*, const RenderStyle* currentStyle, const RenderStyle* targetStyle, std::unique_ptr<RenderStyle>& animatedStyle, bool& didBlendStyle) override;
     47    bool animate(CompositeAnimation&, RenderElement*, const RenderStyle* currentStyle, const RenderStyle& targetStyle, std::unique_ptr<RenderStyle>& animatedStyle, bool& didBlendStyle) override;
    4848    void getAnimatedStyle(std::unique_ptr<RenderStyle>&) override;
    4949
Note: See TracChangeset for help on using the changeset viewer.