Changeset 252879 in webkit


Ignore:
Timestamp:
Nov 26, 2019 2:11:55 AM (4 years ago)
Author:
graouts@webkit.org
Message:

[Web Animations] Layout of children of element with forwards-filling opacity animation may be incorrect after removal
https://bugs.webkit.org/show_bug.cgi?id=204602
<rdar://problem/45311541>

Reviewed by Antti Koivisto.

Source/WebCore:

Test: webanimations/child-layer-position-after-removal-of-animation-triggering-stacking-context-with-fill-forwards.html

In the case where we animate a property that affects whether an element establishes a stacking context, for instance opacity, the animation code,
specifically KeyframeEffect::apply(), forces a stacking context by setting setUsedZIndex(0) on the animated RenderStyle in case the element otherwise
has an "auto" z-index. This is required by the Web Animations specification (https://w3c.github.io/web-animations/#side-effects-section).

This means that a fill-forwards animation will still force the element to establish a stacking context after the animation is no longer "active". When
we remove such an animation, it may go from having a z-index to not having one, unless it had an explicit z-index provided through style. When this change
happens, RenderStyle::diff() will merely return "RepaintLayer" and thus will not foce a layout. However, updating the positions of child layers may be
necessary as the animation being removed may mean that there may not be a RenderLayer associated with that element's renderer anymore, and if that RenderLayer
had a position, then the position of child layers will no longer be correct.

Now, in the case where we destroy a layer in RenderLayerModelObject::styleDidChange(), we check whether the layer had a position before it is removed, and
update the position of child layers if it did.

  • rendering/RenderLayerModelObject.cpp:

(WebCore::RenderLayerModelObject::styleDidChange):

LayoutTests:

Add a new ref test that checks that removing a forwards-filling animation that triggers a stacking context (for instance, animating opacity)
after it has completed from an element affecting layout yields the correct layout.

  • webanimations/child-layer-position-after-removal-of-animation-triggering-stacking-context-with-fill-forwards-expected.html: Added.
  • webanimations/child-layer-position-after-removal-of-animation-triggering-stacking-context-with-fill-forwards.html: Added.
Location:
trunk
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r252873 r252879  
     12019-11-26  Antoine Quint  <graouts@apple.com>
     2
     3        [Web Animations] Layout of children of element with forwards-filling opacity animation may be incorrect after removal
     4        https://bugs.webkit.org/show_bug.cgi?id=204602
     5        <rdar://problem/45311541>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        Add a new ref test that checks that removing a forwards-filling animation that triggers a stacking context (for instance, animating opacity)
     10        after it has completed from an element affecting layout yields the correct layout.
     11
     12        * webanimations/child-layer-position-after-removal-of-animation-triggering-stacking-context-with-fill-forwards-expected.html: Added.
     13        * webanimations/child-layer-position-after-removal-of-animation-triggering-stacking-context-with-fill-forwards.html: Added.
     14
    1152019-11-25  Fujii Hironori  <Hironori.Fujii@sony.com>
    216
  • trunk/Source/WebCore/ChangeLog

    r252878 r252879  
     12019-11-26  Antoine Quint  <graouts@apple.com>
     2
     3        [Web Animations] Layout of children of element with forwards-filling opacity animation may be incorrect after removal
     4        https://bugs.webkit.org/show_bug.cgi?id=204602
     5        <rdar://problem/45311541>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        Test: webanimations/child-layer-position-after-removal-of-animation-triggering-stacking-context-with-fill-forwards.html
     10
     11        In the case where we animate a property that affects whether an element establishes a stacking context, for instance `opacity`, the animation code,
     12        specifically KeyframeEffect::apply(), forces a stacking context by setting setUsedZIndex(0) on the animated RenderStyle in case the element otherwise
     13        has an "auto" z-index. This is required by the Web Animations specification (https://w3c.github.io/web-animations/#side-effects-section).
     14
     15        This means that a fill-forwards animation will still force the element to establish a stacking context after the animation is no longer "active". When
     16        we remove such an animation, it may go from having a z-index to not having one, unless it had an explicit z-index provided through style. When this change
     17        happens, RenderStyle::diff() will merely return "RepaintLayer" and thus will not foce a layout. However, updating the positions of child layers may be
     18        necessary as the animation being removed may mean that there may not be a RenderLayer associated with that element's renderer anymore, and if that RenderLayer
     19        had a position, then the position of child layers will no longer be correct.
     20
     21        Now, in the case where we destroy a layer in RenderLayerModelObject::styleDidChange(), we check whether the layer had a position before it is removed, and
     22        update the position of child layers if it did.
     23
     24        * rendering/RenderLayerModelObject.cpp:
     25        (WebCore::RenderLayerModelObject::styleDidChange):
     26
    1272019-11-26  youenn fablet  <youenn@apple.com>
    228
  • trunk/Source/WebCore/rendering/RenderLayerModelObject.cpp

    r252724 r252879  
    185185        if (layer()->isSelfPaintingLayer() && layer()->repaintStatus() == NeedsFullRepaint && hasRepaintLayoutRects())
    186186            repaintUsingContainer(containerForRepaint(), repaintLayoutRects().m_repaintRect);
     187        // If the layer we're about to destroy had a position, then the positions of the current children will no longer be correct.
     188        auto* parentLayer = layer()->parent();
     189        bool layerHadLocation = !layer()->location().isZero();
    187190        layer()->removeOnlyThisLayer(); // calls destroyLayer() which clears m_layer
     191        if (layerHadLocation && parentLayer && !parentLayer->renderer().needsLayout())
     192            parentLayer->updateLayerPositionsAfterStyleChange();
    188193        if (s_wasFloating && isFloating())
    189194            setChildNeedsLayout();
Note: See TracChangeset for help on using the changeset viewer.