Commit b2432bbb authored by Justin Cohen's avatar Justin Cohen Committed by Commit Bot

Reland "[ios] Enable WebKit based side swipe with Chrome side swipe."

Enables WebKit based side swipe, and only enables Chrome side swipe when the
page swiped page is to or from an NTP.

This reverts commit 1baa2855.

Change-Id: If29fd2c98bf475bfe9251e3eae18b24cb9c9c773
Reviewed-on: https://chromium-review.googlesource.com/c/1352958Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Commit-Queue: Justin Cohen <justincohen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#612289}
parent 6d98c763
...@@ -33,6 +33,7 @@ source_set("side_swipe") { ...@@ -33,6 +33,7 @@ source_set("side_swipe") {
"//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/ui:feature_flags",
"//ios/chrome/browser/ui/fullscreen", "//ios/chrome/browser/ui/fullscreen",
"//ios/chrome/browser/ui/ntp", "//ios/chrome/browser/ui/ntp",
"//ios/chrome/browser/ui/ntp:util",
"//ios/chrome/browser/ui/tab_grid/grid:grid_ui", "//ios/chrome/browser/ui/tab_grid/grid:grid_ui",
"//ios/chrome/browser/ui/tabs/requirements", "//ios/chrome/browser/ui/tabs/requirements",
"//ios/chrome/browser/ui/toolbar/public", "//ios/chrome/browser/ui/toolbar/public",
...@@ -54,6 +55,8 @@ source_set("unit_tests") { ...@@ -54,6 +55,8 @@ source_set("unit_tests") {
deps = [ deps = [
":side_swipe", ":side_swipe",
"//base", "//base",
"//base/test:test_support",
"//ios/chrome/browser",
"//ios/chrome/browser/browser_state:test_support", "//ios/chrome/browser/browser_state:test_support",
"//ios/web/public/test", "//ios/web/public/test",
"//testing/gtest", "//testing/gtest",
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#import "ios/chrome/browser/ui/toolbar/public/side_swipe_toolbar_interacting.h" #import "ios/chrome/browser/ui/toolbar/public/side_swipe_toolbar_interacting.h"
#include "ios/chrome/browser/ui/util/ui_util.h" #include "ios/chrome/browser/ui/util/ui_util.h"
#import "ios/chrome/browser/web/page_placeholder_tab_helper.h" #import "ios/chrome/browser/web/page_placeholder_tab_helper.h"
#import "ios/web/public/navigation_item.h"
#import "ios/web/public/web_client.h" #import "ios/web/public/web_client.h"
#import "ios/web/public/web_state/web_state_observer_bridge.h" #import "ios/web/public/web_state/web_state_observer_bridge.h"
...@@ -114,6 +115,11 @@ const NSUInteger kIpadGreySwipeTabCount = 8; ...@@ -114,6 +115,11 @@ const NSUInteger kIpadGreySwipeTabCount = 8;
ios::ChromeBrowserState* browserState_; ios::ChromeBrowserState* browserState_;
} }
// Whether to allow navigating from the leading edge.
@property(nonatomic, assign) BOOL leadingEdgeNavigationEnabled;
// Whether to allow navigating from the trailing edge.
@property(nonatomic, assign) BOOL trailingEdgeNavigationEnabled;
// Load grey snapshots for the next |kIpadGreySwipeTabCount| tabs in // Load grey snapshots for the next |kIpadGreySwipeTabCount| tabs in
// |direction|. // |direction|.
- (void)createGreyCache:(UISwipeGestureRecognizerDirection)direction; - (void)createGreyCache:(UISwipeGestureRecognizerDirection)direction;
...@@ -219,11 +225,17 @@ const NSUInteger kIpadGreySwipeTabCount = 8; ...@@ -219,11 +225,17 @@ const NSUInteger kIpadGreySwipeTabCount = 8;
- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer - (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer
shouldBeRequiredToFailByGestureRecognizer: shouldBeRequiredToFailByGestureRecognizer:
(UIGestureRecognizer*)otherGestureRecognizer { (UIGestureRecognizer*)otherGestureRecognizer {
// Only take precedence over a pan gesture recognizer so that moving up and // Take precedence over a pan gesture recognizer so that moving up and
// down while swiping doesn't trigger overscroll actions. // down while swiping doesn't trigger overscroll actions.
if ([otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) { if ([otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
return YES; return YES;
} }
// Take precedence over a WKWebView side swipe gesture.
if ([otherGestureRecognizer
isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) {
return YES;
}
return NO; return NO;
} }
...@@ -259,6 +271,16 @@ const NSUInteger kIpadGreySwipeTabCount = 8; ...@@ -259,6 +271,16 @@ const NSUInteger kIpadGreySwipeTabCount = 8;
if (![gesture isEqual:swipeGestureRecognizer_]) { if (![gesture isEqual:swipeGestureRecognizer_]) {
return NO; return NO;
} }
if (gesture.direction == UISwipeGestureRecognizerDirectionRight &&
!self.leadingEdgeNavigationEnabled) {
return NO;
}
if (gesture.direction == UISwipeGestureRecognizerDirectionLeft &&
!self.trailingEdgeNavigationEnabled) {
return NO;
}
swipeType_ = SwipeType::CHANGE_PAGE; swipeType_ = SwipeType::CHANGE_PAGE;
return YES; return YES;
} }
...@@ -586,6 +608,41 @@ const NSUInteger kIpadGreySwipeTabCount = 8; ...@@ -586,6 +608,41 @@ const NSUInteger kIpadGreySwipeTabCount = 8;
completionHandler(); completionHandler();
} }
- (void)updateNavigationEdgeSwipeForWebState:(web::WebState*)webState {
// With slim nav disabled, always use SideSwipeController's edge swipe for
// navigation.
if (!web::GetWebClient()->IsSlimNavigationManagerEnabled()) {
self.leadingEdgeNavigationEnabled = YES;
self.trailingEdgeNavigationEnabled = YES;
return;
}
// With slim nav enabled, disable SideSwipeController's edge swipe for a
// typical navigation. Continue to use SideSwipeController when on, before,
// or after a native page.
self.leadingEdgeNavigationEnabled = NO;
self.trailingEdgeNavigationEnabled = NO;
web::NavigationItem* item =
webState->GetNavigationManager()->GetVisibleItem();
if (item && UseNativeSwipe(item)) {
self.leadingEdgeNavigationEnabled = YES;
self.trailingEdgeNavigationEnabled = YES;
}
// If the previous page is an NTP, enable leading edge swipe.
web::NavigationItemList backItems =
webState->GetNavigationManager()->GetBackwardItems();
if (backItems.size() > 0 && UseNativeSwipe(backItems[0]))
self.leadingEdgeNavigationEnabled = YES;
// If the next page is an NTP, enable trailing edge swipe.
web::NavigationItemList fordwardItems =
webState->GetNavigationManager()->GetForwardItems();
if (fordwardItems.size() > 0 && UseNativeSwipe(fordwardItems[0]))
self.trailingEdgeNavigationEnabled = YES;
}
#pragma mark - CRWWebStateObserver Methods #pragma mark - CRWWebStateObserver Methods
// Checking -webStateDidStopLoading is likely incorrect, but to narrow the scope // Checking -webStateDidStopLoading is likely incorrect, but to narrow the scope
...@@ -621,6 +678,12 @@ const NSUInteger kIpadGreySwipeTabCount = 8; ...@@ -621,6 +678,12 @@ const NSUInteger kIpadGreySwipeTabCount = 8;
// the gesture recognizer. // the gesture recognizer.
[swipeGestureRecognizer_ setEnabled:NO]; [swipeGestureRecognizer_ setEnabled:NO];
[swipeGestureRecognizer_ setEnabled:YES]; [swipeGestureRecognizer_ setEnabled:YES];
[self updateNavigationEdgeSwipeForWebState:newTab.webState];
}
- (void)tabModel:(TabModel*)model didChangeTab:(Tab*)tab {
[self updateNavigationEdgeSwipeForWebState:tab.webState];
} }
@end @end
...@@ -2,8 +2,14 @@ ...@@ -2,8 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
#import "ios/chrome/browser/ui/side_swipe/side_swipe_controller.h" #import "ios/chrome/browser/ui/side_swipe/side_swipe_controller.h"
#include "base/test/scoped_feature_list.h"
#include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
#include "ios/chrome/browser/chrome_url_constants.h"
#include "ios/web/public/features.h"
#import "ios/web/public/navigation_item.h"
#import "ios/web/public/test/fakes/test_navigation_manager.h"
#import "ios/web/public/test/fakes/test_web_state.h"
#include "ios/web/public/test/test_web_thread_bundle.h" #include "ios/web/public/test/test_web_thread_bundle.h"
#include "testing/platform_test.h" #include "testing/platform_test.h"
#import "third_party/ocmock/OCMock/OCMock.h" #import "third_party/ocmock/OCMock/OCMock.h"
...@@ -14,6 +20,12 @@ ...@@ -14,6 +20,12 @@
#error "This file requires ARC support." #error "This file requires ARC support."
#endif #endif
@interface SideSwipeController (ExposedForTesting)
@property(nonatomic, assign) BOOL leadingEdgeNavigationEnabled;
@property(nonatomic, assign) BOOL trailingEdgeNavigationEnabled;
- (void)updateNavigationEdgeSwipeForWebState:(web::WebState*)webState;
@end
namespace { namespace {
class SideSwipeControllerTest : public PlatformTest { class SideSwipeControllerTest : public PlatformTest {
...@@ -39,6 +51,7 @@ class SideSwipeControllerTest : public PlatformTest { ...@@ -39,6 +51,7 @@ class SideSwipeControllerTest : public PlatformTest {
UIView* view_; UIView* view_;
TabModel* tab_model_; TabModel* tab_model_;
SideSwipeController* side_swipe_controller_; SideSwipeController* side_swipe_controller_;
base::test::ScopedFeatureList feature_list_;
}; };
TEST_F(SideSwipeControllerTest, TestConstructor) { TEST_F(SideSwipeControllerTest, TestConstructor) {
...@@ -55,4 +68,46 @@ TEST_F(SideSwipeControllerTest, TestSwipeRecognizers) { ...@@ -55,4 +68,46 @@ TEST_F(SideSwipeControllerTest, TestSwipeRecognizers) {
EXPECT_TRUE(hasRecognizer); EXPECT_TRUE(hasRecognizer);
} }
// Tests that pages that need to use Chromium native swipe
TEST_F(SideSwipeControllerTest, TestEdgeNavigationEnabled) {
feature_list_.InitAndEnableFeature(web::features::kSlimNavigationManager);
auto testWebState = std::make_unique<web::TestWebState>();
auto testNavigationManager = std::make_unique<web::TestNavigationManager>();
std::unique_ptr<web::NavigationItem> item = web::NavigationItem::Create();
testNavigationManager->SetVisibleItem(item.get());
testWebState->SetNavigationManager(std::move(testNavigationManager));
// The NTP and chrome://crash should use native swipe.
item->SetURL(GURL(kChromeUINewTabURL));
[side_swipe_controller_
updateNavigationEdgeSwipeForWebState:testWebState.get()];
EXPECT_TRUE(side_swipe_controller_.leadingEdgeNavigationEnabled);
EXPECT_TRUE(side_swipe_controller_.trailingEdgeNavigationEnabled);
item->SetURL(GURL("chrome://crash"));
[side_swipe_controller_
updateNavigationEdgeSwipeForWebState:testWebState.get()];
EXPECT_TRUE(side_swipe_controller_.leadingEdgeNavigationEnabled);
EXPECT_TRUE(side_swipe_controller_.trailingEdgeNavigationEnabled);
item->SetURL(GURL("http://wwww.test.com"));
[side_swipe_controller_
updateNavigationEdgeSwipeForWebState:testWebState.get()];
EXPECT_FALSE(side_swipe_controller_.leadingEdgeNavigationEnabled);
EXPECT_FALSE(side_swipe_controller_.trailingEdgeNavigationEnabled);
item->SetURL(GURL("chrome://foo"));
[side_swipe_controller_
updateNavigationEdgeSwipeForWebState:testWebState.get()];
EXPECT_FALSE(side_swipe_controller_.leadingEdgeNavigationEnabled);
EXPECT_FALSE(side_swipe_controller_.trailingEdgeNavigationEnabled);
item->SetURL(GURL("chrome://version"));
[side_swipe_controller_
updateNavigationEdgeSwipeForWebState:testWebState.get()];
EXPECT_FALSE(side_swipe_controller_.leadingEdgeNavigationEnabled);
EXPECT_FALSE(side_swipe_controller_.trailingEdgeNavigationEnabled);
}
} // anonymous namespace } // anonymous namespace
...@@ -7,10 +7,18 @@ ...@@ -7,10 +7,18 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
namespace web {
class NavigationItem;
}
// If swiping to the right (or left in RTL). // If swiping to the right (or left in RTL).
BOOL IsSwipingBack(UISwipeGestureRecognizerDirection direction); BOOL IsSwipingBack(UISwipeGestureRecognizerDirection direction);
// If swiping to the left (or right in RTL). // If swiping to the left (or right in RTL).
BOOL IsSwipingForward(UISwipeGestureRecognizerDirection direction); BOOL IsSwipingForward(UISwipeGestureRecognizerDirection direction);
// Returns |YES| if the item should use Chromium native swipe. This is true for
// the NTP and chrome://crash.
BOOL UseNativeSwipe(web::NavigationItem* item);
#endif // IOS_CHROME_BROWSER_UI_SIDE_SWIPE_SIDE_SWIPE_UTIL_H_ #endif // IOS_CHROME_BROWSER_UI_SIDE_SWIPE_SIDE_SWIPE_UTIL_H_
...@@ -6,7 +6,11 @@ ...@@ -6,7 +6,11 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#include "ios/chrome/browser/chrome_url_constants.h"
#import "ios/chrome/browser/chrome_url_util.h"
#import "ios/chrome/browser/ui/ntp/ntp_util.h"
#include "ios/chrome/browser/ui/util/rtl_geometry.h" #include "ios/chrome/browser/ui/util/rtl_geometry.h"
#import "ios/web/public/navigation_item.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support." #error "This file requires ARC support."
...@@ -25,3 +29,14 @@ BOOL IsSwipingForward(UISwipeGestureRecognizerDirection direction) { ...@@ -25,3 +29,14 @@ BOOL IsSwipingForward(UISwipeGestureRecognizerDirection direction) {
else else
return direction == UISwipeGestureRecognizerDirectionLeft; return direction == UISwipeGestureRecognizerDirectionLeft;
} }
BOOL UseNativeSwipe(web::NavigationItem* item) {
if (IsURLNewTabPage(item->GetVirtualURL()))
return YES;
GURL url(item->GetURL());
if (UrlHasChromeScheme(url) && url.host_piece() == kChromeUICrashHost)
return YES;
return NO;
}
...@@ -154,12 +154,10 @@ void TestNavigationManager::ReloadWithUserAgentType( ...@@ -154,12 +154,10 @@ void TestNavigationManager::ReloadWithUserAgentType(
} }
NavigationItemList TestNavigationManager::GetBackwardItems() const { NavigationItemList TestNavigationManager::GetBackwardItems() const {
NOTREACHED();
return NavigationItemList(); return NavigationItemList();
} }
NavigationItemList TestNavigationManager::GetForwardItems() const { NavigationItemList TestNavigationManager::GetForwardItems() const {
NOTREACHED();
return NavigationItemList(); return NavigationItemList();
} }
......
...@@ -954,6 +954,10 @@ GURL URLEscapedForHistory(const GURL& url) { ...@@ -954,6 +954,10 @@ GURL URLEscapedForHistory(const GURL& url) {
if (self) { if (self) {
_webStateImpl = webState; _webStateImpl = webState;
_webUsageEnabled = YES; _webUsageEnabled = YES;
if (web::GetWebClient()->IsSlimNavigationManagerEnabled())
_allowsBackForwardNavigationGestures = YES;
DCHECK(_webStateImpl); DCHECK(_webStateImpl);
// Load phase when no WebView present is 'loaded' because this represents // Load phase when no WebView present is 'loaded' because this represents
// the idle state. // the idle state.
......
...@@ -212,7 +212,7 @@ class CRWWebControllerTest : public WebTestWithWebController, ...@@ -212,7 +212,7 @@ class CRWWebControllerTest : public WebTestWithWebController,
context:nullptr]; context:nullptr];
[[result stub] removeObserver:web_controller() forKeyPath:OCMOCK_ANY]; [[result stub] removeObserver:web_controller() forKeyPath:OCMOCK_ANY];
[[result stub] evaluateJavaScript:OCMOCK_ANY completionHandler:OCMOCK_ANY]; [[result stub] evaluateJavaScript:OCMOCK_ANY completionHandler:OCMOCK_ANY];
// CRWWebController sets this property to NO by default. [[result stub] setAllowsBackForwardNavigationGestures:YES];
[[result stub] setAllowsBackForwardNavigationGestures:NO]; [[result stub] setAllowsBackForwardNavigationGestures:NO];
return result; return result;
...@@ -310,13 +310,18 @@ TEST_P(CRWWebControllerTest, AbortNativeUrlNavigation) { ...@@ -310,13 +310,18 @@ TEST_P(CRWWebControllerTest, AbortNativeUrlNavigation) {
EXPECT_FALSE(observer.did_finish_navigation_info()); EXPECT_FALSE(observer.did_finish_navigation_info());
} }
// Tests allowsBackForwardNavigationGestures default value and setting this // Tests allowsBackForwardNavigationGestures default value and negating this
// property to YES. // property.
TEST_P(CRWWebControllerTest, SetAllowsBackForwardNavigationGestures) { TEST_P(CRWWebControllerTest, SetAllowsBackForwardNavigationGestures) {
OCMExpect([mock_web_view_ setAllowsBackForwardNavigationGestures:YES]); if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) {
EXPECT_TRUE(web_controller().allowsBackForwardNavigationGestures);
web_controller().allowsBackForwardNavigationGestures = NO;
EXPECT_FALSE(web_controller().allowsBackForwardNavigationGestures);
} else {
EXPECT_FALSE(web_controller().allowsBackForwardNavigationGestures); EXPECT_FALSE(web_controller().allowsBackForwardNavigationGestures);
web_controller().allowsBackForwardNavigationGestures = YES; web_controller().allowsBackForwardNavigationGestures = YES;
EXPECT_TRUE(web_controller().allowsBackForwardNavigationGestures); EXPECT_TRUE(web_controller().allowsBackForwardNavigationGestures);
}
} }
INSTANTIATE_TEST_CASES(CRWWebControllerTest); INSTANTIATE_TEST_CASES(CRWWebControllerTest);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment