[WK2 iOS] Scrolling to anchor links is broken
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 14 Apr 2014 19:49:37 +0000 (19:49 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 14 Apr 2014 19:49:37 +0000 (19:49 +0000)
https://bugs.webkit.org/show_bug.cgi?id=131618
<rdar://problem/16599144>

Source/WebCore:

Reviewed by Tim Horton.

Have ScrollingTreeScrollingNode pass RequestedScrollPosition updates
to the scrolling tree, so that the scrolling tree can have custom behavior
for them if necessary.

* page/scrolling/ScrollingTree.h:
(WebCore::ScrollingTree::scrollingTreeNodeRequestsScroll):
* page/scrolling/ScrollingTreeScrollingNode.cpp:
(WebCore::ScrollingTreeScrollingNode::updateAfterChildren):
* page/scrolling/ScrollingTreeScrollingNode.h:

Source/WebKit2:

Reviewed by Tim Horton.

The RemoteScrollingTree implements scrollingTreeNodeRequestsScroll
to get informed about requested scroll position updates, and passes
them along via the RemoteScrollingCoordinatorProxy, WebPageProxy and PageClient
to the WKWebView, which performs a scroll.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _scrollToContentOffset:WebCore::]): Scroll to content offset,
taking page scale and insets into account.
* UIProcess/API/Cocoa/WKWebViewInternal.h:
* UIProcess/CoordinatedGraphics/WebView.cpp:
(WebKit::WebView::requestScroll):
* UIProcess/CoordinatedGraphics/WebView.h:
* UIProcess/PageClient.h:
* UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp:
(WebKit::RemoteScrollingCoordinatorProxy::scrollingTreeNodeRequestsScroll):
Pass scrolls along to the WebPageProxy for the root node. We will also need
to handle programmatic scrolls for overflow soon.
* UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h:
* UIProcess/Scrolling/RemoteScrollingTree.cpp:
(WebKit::RemoteScrollingTree::scrollingTreeNodeRequestsScroll):
* UIProcess/Scrolling/RemoteScrollingTree.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::requestScroll):
* UIProcess/WebPageProxy.h:
* UIProcess/ios/PageClientImplIOS.h:
* UIProcess/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::canScrollView):
(WebKit::PageClientImpl::requestScroll):
* UIProcess/mac/PageClientImpl.mm:
(WebKit::PageClientImpl::requestScroll):

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

21 files changed:
Source/WebCore/ChangeLog
Source/WebCore/page/scrolling/ScrollingTree.h
Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp
Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h
Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit2/UIProcess/API/Cocoa/WKWebViewInternal.h
Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp
Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h
Source/WebKit2/UIProcess/CoordinatedGraphics/WebView.cpp
Source/WebKit2/UIProcess/CoordinatedGraphics/WebView.h
Source/WebKit2/UIProcess/PageClient.h
Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp
Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h
Source/WebKit2/UIProcess/Scrolling/RemoteScrollingTree.cpp
Source/WebKit2/UIProcess/Scrolling/RemoteScrollingTree.h
Source/WebKit2/UIProcess/WebPageProxy.cpp
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/ios/PageClientImplIOS.h
Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm
Source/WebKit2/UIProcess/mac/PageClientImpl.mm

index 93d0d1e..fda85af 100644 (file)
@@ -1,3 +1,21 @@
+2014-04-14  Simon Fraser  <simon.fraser@apple.com>
+
+        [WK2 iOS] Scrolling to anchor links is broken
+        https://bugs.webkit.org/show_bug.cgi?id=131618
+        <rdar://problem/16599144>
+
+        Reviewed by Tim Horton.
+
+        Have ScrollingTreeScrollingNode pass RequestedScrollPosition updates
+        to the scrolling tree, so that the scrolling tree can have custom behavior
+        for them if necessary.
+
+        * page/scrolling/ScrollingTree.h:
+        (WebCore::ScrollingTree::scrollingTreeNodeRequestsScroll):
+        * page/scrolling/ScrollingTreeScrollingNode.cpp:
+        (WebCore::ScrollingTreeScrollingNode::updateAfterChildren):
+        * page/scrolling/ScrollingTreeScrollingNode.h:
+
 2014-04-14  Brian J. Burg  <burg@cs.washington.edu>
 
         Web Replay: memoize fallback time values for document.lastModified
index aca64fd..2f47a6a 100644 (file)
@@ -75,6 +75,9 @@ public:
     // Updates FrameView/RenderLayer scrolling state and GraphicsLayers.
     virtual void scrollingTreeNodeDidScroll(ScrollingNodeID, const FloatPoint& scrollPosition, SetOrSyncScrollingLayerPosition = SyncScrollingLayerPosition) = 0;
 
+    // Called for requested scroll position updates.
+    virtual void scrollingTreeNodeRequestsScroll(ScrollingNodeID, const FloatPoint& /*scrollPosition*/, bool /*representsProgrammaticScroll*/) { }
+
     // Delegated scrolling/zooming has caused the viewport to change, so update viewport-constrained layers
     // (but don't cause scroll events to be fired).
     virtual void viewportChangedViaDelegatedScrolling(ScrollingNodeID, const WebCore::FloatRect& viewportRect, double scale);
index f841397..f5d8b3a 100644 (file)
@@ -87,6 +87,13 @@ void ScrollingTreeScrollingNode::updateBeforeChildren(const ScrollingStateNode&
         m_behaviorForFixed = state.scrollBehaviorForFixedElements();
 }
 
+void ScrollingTreeScrollingNode::updateAfterChildren(const ScrollingStateNode& stateNode)
+{
+    const ScrollingStateScrollingNode& scrollingStateNode = toScrollingStateScrollingNode(stateNode);
+    if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition))
+        scrollingTree().scrollingTreeNodeRequestsScroll(scrollingNodeID(), scrollingStateNode.requestedScrollPosition(), scrollingStateNode.requestedScrollPositionRepresentsProgrammaticScroll());
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(ASYNC_SCROLLING)
index 2c72bfd..1f1815b 100644 (file)
@@ -45,6 +45,7 @@ public:
     virtual ~ScrollingTreeScrollingNode();
 
     virtual void updateBeforeChildren(const ScrollingStateNode&) override;
+    virtual void updateAfterChildren(const ScrollingStateNode&) override;
 
     // FIXME: We should implement this when we support ScrollingTreeScrollingNodes as children.
     virtual void parentScrollPositionDidChange(const FloatRect& /*viewportRect*/, const FloatSize& /*cumulativeDelta*/) override { }
index 3e6546b..56da292 100644 (file)
@@ -1,3 +1,42 @@
+2014-04-14  Simon Fraser  <simon.fraser@apple.com>
+
+        [WK2 iOS] Scrolling to anchor links is broken
+        https://bugs.webkit.org/show_bug.cgi?id=131618
+        <rdar://problem/16599144>
+
+        Reviewed by Tim Horton.
+        
+        The RemoteScrollingTree implements scrollingTreeNodeRequestsScroll
+        to get informed about requested scroll position updates, and passes
+        them along via the RemoteScrollingCoordinatorProxy, WebPageProxy and PageClient
+        to the WKWebView, which performs a scroll.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _scrollToContentOffset:WebCore::]): Scroll to content offset,
+        taking page scale and insets into account.
+        * UIProcess/API/Cocoa/WKWebViewInternal.h:
+        * UIProcess/CoordinatedGraphics/WebView.cpp:
+        (WebKit::WebView::requestScroll):
+        * UIProcess/CoordinatedGraphics/WebView.h:
+        * UIProcess/PageClient.h:
+        * UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp:
+        (WebKit::RemoteScrollingCoordinatorProxy::scrollingTreeNodeRequestsScroll):
+        Pass scrolls along to the WebPageProxy for the root node. We will also need
+        to handle programmatic scrolls for overflow soon.
+        * UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h:
+        * UIProcess/Scrolling/RemoteScrollingTree.cpp:
+        (WebKit::RemoteScrollingTree::scrollingTreeNodeRequestsScroll):
+        * UIProcess/Scrolling/RemoteScrollingTree.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::requestScroll):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/ios/PageClientImplIOS.h:
+        * UIProcess/ios/PageClientImplIOS.mm:
+        (WebKit::PageClientImpl::canScrollView):
+        (WebKit::PageClientImpl::requestScroll):
+        * UIProcess/mac/PageClientImpl.mm:
+        (WebKit::PageClientImpl::requestScroll):
+
 2014-04-12  Antti Koivisto  <antti@apple.com>
 
         Keep secondary tile grid for zoomed-out scale
index 2ad46f7..21eb205 100644 (file)
@@ -544,6 +544,18 @@ static WebCore::FloatPoint constrainContentOffset(WebCore::FloatPoint contentOff
     return contentOffset;
 }
 
+- (void)_scrollToContentOffset:(WebCore::FloatPoint)contentOffset
+{
+    WebCore::FloatPoint scaledOffset = contentOffset;
+    CGFloat zoomScale = contentZoomScale(self);
+    scaledOffset.scale(zoomScale, zoomScale);
+
+    UIEdgeInsets inset = [_scrollView contentInset];
+    scaledOffset += WebCore::FloatSize(-inset.left, -inset.top);
+
+    [_scrollView setContentOffset:scaledOffset];
+}
+
 - (BOOL)_scrollToRect:(WebCore::FloatRect)targetRect origin:(WebCore::FloatPoint)origin minimumScrollDistance:(float)minimumScrollDistance
 {
     WebCore::FloatRect unobscuredContentRect([self _contentRectForUserInteraction]);
index 6f9d2b3..5cf91e2 100644 (file)
@@ -64,6 +64,7 @@ class WebPageProxy;
 
 - (RetainPtr<CGImageRef>)_takeViewSnapshot;
 
+- (void)_scrollToContentOffset:(WebCore::FloatPoint)contentOffset;
 - (BOOL)_scrollToRect:(WebCore::FloatRect)targetRect origin:(WebCore::FloatPoint)origin minimumScrollDistance:(float)minimumScrollDistance;
 - (BOOL)_zoomToRect:(WebCore::FloatRect)targetRect withOrigin:(WebCore::FloatPoint)origin fitEntireRect:(BOOL)fitEntireRect minimumScale:(double)minimumScale maximumScale:(double)maximumScale minimumScrollDistance:(float)minimumScrollDistance;
 - (void)_zoomOutWithOrigin:(WebCore::FloatPoint)origin;
index 91fac08..c6fc610 100644 (file)
@@ -83,6 +83,11 @@ void PageClientImpl::scrollView(const WebCore::IntRect& scrollRect, const WebCor
     setViewNeedsDisplay(scrollRect);
 }
 
+void PageClientImpl::requestScroll(const WebCore::FloatPoint&, bool)
+{
+    notImplemented();
+}
+
 WebCore::IntSize PageClientImpl::viewSize()
 {
     if (!gtk_widget_get_realized(m_viewWidget))
index 5209208..a4142fa 100644 (file)
@@ -65,6 +65,7 @@ private:
     virtual void displayView() override;
     virtual bool canScrollView() override { return false; }
     virtual void scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset) override;
+    virtual void requestScroll(const WebCore::FloatPoint& scrollPosition, bool isProgrammaticScroll) override;
     virtual WebCore::IntSize viewSize() override;
     virtual bool isViewWindowActive() override;
     virtual bool isViewFocused() override;
index e617df1..6144aba 100644 (file)
@@ -304,6 +304,11 @@ void WebView::scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntS
     setViewNeedsDisplay(scrollRect);
 }
 
+void WebView::requestScroll(const WebCore::FloatPoint&, bool)
+{
+    notImplemented();
+}
+
 WebCore::IntSize WebView::viewSize()
 {
     return roundedIntSize(dipSize());
index c441974..754fa2a 100644 (file)
@@ -131,6 +131,7 @@ protected:
 
     virtual bool canScrollView() override { return false; }
     virtual void scrollView(const WebCore::IntRect&, const WebCore::IntSize&) override;
+    virtual void requestScroll(const WebCore::FloatPoint&, bool) override;
 
     virtual WebCore::IntSize viewSize() override;
 
index fce15ac..33b6274 100644 (file)
@@ -93,6 +93,8 @@ public:
     virtual bool canScrollView() = 0;
     // Tell the view to scroll scrollRect by scrollOffset.
     virtual void scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset) = 0;
+    // Tell the view to scroll to the given position, and whether this was a programmatic scroll.
+    virtual void requestScroll(const WebCore::FloatPoint& scrollPosition, bool isProgrammaticScroll) = 0;
 
     // Return the size of the view the page is associated with.
     virtual WebCore::IntSize viewSize() = 0;
index 10a0f48..94b14ad 100644 (file)
@@ -160,6 +160,12 @@ void RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll(WebCore::Scroll
     m_webPageProxy.send(Messages::RemoteScrollingCoordinator::ScrollPositionChangedForNode(scrolledNodeID, newScrollPosition));
 }
 
+void RemoteScrollingCoordinatorProxy::scrollingTreeNodeRequestsScroll(ScrollingNodeID scrolledNodeID, const FloatPoint& scrollPosition, bool representsProgrammaticScroll)
+{
+    if (scrolledNodeID == rootScrollingNodeID())
+        m_webPageProxy.requestScroll(scrollPosition, representsProgrammaticScroll);
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(ASYNC_SCROLLING)
index 16c8d48..b73aaf1 100644 (file)
@@ -53,6 +53,7 @@ public:
     
     // Inform the web process that the scroll position changed (called from the scrolling tree)
     void scrollingTreeNodeDidScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& newScrollPosition);
+    void scrollingTreeNodeRequestsScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, bool representsProgrammaticScroll);
 
     bool isPointInNonFastScrollableRegion(const WebCore::IntPoint&) const;
 
index f8c95cb..fb0df37 100644 (file)
@@ -82,6 +82,11 @@ void RemoteScrollingTree::scrollingTreeNodeDidScroll(ScrollingNodeID nodeID, con
     m_scrollingCoordinatorProxy.scrollingTreeNodeDidScroll(nodeID, scrollPosition);
 }
 
+void RemoteScrollingTree::scrollingTreeNodeRequestsScroll(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, bool representsProgrammaticScroll)
+{
+    m_scrollingCoordinatorProxy.scrollingTreeNodeRequestsScroll(nodeID, scrollPosition, representsProgrammaticScroll);
+}
+
 PassOwnPtr<ScrollingTreeNode> RemoteScrollingTree::createNode(ScrollingNodeType nodeType, ScrollingNodeID nodeID)
 {
     switch (nodeType) {
index 51f0adf..bcd751d 100644 (file)
@@ -47,6 +47,7 @@ public:
     const RemoteScrollingCoordinatorProxy& scrollingCoordinatorProxy() const { return m_scrollingCoordinatorProxy; }
 
     virtual void scrollingTreeNodeDidScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, WebCore::SetOrSyncScrollingLayerPosition = WebCore::SyncScrollingLayerPosition) override;
+    virtual void scrollingTreeNodeRequestsScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, bool representsProgrammaticScroll) override;
 
 private:
     explicit RemoteScrollingTree(RemoteScrollingCoordinatorProxy&);
index 4aaee45..3d35139 100644 (file)
@@ -1008,6 +1008,11 @@ void WebPageProxy::scrollView(const IntRect& scrollRect, const IntSize& scrollOf
     m_pageClient.scrollView(scrollRect, scrollOffset);
 }
 
+void WebPageProxy::requestScroll(const FloatPoint& scrollPosition, bool isProgrammaticScroll)
+{
+    m_pageClient.requestScroll(scrollPosition, isProgrammaticScroll);
+}
+
 void WebPageProxy::updateViewState(ViewState::Flags flagsToUpdate)
 {
     m_viewState &= ~flagsToUpdate;
index 229a5e6..1ccdf00 100644 (file)
@@ -545,7 +545,8 @@ public:
     void setViewNeedsDisplay(const WebCore::IntRect&);
     void displayView();
     bool canScrollView();
-    void scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset);
+    void scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset); // FIXME: CoordinatedGraphics should use requestScroll().
+    void requestScroll(const WebCore::FloatPoint& scrollPosition, bool isProgrammaticScroll);
     
     void setDelegatesScrolling(bool delegatesScrolling) { m_delegatesScrolling = delegatesScrolling; }
     bool delegatesScrolling() const { return m_delegatesScrolling; }
index 6dd3910..db60692 100644 (file)
@@ -53,6 +53,7 @@ private:
     virtual void displayView() override;
     virtual bool canScrollView() override;
     virtual void scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset) override;
+    virtual void requestScroll(const WebCore::FloatPoint& scrollPosition, bool isProgrammaticScroll) override;
     virtual WebCore::IntSize viewSize() override;
     virtual bool isViewWindowActive() override;
     virtual bool isViewFocused() override;
index a408666..e912438 100644 (file)
@@ -82,15 +82,21 @@ void PageClientImpl::displayView()
     ASSERT_NOT_REACHED();
 }
 
+bool PageClientImpl::canScrollView()
+{
+    notImplemented();
+    return false;
+}
+
 void PageClientImpl::scrollView(const IntRect&, const IntSize&)
 {
     ASSERT_NOT_REACHED();
 }
 
-bool PageClientImpl::canScrollView()
+void PageClientImpl::requestScroll(const FloatPoint& scrollPosition, bool isProgrammaticScroll)
 {
-    notImplemented();
-    return false;
+    UNUSED_PARAM(isProgrammaticScroll);
+    [m_webView _scrollToContentOffset:scrollPosition];
 }
 
 IntSize PageClientImpl::viewSize()
index 19b638a..6b7b1c0 100644 (file)
@@ -170,6 +170,11 @@ void PageClientImpl::scrollView(const IntRect& scrollRect, const IntSize& scroll
     ASSERT_NOT_REACHED();
 }
 
+void PageClientImpl::requestScroll(const FloatPoint& scrollPosition, bool isProgrammaticScroll)
+{
+    ASSERT_NOT_REACHED();
+}
+
 IntSize PageClientImpl::viewSize()
 {
     return IntSize([m_wkView bounds].size);