Changeset 284084 in webkit


Ignore:
Timestamp:
Oct 13, 2021 12:59:14 AM (9 months ago)
Author:
Martin Robinson
Message:

Sticky element inside another sticky element does not redraw properly on scroll
https://bugs.webkit.org/show_bug.cgi?id=199915
<rdar://problem/53375284>

Reviewed by Simon Fraser.

When calculating layer position for sticky nodes in the scrolling tree, take into
account situations where the sticky parents of sticky nodes don't stick (due to
sizing). This was handled properly in layout, but not in the scrolling tree, which
caused these kinds of nodes to jump around.

Source/WebCore:

Test: scrollingcoordinator/mac/nested-sticky-with-nonsticking-sticky-parent.html

  • page/scrolling/ScrollingStateStickyNode.cpp:

(WebCore::ScrollingStateStickyNode::computeLayerPosition const):
(WebCore::ScrollingStateStickyNode::scrollDeltaSinceLastCommit const):

  • page/scrolling/ScrollingStateStickyNode.h:
  • page/scrolling/cocoa/ScrollingTreeStickyNode.mm:

(WebCore::ScrollingTreeStickyNode::computeLayerPosition const):

  • page/scrolling/nicosia/ScrollingTreeStickyNode.cpp:

(WebCore::ScrollingTreeStickyNode::computeLayerPosition const):
(WebCore::ScrollingTreeStickyNode::scrollDeltaSinceLastCommit const):

  • page/scrolling/nicosia/ScrollingTreeStickyNode.h:

LayoutTests:

  • scrollingcoordinator/mac/nested-sticky-with-nonsticking-sticky-parent-expected.html: Added.
  • scrollingcoordinator/mac/nested-sticky-with-nonsticking-sticky-parent.html: Added.
Location:
trunk
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r284068 r284084  
     12021-10-13  Martin Robinson  <mrobinson@webkit.org>
     2
     3        Sticky element inside another sticky element does not redraw properly on scroll
     4        https://bugs.webkit.org/show_bug.cgi?id=199915
     5        <rdar://problem/53375284>
     6
     7        Reviewed by Simon Fraser.
     8
     9        When calculating layer position for sticky nodes in the scrolling tree, take into
     10        account situations where the sticky parents of sticky nodes don't stick (due to
     11        sizing). This was handled properly in layout, but not in the scrolling tree, which
     12        caused these kinds of nodes to jump around.
     13
     14        * scrollingcoordinator/mac/nested-sticky-with-nonsticking-sticky-parent-expected.html: Added.
     15        * scrollingcoordinator/mac/nested-sticky-with-nonsticking-sticky-parent.html: Added.
     16
    1172021-10-12  Arcady Goldmints-Orlov  <agoldmints@igalia.com>
    218
  • trunk/Source/WebCore/ChangeLog

    r284080 r284084  
     12021-10-13  Martin Robinson  <mrobinson@webkit.org>
     2
     3        Sticky element inside another sticky element does not redraw properly on scroll
     4        https://bugs.webkit.org/show_bug.cgi?id=199915
     5        <rdar://problem/53375284>
     6
     7        Reviewed by Simon Fraser.
     8
     9        When calculating layer position for sticky nodes in the scrolling tree, take into
     10        account situations where the sticky parents of sticky nodes don't stick (due to
     11        sizing). This was handled properly in layout, but not in the scrolling tree, which
     12        caused these kinds of nodes to jump around.
     13
     14        Test: scrollingcoordinator/mac/nested-sticky-with-nonsticking-sticky-parent.html
     15
     16        * page/scrolling/ScrollingStateStickyNode.cpp:
     17        (WebCore::ScrollingStateStickyNode::computeLayerPosition const):
     18        (WebCore::ScrollingStateStickyNode::scrollDeltaSinceLastCommit const):
     19        * page/scrolling/ScrollingStateStickyNode.h:
     20        * page/scrolling/cocoa/ScrollingTreeStickyNode.mm:
     21        (WebCore::ScrollingTreeStickyNode::computeLayerPosition const):
     22        * page/scrolling/nicosia/ScrollingTreeStickyNode.cpp:
     23        (WebCore::ScrollingTreeStickyNode::computeLayerPosition const):
     24        (WebCore::ScrollingTreeStickyNode::scrollDeltaSinceLastCommit const):
     25        * page/scrolling/nicosia/ScrollingTreeStickyNode.h:
     26
    1272021-10-12  Jer Noble  <jer.noble@apple.com>
    228
  • trunk/Source/WebCore/page/scrolling/ScrollingStateStickyNode.cpp

    r269458 r284084  
    8787{
    8888    // This logic follows ScrollingTreeStickyNode::computeLayerPosition().
     89    FloatSize offsetFromStickyAncestors;
    8990    auto computeLayerPositionForScrollingNode = [&](ScrollingStateNode& scrollingStateNode) {
    9091        FloatRect constrainingRect;
     
    9596            constrainingRect = FloatRect(overflowScrollingNode.scrollPosition(), m_constraints.constrainingRectAtLastLayout().size());
    9697        }
     98        constrainingRect.move(offsetFromStickyAncestors);
    9799        return m_constraints.layerPositionForConstrainingRect(constrainingRect);
    98100    };
     
    111113            return computeLayerPositionForScrollingNode(*ancestor);
    112114
    113         if (is<ScrollingStateFixedNode>(*ancestor) || is<ScrollingStateStickyNode>(*ancestor)) {
     115        if (is<ScrollingStateStickyNode>(*ancestor))
     116            offsetFromStickyAncestors += downcast<ScrollingStateStickyNode>(*ancestor).scrollDeltaSinceLastCommit(viewportRect);
     117
     118        if (is<ScrollingStateFixedNode>(*ancestor)) {
    114119            // FIXME: Do we need scrolling tree nodes at all for nested cases?
    115120            return m_constraints.layerPositionAtLastLayout();
     
    142147        }
    143148    }
     149}
     150
     151FloatSize ScrollingStateStickyNode::scrollDeltaSinceLastCommit(const LayoutRect& viewportRect) const
     152{
     153    auto layerPosition = computeLayerPosition(viewportRect);
     154    return layerPosition - m_constraints.layerPositionAtLastLayout();
    144155}
    145156
  • trunk/Source/WebCore/page/scrolling/ScrollingStateStickyNode.h

    r269458 r284084  
    5454    FloatPoint computeLayerPosition(const LayoutRect& viewportRect) const;
    5555    void reconcileLayerPositionForViewportRect(const LayoutRect& viewportRect, ScrollingLayerPositionAction) final;
     56    FloatSize scrollDeltaSinceLastCommit(const LayoutRect& viewportRect) const;
    5657
    5758    void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const final;
  • trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.mm

    r278429 r284084  
    7070FloatPoint ScrollingTreeStickyNode::computeLayerPosition() const
    7171{
     72    FloatSize offsetFromStickyAncestors;
    7273    auto computeLayerPositionForScrollingNode = [&](ScrollingTreeNode& scrollingNode) {
    7374        FloatRect constrainingRect;
     
    8081            constrainingRect.move(overflowScrollingNode.scrollDeltaSinceLastCommit());
    8182        }
     83        constrainingRect.move(-offsetFromStickyAncestors);
    8284        return m_constraints.layerPositionForConstrainingRect(constrainingRect);
    8385    };
     
    9698            return computeLayerPositionForScrollingNode(*ancestor);
    9799
    98         if (is<ScrollingTreeFixedNode>(*ancestor) || is<ScrollingTreeStickyNode>(*ancestor)) {
     100        if (is<ScrollingTreeStickyNode>(*ancestor))
     101            offsetFromStickyAncestors += downcast<ScrollingTreeStickyNode>(*ancestor).scrollDeltaSinceLastCommit();
     102
     103        if (is<ScrollingTreeFixedNode>(*ancestor)) {
    99104            // FIXME: Do we need scrolling tree nodes at all for nested cases?
    100105            return m_constraints.layerPositionAtLastLayout();
  • trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.cpp

    r278429 r284084  
    112112FloatPoint ScrollingTreeStickyNode::computeLayerPosition() const
    113113{
     114    FloatSize offsetFromStickyAncestors;
    114115    auto computeLayerPositionForScrollingNode = [&](ScrollingTreeNode& scrollingNode) {
    115116        FloatRect constrainingRect;
     
    122123            constrainingRect.move(overflowScrollingNode.scrollDeltaSinceLastCommit());
    123124        }
     125        constrainingRect.move(-offsetFromStickyAncestors);
    124126        return m_constraints.layerPositionForConstrainingRect(constrainingRect);
    125127    };
     
    138140            return computeLayerPositionForScrollingNode(*ancestor);
    139141
    140         if (is<ScrollingTreeFixedNode>(*ancestor) || is<ScrollingTreeStickyNode>(*ancestor)) {
     142        if (is<ScrollingTreeStickyNode>(*ancestor))
     143            offsetFromStickyAncestors += downcast<ScrollingTreeStickyNode>(*ancestor).scrollDeltaSinceLastCommit();
     144
     145        if (is<ScrollingTreeFixedNode>(*ancestor)) {
    141146            // FIXME: Do we need scrolling tree nodes at all for nested cases?
    142147            return m_constraints.layerPositionAtLastLayout();
     
    147152}
    148153
     154FloatSize ScrollingTreeStickyNode::scrollDeltaSinceLastCommit() const
     155{
     156    auto layerPosition = computeLayerPosition();
     157    return layerPosition - m_constraints.layerPositionAtLastLayout();
     158}
     159
    149160} // namespace WebCore
    150161
  • trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.h

    r250339 r284084  
    5555
    5656    FloatPoint computeLayerPosition() const;
     57    FloatSize scrollDeltaSinceLastCommit() const;
    5758
    5859    StickyPositionViewportConstraints m_constraints;
Note: See TracChangeset for help on using the changeset viewer.