Title: [170463] trunk/Source/WebKit2
Revision
170463
Author
simon.fra...@apple.com
Date
2014-06-25 21:15:52 -0700 (Wed, 25 Jun 2014)

Log Message

[iOS WK2] Page jumps when rubber-banding on azuremagazine.com
https://bugs.webkit.org/show_bug.cgi?id=134238
<rdar://problem/16918228>

Reviewed by Benjamin Poulain.

If the scroll view is in the process of rubber-banding when -setContentSize: is called,
it clamps the scroll offsets between zero and the max value, which visibly interrupts the
rubberband. This can easily happen now that we continually send scroll events to the page
on scrolling, especially when pages like azuremagazine.com do fake sticky by toggling
in-flow elements into position:fixed.

Fix by computing the amount of rubber-band before calling -setContentSize:, and then
restoring the contentOffset with the same amount of rubber-band even when the content size
is different, for top/left rubberbands.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _didCommitLayerTree:WebKit::]):
* UIProcess/ios/WKScrollView.h:
* UIProcess/ios/WKScrollView.mm:
(-[WKScrollView _currentTopLeftRubberbandAmount]):
(-[WKScrollView _restoreContentOffsetWithRubberbandAmount:]):
(-[WKScrollView _setContentSizePreservingContentOffsetDuringRubberband:]):

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (170462 => 170463)


--- trunk/Source/WebKit2/ChangeLog	2014-06-26 04:15:50 UTC (rev 170462)
+++ trunk/Source/WebKit2/ChangeLog	2014-06-26 04:15:52 UTC (rev 170463)
@@ -1,5 +1,31 @@
 2014-06-25  Simon Fraser  <simon.fra...@apple.com>
 
+        [iOS WK2] Page jumps when rubber-banding on azuremagazine.com 
+        https://bugs.webkit.org/show_bug.cgi?id=134238
+        <rdar://problem/16918228>
+
+        Reviewed by Benjamin Poulain.
+        
+        If the scroll view is in the process of rubber-banding when -setContentSize: is called,
+        it clamps the scroll offsets between zero and the max value, which visibly interrupts the
+        rubberband. This can easily happen now that we continually send scroll events to the page
+        on scrolling, especially when pages like azuremagazine.com do fake sticky by toggling
+        in-flow elements into position:fixed.
+        
+        Fix by computing the amount of rubber-band before calling -setContentSize:, and then
+        restoring the contentOffset with the same amount of rubber-band even when the content size
+        is different, for top/left rubberbands.
+        
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _didCommitLayerTree:WebKit::]):
+        * UIProcess/ios/WKScrollView.h:
+        * UIProcess/ios/WKScrollView.mm:
+        (-[WKScrollView _currentTopLeftRubberbandAmount]):
+        (-[WKScrollView _restoreContentOffsetWithRubberbandAmount:]):
+        (-[WKScrollView _setContentSizePreservingContentOffsetDuringRubberband:]):
+
+2014-06-25  Simon Fraser  <simon.fra...@apple.com>
+
         [iOS WK2] Fixed position elements jump around when zooming
         https://bugs.webkit.org/show_bug.cgi?id=134328
         <rdar://problem/17447048>

Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm (170462 => 170463)


--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm	2014-06-26 04:15:50 UTC (rev 170462)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm	2014-06-26 04:15:52 UTC (rev 170463)
@@ -774,7 +774,9 @@
         return;
     }
 
-    [_scrollView setContentSize:roundScrollViewContentSize(*_page, [_contentView frame].size)];
+    CGSize newContentSize = roundScrollViewContentSize(*_page, [_contentView frame].size);
+    [_scrollView _setContentSizePreservingContentOffsetDuringRubberband:newContentSize];
+
     [_scrollView setMinimumZoomScale:layerTreeTransaction.minimumScaleFactor()];
     [_scrollView setMaximumZoomScale:layerTreeTransaction.maximumScaleFactor()];
     [_scrollView setZoomEnabled:layerTreeTransaction.allowsUserScaling()];

Modified: trunk/Source/WebKit2/UIProcess/ios/WKScrollView.h (170462 => 170463)


--- trunk/Source/WebKit2/UIProcess/ios/WKScrollView.h	2014-06-26 04:15:50 UTC (rev 170462)
+++ trunk/Source/WebKit2/UIProcess/ios/WKScrollView.h	2014-06-26 04:15:52 UTC (rev 170463)
@@ -33,6 +33,8 @@
 
 @property (nonatomic, assign) WKWebView <UIScrollViewDelegate> *internalDelegate;
 
+- (void)_setContentSizePreservingContentOffsetDuringRubberband:(CGSize)contentSize;
+
 @end
 
 #endif // PLATFORM(IOS)

Modified: trunk/Source/WebKit2/UIProcess/ios/WKScrollView.mm (170462 => 170463)


--- trunk/Source/WebKit2/UIProcess/ios/WKScrollView.mm	2014-06-26 04:15:50 UTC (rev 170462)
+++ trunk/Source/WebKit2/UIProcess/ios/WKScrollView.mm	2014-06-26 04:15:52 UTC (rev 170463)
@@ -198,6 +198,54 @@
     [_internalDelegate _updateVisibleContentRects];
 }
 
+// Fetch top/left rubberband amounts (as negative values).
+- (CGSize)_currentTopLeftRubberbandAmount
+{
+    UIEdgeInsets edgeInsets = [self contentInset];
+
+    CGSize rubberbandAmount = CGSizeZero;
+
+    CGPoint contentOffset = [self contentOffset];
+    if (contentOffset.x < -edgeInsets.left)
+        rubberbandAmount.width = std::min<CGFloat>(contentOffset.x + -edgeInsets.left, 0);
+
+    if (contentOffset.y < -edgeInsets.top)
+        rubberbandAmount.height = std::min<CGFloat>(contentOffset.y + edgeInsets.top, 0);
+    
+    return rubberbandAmount;
+}
+
+- (void)_restoreContentOffsetWithRubberbandAmount:(CGSize)rubberbandAmount
+{
+    UIEdgeInsets edgeInsets = [self contentInset];
+    CGPoint adjustedOffset = [self contentOffset];
+
+    if (rubberbandAmount.width < 0)
+        adjustedOffset.x = -edgeInsets.left + rubberbandAmount.width;
+
+    if (rubberbandAmount.height < 0)
+        adjustedOffset.y = -edgeInsets.top + rubberbandAmount.height;
+
+    [self setContentOffset:adjustedOffset];
+}
+
+- (void)_setContentSizePreservingContentOffsetDuringRubberband:(CGSize)contentSize
+{
+    CGSize currentContentSize = [self contentSize];
+
+    if (CGSizeEqualToSize(currentContentSize, CGSizeZero) || CGSizeEqualToSize(currentContentSize, contentSize) || self.zoomScale < self.minimumZoomScale) {
+        [self setContentSize:contentSize];
+        return;
+    }
+
+    CGSize rubberbandAmount = [self _currentTopLeftRubberbandAmount];
+
+    [self setContentSize:contentSize];
+
+    if (!CGSizeEqualToSize(rubberbandAmount, CGSizeZero))
+        [self _restoreContentOffsetWithRubberbandAmount:rubberbandAmount];
+}
+
 @end
 
 #endif // PLATFORM(IOS)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to