Title: [171219] trunk/Source/WebKit2
Revision
171219
Author
[email protected]
Date
2014-07-18 06:41:06 -0700 (Fri, 18 Jul 2014)

Log Message

[WK2] Provide a mechanism to grab the back-forward list for gesture navigation purposes from another WKWebView
https://bugs.webkit.org/show_bug.cgi?id=134999
<rdar://problem/17238025>

Reviewed by Sam Weinig.

In some cases, clients may need to throw a WKWebView with no back-forward list over
another WKWebView, and want to participate in gesture swipe as if they were actually
the page being overlaid.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView setAllowsBackForwardNavigationGestures:]):
* UIProcess/API/Cocoa/WKWebViewConfiguration.mm:
(-[WKWebViewConfiguration copyWithZone:]):
(-[WKWebViewConfiguration _alternateWebViewForNavigationGestures]):
(-[WKWebViewConfiguration _setAlternateWebViewForNavigationGestures:]):
* UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h:
Keep an "alternate" WKWebView "for navigation gestures", which ViewGestureController
will use as the real source of back-forward items, and the destination of the swipe navigation.
All swipe delegate callbacks will also fire from the alternate view, because it owns the items
and will be doing the navigation.

* UIProcess/ios/ViewGestureControllerIOS.mm:
(WebKit::ViewGestureController::setAlternateBackForwardListSourceView):
(WebKit::ViewGestureController::beginSwipeGesture):
Send navigationGestureDidBegin via the alternate view's WebPageProxy if it exists.
Record a new snapshot on the current page, but copy it to the alternate view if necessary,
so that when swiping forward from the alternate view, it will have the "right" snapshot.
Get the target back forward item from the alternate view.
Send navigationGestureWillEnd via the alternate view's WebPageProxy if it exists.

(WebKit::ViewGestureController::canSwipeInDirection):
Determine if we can swipe in a direction by looking at the alternate view's back-forward list if necessary.

(WebKit::ViewGestureController::endSwipeGesture):
Send navigationGestureDidEnd via the alternate view's WebPageProxy if it exists.
Perform the navigation on the alternate view if necessary.

(WebKit::ViewGestureController::removeSwipeSnapshot):
Send navigationGestureSnapshotWasRemoved via the alternate view's WebPageProxy if it exists.

* UIProcess/mac/ViewGestureController.h:

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (171218 => 171219)


--- trunk/Source/WebKit2/ChangeLog	2014-07-18 09:50:01 UTC (rev 171218)
+++ trunk/Source/WebKit2/ChangeLog	2014-07-18 13:41:06 UTC (rev 171219)
@@ -1,3 +1,48 @@
+2014-07-18  Tim Horton  <[email protected]>
+
+        [WK2] Provide a mechanism to grab the back-forward list for gesture navigation purposes from another WKWebView
+        https://bugs.webkit.org/show_bug.cgi?id=134999
+        <rdar://problem/17238025>
+
+        Reviewed by Sam Weinig.
+
+        In some cases, clients may need to throw a WKWebView with no back-forward list over
+        another WKWebView, and want to participate in gesture swipe as if they were actually
+        the page being overlaid.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView setAllowsBackForwardNavigationGestures:]):
+        * UIProcess/API/Cocoa/WKWebViewConfiguration.mm:
+        (-[WKWebViewConfiguration copyWithZone:]):
+        (-[WKWebViewConfiguration _alternateWebViewForNavigationGestures]):
+        (-[WKWebViewConfiguration _setAlternateWebViewForNavigationGestures:]):
+        * UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h:
+        Keep an "alternate" WKWebView "for navigation gestures", which ViewGestureController
+        will use as the real source of back-forward items, and the destination of the swipe navigation.
+        All swipe delegate callbacks will also fire from the alternate view, because it owns the items
+        and will be doing the navigation.
+
+        * UIProcess/ios/ViewGestureControllerIOS.mm:
+        (WebKit::ViewGestureController::setAlternateBackForwardListSourceView):
+        (WebKit::ViewGestureController::beginSwipeGesture):
+        Send navigationGestureDidBegin via the alternate view's WebPageProxy if it exists.
+        Record a new snapshot on the current page, but copy it to the alternate view if necessary,
+        so that when swiping forward from the alternate view, it will have the "right" snapshot.
+        Get the target back forward item from the alternate view.
+        Send navigationGestureWillEnd via the alternate view's WebPageProxy if it exists.
+
+        (WebKit::ViewGestureController::canSwipeInDirection):
+        Determine if we can swipe in a direction by looking at the alternate view's back-forward list if necessary.
+
+        (WebKit::ViewGestureController::endSwipeGesture):
+        Send navigationGestureDidEnd via the alternate view's WebPageProxy if it exists.
+        Perform the navigation on the alternate view if necessary.
+
+        (WebKit::ViewGestureController::removeSwipeSnapshot):
+        Send navigationGestureSnapshotWasRemoved via the alternate view's WebPageProxy if it exists.
+
+        * UIProcess/mac/ViewGestureController.h:
+
 2014-07-17  David Kilzer  <[email protected]>
 
         SECTORDER_FLAGS should be defined in target's xcconfig file, not Base.xcconfig

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


--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm	2014-07-18 09:50:01 UTC (rev 171218)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm	2014-07-18 13:41:06 UTC (rev 171219)
@@ -1481,6 +1481,7 @@
         if (!_gestureController) {
             _gestureController = std::make_unique<WebKit::ViewGestureController>(*_page);
             _gestureController->installSwipeHandler(self, [self scrollView]);
+            _gestureController->setAlternateBackForwardListSourceView([_configuration _alternateWebViewForNavigationGestures]);
         }
     } else
         _gestureController = nullptr;

Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewConfiguration.mm (171218 => 171219)


--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewConfiguration.mm	2014-07-18 09:50:01 UTC (rev 171218)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewConfiguration.mm	2014-07-18 13:41:06 UTC (rev 171219)
@@ -73,6 +73,7 @@
     LazyInitialized<_WKVisitedLinkProvider> _visitedLinkProvider;
     LazyInitialized<_WKWebsiteDataStore> _websiteDataStore;
     WebKit::WeakObjCPtr<WKWebView> _relatedWebView;
+    WebKit::WeakObjCPtr<WKWebView> _alternateWebViewForNavigationGestures;
     RetainPtr<NSString> _groupIdentifier;
 #if PLATFORM(IOS)
     LazyInitialized<WKWebViewContentProviderRegistry> _contentProviderRegistry;
@@ -107,6 +108,7 @@
     configuration._visitedLinkProvider = self._visitedLinkProvider;
     configuration._websiteDataStore = self._websiteDataStore;
     configuration._relatedWebView = _relatedWebView.get().get();
+    configuration._alternateWebViewForNavigationGestures = _alternateWebViewForNavigationGestures.get().get();
 #if PLATFORM(IOS)
     configuration._contentProviderRegistry = self._contentProviderRegistry;
 #endif
@@ -221,6 +223,16 @@
     _relatedWebView = relatedWebView;
 }
 
+- (WKWebView *)_alternateWebViewForNavigationGestures
+{
+    return _alternateWebViewForNavigationGestures.getAutoreleased();
+}
+
+- (void)_setAlternateWebViewForNavigationGestures:(WKWebView *)alternateView
+{
+    _alternateWebViewForNavigationGestures = alternateView;
+}
+
 - (NSString *)_groupIdentifier
 {
     return _groupIdentifier.get();

Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h (171218 => 171219)


--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h	2014-07-18 09:50:01 UTC (rev 171218)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h	2014-07-18 13:41:06 UTC (rev 171219)
@@ -40,6 +40,8 @@
 
 @property (nonatomic, strong, setter=_setWebsiteDataStore:) _WKWebsiteDataStore *_websiteDataStore;
 
+@property (nonatomic, weak, setter=_setAlternateWebViewForNavigationGestures:) WKWebView *_alternateWebViewForNavigationGestures;
+
 @end
 
 #endif

Modified: trunk/Source/WebKit2/UIProcess/ios/ViewGestureControllerIOS.mm (171218 => 171219)


--- trunk/Source/WebKit2/UIProcess/ios/ViewGestureControllerIOS.mm	2014-07-18 09:50:01 UTC (rev 171218)
+++ trunk/Source/WebKit2/UIProcess/ios/ViewGestureControllerIOS.mm	2014-07-18 13:41:06 UTC (rev 171219)
@@ -31,6 +31,8 @@
 #import "ViewGestureControllerMessages.h"
 #import "ViewGestureGeometryCollectorMessages.h"
 #import "ViewSnapshotStore.h"
+#import "WKBackForwardListItemInternal.h"
+#import "WKWebViewInternal.h"
 #import "WebBackForwardList.h"
 #import "WebPageGroup.h"
 #import "WebPageMessages.h"
@@ -146,6 +148,11 @@
     viewGestureControllersForAllPages().remove(m_webPageProxy.pageID());
 }
 
+void ViewGestureController::setAlternateBackForwardListSourceView(WKWebView *view)
+{
+    m_alternateBackForwardListSourceView = view;
+}
+
 void ViewGestureController::installSwipeHandler(UIView *gestureRecognizerView, UIView *swipingView)
 {
     ASSERT(!m_swipeInteractiveTransitionDelegate);
@@ -158,12 +165,21 @@
     if (m_activeGestureType != ViewGestureType::None)
         return;
 
-    m_webPageProxy.navigationGestureDidBegin();
+    m_webPageProxyForBackForwardListForCurrentSwipe = m_alternateBackForwardListSourceView.get() ? m_alternateBackForwardListSourceView.get()->_page : &m_webPageProxy;
 
-    ViewSnapshotStore::shared().recordSnapshot(m_webPageProxy);
+    m_webPageProxyForBackForwardListForCurrentSwipe->navigationGestureDidBegin();
 
-    WebKit::WebBackForwardListItem* targetItem = direction == SwipeDirection::Left ? m_webPageProxy.backForwardList().backItem() : m_webPageProxy.backForwardList().forwardItem();
+    m_webPageProxy.recordNavigationSnapshot();
 
+    auto backForwardList = m_webPageProxyForBackForwardListForCurrentSwipe->backForwardList();
+
+    // Copy the snapshot from this view to the one that owns the back forward list, so that
+    // swiping forward will have the correct snapshot.
+    if (m_webPageProxyForBackForwardListForCurrentSwipe != &m_webPageProxy)
+        backForwardList.currentItem()->setSnapshot(m_webPageProxy.backForwardList().currentItem()->snapshot());
+
+    WebBackForwardListItem* targetItem = direction == SwipeDirection::Left ? backForwardList.backItem() : backForwardList.forwardItem();
+
     CGRect liveSwipeViewFrame = [m_liveSwipeView frame];
 
     RetainPtr<UIViewController> snapshotViewController = adoptNS([[UIViewController alloc] init]);
@@ -213,7 +229,7 @@
     [transitionContext _setTransitionIsInFlight:YES];
     [transitionContext _setInteractiveUpdateHandler:^(BOOL finish, CGFloat percent, BOOL transitionCompleted, _UIViewControllerTransitionContext *) {
         if (finish)
-            m_webPageProxy.navigationGestureWillEnd(transitionCompleted, *targetItem);
+            m_webPageProxyForBackForwardListForCurrentSwipe->navigationGestureWillEnd(transitionCompleted, *targetItem);
     }];
     [transitionContext _setCompletionHandler:^(_UIViewControllerTransitionContext *context, BOOL didComplete) { endSwipeGesture(targetItem, context, !didComplete); }];
     [transitionContext _setInteractiveUpdateHandler:^(BOOL, CGFloat, BOOL, _UIViewControllerTransitionContext *) { }];
@@ -226,9 +242,10 @@
 
 bool ViewGestureController::canSwipeInDirection(SwipeDirection direction)
 {
+    auto backForwardList = m_alternateBackForwardListSourceView.get() ? m_alternateBackForwardListSourceView.get()->_page->backForwardList() : m_webPageProxy.backForwardList();
     if (direction == SwipeDirection::Left)
-        return !!m_webPageProxy.backForwardList().backItem();
-    return !!m_webPageProxy.backForwardList().forwardItem();
+        return !!backForwardList.backItem();
+    return !!backForwardList.forwardItem();
 }
 
 void ViewGestureController::endSwipeGesture(WebBackForwardListItem* targetItem, _UIViewControllerTransitionContext *context, bool cancelled)
@@ -243,10 +260,12 @@
     m_liveSwipeViewClippingView = nullptr;
     [m_transitionContainerView removeFromSuperview];
     m_transitionContainerView = nullptr;
-    
+
     if (cancelled) {
+        // removeSwipeSnapshot will clear m_webPageProxyForBackForwardListForCurrentSwipe, so hold on to it here.
+        RefPtr<WebPageProxy> webPageProxyForBackForwardListForCurrentSwipe = m_webPageProxyForBackForwardListForCurrentSwipe;
         removeSwipeSnapshot();
-        m_webPageProxy.navigationGestureDidEnd(false, *targetItem);
+        webPageProxyForBackForwardListForCurrentSwipe->navigationGestureDidEnd(false, *targetItem);
         return;
     }
 
@@ -259,8 +278,9 @@
     // displaying the destination item's snapshot.
     ViewSnapshotStore::shared().disableSnapshotting();
 
-    m_webPageProxy.navigationGestureDidEnd(true, *targetItem);
-    m_webPageProxy.goToBackForwardItem(targetItem);
+    m_webPageProxyForBackForwardListForCurrentSwipe->navigationGestureDidEnd(true, *targetItem);
+    m_webPageProxyForBackForwardListForCurrentSwipe->goToBackForwardItem(targetItem);
+
     ViewSnapshotStore::shared().enableSnapshotting();
 
     uint64_t pageID = m_webPageProxy.pageID();
@@ -324,7 +344,8 @@
     m_snapshotRemovalTargetRenderTreeSize = 0;
     m_activeGestureType = ViewGestureType::None;
 
-    m_webPageProxy.navigationGestureSnapshotWasRemoved();
+    m_webPageProxyForBackForwardListForCurrentSwipe->navigationGestureSnapshotWasRemoved();
+    m_webPageProxyForBackForwardListForCurrentSwipe = nullptr;
 }
 
 } // namespace WebKit

Modified: trunk/Source/WebKit2/UIProcess/mac/ViewGestureController.h (171218 => 171219)


--- trunk/Source/WebKit2/UIProcess/mac/ViewGestureController.h	2014-07-18 09:50:01 UTC (rev 171218)
+++ trunk/Source/WebKit2/UIProcess/mac/ViewGestureController.h	2014-07-18 13:41:06 UTC (rev 171219)
@@ -27,6 +27,7 @@
 #define ViewGestureController_h
 
 #include "MessageReceiver.h"
+#include "WeakObjCPtr.h"
 #include <WebCore/FloatRect.h>
 #include <WebCore/Timer.h>
 #include <wtf/RetainPtr.h>
@@ -36,6 +37,7 @@
 #if PLATFORM(IOS)
 OBJC_CLASS UIView;
 OBJC_CLASS WKSwipeTransitionController;
+OBJC_CLASS WKWebView;
 OBJC_CLASS _UIViewControllerTransitionContext;
 OBJC_CLASS _UINavigationInteractiveTransitionBase;
 #else
@@ -104,6 +106,7 @@
     void setShouldIgnorePinnedState(bool ignore) { m_shouldIgnorePinnedState = ignore; }
 #else
     void installSwipeHandler(UIView *gestureRecognizerView, UIView *swipingView);
+    void setAlternateBackForwardListSourceView(WKWebView *);
     bool canSwipeInDirection(SwipeDirection);
     void beginSwipeGesture(_UINavigationInteractiveTransitionBase *, SwipeDirection);
     void endSwipeGesture(WebBackForwardListItem* targetItem, _UIViewControllerTransitionContext *, bool cancelled);
@@ -139,7 +142,7 @@
     CALayer *determineLayerAdjacentToSnapshotForParent(SwipeDirection, CALayer *snapshotLayerParent) const;
     void applyDebuggingPropertiesToSwipeViews();
 #endif
-    
+
     WebPageProxy& m_webPageProxy;
     ViewGestureType m_activeGestureType;
     
@@ -186,6 +189,8 @@
     RetainPtr<WKSwipeTransitionController> m_swipeInteractiveTransitionDelegate;
     uint64_t m_snapshotRemovalTargetRenderTreeSize;
     bool m_shouldRemoveSnapshotWhenTargetRenderTreeSizeHit;
+    WeakObjCPtr<WKWebView> m_alternateBackForwardListSourceView;
+    RefPtr<WebPageProxy> m_webPageProxyForBackForwardListForCurrentSwipe;
 #endif
 };
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to