Modified: trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm (254360 => 254361)
--- trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm 2020-01-10 19:56:50 UTC (rev 254360)
+++ trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm 2020-01-10 19:56:52 UTC (rev 254361)
@@ -722,13 +722,6 @@
return bounds;
}
-// WebCore stores the page scale factor as float instead of double. When we get a scale from WebCore,
-// we need to ignore differences that are within a small rounding error on floats.
-static inline bool areEssentiallyEqualAsFloat(float a, float b)
-{
- return WTF::areEssentiallyEqual(a, b);
-}
-
- (void)_didCommitLayerTreeDuringAnimatedResize:(const WebKit::RemoteLayerTreeTransaction&)layerTreeTransaction
{
auto updateID = layerTreeTransaction.dynamicViewportSizeUpdateID();
@@ -772,7 +765,7 @@
[[_resizeAnimationView layer] setSublayerTransform:CATransform3DMakeScale(resizeAnimationViewScale, resizeAnimationViewScale, 1)];
}
-- (void)_didCommitLayerTree:(const WebKit::RemoteLayerTreeTransaction&)layerTreeTransaction
+- (void)_trackTransactionCommit:(const WebKit::RemoteLayerTreeTransaction&)layerTreeTransaction
{
if (_didDeferUpdateVisibleContentRectsForUnstableScrollView) {
RELEASE_LOG_IF_ALLOWED("%p (pageProxyID=%llu) -[WKWebView _didCommitLayerTree:] - received a commit (%llu) while deferring visible content rect updates (_dynamicViewportUpdateMode %d, _needsResetViewStateAfterCommitLoadForMainFrame %d (wants commit %llu), sizeChangedSinceLastVisibleContentRectUpdate %d, [_scrollView isZoomBouncing] %d, _currentlyAdjustingScrollViewInsetsForKeyboard %d)",
@@ -785,24 +778,10 @@
RELEASE_LOG_IF_ALLOWED("%p (pageProxyID=%llu) -[WKWebView _didCommitLayerTree:] - finally received commit %.2fs after visible content rect update request; transactionID %llu", self, _page->identifier().toUInt64(), timeSinceFirstRequestWithPendingCommit.value(), layerTreeTransaction.transactionID().toUInt64());
_timeOfFirstVisibleContentRectUpdateWithPendingCommit = WTF::nullopt;
}
+}
- _lastTransactionID = layerTreeTransaction.transactionID();
-
- if (![self usesStandardContentView])
- return;
-
- LOG_WITH_STREAM(VisibleRects, stream << "-[WKWebView " << _page->identifier() << " _didCommitLayerTree:] transactionID " << layerTreeTransaction.transactionID() << " _dynamicViewportUpdateMode " << (int)_dynamicViewportUpdateMode);
-
- bool needUpdateVisibleContentRects = _page->updateLayoutViewportParameters(layerTreeTransaction);
-
- if (_dynamicViewportUpdateMode != WebKit::DynamicViewportUpdateMode::NotResizing) {
- [self _didCommitLayerTreeDuringAnimatedResize:layerTreeTransaction];
- return;
- }
-
- if (_resizeAnimationView)
- RELEASE_LOG_IF_ALLOWED("%p -[WKWebView _didCommitLayerTree:] - dynamicViewportUpdateMode is NotResizing, but still have a live resizeAnimationView (unpaired begin/endAnimatedResize?)", self);
-
+- (void)_updateScrollViewForTransaction:(const WebKit::RemoteLayerTreeTransaction&)layerTreeTransaction
+{
CGSize newContentSize = roundScrollViewContentSize(*_page, [_contentView frame].size);
[_scrollView _setContentSizePreservingContentOffsetDuringRubberband:newContentSize];
@@ -809,7 +788,7 @@
[_scrollView setMinimumZoomScale:layerTreeTransaction.minimumScaleFactor()];
[_scrollView setMaximumZoomScale:layerTreeTransaction.maximumScaleFactor()];
[_scrollView _setZoomEnabledInternal:layerTreeTransaction.allowsUserScaling()];
-#if ENABLE(ASYNC_SCROLLING)
+
bool hasDockedInputView = !CGRectIsEmpty(_inputViewBounds);
bool isZoomed = layerTreeTransaction.pageScaleFactor() > layerTreeTransaction.initialScaleFactor();
@@ -822,16 +801,89 @@
bool scrollingEnabled = _page->scrollingCoordinatorProxy()->hasScrollableMainFrame() || hasDockedInputView || isZoomed || scrollingNeededToRevealUI;
[_scrollView _setScrollEnabledInternal:scrollingEnabled];
-#endif
+
if (!layerTreeTransaction.scaleWasSetByUIProcess() && ![_scrollView isZooming] && ![_scrollView isZoomBouncing] && ![_scrollView _isAnimatingZoom] && [_scrollView zoomScale] != layerTreeTransaction.pageScaleFactor()) {
LOG_WITH_STREAM(VisibleRects, stream << " updating scroll view with pageScaleFactor " << layerTreeTransaction.pageScaleFactor());
[_scrollView setZoomScale:layerTreeTransaction.pageScaleFactor()];
}
+}
+- (BOOL)_restoreScrollAndZoomStateForTransaction:(const WebKit::RemoteLayerTreeTransaction&)layerTreeTransaction
+{
+ if (!_firstTransactionIDAfterPageRestore || layerTreeTransaction.transactionID() < _firstTransactionIDAfterPageRestore.value())
+ return NO;
+
+ _firstTransactionIDAfterPageRestore = WTF::nullopt;
+
+ BOOL needUpdateVisibleContentRects = NO;
+
+ if (_scrollOffsetToRestore) {
+ WebCore::FloatPoint scaledScrollOffset = _scrollOffsetToRestore.value();
+ _scrollOffsetToRestore = WTF::nullopt;
+
+ if (WTF::areEssentiallyEqual<float>(contentZoomScale(self), _scaleToRestore)) {
+ scaledScrollOffset.scale(_scaleToRestore);
+ WebCore::FloatPoint contentOffsetInScrollViewCoordinates = scaledScrollOffset - WebCore::FloatSize(_obscuredInsetsWhenSaved.left(), _obscuredInsetsWhenSaved.top());
+
+ changeContentOffsetBoundedInValidRange(_scrollView.get(), contentOffsetInScrollViewCoordinates);
+ _commitDidRestoreScrollPosition = YES;
+ }
+
+ needUpdateVisibleContentRects = YES;
+ }
+
+ if (_unobscuredCenterToRestore) {
+ WebCore::FloatPoint unobscuredCenterToRestore = _unobscuredCenterToRestore.value();
+ _unobscuredCenterToRestore = WTF::nullopt;
+
+ if (WTF::areEssentiallyEqual<float>(contentZoomScale(self), _scaleToRestore)) {
+ CGRect unobscuredRect = UIEdgeInsetsInsetRect(self.bounds, _obscuredInsets);
+ WebCore::FloatSize unobscuredContentSizeAtNewScale = WebCore::FloatSize(unobscuredRect.size) / _scaleToRestore;
+ WebCore::FloatPoint topLeftInDocumentCoordinates = unobscuredCenterToRestore - unobscuredContentSizeAtNewScale / 2;
+
+ topLeftInDocumentCoordinates.scale(_scaleToRestore);
+ topLeftInDocumentCoordinates.moveBy(WebCore::FloatPoint(-_obscuredInsets.left, -_obscuredInsets.top));
+
+ changeContentOffsetBoundedInValidRange(_scrollView.get(), topLeftInDocumentCoordinates);
+ }
+
+ needUpdateVisibleContentRects = YES;
+ }
+
+ if (_gestureController)
+ _gestureController->didRestoreScrollPosition();
+
+ return needUpdateVisibleContentRects;
+}
+
+- (void)_didCommitLayerTree:(const WebKit::RemoteLayerTreeTransaction&)layerTreeTransaction
+{
+ [self _trackTransactionCommit:layerTreeTransaction];
+
+ _lastTransactionID = layerTreeTransaction.transactionID();
+
+ if (![self usesStandardContentView])
+ return;
+
+ LOG_WITH_STREAM(VisibleRects, stream << "-[WKWebView " << _page->identifier() << " _didCommitLayerTree:] transactionID " << layerTreeTransaction.transactionID() << " _dynamicViewportUpdateMode " << (int)_dynamicViewportUpdateMode);
+
+ bool needUpdateVisibleContentRects = _page->updateLayoutViewportParameters(layerTreeTransaction);
+
+ if (_dynamicViewportUpdateMode != WebKit::DynamicViewportUpdateMode::NotResizing) {
+ [self _didCommitLayerTreeDuringAnimatedResize:layerTreeTransaction];
+ return;
+ }
+
+ if (_resizeAnimationView)
+ RELEASE_LOG_IF_ALLOWED("%p -[WKWebView _didCommitLayerTree:] - dynamicViewportUpdateMode is NotResizing, but still have a live resizeAnimationView (unpaired begin/endAnimatedResize?)", self);
+
+ [self _updateScrollViewForTransaction:layerTreeTransaction];
+
_viewportMetaTagWidth = layerTreeTransaction.viewportMetaTagWidth();
_viewportMetaTagWidthWasExplicit = layerTreeTransaction.viewportMetaTagWidthWasExplicit();
_viewportMetaTagCameFromImageDocument = layerTreeTransaction.viewportMetaTagCameFromImageDocument();
_initialScaleFactor = layerTreeTransaction.initialScaleFactor();
+
if (_page->inStableState() && layerTreeTransaction.isInStableState() && [_stableStatePresentationUpdateCallbacks count]) {
for (dispatch_block_t action in _stableStatePresentationUpdateCallbacks.get())
action();
@@ -858,46 +910,9 @@
needUpdateVisibleContentRects = true;
}
- if (_firstTransactionIDAfterPageRestore && layerTreeTransaction.transactionID() >= _firstTransactionIDAfterPageRestore.value()) {
- if (_scrollOffsetToRestore) {
- WebCore::FloatPoint scaledScrollOffset = _scrollOffsetToRestore.value();
- _scrollOffsetToRestore = WTF::nullopt;
+ if ([self _restoreScrollAndZoomStateForTransaction:layerTreeTransaction])
+ needUpdateVisibleContentRects = true;
- if (areEssentiallyEqualAsFloat(contentZoomScale(self), _scaleToRestore)) {
- scaledScrollOffset.scale(_scaleToRestore);
- WebCore::FloatPoint contentOffsetInScrollViewCoordinates = scaledScrollOffset - WebCore::FloatSize(_obscuredInsetsWhenSaved.left(), _obscuredInsetsWhenSaved.top());
-
- changeContentOffsetBoundedInValidRange(_scrollView.get(), contentOffsetInScrollViewCoordinates);
- _commitDidRestoreScrollPosition = YES;
- }
-
- needUpdateVisibleContentRects = true;
- }
-
- if (_unobscuredCenterToRestore) {
- WebCore::FloatPoint unobscuredCenterToRestore = _unobscuredCenterToRestore.value();
- _unobscuredCenterToRestore = WTF::nullopt;
-
- if (areEssentiallyEqualAsFloat(contentZoomScale(self), _scaleToRestore)) {
- CGRect unobscuredRect = UIEdgeInsetsInsetRect(self.bounds, _obscuredInsets);
- WebCore::FloatSize unobscuredContentSizeAtNewScale = WebCore::FloatSize(unobscuredRect.size) / _scaleToRestore;
- WebCore::FloatPoint topLeftInDocumentCoordinates = unobscuredCenterToRestore - unobscuredContentSizeAtNewScale / 2;
-
- topLeftInDocumentCoordinates.scale(_scaleToRestore);
- topLeftInDocumentCoordinates.moveBy(WebCore::FloatPoint(-_obscuredInsets.left, -_obscuredInsets.top));
-
- changeContentOffsetBoundedInValidRange(_scrollView.get(), topLeftInDocumentCoordinates);
- }
-
- needUpdateVisibleContentRects = true;
- }
-
- if (_gestureController)
- _gestureController->didRestoreScrollPosition();
-
- _firstTransactionIDAfterPageRestore = WTF::nullopt;
- }
-
if (needUpdateVisibleContentRects)
[self _scheduleVisibleContentRectUpdate];
@@ -1422,7 +1437,7 @@
// At this point, we have a page that asked for width = device-width. However,
// if the content's width and height were large, we might have had to shrink it.
// We'll enable double tap zoom whenever we're not at the actual initial scale.
- return !areEssentiallyEqualAsFloat(contentZoomScale(self), _initialScaleFactor);
+ return !WTF::areEssentiallyEqual<float>(contentZoomScale(self), _initialScaleFactor);
}
- (BOOL)_stylusTapGestureShouldCreateEditableImage
@@ -1884,6 +1899,32 @@
return extendedBounds;
}
+- (UIEdgeInsets)currentlyVisibleContentInsetsWithScale:(CGFloat)scaleFactor obscuredInsets:(UIEdgeInsets)obscuredInsets
+{
+ // The following logic computes the extent to which the bottom, top, left and right content insets are visible.
+ auto scrollViewInsets = [_scrollView contentInset];
+ auto scrollViewBounds = [_scrollView bounds];
+ auto scrollViewContentSize = [_scrollView contentSize];
+ auto scrollViewOriginIncludingInset = UIEdgeInsetsInsetRect(scrollViewBounds, obscuredInsets).origin;
+ auto maximumVerticalScrollExtentWithoutRevealingBottomContentInset = scrollViewContentSize.height - CGRectGetHeight(scrollViewBounds);
+ auto maximumHorizontalScrollExtentWithoutRevealingRightContentInset = scrollViewContentSize.width - CGRectGetWidth(scrollViewBounds);
+ auto contentInsets = UIEdgeInsetsZero;
+
+ if (scrollViewInsets.left > 0 && scrollViewOriginIncludingInset.x < 0)
+ contentInsets.left = std::min(-scrollViewOriginIncludingInset.x, scrollViewInsets.left) / scaleFactor;
+
+ if (scrollViewInsets.top > 0 && scrollViewOriginIncludingInset.y < 0)
+ contentInsets.top = std::min(-scrollViewOriginIncludingInset.y, scrollViewInsets.top) / scaleFactor;
+
+ if (scrollViewInsets.right > 0 && scrollViewOriginIncludingInset.x > maximumHorizontalScrollExtentWithoutRevealingRightContentInset)
+ contentInsets.right = std::min(scrollViewOriginIncludingInset.x - maximumHorizontalScrollExtentWithoutRevealingRightContentInset, scrollViewInsets.right) / scaleFactor;
+
+ if (scrollViewInsets.bottom > 0 && scrollViewOriginIncludingInset.y > maximumVerticalScrollExtentWithoutRevealingBottomContentInset)
+ contentInsets.bottom = std::min(scrollViewOriginIncludingInset.y - maximumVerticalScrollExtentWithoutRevealingBottomContentInset, scrollViewInsets.bottom) / scaleFactor;
+
+ return contentInsets;
+}
+
- (void)_updateVisibleContentRects
{
BOOL inStableState = _visibleContentRectUpdateScheduledFromScrollViewInStableState;
@@ -1935,31 +1976,12 @@
computedContentInsetUnadjustedForKeyboard.bottom -= _totalScrollViewBottomInsetAdjustmentForKeyboard;
CGFloat scaleFactor = contentZoomScale(self);
-
CGRect unobscuredRect = UIEdgeInsetsInsetRect(self.bounds, computedContentInsetUnadjustedForKeyboard);
CGRect unobscuredRectInContentCoordinates = _frozenUnobscuredContentRect ? _frozenUnobscuredContentRect.value() : [self convertRect:unobscuredRect toView:_contentView.get()];
unobscuredRectInContentCoordinates = CGRectIntersection(unobscuredRectInContentCoordinates, [self _contentBoundsExtendedForRubberbandingWithScale:scaleFactor]);
- // The following logic computes the extent to which the bottom, top, left and right content insets are visible.
- auto scrollViewInsets = [_scrollView contentInset];
- auto scrollViewBounds = [_scrollView bounds];
- auto scrollViewContentSize = [_scrollView contentSize];
- auto scrollViewOriginIncludingInset = UIEdgeInsetsInsetRect(scrollViewBounds, computedContentInsetUnadjustedForKeyboard).origin;
- auto maximumVerticalScrollExtentWithoutRevealingBottomContentInset = scrollViewContentSize.height - CGRectGetHeight(scrollViewBounds);
- auto maximumHorizontalScrollExtentWithoutRevealingRightContentInset = scrollViewContentSize.width - CGRectGetWidth(scrollViewBounds);
- auto contentInsets = UIEdgeInsetsZero;
- if (scrollViewInsets.left > 0 && scrollViewOriginIncludingInset.x < 0)
- contentInsets.left = std::min(-scrollViewOriginIncludingInset.x, scrollViewInsets.left) / scaleFactor;
+ auto contentInsets = [self currentlyVisibleContentInsetsWithScale:scaleFactor obscuredInsets:computedContentInsetUnadjustedForKeyboard];
- if (scrollViewInsets.top > 0 && scrollViewOriginIncludingInset.y < 0)
- contentInsets.top = std::min(-scrollViewOriginIncludingInset.y, scrollViewInsets.top) / scaleFactor;
-
- if (scrollViewInsets.right > 0 && scrollViewOriginIncludingInset.x > maximumHorizontalScrollExtentWithoutRevealingRightContentInset)
- contentInsets.right = std::min(scrollViewOriginIncludingInset.x - maximumHorizontalScrollExtentWithoutRevealingRightContentInset, scrollViewInsets.right) / scaleFactor;
-
- if (scrollViewInsets.bottom > 0 && scrollViewOriginIncludingInset.y > maximumVerticalScrollExtentWithoutRevealingBottomContentInset)
- contentInsets.bottom = std::min(scrollViewOriginIncludingInset.y - maximumVerticalScrollExtentWithoutRevealingBottomContentInset, scrollViewInsets.bottom) / scaleFactor;
-
#if ENABLE(CSS_SCROLL_SNAP) && ENABLE(ASYNC_SCROLLING)
if (inStableState) {
WebKit::RemoteScrollingCoordinatorProxy* coordinator = _page->scrollingCoordinatorProxy();