Changeset 274165 in webkit


Ignore:
Timestamp:
Mar 9, 2021 12:09:49 PM (17 months ago)
Author:
graouts@webkit.org
Message:

[Web Animations] setKeyframes does not preserve animation's current offset
https://bugs.webkit.org/show_bug.cgi?id=222939
<rdar://problem/75207793>

Reviewed by Dean Jackson.

Source/WebCore:

Test: webanimations/set-keyframes-after-animation-completion.html

When setKeyframes() is called on a KeyframeEffect, it clears the existing blending keyframes
created for the style system which will be re-populated on the next style update.

When an animation completes, it becomes eligible for being removed unless its effect is the
top-most effect in the target element's effect stack affecting one of the CSS properties
animated by effects in the stack. To determine what properties an effect animates, the method
KeyframeEffect::animatedProperties() is used.

Until now, KeyframeEffect::animatedProperties() simply returned the properties from the
blending keyframes. As such, if blending keyframes are empty, that method returns an empty
set of properties.

Since blending keyframes are cleared by a call to setKeyframes(), calling this method on
the effect of an animation that just finished will remove that animation and the effect
will no longer be applied when updating styles.

To fix this, we add a new instance variable on KeyframeEffect to store the list of properties
affected by the effect from the keyframes parsed by setKeyframes() until we generate the
blending keyframes during the next style update.

As soon as we generate the blending keyframes and setBlendingKeyframes() is called, we clear
that new property. This guarantees that no matter how keyframes are specified – CSS Transitions,
CSS Animations or Web Animations JS API – the animatedProperties() method returns the set
of affected properties.

  • animation/KeyframeEffect.cpp:

(WebCore::KeyframeEffect::animatedProperties):
(WebCore::KeyframeEffect::setBlendingKeyframes):

  • animation/KeyframeEffect.h:

(WebCore::KeyframeEffect::animatedProperties const): Deleted.

LayoutTests:

Add a new test that checks that updating keyframes after an animation has completed
correctly updates styles accounting for the new keyframes.

  • webanimations/set-keyframes-after-animation-completion-expected.html: Added.
  • webanimations/set-keyframes-after-animation-completion.html: Added.
Location:
trunk
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r274156 r274165  
     12021-03-09  Antoine Quint  <graouts@webkit.org>
     2
     3        [Web Animations] setKeyframes does not preserve animation's current offset
     4        https://bugs.webkit.org/show_bug.cgi?id=222939
     5        <rdar://problem/75207793>
     6
     7        Reviewed by Dean Jackson.
     8
     9        Add a new test that checks that updating keyframes after an animation has completed
     10        correctly updates styles accounting for the new keyframes.
     11
     12        * webanimations/set-keyframes-after-animation-completion-expected.html: Added.
     13        * webanimations/set-keyframes-after-animation-completion.html: Added.
     14
    1152021-03-09  Peng Liu  <peng.liu6@apple.com>
    216
  • trunk/Source/WebCore/ChangeLog

    r274164 r274165  
     12021-03-09  Antoine Quint  <graouts@webkit.org>
     2
     3        [Web Animations] setKeyframes does not preserve animation's current offset
     4        https://bugs.webkit.org/show_bug.cgi?id=222939
     5        <rdar://problem/75207793>
     6
     7        Reviewed by Dean Jackson.
     8
     9        Test: webanimations/set-keyframes-after-animation-completion.html
     10
     11        When setKeyframes() is called on a KeyframeEffect, it clears the existing blending keyframes
     12        created for the style system which will be re-populated on the next style update.
     13
     14        When an animation completes, it becomes eligible for being removed unless its effect is the
     15        top-most effect in the target element's effect stack affecting one of the CSS properties
     16        animated by effects in the stack. To determine what properties an effect animates, the method
     17        KeyframeEffect::animatedProperties() is used.
     18       
     19        Until now, KeyframeEffect::animatedProperties() simply returned the properties from the
     20        blending keyframes. As such, if blending keyframes are empty, that method returns an empty
     21        set of properties.
     22
     23        Since blending keyframes are cleared by a call to setKeyframes(), calling this method on
     24        the effect of an animation that just finished will remove that animation and the effect
     25        will no longer be applied when updating styles.
     26
     27        To fix this, we add a new instance variable on KeyframeEffect to store the list of properties
     28        affected by the effect from the keyframes parsed by setKeyframes() until we generate the
     29        blending keyframes during the next style update.
     30
     31        As soon as we generate the blending keyframes and setBlendingKeyframes() is called, we clear
     32        that new property. This guarantees that no matter how keyframes are specified – CSS Transitions,
     33        CSS Animations or Web Animations JS API – the animatedProperties() method returns the set
     34        of affected properties.
     35
     36        * animation/KeyframeEffect.cpp:
     37        (WebCore::KeyframeEffect::animatedProperties):
     38        (WebCore::KeyframeEffect::setBlendingKeyframes):
     39        * animation/KeyframeEffect.h:
     40        (WebCore::KeyframeEffect::animatedProperties const): Deleted.
     41
    1422021-03-09  Said Abou-Hallawa  <said@apple.com>
    243
  • trunk/Source/WebCore/animation/KeyframeEffect.cpp

    r273752 r274165  
    835835}
    836836
     837const HashSet<CSSPropertyID>& KeyframeEffect::animatedProperties()
     838{
     839    if (!m_blendingKeyframes.isEmpty())
     840        return m_blendingKeyframes.properties();
     841
     842    if (m_animatedProperties.isEmpty()) {
     843        for (auto& keyframe : m_parsedKeyframes) {
     844            for (auto keyframeProperty : keyframe.unparsedStyle.keys())
     845                m_animatedProperties.add(keyframeProperty);
     846        }
     847    }
     848
     849    return m_animatedProperties;
     850}
     851
    837852bool KeyframeEffect::animatesProperty(CSSPropertyID property) const
    838853{
     
    877892{
    878893    m_blendingKeyframes = WTFMove(blendingKeyframes);
     894    m_animatedProperties.clear();
    879895
    880896    computedNeedsForcedLayout();
  • trunk/Source/WebCore/animation/KeyframeEffect.h

    r272904 r274165  
    157157    void computeDeclarativeAnimationBlendingKeyframes(const RenderStyle* oldStyle, const RenderStyle& newStyle, const RenderStyle* parentElementStyle);
    158158    const KeyframeList& blendingKeyframes() const { return m_blendingKeyframes; }
    159     const HashSet<CSSPropertyID>& animatedProperties() const { return m_blendingKeyframes.properties(); }
     159    const HashSet<CSSPropertyID>& animatedProperties();
    160160    bool animatesProperty(CSSPropertyID) const;
    161161
     
    216216
    217217    KeyframeList m_blendingKeyframes { emptyString() };
     218    HashSet<CSSPropertyID> m_animatedProperties;
    218219    Vector<ParsedKeyframe> m_parsedKeyframes;
    219220    Vector<AcceleratedAction> m_pendingAcceleratedActions;
Note: See TracChangeset for help on using the changeset viewer.