Commit 271bc853 authored by Mark Cogan's avatar Mark Cogan Committed by Commit Bot

[ios] Remove Contextual Search code from the BVC.

This CL removes all contextual search code from the BVC. Almost all of
the logic contained in the BVC is ported to a new wrangler class.

Any object wishing to use contextual search (without further refactoring)
will need to furnish a provider object as defined in the wrangler class
header, which at this stage just encapsulates all of the interfaces into
the BVC that the contextual search code used to use.

Bug: 
Change-Id: I23ffe787b26ead87c9c50e4730851f6b992c95a4
Reviewed-on: https://chromium-review.googlesource.com/574534
Commit-Queue: Mark Cogan <marq@chromium.org>
Reviewed-by: default avatarOlivier Robin <olivierrobin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#487435}
parent 059ce7c0
......@@ -258,7 +258,6 @@ source_set("ui_internal_arc") {
"//ios/chrome/browser/ui/colors",
"//ios/chrome/browser/ui/commands",
"//ios/chrome/browser/ui/context_menu",
"//ios/chrome/browser/ui/contextual_search",
"//ios/chrome/browser/ui/dialogs:dialogs_internal",
"//ios/chrome/browser/ui/elements:elements_internal",
"//ios/chrome/browser/ui/find_bar",
......
......@@ -106,12 +106,6 @@
#import "ios/chrome/browser/ui/commands/reading_list_add_command.h"
#import "ios/chrome/browser/ui/commands/show_mail_composer_command.h"
#import "ios/chrome/browser/ui/context_menu/context_menu_coordinator.h"
#import "ios/chrome/browser/ui/contextual_search/contextual_search_controller.h"
#import "ios/chrome/browser/ui/contextual_search/contextual_search_mask_view.h"
#import "ios/chrome/browser/ui/contextual_search/contextual_search_metrics.h"
#import "ios/chrome/browser/ui/contextual_search/contextual_search_panel_protocols.h"
#import "ios/chrome/browser/ui/contextual_search/contextual_search_panel_view.h"
#import "ios/chrome/browser/ui/contextual_search/touch_to_search_permissions_mediator.h"
#import "ios/chrome/browser/ui/dialogs/dialog_presenter.h"
#import "ios/chrome/browser/ui/dialogs/java_script_dialog_presenter_impl.h"
#import "ios/chrome/browser/ui/elements/activity_overlay_coordinator.h"
......@@ -160,7 +154,6 @@
#import "ios/chrome/browser/web/repost_form_tab_helper.h"
#import "ios/chrome/browser/web_state_list/web_state_list.h"
#import "ios/chrome/browser/web_state_list/web_state_opener.h"
#import "ios/chrome/common/material_timing.h"
#include "ios/chrome/grit/ios_chromium_strings.h"
#include "ios/chrome/grit/ios_strings.h"
#import "ios/net/request_tracker.h"
......@@ -346,8 +339,6 @@ NSString* const kNativeControllerTemporaryKey = @"NativeControllerTemporaryKey";
#pragma mark - BVC
@interface BrowserViewController ()<AppRatingPromptDelegate,
ContextualSearchControllerDelegate,
ContextualSearchPanelMotionObserver,
CRWNativeContentProvider,
CRWWebStateDelegate,
DialogPresenterDelegate,
......@@ -420,15 +411,6 @@ NSString* const kNativeControllerTemporaryKey = @"NativeControllerTemporaryKey";
// Always present on tablet; always nil on phone.
TabStripController* _tabStripController;
// The contextual search controller.
ContextualSearchController* _contextualSearchController;
// The contextual search panel (always a subview of |self.view| if it exists).
ContextualSearchPanelView* _contextualSearchPanel;
// The contextual search mask (always a subview of |self.view| if it exists).
ContextualSearchMaskView* _contextualSearchMask;
// Used to inject Javascript implementing the PaymentRequest API and to
// display the UI.
PaymentRequestManager* _paymentRequestManager;
......@@ -1055,7 +1037,6 @@ applicationCommandEndpoint:(id<ApplicationCommands>)applicationCommandEndpoint {
} else {
[_dialogPresenter cancelAllDialogs];
}
[_contextualSearchController enableContextualSearch:active];
[_paymentRequestManager enablePaymentRequest:active];
[self setNeedsStatusBarAppearanceUpdate];
......@@ -1735,10 +1716,6 @@ applicationCommandEndpoint:(id<ApplicationCommands>)applicationCommandEndpoint {
// Reset the toolbar opacity in case it was changed for contextual search.
[self updateToolbarControlsAlpha:1.0];
[self updateToolbarBackgroundAlpha:1.0];
[_contextualSearchController close];
_contextualSearchController = nil;
[_contextualSearchPanel removeFromSuperview];
[_contextualSearchMask removeFromSuperview];
[_paymentRequestManager close];
_paymentRequestManager = nil;
[_toolbarController browserStateDestroyed];
......@@ -1832,22 +1809,6 @@ applicationCommandEndpoint:(id<ApplicationCommands>)applicationCommandEndpoint {
[[_model currentTab] infoBarManager];
_infoBarContainer->ChangeInfoBarManager(infoBarManager);
// Create contextual search views and controller.
if ([TouchToSearchPermissionsMediator isTouchToSearchAvailableOnDevice] &&
!_browserState->IsOffTheRecord()) {
_contextualSearchMask = [[ContextualSearchMaskView alloc] init];
[self.view insertSubview:_contextualSearchMask
belowSubview:[_toolbarController view]];
_contextualSearchPanel = [self createPanelView];
[self.view insertSubview:_contextualSearchPanel
aboveSubview:[_toolbarController view]];
_contextualSearchController =
[[ContextualSearchController alloc] initWithBrowserState:_browserState
delegate:self];
[_contextualSearchController setPanel:_contextualSearchPanel];
[_contextualSearchController setTab:[_model currentTab]];
}
if (base::FeatureList::IsEnabled(payments::features::kWebPayments)) {
_paymentRequestManager = [[PaymentRequestManager alloc]
initWithBaseViewController:self
......@@ -4283,7 +4244,6 @@ applicationCommandEndpoint:(id<ApplicationCommands>)applicationCommandEndpoint {
}
}
[_contextualSearchController movePanelOffscreen];
[_paymentRequestManager cancelRequest];
[_printController dismissAnimated:YES];
_printController = nil;
......@@ -4594,11 +4554,6 @@ applicationCommandEndpoint:(id<ApplicationCommands>)applicationCommandEndpoint {
} else {
[self.view addSubview:[_toolbarController view]];
}
if (_contextualSearchPanel) {
// Move panel back into its correct place.
[self.view insertSubview:_contextualSearchPanel
aboveSubview:[_toolbarController view]];
}
_isToolbarControllerRelinquished = NO;
}
}
......@@ -4614,7 +4569,6 @@ applicationCommandEndpoint:(id<ApplicationCommands>)applicationCommandEndpoint {
[self installDelegatesForTab:tab];
if (fg) {
[_contextualSearchController setTab:tab];
[_paymentRequestManager setActiveWebState:tab.webState];
}
}
......@@ -4634,7 +4588,6 @@ applicationCommandEndpoint:(id<ApplicationCommands>)applicationCommandEndpoint {
}
[self updateVoiceSearchBarVisibilityAnimated:NO];
[_contextualSearchController setTab:newTab];
[_paymentRequestManager setActiveWebState:newTab.webState];
[self tabSelected:newTab];
......@@ -4647,9 +4600,6 @@ applicationCommandEndpoint:(id<ApplicationCommands>)applicationCommandEndpoint {
DCHECK(tab && ([_model indexOfTab:tab] != NSNotFound));
if (tab == [_model currentTab]) {
[self updateToolbar];
// Disable contextual search when |tab| is a voice search result tab.
BOOL enableContextualSearch = self.active && !tab.isVoiceSearchResultsTab;
[_contextualSearchController enableContextualSearch:enableContextualSearch];
}
}
......@@ -4702,7 +4652,6 @@ applicationCommandEndpoint:(id<ApplicationCommands>)applicationCommandEndpoint {
[[UpgradeCenter sharedInstance] tabWillClose:tab.tabId];
if ([model count] == 1) { // About to remove the last tab.
[_contextualSearchController setTab:nil];
[_paymentRequestManager setActiveWebState:nullptr];
}
}
......@@ -4724,169 +4673,6 @@ applicationCommandEndpoint:(id<ApplicationCommands>)applicationCommandEndpoint {
}
}
#pragma mark - ContextualSearchControllerDelegate
- (void)createTabFromContextualSearchController:(const GURL&)url {
Tab* currentTab = [_model currentTab];
DCHECK(currentTab);
NSUInteger index = [_model indexOfTab:currentTab];
[self addSelectedTabWithURL:url
atIndex:index + 1
transition:ui::PAGE_TRANSITION_LINK];
}
- (void)promotePanelToTabProvidedBy:(id<ContextualSearchTabProvider>)tabProvider
focusInput:(BOOL)focusInput {
// Tell the panel it will be promoted.
ContextualSearchPanelView* promotingPanel = _contextualSearchPanel;
[promotingPanel prepareForPromotion];
// Make a new panel and tell the controller about it.
_contextualSearchPanel = [self createPanelView];
[self.view insertSubview:_contextualSearchPanel belowSubview:promotingPanel];
[_contextualSearchController setPanel:_contextualSearchPanel];
// Figure out vertical offset.
CGFloat offset = StatusBarHeight();
if (IsIPadIdiom()) {
offset = MAX(offset, CGRectGetMaxY([_tabStripController view].frame));
}
// Transition steps: Animate the panel position, fade in the toolbar and
// tab strip.
ProceduralBlock transition = ^{
[promotingPanel promoteToMatchSuperviewWithVerticalOffset:offset];
[self updateToolbarControlsAlpha:1.0];
[self updateToolbarBackgroundAlpha:1.0];
[_tabStripController view].alpha = 1.0;
};
// After the transition animation completes, add the tab to the tab model
// (on iPad this triggers the tab strip animation too), then fade out the
// transitioning panel and remove it.
void (^completion)(BOOL) = ^(BOOL finished) {
_contextualSearchMask.alpha = 0;
std::unique_ptr<web::WebState> webState = [tabProvider releaseWebState];
DCHECK(webState);
DCHECK(webState->GetNavigationManager());
Tab* newTab = LegacyTabHelper::GetTabForWebState(webState.get());
WebStateList* webStateList = [_model webStateList];
// Insert the new tab after the current tab.
DCHECK_NE(webStateList->active_index(), WebStateList::kInvalidIndex);
DCHECK_NE(webStateList->active_index(), INT_MAX);
int insertion_index = webStateList->active_index() + 1;
webStateList->InsertWebState(insertion_index, std::move(webState));
webStateList->SetOpenerOfWebStateAt(insertion_index,
[tabProvider webStateOpener]);
// Set isPrerenderTab to NO after inserting the tab. This will allow the
// BrowserViewController to detect that a pre-rendered tab is switched in,
// and show the prerendering animation. This needs to happen before the
// tab is made the current tab.
// This also enables contextual search (if otherwise applicable) on
// |newTab|.
newTab.isPrerenderTab = NO;
[_model setCurrentTab:newTab];
if (newTab.loadFinished)
[self tabLoadComplete:newTab withSuccess:YES];
if (focusInput) {
[_toolbarController focusOmnibox];
}
_infoBarContainer->RestoreInfobars();
[UIView animateWithDuration:ios::material::kDuration2
animations:^{
promotingPanel.alpha = 0;
}
completion:^(BOOL finished) {
[promotingPanel removeFromSuperview];
}];
};
[UIView animateWithDuration:ios::material::kDuration3
animations:transition
completion:completion];
}
- (ContextualSearchPanelView*)createPanelView {
PanelConfiguration* config;
CGSize panelContainerSize = self.view.bounds.size;
if (IsIPadIdiom()) {
config = [PadPanelConfiguration
configurationForContainerSize:panelContainerSize
horizontalSizeClass:self.traitCollection.horizontalSizeClass];
} else {
config = [PhonePanelConfiguration
configurationForContainerSize:panelContainerSize
horizontalSizeClass:self.traitCollection.horizontalSizeClass];
}
ContextualSearchPanelView* newPanel =
[[ContextualSearchPanelView alloc] initWithConfiguration:config];
[newPanel addMotionObserver:self];
[newPanel addMotionObserver:_contextualSearchMask];
return newPanel;
}
#pragma mark - ContextualSearchPanelMotionObserver
- (void)panel:(ContextualSearchPanelView*)panel
didMoveWithMotion:(ContextualSearch::PanelMotion)motion {
// If the header is offset, it's offscreen (or moving offscreen) and the
// toolbar shouldn't be opacity-adjusted by the contextual search panel.
if ([self currentHeaderOffset] != 0)
return;
CGFloat toolbarAlpha;
if (motion.state == ContextualSearch::PREVIEWING) {
// As the panel moves past the previewing position, the toolbar should
// become more transparent.
toolbarAlpha = 1 - motion.gradation;
} else if (motion.state == ContextualSearch::COVERING) {
// The toolbar should be totally transparent when the panel is covering.
toolbarAlpha = 0.0;
} else {
return;
}
// On iPad, the toolbar doesn't go fully transparent, so map |toolbarAlpha|'s
// [0-1.0] range to [0.5-1.0].
if (IsIPadIdiom()) {
toolbarAlpha = 0.5 + (toolbarAlpha * 0.5);
[_tabStripController view].alpha = toolbarAlpha;
}
[self updateToolbarControlsAlpha:toolbarAlpha];
[self updateToolbarBackgroundAlpha:toolbarAlpha];
}
- (void)panel:(ContextualSearchPanelView*)panel
didChangeToState:(ContextualSearch::PanelState)toState
fromState:(ContextualSearch::PanelState)fromState {
if (toState == ContextualSearch::DISMISSED) {
// Panel has become hidden.
_infoBarContainer->RestoreInfobars();
[self updateToolbarControlsAlpha:1.0];
[self updateToolbarBackgroundAlpha:1.0];
[_tabStripController view].alpha = 1.0;
} else if (fromState == ContextualSearch::DISMISSED) {
// Panel has become visible.
_infoBarContainer->SuspendInfobars();
}
}
- (void)panelWillPromote:(ContextualSearchPanelView*)panel {
[panel removeMotionObserver:self];
}
- (CGFloat)currentHeaderHeight {
return [self headerHeight] - [self currentHeaderOffset];
}
#pragma mark - InfoBarControllerDelegate
......@@ -4979,9 +4765,6 @@ applicationCommandEndpoint:(id<ApplicationCommands>)applicationCommandEndpoint {
if (_voiceSearchController && _voiceSearchController->IsVisible())
return YES;
if ([_contextualSearchPanel state] >= ContextualSearch::PEEKING)
return YES;
if (!self.active)
return YES;
......
......@@ -46,6 +46,8 @@ source_set("contextual_search") {
"contextual_search_results_view.mm",
"contextual_search_web_state_observer.h",
"contextual_search_web_state_observer.mm",
"contextual_search_wrangler.h",
"contextual_search_wrangler.mm",
"js_contextual_search_manager.h",
"js_contextual_search_manager.mm",
"panel_configuration.h",
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_UI_CONTEXTUAL_SEARCH_CONTEXTUAL_SEARCH_WRANGLER_H_
#define IOS_CHROME_BROWSER_UI_CONTEXTUAL_SEARCH_CONTEXTUAL_SEARCH_WRANGLER_H_
#import <UIKit/UIKit.h>
namespace ios {
class ChromeBrowserState;
}
@class Tab;
@class TabModel;
// A provider protocol for Contextual Search; this defines all of the things
// that the Contextual Search system needs to be able to ask for from or change
// in the application as a whole.
@protocol ContextualSearchProvider<NSObject>
// The parent view that the contextual search panel will be a subview of.
@property(nonatomic, readonly) UIView* view;
// The view (if any) containing the tab strip. This may be used for height
// calculations for positioning or aninmating the contextual search view.
@property(nonatomic, readonly) UIView* tabStripView;
// The view containing the toolbar. This should be a subview of the view
// exposed in |view|, above. The contextual search panel will be
// positioned in front of this view, and the contexual search mask will be
// positioned behind it (in the z-axis).
@property(nonatomic, readonly) UIView* toolbarView;
// Tells the provider to set the toolbar control alpha.
- (void)updateToolbarControlsAlpha:(CGFloat)alpha;
// Tells the provider to set the toolbar background alpha.
- (void)updateToolbarBackgroundAlpha:(CGFloat)alpha;
// Tell the provider that a tab load inside contextual search has completed.
// |tab| is that tab that has loaded, and |sucess| is YES if the tab loaded
// without error, and NO otherwise.
- (void)tabLoadComplete:(Tab*)tab withSuccess:(BOOL)success;
// Tells the pr=ovider to focus the omnibox.
- (void)focusOmnibox;
// Tells the provider to restore any suspended infobars.
- (void)restoreInfobars;
// Tells the provider to suspend any infobars..
- (void)suspendInfobars;
// Asks the provider for the current header offset for positinioning the panel.
- (CGFloat)currentHeaderOffset;
@end
// An object that manages the interactions of the contextual search system with
// the rest of teh application. An instance of this object handles creating and
// positioning all of the views required for contextual search, as well as all
// of the other controller objects.
@interface ContextualSearchWrangler : NSObject
// Creates a new wrangler object for |provider| and |tabModel|.
- (instancetype)initWithProvider:(id<ContextualSearchProvider>)provider
tabModel:(TabModel*)tabModel NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
// Inserts the panel view into the view hierarchy provided by the provider the
// receiver was initialized with.
- (void)insertPanelView;
// Starts contextual search using the reciever for |browserState|. This should
// only be called once in the lifetime of the receiver. If it is possible
// (as determined by TouchToSearchPermissionsMediator) to start contextual
// search on this device, and |browserState| isn't incognito, then this method
// will create the contextual search controller objects and views and start
// observing the tab model it was initialized with.
- (void)maybeStartForBrowserState:(ios::ChromeBrowserState*)browserState;
// Enables or disables contextual search for the reciever; this may be called
// multiple times during the lifetime of the receiver.
- (void)enable:(BOOL)enabled;
// Tears down the controller and views the receiver has created. This method
// must be called before the receiver is deallocated.
- (void)stop;
@end
#endif // IOS_CHROME_BROWSER_UI_CONTEXTUAL_SEARCH_CONTEXTUAL_SEARCH_WRANGLER_H_
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/contextual_search/contextual_search_wrangler.h"
#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
#import "ios/chrome/browser/tabs/legacy_tab_helper.h"
#import "ios/chrome/browser/tabs/tab.h"
#import "ios/chrome/browser/tabs/tab_model.h"
#import "ios/chrome/browser/tabs/tab_model_observer.h"
#import "ios/chrome/browser/ui/contextual_search/contextual_search_controller.h"
#import "ios/chrome/browser/ui/contextual_search/contextual_search_mask_view.h"
#import "ios/chrome/browser/ui/contextual_search/contextual_search_metrics.h"
#import "ios/chrome/browser/ui/contextual_search/contextual_search_panel_protocols.h"
#import "ios/chrome/browser/ui/contextual_search/contextual_search_panel_view.h"
#import "ios/chrome/browser/ui/contextual_search/touch_to_search_permissions_mediator.h"
#include "ios/chrome/browser/ui/ui_util.h"
#import "ios/chrome/browser/web_state_list/web_state_list.h"
#import "ios/chrome/browser/web_state_list/web_state_opener.h"
#import "ios/chrome/common/material_timing.h"
#include "ios/web/public/web_state/web_state.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@interface ContextualSearchWrangler ()<ContextualSearchControllerDelegate,
ContextualSearchPanelMotionObserver,
TabModelObserver>
@property(nonatomic, readonly, weak) TabModel* tabModel;
@property(nonatomic, readonly, weak) id<ContextualSearchProvider> provider;
@property(nonatomic) ContextualSearchPanelView* panel;
@property(nonatomic) ContextualSearchController* controller;
@property(nonatomic) ContextualSearchMaskView* mask;
@end
@implementation ContextualSearchWrangler
@synthesize tabModel = _tabModel;
@synthesize provider = _provider;
@synthesize panel = _panel;
@synthesize controller = _controller;
@synthesize mask = _mask;
- (instancetype)initWithProvider:(id<ContextualSearchProvider>)provider
tabModel:(TabModel*)tabModel {
if ((self = [super init])) {
_provider = provider;
_tabModel = tabModel;
}
return self;
}
- (void)enable:(BOOL)enabled {
[self.controller enableContextualSearch:enabled];
if (enabled)
[self.tabModel addObserver:self];
else
[self.tabModel removeObserver:self];
}
- (void)insertPanelView {
// Move panel back into its correct place.
[self.provider.view insertSubview:self.panel
aboveSubview:self.provider.toolbarView];
}
- (void)maybeStartForBrowserState:(ios::ChromeBrowserState*)browserState {
// Create contextual search views and controller.
if ([TouchToSearchPermissionsMediator isTouchToSearchAvailableOnDevice] &&
!browserState->IsOffTheRecord()) {
self.mask = [[ContextualSearchMaskView alloc] init];
[self.provider.view insertSubview:self.mask
belowSubview:self.provider.toolbarView];
self.panel = [self createPanelView];
[self.provider.view insertSubview:self.panel
aboveSubview:self.provider.toolbarView];
self.controller =
[[ContextualSearchController alloc] initWithBrowserState:browserState
delegate:self];
[self.controller setPanel:self.panel];
[self.controller setTab:[self.tabModel currentTab]];
[self enable:YES];
}
}
- (void)stop {
[self.tabModel removeObserver:self];
[self.controller close];
self.controller = nil;
[self.panel removeFromSuperview];
[self.mask removeFromSuperview];
}
#pragma mark - ContextualSearchControllerDelegate
- (void)promotePanelToTabProvidedBy:(id<ContextualSearchTabProvider>)tabProvider
focusInput:(BOOL)focusInput {
// Tell the panel it will be promoted.
ContextualSearchPanelView* promotingPanel = self.panel;
[promotingPanel prepareForPromotion];
// Make a new panel and tell the controller about it.
self.panel = [self createPanelView];
[self.provider.view insertSubview:self.panel belowSubview:promotingPanel];
[self.controller setPanel:self.panel];
// Figure out vertical offset.
CGFloat offset = StatusBarHeight();
if (IsIPadIdiom()) {
offset = MAX(offset, CGRectGetMaxY(self.provider.tabStripView.frame));
}
// Transition steps: Animate the panel position, fade in the toolbar and
// tab strip.
ProceduralBlock transition = ^{
[promotingPanel promoteToMatchSuperviewWithVerticalOffset:offset];
[self.provider updateToolbarControlsAlpha:1.0];
[self.provider updateToolbarBackgroundAlpha:1.0];
self.provider.tabStripView.alpha = 1.0;
};
// After the transition animation completes, add the tab to the tab model
// (on iPad this triggers the tab strip animation too), then fade out the
// transitioning panel and remove it.
void (^completion)(BOOL) = ^(BOOL finished) {
self.mask.alpha = 0;
std::unique_ptr<web::WebState> webState = [tabProvider releaseWebState];
DCHECK(webState);
DCHECK(webState->GetNavigationManager());
Tab* newTab = LegacyTabHelper::GetTabForWebState(webState.get());
WebStateList* webStateList = [self.tabModel webStateList];
// Insert the new tab after the current tab.
DCHECK_NE(webStateList->active_index(), WebStateList::kInvalidIndex);
DCHECK_NE(webStateList->active_index(), INT_MAX);
int insertion_index = webStateList->active_index() + 1;
webStateList->InsertWebState(insertion_index, std::move(webState));
webStateList->SetOpenerOfWebStateAt(insertion_index,
[tabProvider webStateOpener]);
// Set isPrerenderTab to NO after inserting the tab. This will allow the
// BrowserViewController to detect that a pre-rendered tab is switched in,
// and show the prerendering animation. This needs to happen before the
// tab is made the current tab.
// This also enables contextual search (if otherwise applicable) on
// |newTab|.
newTab.isPrerenderTab = NO;
[self.tabModel setCurrentTab:newTab];
if (newTab.loadFinished)
[self.provider tabLoadComplete:newTab withSuccess:YES];
if (focusInput) {
[self.provider focusOmnibox];
}
[self.provider restoreInfobars];
[UIView animateWithDuration:ios::material::kDuration2
animations:^{
promotingPanel.alpha = 0;
}
completion:^(BOOL finished) {
[promotingPanel removeFromSuperview];
}];
};
[UIView animateWithDuration:ios::material::kDuration3
animations:transition
completion:completion];
}
- (void)createTabFromContextualSearchController:(const GURL&)url {
Tab* currentTab = [self.tabModel currentTab];
DCHECK(currentTab);
NSUInteger index = [self.tabModel indexOfTab:currentTab];
web::NavigationManager::WebLoadParams params(url);
params.transition_type = ui::PAGE_TRANSITION_LINK;
// This returns a Tab, but it's ignored..
[self.tabModel insertTabWithLoadParams:params
opener:nil
openedByDOM:NO
atIndex:index + 1
inBackground:NO];
}
- (CGFloat)currentHeaderHeight {
return 20.0;
}
#pragma mark - ContextualSearchPanelMotionObserver
- (void)panel:(ContextualSearchPanelView*)panel
didMoveWithMotion:(ContextualSearch::PanelMotion)motion {
// If the header is offset, it's offscreen (or moving offscreen) and the
// toolbar shouldn't be opacity-adjusted by the contextual search panel.
if ([self.provider currentHeaderOffset] != 0)
return;
CGFloat toolbarAlpha;
if (motion.state == ContextualSearch::PREVIEWING) {
// As the panel moves past the previewing position, the toolbar should
// become more transparent.
toolbarAlpha = 1 - motion.gradation;
} else if (motion.state == ContextualSearch::COVERING) {
// The toolbar should be totally transparent when the panel is covering.
toolbarAlpha = 0.0;
} else {
return;
}
// On iPad, the toolbar doesn't go fully transparent, so map |toolbarAlpha|'s
// [0-1.0] range to [0.5-1.0].
if (IsIPadIdiom()) {
toolbarAlpha = 0.5 + (toolbarAlpha * 0.5);
self.provider.tabStripView.alpha = toolbarAlpha;
}
[self.provider updateToolbarControlsAlpha:toolbarAlpha];
[self.provider updateToolbarBackgroundAlpha:toolbarAlpha];
}
- (void)panel:(ContextualSearchPanelView*)panel
didChangeToState:(ContextualSearch::PanelState)toState
fromState:(ContextualSearch::PanelState)fromState {
if (toState == ContextualSearch::DISMISSED) {
// Panel has become hidden.
[self.provider restoreInfobars];
[self.provider updateToolbarControlsAlpha:1.0];
[self.provider updateToolbarBackgroundAlpha:1.0];
self.provider.tabStripView.alpha = 1.0;
} else if (fromState == ContextualSearch::DISMISSED) {
// Panel has become visible.
[self.provider suspendInfobars];
}
}
- (void)panelWillPromote:(ContextualSearchPanelView*)panel {
[panel removeMotionObserver:self];
}
#pragma mark - TabModelObsever
- (void)tabModel:(TabModel*)model
didInsertTab:(Tab*)tab
atIndex:(NSUInteger)modelIndex
inForeground:(BOOL)fg {
if (fg) {
[self.controller setTab:tab];
}
}
- (void)tabModel:(TabModel*)model
didChangeActiveTab:(Tab*)newTab
previousTab:(Tab*)previousTab
atIndex:(NSUInteger)index {
[self.controller setTab:newTab];
}
- (void)tabModel:(TabModel*)model didChangeTab:(Tab*)tab {
DCHECK(tab && ([model indexOfTab:tab] != NSNotFound));
if (tab == [self.tabModel currentTab]) {
// Disable contextual search when |tab| is a voice search result tab.
[self.controller enableContextualSearch:!tab.isVoiceSearchResultsTab];
}
}
- (void)tabModel:(TabModel*)model willRemoveTab:(Tab*)tab {
if ([model count] == 1) { // About to remove the last tab.
[self.controller setTab:nil];
}
}
#pragma mark - internal
// Creates a new panel view and sets up observers; the panel view's
// configuration is based on the traits of the provider's view.
- (ContextualSearchPanelView*)createPanelView {
PanelConfiguration* config;
CGSize panelContainerSize = self.provider.view.bounds.size;
if (IsIPadIdiom()) {
config = [PadPanelConfiguration
configurationForContainerSize:panelContainerSize
horizontalSizeClass:self.provider.view.traitCollection
.horizontalSizeClass];
} else {
config = [PhonePanelConfiguration
configurationForContainerSize:panelContainerSize
horizontalSizeClass:self.provider.view.traitCollection
.horizontalSizeClass];
}
ContextualSearchPanelView* newPanel =
[[ContextualSearchPanelView alloc] initWithConfiguration:config];
[newPanel addMotionObserver:self];
[newPanel addMotionObserver:self.mask];
return newPanel;
}
@end
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