Diff
Modified: trunk/LayoutTests/ChangeLog (264367 => 264368)
--- trunk/LayoutTests/ChangeLog 2020-07-14 19:18:39 UTC (rev 264367)
+++ trunk/LayoutTests/ChangeLog 2020-07-14 19:27:34 UTC (rev 264368)
@@ -1,3 +1,16 @@
+2020-07-14 Simon Fraser <simon.fra...@apple.com>
+
+ Flashes of incorrect scroll position when zooming on quip
+ https://bugs.webkit.org/show_bug.cgi?id=214273
+ <rdar://problem/59385421>
+
+ Reviewed by Tim Horton.
+
+ * fast/scrolling/ios/autoscroll-input-when-very-zoomed-expected.txt: Typo fixes.
+ * fast/scrolling/ios/autoscroll-input-when-very-zoomed.html: Typo fixes.
+ * fast/scrolling/ios/programmatic-scroll-while-zoomed-expected.txt: Added.
+ * fast/scrolling/ios/programmatic-scroll-while-zoomed.html: Added.
+
2020-07-14 Jer Noble <jer.no...@apple.com>
Add support for parsing VP-style codec strings.
Modified: trunk/LayoutTests/fast/scrolling/ios/autoscroll-input-when-very-zoomed-expected.txt (264367 => 264368)
--- trunk/LayoutTests/fast/scrolling/ios/autoscroll-input-when-very-zoomed-expected.txt 2020-07-14 19:18:39 UTC (rev 264367)
+++ trunk/LayoutTests/fast/scrolling/ios/autoscroll-input-when-very-zoomed-expected.txt 2020-07-14 19:27:34 UTC (rev 264368)
@@ -1,4 +1,4 @@
-This test focuses a form, them zooms and scrolls the page. Then text is entered in the form, and we check to make sure the page has scrolled when needed to make the input visible again. On iPhone, the page should scroll on the first text input so that the input element in is visible again, but should not scroll more than once, as it should be visible after the first scroll. On iPad, the input should not scroll at all, as the iPad is larger and should not need to scroll for the input element to be visible. The test results should refelct these expectaitions.
+This test focuses a form, them zooms and scrolls the page. Then text is entered in the form, and we check to make sure the page has scrolled when needed to make the input visible again. On iPhone, the page should scroll on the first text input so that the input element in is visible again, but should not scroll more than once, as it should be visible after the first scroll. On iPad, the input should not scroll at all, as the iPad is larger and should not need to scroll for the input element to be visible. The test results should reflect these expectations.
Page has scrolled on the first input
Page has not scrolled on the second input
Modified: trunk/LayoutTests/fast/scrolling/ios/autoscroll-input-when-very-zoomed.html (264367 => 264368)
--- trunk/LayoutTests/fast/scrolling/ios/autoscroll-input-when-very-zoomed.html 2020-07-14 19:18:39 UTC (rev 264367)
+++ trunk/LayoutTests/fast/scrolling/ios/autoscroll-input-when-very-zoomed.html 2020-07-14 19:27:34 UTC (rev 264368)
@@ -34,7 +34,7 @@
var secondXOffset = window.pageXOffset;
var secondYOffset = window.pageYOffset;
- // Scrolling is not immedate, wait until the viewport has time to adjust
+ // Scrolling is not immediate, wait until the viewport has time to adjust
await Promise.all([UIHelper.ensureVisibleContentRectUpdate(), UIHelper.ensurePresentationUpdate()]);
await UIHelper.enterText("a");
@@ -84,7 +84,7 @@
the first text input so that the input element in is visible again, but should not
scroll more than once, as it should be visible after the first scroll. On iPad, the
input should not scroll at all, as the iPad is larger and should not need to scroll
-for the input element to be visible. The test results should refelct these expectaitions.
+for the input element to be visible. The test results should reflect these expectations.
<div id="testArea"><input id="editable" type="text" value="Test text"></input></div>
</body>
</html>
Added: trunk/LayoutTests/fast/scrolling/ios/programmatic-scroll-while-zoomed-expected.txt (0 => 264368)
--- trunk/LayoutTests/fast/scrolling/ios/programmatic-scroll-while-zoomed-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/scrolling/ios/programmatic-scroll-while-zoomed-expected.txt 2020-07-14 19:27:34 UTC (rev 264368)
@@ -0,0 +1,14 @@
+PASS window.pageXOffset is 53
+PASS window.pageYOffset is 91
+PASS window.visualViewport.pageLeft is 53
+PASS window.visualViewport.pageTop is 91
+
+scrolling to 0,0
+PASS window.pageXOffset is 53
+PASS window.pageYOffset is 91
+PASS window.visualViewport.pageLeft is 53
+PASS window.visualViewport.pageTop is 91
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/scrolling/ios/programmatic-scroll-while-zoomed.html (0 => 264368)
--- trunk/LayoutTests/fast/scrolling/ios/programmatic-scroll-while-zoomed.html (rev 0)
+++ trunk/LayoutTests/fast/scrolling/ios/programmatic-scroll-while-zoomed.html 2020-07-14 19:27:34 UTC (rev 264368)
@@ -0,0 +1,57 @@
+<!DOCTYPE html><!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <style>
+ body {
+ overflow: hidden;
+ }
+
+ .contents {
+ width: 100%;
+ height: 100%;
+ }
+ </style>
+ <script src=""
+ <script src=""
+ <script>
+ jsTestIsAsync = true;
+
+ async function runTest() {
+ if (!window.testRunner)
+ return;
+
+ await UIHelper.immediateZoomToScale(1.5);
+
+ shouldBe('window.pageXOffset', '53');
+ shouldBe('window.pageYOffset', '91');
+
+ shouldBe('window.visualViewport.pageLeft', '53');
+ shouldBe('window.visualViewport.pageTop', '91');
+
+ await Promise.all([UIHelper.ensureVisibleContentRectUpdate(), UIHelper.ensureStablePresentationUpdate()]);
+
+ debug('');
+ debug('scrolling to 0,0');
+ window.scrollTo(0, 0);
+
+ await Promise.all([UIHelper.ensureVisibleContentRectUpdate(), UIHelper.ensureStablePresentationUpdate()]);
+
+ shouldBe('window.pageXOffset', '53');
+ shouldBe('window.pageYOffset', '91');
+
+ shouldBe('window.visualViewport.pageLeft', '53');
+ shouldBe('window.visualViewport.pageTop', '91');
+
+ finishJSTest();
+ }
+
+ window.addEventListener('load', runTest, false);
+ </script>
+</head>
+<body>
+ <div class="contents">
+ </div>
+ <script src=""
+</body>
+</html>
Modified: trunk/Source/WebKit/ChangeLog (264367 => 264368)
--- trunk/Source/WebKit/ChangeLog 2020-07-14 19:18:39 UTC (rev 264367)
+++ trunk/Source/WebKit/ChangeLog 2020-07-14 19:27:34 UTC (rev 264368)
@@ -1,3 +1,41 @@
+2020-07-14 Simon Fraser <simon.fra...@apple.com>
+
+ Flashes of incorrect scroll position when zooming on quip
+ https://bugs.webkit.org/show_bug.cgi?id=214273
+ <rdar://problem/59385421>
+
+ Reviewed by Tim Horton.
+
+ Quip uses a non-scrollable "body { overflow:hidden }")" page, but aggressively scrolls to 0,0 if it
+ gets a scroll event and top/left are non-zero. Panning is necessarily allowed on overflow:hidden pages,
+ so to avoid programmatic scrolls yanking the content to 0,0 during interaction, ignore them if
+ the page is non-scrollable yet zoomed.
+
+ When refusing such a scroll, we have to inform the web process to avoid mismatched ui/web process state,
+ and work around the fact that WebPageProxy::updateVisibleContentRects() would bail if the update
+ appeared to be the same as the last one.
+
+ Test: fast/scrolling/ios/programmatic-scroll-while-zoomed.html
+
+ * UIProcess/API/Cocoa/WKWebViewInternal.h:
+ * UIProcess/API/ios/WKWebViewIOS.h:
+ * UIProcess/API/ios/WKWebViewIOS.mm:
+ (-[WKWebView _updateScrollViewForTransaction:]):
+ (-[WKWebView _scrollToContentScrollPosition:scrollOrigin:]):
+ (-[WKWebView _scheduleForcedVisibleContentRectUpdate]):
+ (-[WKWebView _updateVisibleContentRects]):
+ * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp:
+ (WebKit::RemoteScrollingCoordinatorProxy::hasScrollableMainFrame const):
+ (WebKit::RemoteScrollingCoordinatorProxy::hasScrollableOrZoomedMainFrame const):
+ * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h:
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/ios/WKContentView.h:
+ * UIProcess/ios/WKContentView.mm:
+ (-[WKContentView didUpdateVisibleRect:unobscuredRect:contentInsets:unobscuredRectInScrollViewCoordinates:obscuredInsets:unobscuredSafeAreaInsets:inputViewBounds:scale:minimumScale:inStableState:isChangingObscuredInsetsInteractively:enclosedInScrollableAncestorView:sendEvenIfUnchanged:]):
+ (-[WKContentView didUpdateVisibleRect:unobscuredRect:contentInsets:unobscuredRectInScrollViewCoordinates:obscuredInsets:unobscuredSafeAreaInsets:inputViewBounds:scale:minimumScale:inStableState:isChangingObscuredInsetsInteractively:enclosedInScrollableAncestorView:]): Deleted.
+ * UIProcess/ios/WebPageProxyIOS.mm:
+ (WebKit::WebPageProxy::updateVisibleContentRects):
+
2020-07-14 Kate Cheney <katherine_che...@apple.com>
[ macOS iOS ] http/tests/resourceLoadStatistics/telemetry-generation-basic-functionality-database.html is a rare flaky failure
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h (264367 => 264368)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h 2020-07-14 19:18:39 UTC (rev 264367)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h 2020-07-14 19:27:34 UTC (rev 264368)
@@ -217,6 +217,7 @@
BOOL _didDeferUpdateVisibleContentRectsForUIScrollViewDelegateCallback;
BOOL _didDeferUpdateVisibleContentRectsForAnyReason;
BOOL _didDeferUpdateVisibleContentRectsForUnstableScrollView;
+ BOOL _alwaysSendNextVisibleContentRectUpdate;
BOOL _waitingForEndAnimatedResize;
BOOL _waitingForCommitAfterAnimatedResize;
Modified: trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.h (264367 => 264368)
--- trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.h 2020-07-14 19:18:39 UTC (rev 264367)
+++ trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.h 2020-07-14 19:27:34 UTC (rev 264368)
@@ -80,6 +80,7 @@
- (void)_didInvokeUIScrollViewDelegateCallback;
- (void)_scheduleVisibleContentRectUpdate;
+- (void)_scheduleForcedVisibleContentRectUpdate;
- (void)_didCompleteAnimatedResize;
Modified: trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm (264367 => 264368)
--- trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm 2020-07-14 19:18:39 UTC (rev 264367)
+++ trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm 2020-07-14 19:27:34 UTC (rev 264368)
@@ -819,7 +819,7 @@
scrollingNeededToRevealUI = maxUnobscuredSize.width() == unobscuredContentRect.width() && maxUnobscuredSize.height() == unobscuredContentRect.height();
}
- bool scrollingEnabled = _page->scrollingCoordinatorProxy()->hasScrollableMainFrame() || hasDockedInputView || isZoomed || scrollingNeededToRevealUI;
+ bool scrollingEnabled = _page->scrollingCoordinatorProxy()->hasScrollableOrZoomedMainFrame() || hasDockedInputView || isZoomed || scrollingNeededToRevealUI;
[_scrollView _setScrollEnabledInternal:scrollingEnabled];
if (!layerTreeTransaction.scaleWasSetByUIProcess() && ![_scrollView isZooming] && ![_scrollView isZoomBouncing] && ![_scrollView _isAnimatingZoom] && [_scrollView zoomScale] != layerTreeTransaction.pageScaleFactor()) {
@@ -1098,6 +1098,12 @@
if (_commitDidRestoreScrollPosition || _dynamicViewportUpdateMode != WebKit::DynamicViewportUpdateMode::NotResizing)
return;
+ // Don't allow content to do programmatic scrolls for non-scrollable pages when zoomed.
+ if (!_page->scrollingCoordinatorProxy()->hasScrollableMainFrame() && ([_scrollView zoomScale] > [_scrollView minimumZoomScale] || [_scrollView zoomScale] < [_scrollView minimumZoomScale])) {
+ [self _scheduleForcedVisibleContentRectUpdate];
+ return;
+ }
+
WebCore::FloatPoint contentOffset = WebCore::ScrollableArea::scrollOffsetFromPosition(scrollPosition, toFloatSize(scrollOrigin));
WebCore::FloatPoint scaledOffset = contentOffset;
@@ -1806,6 +1812,12 @@
[self _scheduleVisibleContentRectUpdateAfterScrollInView:_scrollView.get()];
}
+- (void)_scheduleForcedVisibleContentRectUpdate
+{
+ _alwaysSendNextVisibleContentRectUpdate = YES;
+ [self _scheduleVisibleContentRectUpdate];
+}
+
- (BOOL)_scrollViewIsInStableState:(UIScrollView *)scrollView
{
BOOL isStableState = !([scrollView isDragging] || [scrollView isDecelerating] || [scrollView isZooming] || [scrollView _isAnimatingZoom] || [scrollView _isScrollingToTop]);
@@ -2022,7 +2034,8 @@
scale:scaleFactor minimumScale:[_scrollView minimumZoomScale]
inStableState:inStableState
isChangingObscuredInsetsInteractively:_isChangingObscuredInsetsInteractively
- enclosedInScrollableAncestorView:scrollViewCanScroll([self _scroller])];
+ enclosedInScrollableAncestorView:scrollViewCanScroll([self _scroller])
+ sendEvenIfUnchanged:_alwaysSendNextVisibleContentRectUpdate];
while (!_visibleContentRectUpdateCallbacks.isEmpty()) {
auto callback = _visibleContentRectUpdateCallbacks.takeLast();
@@ -2032,6 +2045,7 @@
if ((timeNow - _timeOfRequestForVisibleContentRectUpdate) > delayBeforeNoVisibleContentsRectsLogging)
RELEASE_LOG_IF_ALLOWED("%p -[WKWebView _updateVisibleContentRects:] finally ran %.2fs after being scheduled", self, (timeNow - _timeOfRequestForVisibleContentRectUpdate).value());
+ _alwaysSendNextVisibleContentRectUpdate = NO;
_timeOfLastVisibleContentRectUpdate = timeNow;
if (!_timeOfFirstVisibleContentRectUpdateWithPendingCommit)
_timeOfFirstVisibleContentRectUpdateWithPendingCommit = timeNow;
Modified: trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp (264367 => 264368)
--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp 2020-07-14 19:18:39 UTC (rev 264367)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp 2020-07-14 19:27:34 UTC (rev 264368)
@@ -258,6 +258,12 @@
bool RemoteScrollingCoordinatorProxy::hasScrollableMainFrame() const
{
auto* rootNode = m_scrollingTree->rootNode();
+ return rootNode && rootNode->canHaveScrollbars();
+}
+
+bool RemoteScrollingCoordinatorProxy::hasScrollableOrZoomedMainFrame() const
+{
+ auto* rootNode = m_scrollingTree->rootNode();
if (!rootNode)
return false;
Modified: trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h (264367 => 264368)
--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h 2020-07-14 19:18:39 UTC (rev 264367)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h 2020-07-14 19:27:34 UTC (rev 264368)
@@ -88,6 +88,7 @@
bool propagatesMainFrameScrolls() const { return m_propagatesMainFrameScrolls; }
bool hasFixedOrSticky() const { return m_scrollingTree->hasFixedOrSticky(); }
bool hasScrollableMainFrame() const;
+ bool hasScrollableOrZoomedMainFrame() const;
#if PLATFORM(IOS_FAMILY)
UIScrollView *scrollViewForScrollingNodeID(WebCore::ScrollingNodeID) const;
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (264367 => 264368)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2020-07-14 19:18:39 UTC (rev 264367)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2020-07-14 19:27:34 UTC (rev 264368)
@@ -718,7 +718,7 @@
void setCanShowPlaceholder(const WebCore::ElementContext&, bool);
#if ENABLE(UI_SIDE_COMPOSITING)
- void updateVisibleContentRects(const VisibleContentRectUpdateInfo&);
+ void updateVisibleContentRects(const VisibleContentRectUpdateInfo&, bool sendEvenIfUnchanged);
#endif
#if PLATFORM(IOS_FAMILY)
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentView.h (264367 => 264368)
--- trunk/Source/WebKit/UIProcess/ios/WKContentView.h 2020-07-14 19:18:39 UTC (rev 264367)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentView.h 2020-07-14 19:27:34 UTC (rev 264368)
@@ -83,7 +83,8 @@
scale:(CGFloat)scale minimumScale:(CGFloat)minimumScale
inStableState:(BOOL)isStableState
isChangingObscuredInsetsInteractively:(BOOL)isChangingObscuredInsetsInteractively
- enclosedInScrollableAncestorView:(BOOL)enclosedInScrollableAncestorView;
+ enclosedInScrollableAncestorView:(BOOL)enclosedInScrollableAncestorView
+ sendEvenIfUnchanged:(BOOL)sendEvenIfUnchanged;
- (void)didFinishScrolling;
- (void)didInterruptScrolling;
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentView.mm (264367 => 264368)
--- trunk/Source/WebKit/UIProcess/ios/WKContentView.mm 2020-07-14 19:18:39 UTC (rev 264367)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentView.mm 2020-07-14 19:27:34 UTC (rev 264368)
@@ -436,6 +436,7 @@
inStableState:(BOOL)isStableState
isChangingObscuredInsetsInteractively:(BOOL)isChangingObscuredInsetsInteractively
enclosedInScrollableAncestorView:(BOOL)enclosedInScrollableAncestorView
+ sendEvenIfUnchanged:(BOOL)sendEvenIfUnchanged
{
auto drawingArea = _page->drawingArea();
if (!drawingArea)
@@ -475,7 +476,7 @@
bool wasStableState = _page->inStableState();
- _page->updateVisibleContentRects(visibleContentRectUpdateInfo);
+ _page->updateVisibleContentRects(visibleContentRectUpdateInfo, sendEvenIfUnchanged);
auto layoutViewport = _page->unconstrainedLayoutViewportRect();
_page->adjustLayersForLayoutViewport(layoutViewport);
Modified: trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (264367 => 264368)
--- trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2020-07-14 19:18:39 UTC (rev 264367)
+++ trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2020-07-14 19:27:34 UTC (rev 264368)
@@ -210,9 +210,9 @@
m_process->send(Messages::WebPage::RequestFocusedElementInformation(callbackID), m_webPageID);
}
-void WebPageProxy::updateVisibleContentRects(const VisibleContentRectUpdateInfo& visibleContentRectUpdate)
+void WebPageProxy::updateVisibleContentRects(const VisibleContentRectUpdateInfo& visibleContentRectUpdate, bool sendEvenIfUnchanged)
{
- if (visibleContentRectUpdate == m_lastVisibleContentRectUpdate)
+ if (visibleContentRectUpdate == m_lastVisibleContentRectUpdate && !sendEvenIfUnchanged)
return;
m_lastVisibleContentRectUpdate = visibleContentRectUpdate;