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") {
"//ios/chrome/browser/ui:feature_flags",
"//ios/chrome/browser/ui/fullscreen",
"//ios/chrome/browser/ui/ntp",
"//ios/chrome/browser/ui/ntp:util",
"//ios/chrome/browser/ui/tab_grid/grid:grid_ui",
"//ios/chrome/browser/ui/tabs/requirements",
"//ios/chrome/browser/ui/toolbar/public",
......@@ -54,6 +55,8 @@ source_set("unit_tests") {
deps = [
":side_swipe",
"//base",
"//base/test:test_support",
"//ios/chrome/browser",
"//ios/chrome/browser/browser_state:test_support",
"//ios/web/public/test",
"//testing/gtest",
......
......@@ -31,6 +31,7 @@
#import "ios/chrome/browser/ui/toolbar/public/side_swipe_toolbar_interacting.h"
#include "ios/chrome/browser/ui/util/ui_util.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_state/web_state_observer_bridge.h"
......@@ -114,6 +115,11 @@ const NSUInteger kIpadGreySwipeTabCount = 8;
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
// |direction|.
- (void)createGreyCache:(UISwipeGestureRecognizerDirection)direction;
......@@ -219,11 +225,17 @@ const NSUInteger kIpadGreySwipeTabCount = 8;
- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer
shouldBeRequiredToFailByGestureRecognizer:
(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.
if ([otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
return YES;
}
// Take precedence over a WKWebView side swipe gesture.
if ([otherGestureRecognizer
isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) {
return YES;
}
return NO;
}
......@@ -259,6 +271,16 @@ const NSUInteger kIpadGreySwipeTabCount = 8;
if (![gesture isEqual:swipeGestureRecognizer_]) {
return NO;
}
if (gesture.direction == UISwipeGestureRecognizerDirectionRight &&
!self.leadingEdgeNavigationEnabled) {
return NO;
}
if (gesture.direction == UISwipeGestureRecognizerDirectionLeft &&
!self.trailingEdgeNavigationEnabled) {
return NO;
}
swipeType_ = SwipeType::CHANGE_PAGE;
return YES;
}
......@@ -586,6 +608,41 @@ const NSUInteger kIpadGreySwipeTabCount = 8;
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
// Checking -webStateDidStopLoading is likely incorrect, but to narrow the scope
......@@ -621,6 +678,12 @@ const NSUInteger kIpadGreySwipeTabCount = 8;
// the gesture recognizer.
[swipeGestureRecognizer_ setEnabled:NO];
[swipeGestureRecognizer_ setEnabled:YES];
[self updateNavigationEdgeSwipeForWebState:newTab.webState];
}
- (void)tabModel:(TabModel*)model didChangeTab:(Tab*)tab {
[self updateNavigationEdgeSwipeForWebState:tab.webState];
}
@end
......@@ -2,8 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// 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"
#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 "testing/platform_test.h"
#import "third_party/ocmock/OCMock/OCMock.h"
......@@ -14,6 +20,12 @@
#error "This file requires ARC support."
#endif
@interface SideSwipeController (ExposedForTesting)
@property(nonatomic, assign) BOOL leadingEdgeNavigationEnabled;
@property(nonatomic, assign) BOOL trailingEdgeNavigationEnabled;
- (void)updateNavigationEdgeSwipeForWebState:(web::WebState*)webState;
@end
namespace {
class SideSwipeControllerTest : public PlatformTest {
......@@ -39,6 +51,7 @@ class SideSwipeControllerTest : public PlatformTest {
UIView* view_;
TabModel* tab_model_;
SideSwipeController* side_swipe_controller_;
base::test::ScopedFeatureList feature_list_;
};
TEST_F(SideSwipeControllerTest, TestConstructor) {
......@@ -55,4 +68,46 @@ TEST_F(SideSwipeControllerTest, TestSwipeRecognizers) {
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
......@@ -7,10 +7,18 @@
#import <UIKit/UIKit.h>
namespace web {
class NavigationItem;
}
// If swiping to the right (or left in RTL).
BOOL IsSwipingBack(UISwipeGestureRecognizerDirection direction);
// If swiping to the left (or right in RTL).
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_
......@@ -6,7 +6,11 @@
#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"
#import "ios/web/public/navigation_item.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
......@@ -25,3 +29,14 @@ BOOL IsSwipingForward(UISwipeGestureRecognizerDirection direction) {
else
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(
}
NavigationItemList TestNavigationManager::GetBackwardItems() const {
NOTREACHED();
return NavigationItemList();
}
NavigationItemList TestNavigationManager::GetForwardItems() const {
NOTREACHED();
return NavigationItemList();
}
......
......@@ -954,6 +954,10 @@ GURL URLEscapedForHistory(const GURL& url) {
if (self) {
_webStateImpl = webState;
_webUsageEnabled = YES;
if (web::GetWebClient()->IsSlimNavigationManagerEnabled())
_allowsBackForwardNavigationGestures = YES;
DCHECK(_webStateImpl);
// Load phase when no WebView present is 'loaded' because this represents
// the idle state.
......
......@@ -212,7 +212,7 @@ class CRWWebControllerTest : public WebTestWithWebController,
context:nullptr];
[[result stub] removeObserver:web_controller() forKeyPath: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];
return result;
......@@ -310,13 +310,18 @@ TEST_P(CRWWebControllerTest, AbortNativeUrlNavigation) {
EXPECT_FALSE(observer.did_finish_navigation_info());
}
// Tests allowsBackForwardNavigationGestures default value and setting this
// property to YES.
// Tests allowsBackForwardNavigationGestures default value and negating this
// property.
TEST_P(CRWWebControllerTest, SetAllowsBackForwardNavigationGestures) {
OCMExpect([mock_web_view_ setAllowsBackForwardNavigationGestures:YES]);
EXPECT_FALSE(web_controller().allowsBackForwardNavigationGestures);
web_controller().allowsBackForwardNavigationGestures = YES;
EXPECT_TRUE(web_controller().allowsBackForwardNavigationGestures);
if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) {
EXPECT_TRUE(web_controller().allowsBackForwardNavigationGestures);
web_controller().allowsBackForwardNavigationGestures = NO;
EXPECT_FALSE(web_controller().allowsBackForwardNavigationGestures);
} else {
EXPECT_FALSE(web_controller().allowsBackForwardNavigationGestures);
web_controller().allowsBackForwardNavigationGestures = YES;
EXPECT_TRUE(web_controller().allowsBackForwardNavigationGestures);
}
}
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