Title: [272260] branches/safari-611-branch
Revision
272260
Author
[email protected]
Date
2021-02-02 17:40:05 -0800 (Tue, 02 Feb 2021)

Log Message

Cherry-pick r271786. rdar://problem/73890368

    [iOS WK2] theverge.com - rubber band scrolling at the top of the page causes an abrupt jump
    https://bugs.webkit.org/show_bug.cgi?id=220886
    <rdar://71177566>

    Reviewed by Sam Weinig.
    Source/WebCore:

    theverge.com on iOS is a page that has long main thread stalls with forced layouts on a timer
    that alter the page height; this caused the post-layout updateScrollbars() called from
    FrameView::adjustViewSize() to call scrollToPosition() after adjusting the scroll position
    to the allowed range.

    If the page laid out while rubberbanding was happening, the current scroll position would
    be negative, then clamped to 0, then sent to the UI process as a requested scroll to 0,
    triggering the jump to top in the UI process.

    There's existing code to prevent this from happening if we know that rubberbanding is
    happening; this patch makes isRubberBandInProgress() work for iOS WK2. It does so
    by having updateVisibleContentRects() push information about rubberbanding nodes onto
    RemoteScrollingCoordinator.

    We remove an unnecessary shouldUpdateScrollLayerPositionSynchronously() check in
    FrameView::isRubberBandInProgress() - if it's true, then the scrolling coordinator
    won't see any rubberbanding nodes anyway.

    Test: fast/scrolling/ios/content-size-change-during-rubberband.html

    * page/FrameView.cpp:
    (WebCore::FrameView::isRubberBandInProgress const):
    * page/FrameView.h:
    * platform/ScrollView.cpp:
    (WebCore::ScrollView::updateScrollbars):

    Source/WebKit:

    theverge.com on iOS is a page that has long main thread stalls with forced layouts on a timer
    that alter the page height; this caused the post-layout updateScrollbars() called from
    FrameView::adjustViewSize() to call scrollToPosition() after adjusting the scroll position
    to the allowed range.

    If the page laid out while rubberbanding was happening, the current scroll position would
    be negative, then clamped to 0, then sent to the UI process as a requested scroll to 0,
    triggering the jump to top in the UI process.

    There's existing code to prevent this from happening if we know that rubberbanding is
    happening; this patch makes isRubberBandInProgress() work for iOS WK2. It does so
    by having updateVisibleContentRects() push information about rubberbanding nodes onto
    RemoteScrollingCoordinator.

    We remove an unnecessary shouldUpdateScrollLayerPositionSynchronously() check in
    FrameView::isRubberBandInProgress() - if it's true, then the scrolling coordinator
    won't see any rubberbanding nodes anyway.

    * UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:
    * WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.h:
    * WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.mm:
    (WebKit::RemoteScrollingCoordinator::addNodeWithActiveRubberBanding):
    (WebKit::RemoteScrollingCoordinator::removeNodeWithActiveRubberBanding):
    * WebProcess/WebPage/ios/WebPageIOS.mm:
    (WebKit::WebPage::updateVisibleContentRects):

    Tools:

    Add test infrastructure to allow UIScriptController::scrollToOffset() and
    UIScriptController::immediateScrollToOffset() to take an options argument with
    a 'unconstrained' property, which allows scrolling to unstable offset to simulate
    rubberbanding.

    * DumpRenderTree/ios/UIScriptControllerIOS.h:
    * DumpRenderTree/ios/UIScriptControllerIOS.mm:
    (WTR::contentOffsetBoundedIfNecessary):
    (WTR::UIScriptControllerIOS::scrollToOffset):
    (WTR::UIScriptControllerIOS::immediateScrollToOffset):
    (WTR::contentOffsetBoundedInValidRange): Deleted.
    * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
    * TestRunnerShared/UIScriptContext/UIScriptController.h:
    (WTR::UIScriptController::scrollToOffset):
    (WTR::UIScriptController::immediateScrollToOffset):
    * TestRunnerShared/UIScriptContext/UIScriptControllerShared.cpp:
    (WTR::toScrollToOptions):
    * WebKitTestRunner/ios/UIScriptControllerIOS.h:
    * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
    (WTR::contentOffsetBoundedIfNecessary):
    (WTR::UIScriptControllerIOS::scrollToOffset):
    (WTR::UIScriptControllerIOS::immediateScrollToOffset):
    (WTR::contentOffsetBoundedInValidRange): Deleted.

    LayoutTests:

    Add test infrastructure to allow UIScriptController::scrollToOffset() and
    UIScriptController::immediateScrollToOffset() to take an options argument with
    a 'unconstrained' property, which allows scrolling to unstable offset to simulate
    rubberbanding.

    * fast/scrolling/ios/content-size-change-during-rubberband-expected.txt: Added.
    * fast/scrolling/ios/content-size-change-during-rubberband.html: Added.
    * resources/ui-helper.js:
    (window.UIHelper.scrollTo.return.new.Promise.):
    (window.UIHelper.scrollTo.return.new.Promise):
    (window.UIHelper.scrollTo):
    (window.UIHelper.immediateScrollTo):
    (window.UIHelper.immediateUnstableScrollTo):

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271786 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Modified Paths

Added Paths

Diff

Modified: branches/safari-611-branch/LayoutTests/ChangeLog (272259 => 272260)


--- branches/safari-611-branch/LayoutTests/ChangeLog	2021-02-03 01:39:57 UTC (rev 272259)
+++ branches/safari-611-branch/LayoutTests/ChangeLog	2021-02-03 01:40:05 UTC (rev 272260)
@@ -1,5 +1,137 @@
 2021-02-02  Alan Coon  <[email protected]>
 
+        Cherry-pick r271786. rdar://problem/73890368
+
+    [iOS WK2] theverge.com - rubber band scrolling at the top of the page causes an abrupt jump
+    https://bugs.webkit.org/show_bug.cgi?id=220886
+    <rdar://71177566>
+    
+    Reviewed by Sam Weinig.
+    Source/WebCore:
+    
+    theverge.com on iOS is a page that has long main thread stalls with forced layouts on a timer
+    that alter the page height; this caused the post-layout updateScrollbars() called from
+    FrameView::adjustViewSize() to call scrollToPosition() after adjusting the scroll position
+    to the allowed range.
+    
+    If the page laid out while rubberbanding was happening, the current scroll position would
+    be negative, then clamped to 0, then sent to the UI process as a requested scroll to 0,
+    triggering the jump to top in the UI process.
+    
+    There's existing code to prevent this from happening if we know that rubberbanding is
+    happening; this patch makes isRubberBandInProgress() work for iOS WK2. It does so
+    by having updateVisibleContentRects() push information about rubberbanding nodes onto
+    RemoteScrollingCoordinator.
+    
+    We remove an unnecessary shouldUpdateScrollLayerPositionSynchronously() check in
+    FrameView::isRubberBandInProgress() - if it's true, then the scrolling coordinator
+    won't see any rubberbanding nodes anyway.
+    
+    Test: fast/scrolling/ios/content-size-change-during-rubberband.html
+    
+    * page/FrameView.cpp:
+    (WebCore::FrameView::isRubberBandInProgress const):
+    * page/FrameView.h:
+    * platform/ScrollView.cpp:
+    (WebCore::ScrollView::updateScrollbars):
+    
+    Source/WebKit:
+    
+    theverge.com on iOS is a page that has long main thread stalls with forced layouts on a timer
+    that alter the page height; this caused the post-layout updateScrollbars() called from
+    FrameView::adjustViewSize() to call scrollToPosition() after adjusting the scroll position
+    to the allowed range.
+    
+    If the page laid out while rubberbanding was happening, the current scroll position would
+    be negative, then clamped to 0, then sent to the UI process as a requested scroll to 0,
+    triggering the jump to top in the UI process.
+    
+    There's existing code to prevent this from happening if we know that rubberbanding is
+    happening; this patch makes isRubberBandInProgress() work for iOS WK2. It does so
+    by having updateVisibleContentRects() push information about rubberbanding nodes onto
+    RemoteScrollingCoordinator.
+    
+    We remove an unnecessary shouldUpdateScrollLayerPositionSynchronously() check in
+    FrameView::isRubberBandInProgress() - if it's true, then the scrolling coordinator
+    won't see any rubberbanding nodes anyway.
+    
+    * UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:
+    * WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.h:
+    * WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.mm:
+    (WebKit::RemoteScrollingCoordinator::addNodeWithActiveRubberBanding):
+    (WebKit::RemoteScrollingCoordinator::removeNodeWithActiveRubberBanding):
+    * WebProcess/WebPage/ios/WebPageIOS.mm:
+    (WebKit::WebPage::updateVisibleContentRects):
+    
+    Tools:
+    
+    Add test infrastructure to allow UIScriptController::scrollToOffset() and
+    UIScriptController::immediateScrollToOffset() to take an options argument with
+    a 'unconstrained' property, which allows scrolling to unstable offset to simulate
+    rubberbanding.
+    
+    * DumpRenderTree/ios/UIScriptControllerIOS.h:
+    * DumpRenderTree/ios/UIScriptControllerIOS.mm:
+    (WTR::contentOffsetBoundedIfNecessary):
+    (WTR::UIScriptControllerIOS::scrollToOffset):
+    (WTR::UIScriptControllerIOS::immediateScrollToOffset):
+    (WTR::contentOffsetBoundedInValidRange): Deleted.
+    * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
+    * TestRunnerShared/UIScriptContext/UIScriptController.h:
+    (WTR::UIScriptController::scrollToOffset):
+    (WTR::UIScriptController::immediateScrollToOffset):
+    * TestRunnerShared/UIScriptContext/UIScriptControllerShared.cpp:
+    (WTR::toScrollToOptions):
+    * WebKitTestRunner/ios/UIScriptControllerIOS.h:
+    * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+    (WTR::contentOffsetBoundedIfNecessary):
+    (WTR::UIScriptControllerIOS::scrollToOffset):
+    (WTR::UIScriptControllerIOS::immediateScrollToOffset):
+    (WTR::contentOffsetBoundedInValidRange): Deleted.
+    
+    LayoutTests:
+    
+    Add test infrastructure to allow UIScriptController::scrollToOffset() and
+    UIScriptController::immediateScrollToOffset() to take an options argument with
+    a 'unconstrained' property, which allows scrolling to unstable offset to simulate
+    rubberbanding.
+    
+    * fast/scrolling/ios/content-size-change-during-rubberband-expected.txt: Added.
+    * fast/scrolling/ios/content-size-change-during-rubberband.html: Added.
+    * resources/ui-helper.js:
+    (window.UIHelper.scrollTo.return.new.Promise.):
+    (window.UIHelper.scrollTo.return.new.Promise):
+    (window.UIHelper.scrollTo):
+    (window.UIHelper.immediateScrollTo):
+    (window.UIHelper.immediateUnstableScrollTo):
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271786 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-01-24  Simon Fraser  <[email protected]>
+
+            [iOS WK2] theverge.com - rubber band scrolling at the top of the page causes an abrupt jump
+            https://bugs.webkit.org/show_bug.cgi?id=220886
+            <rdar://71177566>
+
+            Reviewed by Sam Weinig.
+
+            Add test infrastructure to allow UIScriptController::scrollToOffset() and
+            UIScriptController::immediateScrollToOffset() to take an options argument with
+            a 'unconstrained' property, which allows scrolling to unstable offset to simulate
+            rubberbanding.
+
+            * fast/scrolling/ios/content-size-change-during-rubberband-expected.txt: Added.
+            * fast/scrolling/ios/content-size-change-during-rubberband.html: Added.
+            * resources/ui-helper.js:
+            (window.UIHelper.scrollTo.return.new.Promise.):
+            (window.UIHelper.scrollTo.return.new.Promise):
+            (window.UIHelper.scrollTo):
+            (window.UIHelper.immediateScrollTo):
+            (window.UIHelper.immediateUnstableScrollTo):
+
+2021-02-02  Alan Coon  <[email protected]>
+
         Cherry-pick r271760. rdar://problem/73890156
 
     AX: AT-synthesized key events for common user actions (increment/decrement) are detectably different in many ways, potentially causing both web app breakage and AT identification

Added: branches/safari-611-branch/LayoutTests/fast/scrolling/ios/content-size-change-during-rubberband-expected.txt (0 => 272260)


--- branches/safari-611-branch/LayoutTests/fast/scrolling/ios/content-size-change-during-rubberband-expected.txt	                        (rev 0)
+++ branches/safari-611-branch/LayoutTests/fast/scrolling/ios/content-size-change-during-rubberband-expected.txt	2021-02-03 01:40:05 UTC (rev 272260)
@@ -0,0 +1,6 @@
+Top
+PASS window.pageYOffset is -100
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: branches/safari-611-branch/LayoutTests/fast/scrolling/ios/content-size-change-during-rubberband.html (0 => 272260)


--- branches/safari-611-branch/LayoutTests/fast/scrolling/ios/content-size-change-during-rubberband.html	                        (rev 0)
+++ branches/safari-611-branch/LayoutTests/fast/scrolling/ios/content-size-change-during-rubberband.html	2021-02-03 01:40:05 UTC (rev 272260)
@@ -0,0 +1,41 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        .content {
+            height: 2000px;
+        }
+
+        body.changed .content {
+            height: 2100px;
+        }
+    </style>
+    <script src=""
+    <script src=""
+    <script>
+        var jsTestIsAsync = true;
+
+        async function doTest()
+        {
+            const unconstrained = true;
+            await UIHelper.scrollTo(0, -100, unconstrained);
+            
+            document.body.classList.add('changed');
+            
+            await UIHelper.renderingUpdate();
+            shouldBe('window.pageYOffset', '-100');
+            finishJSTest();
+        }
+
+        window.addEventListener('load', () => {
+            doTest();
+        }, false);
+    </script>
+</head>
+<body>
+    Top
+    <div class="content"></div>
+    <div id="console"></div>
+    <script src=""
+</body>
+</html>

Modified: branches/safari-611-branch/LayoutTests/resources/ui-helper.js (272259 => 272260)


--- branches/safari-611-branch/LayoutTests/resources/ui-helper.js	2021-02-03 01:39:57 UTC (rev 272259)
+++ branches/safari-611-branch/LayoutTests/resources/ui-helper.js	2021-02-03 01:40:05 UTC (rev 272260)
@@ -423,8 +423,26 @@
     {
         return new Promise(resolve => setTimeout(resolve, ms));
     }
+
+    static scrollTo(x, y, unconstrained)
+    {
+        if (!this.isWebKit2()) {
+            window.scrollTo(x, y);
+            return Promise.resolve();
+        }
+
+        return new Promise(resolve => {
+            testRunner.runUIScript(`
+                (function() {
+                    uiController.didEndScrollingCallback = function() {
+                        uiController.uiScriptComplete();
+                    }
+                    uiController.scrollToOffset(${x}, ${y}, { unconstrained: ${unconstrained} });
+                })()`, resolve);
+        });
+    }
     
-    static immediateScrollTo(x, y)
+    static immediateScrollTo(x, y, unconstrained)
     {
         if (!this.isWebKit2()) {
             window.scrollTo(x, y);
@@ -433,11 +451,11 @@
 
         return new Promise(resolve => {
             testRunner.runUIScript(`
-                uiController.immediateScrollToOffset(${x}, ${y});`, resolve);
+                uiController.immediateScrollToOffset(${x}, ${y}, { unconstrained: ${unconstrained} });`, resolve);
         });
     }
 
-    static immediateUnstableScrollTo(x, y)
+    static immediateUnstableScrollTo(x, y, unconstrained)
     {
         if (!this.isWebKit2()) {
             window.scrollTo(x, y);
@@ -447,7 +465,7 @@
         return new Promise(resolve => {
             testRunner.runUIScript(`
                 uiController.stableStateOverride = false;
-                uiController.immediateScrollToOffset(${x}, ${y});`, resolve);
+                uiController.immediateScrollToOffset(${x}, ${y}, { unconstrained: ${unconstrained} });`, resolve);
         });
     }
 

Modified: branches/safari-611-branch/Source/WebCore/ChangeLog (272259 => 272260)


--- branches/safari-611-branch/Source/WebCore/ChangeLog	2021-02-03 01:39:57 UTC (rev 272259)
+++ branches/safari-611-branch/Source/WebCore/ChangeLog	2021-02-03 01:40:05 UTC (rev 272260)
@@ -1,5 +1,149 @@
 2021-02-02  Alan Coon  <[email protected]>
 
+        Cherry-pick r271786. rdar://problem/73890368
+
+    [iOS WK2] theverge.com - rubber band scrolling at the top of the page causes an abrupt jump
+    https://bugs.webkit.org/show_bug.cgi?id=220886
+    <rdar://71177566>
+    
+    Reviewed by Sam Weinig.
+    Source/WebCore:
+    
+    theverge.com on iOS is a page that has long main thread stalls with forced layouts on a timer
+    that alter the page height; this caused the post-layout updateScrollbars() called from
+    FrameView::adjustViewSize() to call scrollToPosition() after adjusting the scroll position
+    to the allowed range.
+    
+    If the page laid out while rubberbanding was happening, the current scroll position would
+    be negative, then clamped to 0, then sent to the UI process as a requested scroll to 0,
+    triggering the jump to top in the UI process.
+    
+    There's existing code to prevent this from happening if we know that rubberbanding is
+    happening; this patch makes isRubberBandInProgress() work for iOS WK2. It does so
+    by having updateVisibleContentRects() push information about rubberbanding nodes onto
+    RemoteScrollingCoordinator.
+    
+    We remove an unnecessary shouldUpdateScrollLayerPositionSynchronously() check in
+    FrameView::isRubberBandInProgress() - if it's true, then the scrolling coordinator
+    won't see any rubberbanding nodes anyway.
+    
+    Test: fast/scrolling/ios/content-size-change-during-rubberband.html
+    
+    * page/FrameView.cpp:
+    (WebCore::FrameView::isRubberBandInProgress const):
+    * page/FrameView.h:
+    * platform/ScrollView.cpp:
+    (WebCore::ScrollView::updateScrollbars):
+    
+    Source/WebKit:
+    
+    theverge.com on iOS is a page that has long main thread stalls with forced layouts on a timer
+    that alter the page height; this caused the post-layout updateScrollbars() called from
+    FrameView::adjustViewSize() to call scrollToPosition() after adjusting the scroll position
+    to the allowed range.
+    
+    If the page laid out while rubberbanding was happening, the current scroll position would
+    be negative, then clamped to 0, then sent to the UI process as a requested scroll to 0,
+    triggering the jump to top in the UI process.
+    
+    There's existing code to prevent this from happening if we know that rubberbanding is
+    happening; this patch makes isRubberBandInProgress() work for iOS WK2. It does so
+    by having updateVisibleContentRects() push information about rubberbanding nodes onto
+    RemoteScrollingCoordinator.
+    
+    We remove an unnecessary shouldUpdateScrollLayerPositionSynchronously() check in
+    FrameView::isRubberBandInProgress() - if it's true, then the scrolling coordinator
+    won't see any rubberbanding nodes anyway.
+    
+    * UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:
+    * WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.h:
+    * WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.mm:
+    (WebKit::RemoteScrollingCoordinator::addNodeWithActiveRubberBanding):
+    (WebKit::RemoteScrollingCoordinator::removeNodeWithActiveRubberBanding):
+    * WebProcess/WebPage/ios/WebPageIOS.mm:
+    (WebKit::WebPage::updateVisibleContentRects):
+    
+    Tools:
+    
+    Add test infrastructure to allow UIScriptController::scrollToOffset() and
+    UIScriptController::immediateScrollToOffset() to take an options argument with
+    a 'unconstrained' property, which allows scrolling to unstable offset to simulate
+    rubberbanding.
+    
+    * DumpRenderTree/ios/UIScriptControllerIOS.h:
+    * DumpRenderTree/ios/UIScriptControllerIOS.mm:
+    (WTR::contentOffsetBoundedIfNecessary):
+    (WTR::UIScriptControllerIOS::scrollToOffset):
+    (WTR::UIScriptControllerIOS::immediateScrollToOffset):
+    (WTR::contentOffsetBoundedInValidRange): Deleted.
+    * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
+    * TestRunnerShared/UIScriptContext/UIScriptController.h:
+    (WTR::UIScriptController::scrollToOffset):
+    (WTR::UIScriptController::immediateScrollToOffset):
+    * TestRunnerShared/UIScriptContext/UIScriptControllerShared.cpp:
+    (WTR::toScrollToOptions):
+    * WebKitTestRunner/ios/UIScriptControllerIOS.h:
+    * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+    (WTR::contentOffsetBoundedIfNecessary):
+    (WTR::UIScriptControllerIOS::scrollToOffset):
+    (WTR::UIScriptControllerIOS::immediateScrollToOffset):
+    (WTR::contentOffsetBoundedInValidRange): Deleted.
+    
+    LayoutTests:
+    
+    Add test infrastructure to allow UIScriptController::scrollToOffset() and
+    UIScriptController::immediateScrollToOffset() to take an options argument with
+    a 'unconstrained' property, which allows scrolling to unstable offset to simulate
+    rubberbanding.
+    
+    * fast/scrolling/ios/content-size-change-during-rubberband-expected.txt: Added.
+    * fast/scrolling/ios/content-size-change-during-rubberband.html: Added.
+    * resources/ui-helper.js:
+    (window.UIHelper.scrollTo.return.new.Promise.):
+    (window.UIHelper.scrollTo.return.new.Promise):
+    (window.UIHelper.scrollTo):
+    (window.UIHelper.immediateScrollTo):
+    (window.UIHelper.immediateUnstableScrollTo):
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271786 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-01-24  Simon Fraser  <[email protected]>
+
+            [iOS WK2] theverge.com - rubber band scrolling at the top of the page causes an abrupt jump
+            https://bugs.webkit.org/show_bug.cgi?id=220886
+            <rdar://71177566>
+
+            Reviewed by Sam Weinig.
+
+            theverge.com on iOS is a page that has long main thread stalls with forced layouts on a timer
+            that alter the page height; this caused the post-layout updateScrollbars() called from
+            FrameView::adjustViewSize() to call scrollToPosition() after adjusting the scroll position
+            to the allowed range.
+
+            If the page laid out while rubberbanding was happening, the current scroll position would
+            be negative, then clamped to 0, then sent to the UI process as a requested scroll to 0,
+            triggering the jump to top in the UI process.
+
+            There's existing code to prevent this from happening if we know that rubberbanding is
+            happening; this patch makes isRubberBandInProgress() work for iOS WK2. It does so
+            by having updateVisibleContentRects() push information about rubberbanding nodes onto
+            RemoteScrollingCoordinator.
+
+            We remove an unnecessary shouldUpdateScrollLayerPositionSynchronously() check in
+            FrameView::isRubberBandInProgress() - if it's true, then the scrolling coordinator
+            won't see any rubberbanding nodes anyway.
+
+            Test: fast/scrolling/ios/content-size-change-during-rubberband.html
+
+            * page/FrameView.cpp:
+            (WebCore::FrameView::isRubberBandInProgress const):
+            * page/FrameView.h:
+            * platform/ScrollView.cpp:
+            (WebCore::ScrollView::updateScrollbars):
+
+2021-02-02  Alan Coon  <[email protected]>
+
         Cherry-pick r271770. rdar://problem/73890671
 
     REGRESSION(r266148) Cancelling a navigation in decidePolicyForNavigationAction should not suspend the previous document's font loading timer

Modified: branches/safari-611-branch/Source/WebCore/page/FrameView.cpp (272259 => 272260)


--- branches/safari-611-branch/Source/WebCore/page/FrameView.cpp	2021-02-03 01:39:57 UTC (rev 272259)
+++ branches/safari-611-branch/Source/WebCore/page/FrameView.cpp	2021-02-03 01:40:05 UTC (rev 272260)
@@ -2661,10 +2661,8 @@
     if (scrollbarsSuppressed())
         return false;
 
-    if (auto scrollingCoordinator = this->scrollingCoordinator()) {
-        if (!scrollingCoordinator->shouldUpdateScrollLayerPositionSynchronously(*this))
-            return scrollingCoordinator->isRubberBandInProgress(scrollingNodeID());
-    }
+    if (auto scrollingCoordinator = this->scrollingCoordinator())
+        return scrollingCoordinator->isRubberBandInProgress(scrollingNodeID());
 
     if (auto scrollAnimator = existingScrollAnimator())
         return scrollAnimator->isRubberBandInProgress();

Modified: branches/safari-611-branch/Source/WebCore/page/FrameView.h (272259 => 272260)


--- branches/safari-611-branch/Source/WebCore/page/FrameView.h	2021-02-03 01:39:57 UTC (rev 272259)
+++ branches/safari-611-branch/Source/WebCore/page/FrameView.h	2021-02-03 01:40:05 UTC (rev 272260)
@@ -167,7 +167,7 @@
 
     WEBCORE_EXPORT TiledBacking* tiledBacking() const;
 
-    ScrollingNodeID scrollingNodeID() const override;
+    WEBCORE_EXPORT ScrollingNodeID scrollingNodeID() const override;
     ScrollableArea* scrollableAreaForScrollingNodeID(ScrollingNodeID) const;
     bool usesAsyncScrolling() const final;
 

Modified: branches/safari-611-branch/Source/WebCore/platform/ScrollView.cpp (272259 => 272260)


--- branches/safari-611-branch/Source/WebCore/platform/ScrollView.cpp	2021-02-03 01:39:57 UTC (rev 272259)
+++ branches/safari-611-branch/Source/WebCore/platform/ScrollView.cpp	2021-02-03 01:40:05 UTC (rev 272260)
@@ -586,7 +586,7 @@
 
 void ScrollView::updateScrollbars(const ScrollPosition& desiredPosition)
 {
-    LOG_WITH_STREAM(Scrolling, stream << "ScrollView::updateScrollbars " << desiredPosition);
+    LOG_WITH_STREAM(Scrolling, stream << "ScrollView::updateScrollbars " << desiredPosition << " isRubberBandInProgress " << isRubberBandInProgress());
 
     if (m_inUpdateScrollbars || prohibitsScrolling() || platformWidget())
         return;

Modified: branches/safari-611-branch/Source/WebKit/ChangeLog (272259 => 272260)


--- branches/safari-611-branch/Source/WebKit/ChangeLog	2021-02-03 01:39:57 UTC (rev 272259)
+++ branches/safari-611-branch/Source/WebKit/ChangeLog	2021-02-03 01:40:05 UTC (rev 272260)
@@ -1,5 +1,149 @@
 2021-02-02  Alan Coon  <[email protected]>
 
+        Cherry-pick r271786. rdar://problem/73890368
+
+    [iOS WK2] theverge.com - rubber band scrolling at the top of the page causes an abrupt jump
+    https://bugs.webkit.org/show_bug.cgi?id=220886
+    <rdar://71177566>
+    
+    Reviewed by Sam Weinig.
+    Source/WebCore:
+    
+    theverge.com on iOS is a page that has long main thread stalls with forced layouts on a timer
+    that alter the page height; this caused the post-layout updateScrollbars() called from
+    FrameView::adjustViewSize() to call scrollToPosition() after adjusting the scroll position
+    to the allowed range.
+    
+    If the page laid out while rubberbanding was happening, the current scroll position would
+    be negative, then clamped to 0, then sent to the UI process as a requested scroll to 0,
+    triggering the jump to top in the UI process.
+    
+    There's existing code to prevent this from happening if we know that rubberbanding is
+    happening; this patch makes isRubberBandInProgress() work for iOS WK2. It does so
+    by having updateVisibleContentRects() push information about rubberbanding nodes onto
+    RemoteScrollingCoordinator.
+    
+    We remove an unnecessary shouldUpdateScrollLayerPositionSynchronously() check in
+    FrameView::isRubberBandInProgress() - if it's true, then the scrolling coordinator
+    won't see any rubberbanding nodes anyway.
+    
+    Test: fast/scrolling/ios/content-size-change-during-rubberband.html
+    
+    * page/FrameView.cpp:
+    (WebCore::FrameView::isRubberBandInProgress const):
+    * page/FrameView.h:
+    * platform/ScrollView.cpp:
+    (WebCore::ScrollView::updateScrollbars):
+    
+    Source/WebKit:
+    
+    theverge.com on iOS is a page that has long main thread stalls with forced layouts on a timer
+    that alter the page height; this caused the post-layout updateScrollbars() called from
+    FrameView::adjustViewSize() to call scrollToPosition() after adjusting the scroll position
+    to the allowed range.
+    
+    If the page laid out while rubberbanding was happening, the current scroll position would
+    be negative, then clamped to 0, then sent to the UI process as a requested scroll to 0,
+    triggering the jump to top in the UI process.
+    
+    There's existing code to prevent this from happening if we know that rubberbanding is
+    happening; this patch makes isRubberBandInProgress() work for iOS WK2. It does so
+    by having updateVisibleContentRects() push information about rubberbanding nodes onto
+    RemoteScrollingCoordinator.
+    
+    We remove an unnecessary shouldUpdateScrollLayerPositionSynchronously() check in
+    FrameView::isRubberBandInProgress() - if it's true, then the scrolling coordinator
+    won't see any rubberbanding nodes anyway.
+    
+    * UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:
+    * WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.h:
+    * WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.mm:
+    (WebKit::RemoteScrollingCoordinator::addNodeWithActiveRubberBanding):
+    (WebKit::RemoteScrollingCoordinator::removeNodeWithActiveRubberBanding):
+    * WebProcess/WebPage/ios/WebPageIOS.mm:
+    (WebKit::WebPage::updateVisibleContentRects):
+    
+    Tools:
+    
+    Add test infrastructure to allow UIScriptController::scrollToOffset() and
+    UIScriptController::immediateScrollToOffset() to take an options argument with
+    a 'unconstrained' property, which allows scrolling to unstable offset to simulate
+    rubberbanding.
+    
+    * DumpRenderTree/ios/UIScriptControllerIOS.h:
+    * DumpRenderTree/ios/UIScriptControllerIOS.mm:
+    (WTR::contentOffsetBoundedIfNecessary):
+    (WTR::UIScriptControllerIOS::scrollToOffset):
+    (WTR::UIScriptControllerIOS::immediateScrollToOffset):
+    (WTR::contentOffsetBoundedInValidRange): Deleted.
+    * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
+    * TestRunnerShared/UIScriptContext/UIScriptController.h:
+    (WTR::UIScriptController::scrollToOffset):
+    (WTR::UIScriptController::immediateScrollToOffset):
+    * TestRunnerShared/UIScriptContext/UIScriptControllerShared.cpp:
+    (WTR::toScrollToOptions):
+    * WebKitTestRunner/ios/UIScriptControllerIOS.h:
+    * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+    (WTR::contentOffsetBoundedIfNecessary):
+    (WTR::UIScriptControllerIOS::scrollToOffset):
+    (WTR::UIScriptControllerIOS::immediateScrollToOffset):
+    (WTR::contentOffsetBoundedInValidRange): Deleted.
+    
+    LayoutTests:
+    
+    Add test infrastructure to allow UIScriptController::scrollToOffset() and
+    UIScriptController::immediateScrollToOffset() to take an options argument with
+    a 'unconstrained' property, which allows scrolling to unstable offset to simulate
+    rubberbanding.
+    
+    * fast/scrolling/ios/content-size-change-during-rubberband-expected.txt: Added.
+    * fast/scrolling/ios/content-size-change-during-rubberband.html: Added.
+    * resources/ui-helper.js:
+    (window.UIHelper.scrollTo.return.new.Promise.):
+    (window.UIHelper.scrollTo.return.new.Promise):
+    (window.UIHelper.scrollTo):
+    (window.UIHelper.immediateScrollTo):
+    (window.UIHelper.immediateUnstableScrollTo):
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271786 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-01-24  Simon Fraser  <[email protected]>
+
+            [iOS WK2] theverge.com - rubber band scrolling at the top of the page causes an abrupt jump
+            https://bugs.webkit.org/show_bug.cgi?id=220886
+            <rdar://71177566>
+
+            Reviewed by Sam Weinig.
+
+            theverge.com on iOS is a page that has long main thread stalls with forced layouts on a timer
+            that alter the page height; this caused the post-layout updateScrollbars() called from
+            FrameView::adjustViewSize() to call scrollToPosition() after adjusting the scroll position
+            to the allowed range.
+
+            If the page laid out while rubberbanding was happening, the current scroll position would
+            be negative, then clamped to 0, then sent to the UI process as a requested scroll to 0,
+            triggering the jump to top in the UI process.
+
+            There's existing code to prevent this from happening if we know that rubberbanding is
+            happening; this patch makes isRubberBandInProgress() work for iOS WK2. It does so
+            by having updateVisibleContentRects() push information about rubberbanding nodes onto
+            RemoteScrollingCoordinator.
+
+            We remove an unnecessary shouldUpdateScrollLayerPositionSynchronously() check in
+            FrameView::isRubberBandInProgress() - if it's true, then the scrolling coordinator
+            won't see any rubberbanding nodes anyway.
+
+            * UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:
+            * WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.h:
+            * WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.mm:
+            (WebKit::RemoteScrollingCoordinator::addNodeWithActiveRubberBanding):
+            (WebKit::RemoteScrollingCoordinator::removeNodeWithActiveRubberBanding):
+            * WebProcess/WebPage/ios/WebPageIOS.mm:
+            (WebKit::WebPage::updateVisibleContentRects):
+
+2021-02-02  Alan Coon  <[email protected]>
+
         Cherry-pick r271771. rdar://problem/73890368
 
     [iOS WK2] Make the "in stable state" bit in visible content rect updates more fine-grained

Modified: branches/safari-611-branch/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm (272259 => 272260)


--- branches/safari-611-branch/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm	2021-02-03 01:39:57 UTC (rev 272259)
+++ branches/safari-611-branch/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm	2021-02-03 01:40:05 UTC (rev 272260)
@@ -125,6 +125,7 @@
     m_webPageProxy.scrollingNodeScrollViewWillStartPanGesture();
 }
 
+// This is not called for the main scroll view.
 void RemoteScrollingCoordinatorProxy::scrollingTreeNodeWillStartScroll(ScrollingNodeID nodeID)
 {
     m_webPageProxy.scrollingNodeScrollWillStartScroll();
@@ -133,6 +134,7 @@
     sendUIStateChangedIfNecessary();
 }
 
+// This is not called for the main scroll view.
 void RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidEndScroll(ScrollingNodeID nodeID)
 {
     m_webPageProxy.scrollingNodeScrollDidEndScroll();

Modified: branches/safari-611-branch/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.h (272259 => 272260)


--- branches/safari-611-branch/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.h	2021-02-03 01:39:57 UTC (rev 272259)
+++ branches/safari-611-branch/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.h	2021-02-03 01:40:05 UTC (rev 272260)
@@ -55,6 +55,9 @@
 
     void scrollingStateInUIProcessChanged(const RemoteScrollingUIState&);
 
+    void addNodeWithActiveRubberBanding(WebCore::ScrollingNodeID);
+    void removeNodeWithActiveRubberBanding(WebCore::ScrollingNodeID);
+
 private:
     RemoteScrollingCoordinator(WebPage*);
     virtual ~RemoteScrollingCoordinator();

Modified: branches/safari-611-branch/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.mm (272259 => 272260)


--- branches/safari-611-branch/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.mm	2021-02-03 01:39:57 UTC (rev 272259)
+++ branches/safari-611-branch/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.mm	2021-02-03 01:40:05 UTC (rev 272260)
@@ -125,6 +125,16 @@
         m_nodesWithActiveUserScrolls = uiState.nodesWithActiveUserScrolls();
 }
 
+void RemoteScrollingCoordinator::addNodeWithActiveRubberBanding(ScrollingNodeID nodeID)
+{
+    m_nodesWithActiveRubberBanding.add(nodeID);
+}
+
+void RemoteScrollingCoordinator::removeNodeWithActiveRubberBanding(ScrollingNodeID nodeID)
+{
+    m_nodesWithActiveRubberBanding.remove(nodeID);
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(ASYNC_SCROLLING)

Modified: branches/safari-611-branch/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (272259 => 272260)


--- branches/safari-611-branch/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm	2021-02-03 01:39:57 UTC (rev 272259)
+++ branches/safari-611-branch/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm	2021-02-03 01:40:05 UTC (rev 272260)
@@ -40,6 +40,7 @@
 #import "PluginView.h"
 #import "PrintInfo.h"
 #import "RemoteLayerTreeDrawingArea.h"
+#import "RemoteScrollingCoordinator.h"
 #import "SandboxUtilities.h"
 #import "SharedMemory.h"
 #import "SyntheticEditingCommandType.h"
@@ -3835,6 +3836,19 @@
     FloatRect adjustedExposedContentRect = adjustExposedRectForNewScale(exposedContentRect, visibleContentRectUpdateInfo.scale(), scaleToUse);
     m_drawingArea->setExposedContentRect(adjustedExposedContentRect);
 
+    auto& frame = m_page->mainFrame();
+    FrameView& frameView = *frame.view();
+
+    if (auto* scrollingCoordinator = this->scrollingCoordinator()) {
+        auto& remoteScrollingCoordinator = downcast<RemoteScrollingCoordinator>(*scrollingCoordinator);
+        if (auto mainFrameScrollingNodeID = frameView.scrollingNodeID()) {
+            if (visibleContentRectUpdateInfo.viewStability().contains(ViewStabilityFlag::ScrollViewRubberBanding))
+                remoteScrollingCoordinator.addNodeWithActiveRubberBanding(mainFrameScrollingNodeID);
+            else
+                remoteScrollingCoordinator.removeNodeWithActiveRubberBanding(mainFrameScrollingNodeID);
+        }
+    }
+
     IntPoint scrollPosition = roundedIntPoint(visibleContentRectUpdateInfo.unobscuredContentRect().location());
 
     bool pageHasBeenScaledSinceLastLayerTreeCommitThatChangedPageScale = ([&] {
@@ -3870,8 +3884,6 @@
         }
     }
 
-    auto& frame = m_page->mainFrame();
-    FrameView& frameView = *frame.view();
     if (scrollPosition != frameView.scrollPosition())
         m_dynamicSizeUpdateHistory.clear();
 
@@ -3924,9 +3936,9 @@
     if (!isChangingObscuredInsetsInteractively)
         frameView.setCustomSizeForResizeEvent(expandedIntSize(visibleContentRectUpdateInfo.unobscuredRectInScrollViewCoordinates().size()));
 
-    if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
-        ViewportRectStability viewportStability = ViewportRectStability::Stable;
-        ScrollingLayerPositionAction layerAction = ScrollingLayerPositionAction::Sync;
+    if (auto* scrollingCoordinator = this->scrollingCoordinator()) {
+        auto viewportStability = ViewportRectStability::Stable;
+        auto layerAction = ScrollingLayerPositionAction::Sync;
         
         if (isChangingObscuredInsetsInteractively) {
             viewportStability = ViewportRectStability::ChangingObscuredInsetsInteractively;

Modified: branches/safari-611-branch/Tools/ChangeLog (272259 => 272260)


--- branches/safari-611-branch/Tools/ChangeLog	2021-02-03 01:39:57 UTC (rev 272259)
+++ branches/safari-611-branch/Tools/ChangeLog	2021-02-03 01:40:05 UTC (rev 272260)
@@ -1,5 +1,147 @@
 2021-02-02  Alan Coon  <[email protected]>
 
+        Cherry-pick r271786. rdar://problem/73890368
+
+    [iOS WK2] theverge.com - rubber band scrolling at the top of the page causes an abrupt jump
+    https://bugs.webkit.org/show_bug.cgi?id=220886
+    <rdar://71177566>
+    
+    Reviewed by Sam Weinig.
+    Source/WebCore:
+    
+    theverge.com on iOS is a page that has long main thread stalls with forced layouts on a timer
+    that alter the page height; this caused the post-layout updateScrollbars() called from
+    FrameView::adjustViewSize() to call scrollToPosition() after adjusting the scroll position
+    to the allowed range.
+    
+    If the page laid out while rubberbanding was happening, the current scroll position would
+    be negative, then clamped to 0, then sent to the UI process as a requested scroll to 0,
+    triggering the jump to top in the UI process.
+    
+    There's existing code to prevent this from happening if we know that rubberbanding is
+    happening; this patch makes isRubberBandInProgress() work for iOS WK2. It does so
+    by having updateVisibleContentRects() push information about rubberbanding nodes onto
+    RemoteScrollingCoordinator.
+    
+    We remove an unnecessary shouldUpdateScrollLayerPositionSynchronously() check in
+    FrameView::isRubberBandInProgress() - if it's true, then the scrolling coordinator
+    won't see any rubberbanding nodes anyway.
+    
+    Test: fast/scrolling/ios/content-size-change-during-rubberband.html
+    
+    * page/FrameView.cpp:
+    (WebCore::FrameView::isRubberBandInProgress const):
+    * page/FrameView.h:
+    * platform/ScrollView.cpp:
+    (WebCore::ScrollView::updateScrollbars):
+    
+    Source/WebKit:
+    
+    theverge.com on iOS is a page that has long main thread stalls with forced layouts on a timer
+    that alter the page height; this caused the post-layout updateScrollbars() called from
+    FrameView::adjustViewSize() to call scrollToPosition() after adjusting the scroll position
+    to the allowed range.
+    
+    If the page laid out while rubberbanding was happening, the current scroll position would
+    be negative, then clamped to 0, then sent to the UI process as a requested scroll to 0,
+    triggering the jump to top in the UI process.
+    
+    There's existing code to prevent this from happening if we know that rubberbanding is
+    happening; this patch makes isRubberBandInProgress() work for iOS WK2. It does so
+    by having updateVisibleContentRects() push information about rubberbanding nodes onto
+    RemoteScrollingCoordinator.
+    
+    We remove an unnecessary shouldUpdateScrollLayerPositionSynchronously() check in
+    FrameView::isRubberBandInProgress() - if it's true, then the scrolling coordinator
+    won't see any rubberbanding nodes anyway.
+    
+    * UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:
+    * WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.h:
+    * WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.mm:
+    (WebKit::RemoteScrollingCoordinator::addNodeWithActiveRubberBanding):
+    (WebKit::RemoteScrollingCoordinator::removeNodeWithActiveRubberBanding):
+    * WebProcess/WebPage/ios/WebPageIOS.mm:
+    (WebKit::WebPage::updateVisibleContentRects):
+    
+    Tools:
+    
+    Add test infrastructure to allow UIScriptController::scrollToOffset() and
+    UIScriptController::immediateScrollToOffset() to take an options argument with
+    a 'unconstrained' property, which allows scrolling to unstable offset to simulate
+    rubberbanding.
+    
+    * DumpRenderTree/ios/UIScriptControllerIOS.h:
+    * DumpRenderTree/ios/UIScriptControllerIOS.mm:
+    (WTR::contentOffsetBoundedIfNecessary):
+    (WTR::UIScriptControllerIOS::scrollToOffset):
+    (WTR::UIScriptControllerIOS::immediateScrollToOffset):
+    (WTR::contentOffsetBoundedInValidRange): Deleted.
+    * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
+    * TestRunnerShared/UIScriptContext/UIScriptController.h:
+    (WTR::UIScriptController::scrollToOffset):
+    (WTR::UIScriptController::immediateScrollToOffset):
+    * TestRunnerShared/UIScriptContext/UIScriptControllerShared.cpp:
+    (WTR::toScrollToOptions):
+    * WebKitTestRunner/ios/UIScriptControllerIOS.h:
+    * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+    (WTR::contentOffsetBoundedIfNecessary):
+    (WTR::UIScriptControllerIOS::scrollToOffset):
+    (WTR::UIScriptControllerIOS::immediateScrollToOffset):
+    (WTR::contentOffsetBoundedInValidRange): Deleted.
+    
+    LayoutTests:
+    
+    Add test infrastructure to allow UIScriptController::scrollToOffset() and
+    UIScriptController::immediateScrollToOffset() to take an options argument with
+    a 'unconstrained' property, which allows scrolling to unstable offset to simulate
+    rubberbanding.
+    
+    * fast/scrolling/ios/content-size-change-during-rubberband-expected.txt: Added.
+    * fast/scrolling/ios/content-size-change-during-rubberband.html: Added.
+    * resources/ui-helper.js:
+    (window.UIHelper.scrollTo.return.new.Promise.):
+    (window.UIHelper.scrollTo.return.new.Promise):
+    (window.UIHelper.scrollTo):
+    (window.UIHelper.immediateScrollTo):
+    (window.UIHelper.immediateUnstableScrollTo):
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271786 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-01-24  Simon Fraser  <[email protected]>
+
+            [iOS WK2] theverge.com - rubber band scrolling at the top of the page causes an abrupt jump
+            https://bugs.webkit.org/show_bug.cgi?id=220886
+            <rdar://71177566>
+
+            Reviewed by Sam Weinig.
+
+            Add test infrastructure to allow UIScriptController::scrollToOffset() and
+            UIScriptController::immediateScrollToOffset() to take an options argument with
+            a 'unconstrained' property, which allows scrolling to unstable offset to simulate
+            rubberbanding.
+
+            * DumpRenderTree/ios/UIScriptControllerIOS.h:
+            * DumpRenderTree/ios/UIScriptControllerIOS.mm:
+            (WTR::contentOffsetBoundedIfNecessary):
+            (WTR::UIScriptControllerIOS::scrollToOffset):
+            (WTR::UIScriptControllerIOS::immediateScrollToOffset):
+            (WTR::contentOffsetBoundedInValidRange): Deleted.
+            * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
+            * TestRunnerShared/UIScriptContext/UIScriptController.h:
+            (WTR::UIScriptController::scrollToOffset):
+            (WTR::UIScriptController::immediateScrollToOffset):
+            * TestRunnerShared/UIScriptContext/UIScriptControllerShared.cpp:
+            (WTR::toScrollToOptions):
+            * WebKitTestRunner/ios/UIScriptControllerIOS.h:
+            * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+            (WTR::contentOffsetBoundedIfNecessary):
+            (WTR::UIScriptControllerIOS::scrollToOffset):
+            (WTR::UIScriptControllerIOS::immediateScrollToOffset):
+            (WTR::contentOffsetBoundedInValidRange): Deleted.
+
+2021-02-02  Alan Coon  <[email protected]>
+
         Cherry-pick r271770. rdar://problem/73890671
 
     REGRESSION(r266148) Cancelling a navigation in decidePolicyForNavigationAction should not suspend the previous document's font loading timer

Modified: branches/safari-611-branch/Tools/DumpRenderTree/ios/UIScriptControllerIOS.h (272259 => 272260)


--- branches/safari-611-branch/Tools/DumpRenderTree/ios/UIScriptControllerIOS.h	2021-02-03 01:39:57 UTC (rev 272259)
+++ branches/safari-611-branch/Tools/DumpRenderTree/ios/UIScriptControllerIOS.h	2021-02-03 01:40:05 UTC (rev 272260)
@@ -43,8 +43,8 @@
     double zoomScale() const override;
     double contentOffsetX() const override;
     double contentOffsetY() const override;
-    void scrollToOffset(long x, long y) override;
-    void immediateScrollToOffset(long x, long y) override;
+    void scrollToOffset(long x, long y, ScrollToOptions*) override;
+    void immediateScrollToOffset(long x, long y, ScrollToOptions*) override;
     void immediateZoomToScale(double scale) override;
     double minimumZoomScale() const override;
     double maximumZoomScale() const override;

Modified: branches/safari-611-branch/Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm (272259 => 272260)


--- branches/safari-611-branch/Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm	2021-02-03 01:39:57 UTC (rev 272259)
+++ branches/safari-611-branch/Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm	2021-02-03 01:40:05 UTC (rev 272260)
@@ -75,19 +75,24 @@
     return gWebScrollView.zoomScale;
 }
 
-static CGPoint contentOffsetBoundedInValidRange(UIScrollView *scrollView, CGPoint contentOffset)
+static CGPoint contentOffsetBoundedIfNecessary(UIScrollView *scrollView, long x, long y, ScrollToOptions* options)
 {
-    UIEdgeInsets contentInsets = scrollView.contentInset;
-    CGSize contentSize = scrollView.contentSize;
-    CGSize scrollViewSize = scrollView.bounds.size;
+    auto contentOffset = CGPointMake(x, y);
+    bool constrain = !options || !options->unconstrained;
+    if (constrain) {
+        UIEdgeInsets contentInsets = scrollView.contentInset;
+        CGSize contentSize = scrollView.contentSize;
+        CGSize scrollViewSize = scrollView.bounds.size;
 
-    CGFloat maxHorizontalOffset = contentSize.width + contentInsets.right - scrollViewSize.width;
-    contentOffset.x = std::min(maxHorizontalOffset, contentOffset.x);
-    contentOffset.x = std::max(-contentInsets.left, contentOffset.x);
+        CGFloat maxHorizontalOffset = contentSize.width + contentInsets.right - scrollViewSize.width;
+        contentOffset.x = std::min(maxHorizontalOffset, contentOffset.x);
+        contentOffset.x = std::max(-contentInsets.left, contentOffset.x);
 
-    CGFloat maxVerticalOffset = contentSize.height + contentInsets.bottom - scrollViewSize.height;
-    contentOffset.y = std::min(maxVerticalOffset, contentOffset.y);
-    contentOffset.y = std::max(-contentInsets.top, contentOffset.y);
+        CGFloat maxVerticalOffset = contentSize.height + contentInsets.bottom - scrollViewSize.height;
+        contentOffset.y = std::min(maxVerticalOffset, contentOffset.y);
+        contentOffset.y = std::max(-contentInsets.top, contentOffset.y);
+    }
+
     return contentOffset;
 }
 
@@ -101,14 +106,16 @@
     return [gWebScrollView contentOffset].y;
 }
 
-void UIScriptControllerIOS::scrollToOffset(long x, long y)
+void UIScriptControllerIOS::scrollToOffset(long x, long y, ScrollToOptions* options)
 {
-    [gWebScrollView setContentOffset:contentOffsetBoundedInValidRange(gWebScrollView, CGPointMake(x, y)) animated:YES];
+    auto offset = contentOffsetBoundedIfNecessary(gWebScrollView, x, y, options);
+    [gWebScrollView setContentOffset:offset animated:YES];
 }
 
-void UIScriptControllerIOS::immediateScrollToOffset(long x, long y)
+void UIScriptControllerIOS::immediateScrollToOffset(long x, long y, ScrollToOptions* options)
 {
-    [gWebScrollView setContentOffset:contentOffsetBoundedInValidRange(gWebScrollView, CGPointMake(x, y)) animated:NO];
+    auto offset = contentOffsetBoundedIfNecessary(gWebScrollView, x, y, options);
+    [gWebScrollView setContentOffset:offset animated:NO];
 }
 
 void UIScriptControllerIOS::immediateZoomToScale(double scale)

Modified: branches/safari-611-branch/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl (272259 => 272260)


--- branches/safari-611-branch/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl	2021-02-03 01:39:57 UTC (rev 272259)
+++ branches/safari-611-branch/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl	2021-02-03 01:40:05 UTC (rev 272260)
@@ -38,6 +38,10 @@
     "shift"
 };
 
+dictionary ScrollToOptions {
+    boolean unconstrained = false;
+};
+
 interface UIScriptController {
 
     undefined doAsyncTask(object callback); // Used to test the harness.
@@ -282,10 +286,10 @@
 
     attribute boolean scrollUpdatesDisabled; // Turns off notifications back to the web process after scrolls (used for testing scrolling tree).
 
-    undefined scrollToOffset(long x, long y); // Initiate an animated scroll in the UI process.
+    undefined scrollToOffset(long x, long y, ScrollToOptions options); // Initiate an animated scroll in the UI process.
     attribute object didEndScrollingCallback;
 
-    undefined immediateScrollToOffset(long x, long y); // Set the scroll position in the UI process without animation.
+    undefined immediateScrollToOffset(long x, long y, ScrollToOptions options); // Set the scroll position in the UI process without animation.
     undefined immediateZoomToScale(double scale); // Set the zoom scale in the UI process without animation.
 
     // Find the scroller for the given point in content ("absolute") coordinates, and do an immediate scroll.

Modified: branches/safari-611-branch/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h (272259 => 272260)


--- branches/safari-611-branch/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h	2021-02-03 01:39:57 UTC (rev 272259)
+++ branches/safari-611-branch/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h	2021-02-03 01:40:05 UTC (rev 272260)
@@ -23,8 +23,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef UIScriptController_h
-#define UIScriptController_h
+#pragma once
 
 #include "JSWrappable.h"
 #include <_javascript_Core/JSRetainPtr.h>
@@ -52,6 +51,12 @@
 
 DeviceOrientation* toDeviceOrientation(JSContextRef, JSValueRef);
 
+struct ScrollToOptions {
+    bool unconstrained { false };
+};
+
+ScrollToOptions* toScrollToOptions(JSContextRef, JSValueRef);
+
 class UIScriptController : public JSWrappable {
 public:
     static Ref<UIScriptController> create(UIScriptContext&);
@@ -133,9 +138,9 @@
     virtual bool scrollUpdatesDisabled() const { notImplemented(); return false; }
     virtual void setScrollUpdatesDisabled(bool) { notImplemented(); }
 
-    virtual void scrollToOffset(long, long) { notImplemented(); }
+    virtual void scrollToOffset(long, long, ScrollToOptions*) { notImplemented(); }
 
-    virtual void immediateScrollToOffset(long, long) { notImplemented(); }
+    virtual void immediateScrollToOffset(long, long, ScrollToOptions*) { notImplemented(); }
     virtual void immediateScrollElementAtContentPointToOffset(long, long, long, long) { notImplemented(); }
 
     virtual double contentOffsetX() const { notImplemented(); return 0; }
@@ -360,5 +365,3 @@
 };
 
 }
-
-#endif // UIScriptController_h

Modified: branches/safari-611-branch/Tools/TestRunnerShared/UIScriptContext/UIScriptControllerShared.cpp (272259 => 272260)


--- branches/safari-611-branch/Tools/TestRunnerShared/UIScriptContext/UIScriptControllerShared.cpp	2021-02-03 01:39:57 UTC (rev 272259)
+++ branches/safari-611-branch/Tools/TestRunnerShared/UIScriptContext/UIScriptControllerShared.cpp	2021-02-03 01:40:05 UTC (rev 272260)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "UIScriptController.h"
 
+#include "JSBasics.h"
 #include "JSUIScriptController.h"
 #include "UIScriptContext.h"
 #include <_javascript_Core/JSValueRef.h>
@@ -53,6 +54,16 @@
     return nullptr;
 }
 
+ScrollToOptions* toScrollToOptions(JSContextRef context, JSValueRef argument)
+{
+    if (!JSValueIsObject(context, argument))
+        return nullptr;
+
+    static ScrollToOptions options;
+    options.unconstrained = booleanProperty(context, (JSObjectRef)argument, "unconstrained", false);
+    return &options;
+}
+
 UIScriptController::UIScriptController(UIScriptContext& context)
     : m_context(&context)
 {

Modified: branches/safari-611-branch/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.h (272259 => 272260)


--- branches/safari-611-branch/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.h	2021-02-03 01:39:57 UTC (rev 272259)
+++ branches/safari-611-branch/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.h	2021-02-03 01:40:05 UTC (rev 272260)
@@ -94,8 +94,8 @@
     double contentOffsetY() const override;
     bool scrollUpdatesDisabled() const override;
     void setScrollUpdatesDisabled(bool) override;
-    void scrollToOffset(long x, long y) override;
-    void immediateScrollToOffset(long x, long y) override;
+    void scrollToOffset(long x, long y, ScrollToOptions*) override;
+    void immediateScrollToOffset(long x, long y, ScrollToOptions*) override;
     void immediateScrollElementAtContentPointToOffset(long x, long y, long xScrollOffset, long yScrollOffset) override;
     void immediateZoomToScale(double scale) override;
     void keyboardAccessoryBarNext() override;

Modified: branches/safari-611-branch/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm (272259 => 272260)


--- branches/safari-611-branch/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm	2021-02-03 01:39:57 UTC (rev 272259)
+++ branches/safari-611-branch/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm	2021-02-03 01:40:05 UTC (rev 272260)
@@ -612,19 +612,24 @@
     return !!webView().window.rootViewController.presentedViewController;
 }
 
-static CGPoint contentOffsetBoundedInValidRange(UIScrollView *scrollView, CGPoint contentOffset)
+static CGPoint contentOffsetBoundedIfNecessary(UIScrollView *scrollView, long x, long y, ScrollToOptions* options)
 {
-    UIEdgeInsets contentInsets = scrollView.contentInset;
-    CGSize contentSize = scrollView.contentSize;
-    CGSize scrollViewSize = scrollView.bounds.size;
+    auto contentOffset = CGPointMake(x, y);
+    bool constrain = !options || !options->unconstrained;
+    if (constrain) {
+        UIEdgeInsets contentInsets = scrollView.contentInset;
+        CGSize contentSize = scrollView.contentSize;
+        CGSize scrollViewSize = scrollView.bounds.size;
 
-    CGFloat maxHorizontalOffset = contentSize.width + contentInsets.right - scrollViewSize.width;
-    contentOffset.x = std::min(maxHorizontalOffset, contentOffset.x);
-    contentOffset.x = std::max(-contentInsets.left, contentOffset.x);
+        CGFloat maxHorizontalOffset = contentSize.width + contentInsets.right - scrollViewSize.width;
+        contentOffset.x = std::min(maxHorizontalOffset, contentOffset.x);
+        contentOffset.x = std::max(-contentInsets.left, contentOffset.x);
 
-    CGFloat maxVerticalOffset = contentSize.height + contentInsets.bottom - scrollViewSize.height;
-    contentOffset.y = std::min(maxVerticalOffset, contentOffset.y);
-    contentOffset.y = std::max(-contentInsets.top, contentOffset.y);
+        CGFloat maxVerticalOffset = contentSize.height + contentInsets.bottom - scrollViewSize.height;
+        contentOffset.y = std::min(maxVerticalOffset, contentOffset.y);
+        contentOffset.y = std::max(-contentInsets.top, contentOffset.y);
+    }
+
     return contentOffset;
 }
 
@@ -648,16 +653,18 @@
     webView()._scrollingUpdatesDisabledForTesting = disabled;
 }
 
-void UIScriptControllerIOS::scrollToOffset(long x, long y)
+void UIScriptControllerIOS::scrollToOffset(long x, long y, ScrollToOptions* options)
 {
     TestRunnerWKWebView *webView = this->webView();
-    [webView.scrollView setContentOffset:contentOffsetBoundedInValidRange(webView.scrollView, CGPointMake(x, y)) animated:YES];
+    auto offset = contentOffsetBoundedIfNecessary(webView.scrollView, x, y, options);
+    [webView.scrollView setContentOffset:offset animated:YES];
 }
 
-void UIScriptControllerIOS::immediateScrollToOffset(long x, long y)
+void UIScriptControllerIOS::immediateScrollToOffset(long x, long y, ScrollToOptions* options)
 {
     TestRunnerWKWebView *webView = this->webView();
-    [webView.scrollView setContentOffset:contentOffsetBoundedInValidRange(webView.scrollView, CGPointMake(x, y)) animated:NO];
+    auto offset = contentOffsetBoundedIfNecessary(webView.scrollView, x, y, options);
+    [webView.scrollView setContentOffset:offset animated:NO];
 }
 
 static UIScrollView *enclosingScrollViewIncludingSelf(UIView *view)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to