Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(348)

Side by Side Diff: ios/chrome/browser/ui/contextual_search/contextual_search_controller.mm

Issue 2626073003: [ObjC ARC] Converts ios/chrome/browser/ui/contextual_search:contextual_search to ARC. (Closed)
Patch Set: format Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "ios/chrome/browser/ui/contextual_search/contextual_search_controller.h" 5 #import "ios/chrome/browser/ui/contextual_search/contextual_search_controller.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/ios/ios_util.h" 10 #include "base/ios/ios_util.h"
11 #import "base/ios/weak_nsobject.h"
12 #include "base/json/json_reader.h" 11 #include "base/json/json_reader.h"
13 #include "base/logging.h" 12 #include "base/logging.h"
14 #import "base/mac/bind_objc_block.h" 13 #import "base/mac/bind_objc_block.h"
15 #include "base/mac/foundation_util.h" 14 #include "base/mac/foundation_util.h"
16 #include "base/mac/scoped_block.h" 15 #include "base/mac/scoped_block.h"
17 #include "base/mac/scoped_nsobject.h"
18 #include "base/strings/sys_string_conversions.h" 16 #include "base/strings/sys_string_conversions.h"
19 #include "base/strings/utf_string_conversions.h" 17 #include "base/strings/utf_string_conversions.h"
20 #include "base/time/time.h" 18 #include "base/time/time.h"
21 #include "base/values.h" 19 #include "base/values.h"
22 #include "components/google/core/browser/google_util.h" 20 #include "components/google/core/browser/google_util.h"
23 #include "components/search_engines/template_url_service.h" 21 #include "components/search_engines/template_url_service.h"
24 #include "ios/chrome/browser/application_context.h" 22 #include "ios/chrome/browser/application_context.h"
25 #import "ios/chrome/browser/procedural_block_types.h" 23 #import "ios/chrome/browser/procedural_block_types.h"
26 #import "ios/chrome/browser/tabs/tab.h" 24 #import "ios/chrome/browser/tabs/tab.h"
27 #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h" 25 #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h"
(...skipping 26 matching lines...) Expand all
54 #import "ios/web/public/web_state/crw_web_view_scroll_view_proxy.h" 52 #import "ios/web/public/web_state/crw_web_view_scroll_view_proxy.h"
55 #import "ios/web/public/web_state/js/crw_js_injection_receiver.h" 53 #import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
56 #include "ios/web/public/web_state/web_state.h" 54 #include "ios/web/public/web_state/web_state.h"
57 #include "ios/web/public/web_state/web_state_observer.h" 55 #include "ios/web/public/web_state/web_state_observer.h"
58 #include "ui/base/l10n/l10n_util.h" 56 #include "ui/base/l10n/l10n_util.h"
59 #include "ui/base/l10n/l10n_util_mac.h" 57 #include "ui/base/l10n/l10n_util_mac.h"
60 58
61 // Returns |value| clamped so that min <= value <= max 59 // Returns |value| clamped so that min <= value <= max
62 #define CLAMP(min, value, max) MAX(min, MIN(value, max)) 60 #define CLAMP(min, value, max) MAX(min, MIN(value, max))
63 61
62 #if !defined(__has_feature) || !__has_feature(objc_arc)
63 #error "This file requires ARC support."
64 #endif
65
64 namespace { 66 namespace {
65 // command prefix for injected JavaScript. 67 // command prefix for injected JavaScript.
66 const std::string kCommandPrefix = "contextualSearch"; 68 const std::string kCommandPrefix = "contextualSearch";
67 69
68 // Distance from edges of frame when scrolling to show selection. 70 // Distance from edges of frame when scrolling to show selection.
69 const CGFloat kYScrollMargin = 30.0; 71 const CGFloat kYScrollMargin = 30.0;
70 const CGFloat kXScrollMargin = 10.0; 72 const CGFloat kXScrollMargin = 10.0;
71 73
72 // Delay to check if there is a DOM modification (in second). 74 // Delay to check if there is a DOM modification (in second).
73 // If delay is too short, JavaScript won't have time to handle the event and the 75 // If delay is too short, JavaScript won't have time to handle the event and the
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 rectBottom <= rectTop) { 119 rectBottom <= rectTop) {
118 return CGRectNull; 120 return CGRectNull;
119 } 121 }
120 CGRect rect = 122 CGRect rect =
121 CGRectMake(rectLeft, rectTop, rectRight - rectLeft, rectBottom - rectTop); 123 CGRectMake(rectLeft, rectTop, rectRight - rectLeft, rectBottom - rectTop);
122 return rect; 124 return rect;
123 } 125 }
124 126
125 NSArray* StringValueToRectArray(const std::string& list) { 127 NSArray* StringValueToRectArray(const std::string& list) {
126 NSString* nsList = base::SysUTF8ToNSString(list); 128 NSString* nsList = base::SysUTF8ToNSString(list);
127 NSMutableArray* rectsArray = [[[NSMutableArray alloc] init] autorelease]; 129 NSMutableArray* rectsArray = [[NSMutableArray alloc] init];
128 NSArray* items = [nsList componentsSeparatedByString:@","]; 130 NSArray* items = [nsList componentsSeparatedByString:@","];
129 for (NSString* item : items) { 131 for (NSString* item : items) {
130 CGRect rect = StringValueToRect(item); 132 CGRect rect = StringValueToRect(item);
131 if (CGRectIsNull(rect)) { 133 if (CGRectIsNull(rect)) {
132 return nil; 134 return nil;
133 } 135 }
134 [rectsArray addObject:[NSValue valueWithCGRect:rect]]; 136 [rectsArray addObject:[NSValue valueWithCGRect:rect]];
135 } 137 }
136 return rectsArray; 138 return rectsArray;
137 } 139 }
138 140
139 } // namespace 141 } // namespace
140 142
141 @interface ContextualSearchController ()<DOMAltering, 143 @interface ContextualSearchController ()<DOMAltering,
142 CRWWebViewScrollViewProxyObserver, 144 CRWWebViewScrollViewProxyObserver,
143 UIGestureRecognizerDelegate, 145 UIGestureRecognizerDelegate,
144 ContextualSearchHighlighterDelegate, 146 ContextualSearchHighlighterDelegate,
145 ContextualSearchPromoViewDelegate, 147 ContextualSearchPromoViewDelegate,
146 ContextualSearchPanelMotionObserver, 148 ContextualSearchPanelMotionObserver,
147 ContextualSearchPanelTapHandler, 149 ContextualSearchPanelTapHandler,
148 ContextualSearchPreloadChecker, 150 ContextualSearchPreloadChecker,
149 ContextualSearchTabPromoter, 151 ContextualSearchTabPromoter,
150 ContextualSearchWebStateDelegate, 152 ContextualSearchWebStateDelegate,
151 TouchToSearchPermissionsChangeAudience> 153 TouchToSearchPermissionsChangeAudience>
152 154
153 // Controller delegate for the controller to call back to. 155 // Controller delegate for the controller to call back to.
154 @property(nonatomic, readwrite, assign) id<ContextualSearchControllerDelegate> 156 @property(nonatomic, readwrite, weak) id<ContextualSearchControllerDelegate>
155 controllerDelegate; 157 controllerDelegate;
156 158
157 // Permissions interface for this feature. Property is readwrite for testing. 159 // Permissions interface for this feature. Property is readwrite for testing.
158 @property(nonatomic, readwrite, retain) 160 @property(nonatomic, readwrite, strong)
159 TouchToSearchPermissionsMediator* permissions; 161 TouchToSearchPermissionsMediator* permissions;
160 162
161 // Synchronous method executed by -asynchronouslyEnableContextualSearch: 163 // Synchronous method executed by -asynchronouslyEnableContextualSearch:
162 - (void)doEnableContextualSearch:(BOOL)enabled; 164 - (void)doEnableContextualSearch:(BOOL)enabled;
163 165
164 // Handler for injected JavaScript callbacks. 166 // Handler for injected JavaScript callbacks.
165 - (BOOL)handleScriptCommand:(const base::DictionaryValue&)JSONCommand; 167 - (BOOL)handleScriptCommand:(const base::DictionaryValue&)JSONCommand;
166 168
167 // Handle the selection change event if the DOM lock is acquired. 169 // Handle the selection change event if the DOM lock is acquired.
168 // |selection| is the currently selected text in the webview. 170 // |selection| is the currently selected text in the webview.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 // - vertical: put |_highlightBoundingRect| at |kYScrollMargin| from top edge. 238 // - vertical: put |_highlightBoundingRect| at |kYScrollMargin| from top edge.
237 - (void)scrollToShowSelection:(CRWWebViewScrollViewProxy*)scrollView; 239 - (void)scrollToShowSelection:(CRWWebViewScrollViewProxy*)scrollView;
238 240
239 // Creates, enables or disables the dismiss recognizer based on state_. 241 // Creates, enables or disables the dismiss recognizer based on state_.
240 - (void)updateDismissRecognizer; 242 - (void)updateDismissRecognizer;
241 243
242 @end 244 @end
243 245
244 @implementation ContextualSearchController { 246 @implementation ContextualSearchController {
245 // Permissions interface for this feature. 247 // Permissions interface for this feature.
246 base::scoped_nsobject<TouchToSearchPermissionsMediator> _permissions; 248 TouchToSearchPermissionsMediator* _permissions;
247 249
248 // WebState for the tab this object is attached to. 250 // WebState for the tab this object is attached to.
249 web::WebState* _webState; 251 web::WebState* _webState;
250 252
251 // Access to the web view from |_webState|. 253 // Access to the web view from |_webState|.
252 base::scoped_nsprotocol<id<CRWWebViewProxy>> _webViewProxy; 254 id<CRWWebViewProxy> _webViewProxy;
253 255
254 // Observer for |_webState|. 256 // Observer for |_webState|.
255 std::unique_ptr<ContextualSearchWebStateObserver> _webStateObserver; 257 std::unique_ptr<ContextualSearchWebStateObserver> _webStateObserver;
256 258
257 // Observer for search tab's web state. 259 // Observer for search tab's web state.
258 std::unique_ptr<ContextualSearchWebStateObserver> _searchTabWebStateObserver; 260 std::unique_ptr<ContextualSearchWebStateObserver> _searchTabWebStateObserver;
259 261
260 // Object that manages find_in_page.js injection into the web view. 262 // Object that manages find_in_page.js injection into the web view.
261 base::WeakNSObject<JsContextualSearchManager> _contextualSearchJsManager; 263 __weak JsContextualSearchManager* _contextualSearchJsManager;
262 264
263 // Gesture reccognizer for contextual search taps. 265 // Gesture reccognizer for contextual search taps.
264 base::scoped_nsobject<UITapGestureRecognizer> _tapRecognizer; 266 UITapGestureRecognizer* _tapRecognizer;
265 267
266 // Gesture reccognizer for double tap. It is used to prevent |_tapRecognizer| 268 // Gesture reccognizer for double tap. It is used to prevent |_tapRecognizer|
267 // from firing if there is a double tap on the web view. It is disabled when 269 // from firing if there is a double tap on the web view. It is disabled when
268 // the panel is displayed, since any tap will dismiss the panel in that case. 270 // the panel is displayed, since any tap will dismiss the panel in that case.
269 base::scoped_nsobject<UITapGestureRecognizer> _doubleTapRecognizer; 271 UITapGestureRecognizer* _doubleTapRecognizer;
270 272
271 // Gesture recognizer for long-tap copy. 273 // Gesture recognizer for long-tap copy.
272 base::scoped_nsobject<UILongPressGestureRecognizer> _copyGestureRecognizer; 274 UILongPressGestureRecognizer* _copyGestureRecognizer;
273 275
274 // Gesture recognizer to detect taps outside of the CS interface that would 276 // Gesture recognizer to detect taps outside of the CS interface that would
275 // cause it to dismiss. 277 // cause it to dismiss.
276 base::scoped_nsobject<WindowGestureObserver> _dismissRecognizer; 278 WindowGestureObserver* _dismissRecognizer;
277 279
278 // Context information retrieved from a search tap. 280 // Context information retrieved from a search tap.
279 std::shared_ptr<ContextualSearchContext> _searchContext; 281 std::shared_ptr<ContextualSearchContext> _searchContext;
280 282
281 // Resolved search information generated from the context or text selection. 283 // Resolved search information generated from the context or text selection.
282 ContextualSearchDelegate::SearchResolution _resolvedSearch; 284 ContextualSearchDelegate::SearchResolution _resolvedSearch;
283 285
284 // Delegate for fetching search information. 286 // Delegate for fetching search information.
285 std::unique_ptr<ContextualSearchDelegate> _delegate; 287 std::unique_ptr<ContextualSearchDelegate> _delegate;
286 288
287 // The panel view controlled by this object; it is created externally and 289 // The panel view controlled by this object; it is created externally and
288 // owned by its superview. There is no guarantee about its lifetime. 290 // owned by its superview. There is no guarantee about its lifetime.
289 base::WeakNSObject<ContextualSearchPanelView> _panelView; 291 __weak ContextualSearchPanelView* _panelView;
290 292
291 // The view containing the highlighting of the search terms. 293 // The view containing the highlighting of the search terms.
292 base::WeakNSObject<ContextualSearchHighlighterView> _contextualHighlightView; 294 __weak ContextualSearchHighlighterView* _contextualHighlightView;
293 295
294 // Content view displayed in the peeking section of the panel. 296 // Content view displayed in the peeking section of the panel.
295 base::scoped_nsobject<ContextualSearchHeaderView> _headerView; 297 ContextualSearchHeaderView* _headerView;
296 298
297 // Vertical constraints for layout of the search tab. 299 // Vertical constraints for layout of the search tab.
298 base::scoped_nsobject<NSArray> _searchTabVerticalConstraints; 300 NSArray* _searchTabVerticalConstraints;
299 301
300 // Container view for the opt-out promo and the search tab view. 302 // Container view for the opt-out promo and the search tab view.
301 base::scoped_nsobject<ContextualSearchResultsView> _searchResultsView; 303 ContextualSearchResultsView* _searchResultsView;
302 304
303 // View for the opt-out promo. 305 // View for the opt-out promo.
304 base::scoped_nsobject<ContextualSearchPromoView> _promoView; 306 ContextualSearchPromoView* _promoView;
305 307
306 // The tab that should be used as the opener for the search tab. 308 // The tab that should be used as the opener for the search tab.
307 Tab* _opener; 309 Tab* _opener;
308 310
309 // YES if a cancel event was received since last tap, meaning the current tap 311 // YES if a cancel event was received since last tap, meaning the current tap
310 // must not result in a search. 312 // must not result in a search.
311 BOOL _currentTapCancelled; 313 BOOL _currentTapCancelled;
312 314
313 // The current selection text. 315 // The current selection text.
314 std::string _selectedText; 316 std::string _selectedText;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 // True when closed has been called and contextual search controller 372 // True when closed has been called and contextual search controller
371 // has been destroyed. 373 // has been destroyed.
372 BOOL _closed; 374 BOOL _closed;
373 375
374 // When view is resized, JavaScript and UIView sizes are not updated at the 376 // When view is resized, JavaScript and UIView sizes are not updated at the
375 // same time. Computing a scroll delta to make selection visible in these 377 // same time. Computing a scroll delta to make selection visible in these
376 // conditions will likely scroll to a random position. 378 // conditions will likely scroll to a random position.
377 BOOL _preventScrollToShowSelection; 379 BOOL _preventScrollToShowSelection;
378 380
379 // The time of the last dismiss. 381 // The time of the last dismiss.
380 base::scoped_nsobject<NSDate> _lastDismiss; 382 NSDate* _lastDismiss;
381 } 383 }
382 384
383 @synthesize enabled = _enabled; 385 @synthesize enabled = _enabled;
384 @synthesize controllerDelegate = _controllerDelegate; 386 @synthesize controllerDelegate = _controllerDelegate;
385 @synthesize webState = _webState; 387 @synthesize webState = _webState;
386 388
387 - (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState 389 - (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState
388 delegate:(id<ContextualSearchControllerDelegate>) 390 delegate:(id<ContextualSearchControllerDelegate>)
389 delegate { 391 delegate {
390 if ((self = [super init])) { 392 if ((self = [super init])) {
391 _permissions.reset([[TouchToSearchPermissionsMediator alloc] 393 _permissions = [[TouchToSearchPermissionsMediator alloc]
392 initWithBrowserState:browserState]); 394 initWithBrowserState:browserState];
393 [_permissions setAudience:self]; 395 [_permissions setAudience:self];
394 396
395 self.controllerDelegate = delegate; 397 self.controllerDelegate = delegate;
396 398
397 // Set up the web state observer. This lasts as long as this object does, 399 // Set up the web state observer. This lasts as long as this object does,
398 // but it will observe and un-observe the web tabs as it changes over time. 400 // but it will observe and un-observe the web tabs as it changes over time.
399 _webStateObserver.reset(new ContextualSearchWebStateObserver(self)); 401 _webStateObserver.reset(new ContextualSearchWebStateObserver(self));
400 402
401 _copyGestureRecognizer.reset([[UILongPressGestureRecognizer alloc] 403 _copyGestureRecognizer = [[UILongPressGestureRecognizer alloc]
402 initWithTarget:self 404 initWithTarget:self
403 action:@selector(handleLongPressFrom:)]); 405 action:@selector(handleLongPressFrom:)];
404 406
405 base::WeakNSObject<ContextualSearchController> weakself(self); 407 __weak ContextualSearchController* weakself = self;
406 auto callback = base::BindBlock( 408 auto callback = base::BindBlockArc(
407 ^(ContextualSearchDelegate::SearchResolution resolution) { 409 ^(ContextualSearchDelegate::SearchResolution resolution) {
408 [weakself updateForResolvedSearch:resolution]; 410 [weakself updateForResolvedSearch:resolution];
409 }); 411 });
410 412
411 _delegate.reset(new ContextualSearchDelegate(browserState, callback)); 413 _delegate.reset(new ContextualSearchDelegate(browserState, callback));
412 } 414 }
413 return self; 415 return self;
414 } 416 }
415 417
416 - (TouchToSearchPermissionsMediator*)permissions { 418 - (TouchToSearchPermissionsMediator*)permissions {
417 return _permissions; 419 return _permissions;
418 } 420 }
419 421
420 - (void)setPermissions:(TouchToSearchPermissionsMediator*)permissions { 422 - (void)setPermissions:(TouchToSearchPermissionsMediator*)permissions {
421 _permissions.reset(permissions); 423 _permissions = permissions;
422 } 424 }
423 425
424 - (ContextualSearchPanelView*)panel { 426 - (ContextualSearchPanelView*)panel {
425 return _panelView; 427 return _panelView;
426 } 428 }
427 429
428 - (void)setPanel:(ContextualSearchPanelView*)panel { 430 - (void)setPanel:(ContextualSearchPanelView*)panel {
429 DCHECK(!_panelView); 431 DCHECK(!_panelView);
430 DCHECK(panel); 432 DCHECK(panel);
431 433
432 // Save the new panel, set up observation and delegation relationships. 434 // Save the new panel, set up observation and delegation relationships.
433 _panelView.reset(panel); 435 _panelView = panel;
434 [_panelView addMotionObserver:self]; 436 [_panelView addMotionObserver:self];
435 [_dismissRecognizer setViewToExclude:_panelView]; 437 [_dismissRecognizer setViewToExclude:_panelView];
436 438
437 // Create new subviews. 439 // Create new subviews.
438 NSMutableArray* panelContents = [NSMutableArray arrayWithCapacity:3]; 440 NSMutableArray* panelContents = [NSMutableArray arrayWithCapacity:3];
439 441
440 _headerView.reset([[ContextualSearchHeaderView alloc] 442 _headerView = [[ContextualSearchHeaderView alloc]
441 initWithHeight:[_panelView configuration].peekingHeight]); 443 initWithHeight:[_panelView configuration].peekingHeight];
442 [_headerView addGestureRecognizer:_copyGestureRecognizer]; 444 [_headerView addGestureRecognizer:_copyGestureRecognizer];
443 [_headerView setTapHandler:self]; 445 [_headerView setTapHandler:self];
444 446
445 [panelContents addObject:_headerView]; 447 [panelContents addObject:_headerView];
446 448
447 if (self.permissions.preferenceState == TouchToSearch::UNDECIDED) { 449 if (self.permissions.preferenceState == TouchToSearch::UNDECIDED) {
448 _promoView.reset([[ContextualSearchPromoView alloc] initWithFrame:CGRectZero 450 _promoView = [[ContextualSearchPromoView alloc] initWithFrame:CGRectZero
449 delegate:self]); 451 delegate:self];
450 [panelContents addObject:_promoView]; 452 [panelContents addObject:_promoView];
451 } 453 }
452 454
453 _searchResultsView.reset( 455 _searchResultsView =
454 [[ContextualSearchResultsView alloc] initWithFrame:CGRectZero]); 456 [[ContextualSearchResultsView alloc] initWithFrame:CGRectZero];
455 [_searchResultsView setPromoter:self]; 457 [_searchResultsView setPromoter:self];
456 [_searchResultsView setPreloadChecker:self]; 458 [_searchResultsView setPreloadChecker:self];
457 [panelContents addObject:_searchResultsView]; 459 [panelContents addObject:_searchResultsView];
458 460
459 [_panelView addContentViews:panelContents]; 461 [_panelView addContentViews:panelContents];
460 } 462 }
461 463
462 - (void)enableContextualSearch:(BOOL)enabled { 464 - (void)enableContextualSearch:(BOOL)enabled {
463 // Asynchronously enables contextual search, so that some preferences 465 // Asynchronously enables contextual search, so that some preferences
464 // (UIAccessibilityIsVoiceOverRunning(), for example) have time to synchronize 466 // (UIAccessibilityIsVoiceOverRunning(), for example) have time to synchronize
465 // with their own notifications. 467 // with their own notifications.
466 base::WeakNSObject<ContextualSearchController> weakSelf(self); 468 __weak ContextualSearchController* weakSelf = self;
467 dispatch_async(dispatch_get_main_queue(), ^{ 469 dispatch_async(dispatch_get_main_queue(), ^{
468 [weakSelf doEnableContextualSearch:enabled]; 470 [weakSelf doEnableContextualSearch:enabled];
469 }); 471 });
470 } 472 }
471 473
472 - (void)doEnableContextualSearch:(BOOL)enabled { 474 - (void)doEnableContextualSearch:(BOOL)enabled {
473 enabled = enabled && [self.permissions canEnable]; 475 enabled = enabled && [self.permissions canEnable];
474 476
475 BOOL changing = _enabled != enabled; 477 BOOL changing = _enabled != enabled;
476 if (changing) { 478 if (changing) {
477 if (!enabled) { 479 if (!enabled) {
478 [self dismissPane:ContextualSearch::RESET]; 480 [self dismissPane:ContextualSearch::RESET];
479 } 481 }
480 _enabled = enabled; 482 _enabled = enabled;
481 [self enableCurrentWebState]; 483 [self enableCurrentWebState];
482 } 484 }
483 } 485 }
484 486
485 - (void)updateWebViewProxy:(id<CRWWebViewProxy>)webViewProxy { 487 - (void)updateWebViewProxy:(id<CRWWebViewProxy>)webViewProxy {
486 if (_webViewProxy) { 488 if (_webViewProxy) {
487 [[_webViewProxy scrollViewProxy] removeObserver:self]; 489 [[_webViewProxy scrollViewProxy] removeObserver:self];
488 } 490 }
489 _webViewProxy.reset([webViewProxy retain]); 491 _webViewProxy = webViewProxy;
490 if (_webViewProxy) { 492 if (_webViewProxy) {
491 [[_webViewProxy scrollViewProxy] addObserver:self]; 493 [[_webViewProxy scrollViewProxy] addObserver:self];
492 } 494 }
493 } 495 }
494 496
495 - (void)setTab:(Tab*)tab { 497 - (void)setTab:(Tab*)tab {
496 [self setWebState:tab.webState]; 498 [self setWebState:tab.webState];
497 [_searchResultsView setOpener:tab]; 499 [_searchResultsView setOpener:tab];
498 } 500 }
499 501
500 - (void)setWebState:(web::WebState*)webState { 502 - (void)setWebState:(web::WebState*)webState {
501 [self disconnectWebState]; 503 [self disconnectWebState];
502 if (webState) { 504 if (webState) {
503 _contextualSearchJsManager.reset(static_cast<JsContextualSearchManager*>( 505 _contextualSearchJsManager = static_cast<JsContextualSearchManager*>(
504 [webState->GetJSInjectionReceiver() 506 [webState->GetJSInjectionReceiver()
505 instanceOfClass:[JsContextualSearchManager class]])); 507 instanceOfClass:[JsContextualSearchManager class]]);
506 _webState = webState; 508 _webState = webState;
507 _webStateObserver->ObserveWebState(webState); 509 _webStateObserver->ObserveWebState(webState);
508 [self updateWebViewProxy:webState->GetWebViewProxy()]; 510 [self updateWebViewProxy:webState->GetWebViewProxy()];
509 [self enableCurrentWebState]; 511 [self enableCurrentWebState];
510 } else { 512 } else {
511 _webState = nullptr; 513 _webState = nullptr;
512 } 514 }
513 } 515 }
514 516
515 - (void)enableCurrentWebState { 517 - (void)enableCurrentWebState {
516 if (![self webState]) 518 if (![self webState])
517 return; 519 return;
518 if (_enabled && [self webState]->ContentIsHTML()) { 520 if (_enabled && [self webState]->ContentIsHTML()) {
519 if (!_webStateEnabled) { 521 if (!_webStateEnabled) {
520 DOMAlteringLock::CreateForWebState([self webState]); 522 DOMAlteringLock::CreateForWebState([self webState]);
521 523
522 base::WeakNSObject<ContextualSearchController> weakSelf(self); 524 __weak ContextualSearchController* weakSelf = self;
523 auto callback = 525 auto callback = base::BindBlockArc(
524 base::BindBlock(^bool(const base::DictionaryValue& JSON, 526 ^bool(const base::DictionaryValue& JSON, const GURL& originURL,
525 const GURL& originURL, bool userIsInteracting) { 527 bool userIsInteracting) {
526 base::scoped_nsobject<ContextualSearchController> strongSelf( 528 ContextualSearchController* strongSelf = weakSelf;
527 [weakSelf retain]);
528 // |originURL| and |isInteracting| aren't used. 529 // |originURL| and |isInteracting| aren't used.
529 return [strongSelf handleScriptCommand:JSON]; 530 return [strongSelf handleScriptCommand:JSON];
530 }); 531 });
531 [self webState]->AddScriptCommandCallback(callback, kCommandPrefix); 532 [self webState]->AddScriptCommandCallback(callback, kCommandPrefix);
532 533
533 // |_doubleTapRecognizer| should be added to the web view before 534 // |_doubleTapRecognizer| should be added to the web view before
534 // |_tapRecognizer| so |_tapRecognizer| can require it to fail. 535 // |_tapRecognizer| so |_tapRecognizer| can require it to fail.
535 _doubleTapRecognizer.reset([[UITapGestureRecognizer alloc] 536 _doubleTapRecognizer =
536 initWithTarget:self 537 [[UITapGestureRecognizer alloc] initWithTarget:self
537 action:@selector(ignoreTap:)]); 538 action:@selector(ignoreTap:)];
538 [_doubleTapRecognizer setDelegate:self]; 539 [_doubleTapRecognizer setDelegate:self];
539 [_doubleTapRecognizer setNumberOfTapsRequired:2]; 540 [_doubleTapRecognizer setNumberOfTapsRequired:2];
540 [_webViewProxy addGestureRecognizer:_doubleTapRecognizer]; 541 [_webViewProxy addGestureRecognizer:_doubleTapRecognizer];
541 542
542 _tapRecognizer.reset([[UITapGestureRecognizer alloc] 543 _tapRecognizer = [[UITapGestureRecognizer alloc]
543 initWithTarget:self 544 initWithTarget:self
544 action:@selector(handleTapFrom:)]); 545 action:@selector(handleTapFrom:)];
545 [_tapRecognizer setDelegate:self]; 546 [_tapRecognizer setDelegate:self];
546 [_webViewProxy addGestureRecognizer:_tapRecognizer]; 547 [_webViewProxy addGestureRecognizer:_tapRecognizer];
547 548
548 // Make sure that |_tapRecogngizer| doesn't fire if the web view's other 549 // Make sure that |_tapRecogngizer| doesn't fire if the web view's other
549 // non-single-finger non-single-tap recognizers fire. 550 // non-single-finger non-single-tap recognizers fire.
550 for (UIGestureRecognizer* recognizer in 551 for (UIGestureRecognizer* recognizer in
551 [[_tapRecognizer view] gestureRecognizers]) { 552 [[_tapRecognizer view] gestureRecognizers]) {
552 if ([recognizer isKindOfClass:[UITapGestureRecognizer class]] && 553 if ([recognizer isKindOfClass:[UITapGestureRecognizer class]] &&
553 ([static_cast<UITapGestureRecognizer*>(recognizer) 554 ([static_cast<UITapGestureRecognizer*>(recognizer)
554 numberOfTapsRequired] > 1 || 555 numberOfTapsRequired] > 1 ||
(...skipping 22 matching lines...) Expand all
577 _webState->RemoveScriptCommandCallback(kCommandPrefix); 578 _webState->RemoveScriptCommandCallback(kCommandPrefix);
578 DOMAlteringLock::FromWebState(_webState)->Release(self); 579 DOMAlteringLock::FromWebState(_webState)->Release(self);
579 [_webViewProxy removeGestureRecognizer:_tapRecognizer]; 580 [_webViewProxy removeGestureRecognizer:_tapRecognizer];
580 [_webViewProxy removeGestureRecognizer:_doubleTapRecognizer]; 581 [_webViewProxy removeGestureRecognizer:_doubleTapRecognizer];
581 _webStateEnabled = NO; 582 _webStateEnabled = NO;
582 } 583 }
583 } 584 }
584 585
585 - (void)disconnectWebState { 586 - (void)disconnectWebState {
586 if (_webState) { 587 if (_webState) {
587 _contextualSearchJsManager.reset(); 588 _contextualSearchJsManager = nil;
588 _webStateObserver->ObserveWebState(nullptr); 589 _webStateObserver->ObserveWebState(nullptr);
589 [self updateWebViewProxy:nil]; 590 [self updateWebViewProxy:nil];
590 [self disableCurrentWebState]; 591 [self disableCurrentWebState];
591 } 592 }
592 } 593 }
593 594
594 - (void)updateDismissRecognizer { 595 - (void)updateDismissRecognizer {
595 if (!_panelView) 596 if (!_panelView)
596 return; 597 return;
597 if (!_dismissRecognizer) { 598 if (!_dismissRecognizer) {
598 _dismissRecognizer.reset([[WindowGestureObserver alloc] 599 _dismissRecognizer = [[WindowGestureObserver alloc]
599 initWithTarget:self 600 initWithTarget:self
600 action:@selector(handleWindowGesture:)]); 601 action:@selector(handleWindowGesture:)];
601 [_dismissRecognizer setViewToExclude:_panelView]; 602 [_dismissRecognizer setViewToExclude:_panelView];
602 [[_panelView window] addGestureRecognizer:_dismissRecognizer]; 603 [[_panelView window] addGestureRecognizer:_dismissRecognizer];
603 } 604 }
604 605
605 [_dismissRecognizer 606 [_dismissRecognizer
606 setEnabled:[_panelView state] >= ContextualSearch::PEEKING]; 607 setEnabled:[_panelView state] >= ContextualSearch::PEEKING];
607 } 608 }
608 609
609 - (void)showLearnMore { 610 - (void)showLearnMore {
610 [self dismissPane:ContextualSearch::UNKNOWN]; 611 [self dismissPane:ContextualSearch::UNKNOWN];
611 GURL learnMoreUrl = google_util::AppendGoogleLocaleParam( 612 GURL learnMoreUrl = google_util::AppendGoogleLocaleParam(
612 GURL(l10n_util::GetStringUTF8(IDS_IOS_CONTEXTUAL_SEARCH_LEARN_MORE_URL)), 613 GURL(l10n_util::GetStringUTF8(IDS_IOS_CONTEXTUAL_SEARCH_LEARN_MORE_URL)),
613 GetApplicationContext()->GetApplicationLocale()); 614 GetApplicationContext()->GetApplicationLocale());
614 [_controllerDelegate createTabFromContextualSearchController:learnMoreUrl]; 615 [_controllerDelegate createTabFromContextualSearchController:learnMoreUrl];
615 } 616 }
616 617
617 - (void)dealloc { 618 - (void)dealloc {
618 [self close]; 619 [self close];
619 [super dealloc];
620 } 620 }
621 621
622 - (void)handleWindowGesture:(UIGestureRecognizer*)recognizer { 622 - (void)handleWindowGesture:(UIGestureRecognizer*)recognizer {
623 DCHECK(recognizer == _dismissRecognizer.get()); 623 DCHECK(recognizer == _dismissRecognizer);
624 [self dismissPane:ContextualSearch::BASE_PAGE_TAP]; 624 [self dismissPane:ContextualSearch::BASE_PAGE_TAP];
625 } 625 }
626 626
627 - (BOOL)canExtractTapContext { 627 - (BOOL)canExtractTapContext {
628 web::URLVerificationTrustLevel trustLevel = web::kNone; 628 web::URLVerificationTrustLevel trustLevel = web::kNone;
629 GURL pageURL = [self webState]->GetCurrentURL(&trustLevel); 629 GURL pageURL = [self webState]->GetCurrentURL(&trustLevel);
630 return [self.permissions canExtractTapContextForURL:pageURL]; 630 return [self.permissions canExtractTapContextForURL:pageURL];
631 } 631 }
632 632
633 - (void)initializeWebViewForContextualSearch { 633 - (void)initializeWebViewForContextualSearch {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 if (command == "contextualSearch.selectionChanged") { 699 if (command == "contextualSearch.selectionChanged") {
700 std::string selectedText; 700 std::string selectedText;
701 if (!JSONCommand.GetString("text", &selectedText)) 701 if (!JSONCommand.GetString("text", &selectedText))
702 return NO; 702 return NO;
703 bool selectionUpdated; 703 bool selectionUpdated;
704 if (!JSONCommand.GetBoolean("updated", &selectionUpdated)) 704 if (!JSONCommand.GetBoolean("updated", &selectionUpdated))
705 selectionUpdated = false; 705 selectionUpdated = false;
706 bool selectionValid; 706 bool selectionValid;
707 if (!JSONCommand.GetBoolean("valid", &selectionValid)) 707 if (!JSONCommand.GetBoolean("valid", &selectionValid))
708 selectionValid = true; 708 selectionValid = true;
709 base::WeakNSObject<ContextualSearchController> weakSelf(self); 709 __weak ContextualSearchController* weakSelf = self;
710 ProceduralBlockWithBool lockAction = ^(BOOL lockAcquired) { 710 ProceduralBlockWithBool lockAction = ^(BOOL lockAcquired) {
711 if (lockAcquired) { 711 if (lockAcquired) {
712 [weakSelf handleSelectionChanged:selectedText 712 [weakSelf handleSelectionChanged:selectedText
713 selectionUpdated:selectionUpdated 713 selectionUpdated:selectionUpdated
714 selectionValid:selectionValid]; 714 selectionValid:selectionValid];
715 } 715 }
716 }; 716 };
717 DOMAlteringLock::FromWebState([self webState])->Acquire(self, lockAction); 717 DOMAlteringLock::FromWebState([self webState])->Acquire(self, lockAction);
718 return YES; 718 return YES;
719 } 719 }
720 if (command == "contextualSearch.mutationEvent") { 720 if (command == "contextualSearch.mutationEvent") {
721 if ([_panelView state] <= ContextualSearch::PEEKING && 721 if ([_panelView state] <= ContextualSearch::PEEKING &&
722 !_searchTermResolved) { 722 !_searchTermResolved) {
723 [self dismissPane:ContextualSearch::UNKNOWN]; 723 [self dismissPane:ContextualSearch::UNKNOWN];
724 } 724 }
725 return YES; 725 return YES;
726 } 726 }
727 return NO; 727 return NO;
728 } 728 }
729 729
730 - (void)ignoreTap:(UIGestureRecognizer*)recognizer { 730 - (void)ignoreTap:(UIGestureRecognizer*)recognizer {
731 // This method is intentionally empty. It is intended to ignore the tap. 731 // This method is intentionally empty. It is intended to ignore the tap.
732 } 732 }
733 733
734 - (void)handleTapFrom:(UIGestureRecognizer*)recognizer { 734 - (void)handleTapFrom:(UIGestureRecognizer*)recognizer {
735 DCHECK(recognizer == _tapRecognizer.get()); 735 DCHECK(recognizer == _tapRecognizer);
736 // Taps will be triggered by long-presses to make a selection in the webview, 736 // Taps will be triggered by long-presses to make a selection in the webview,
737 // as well as 'regular' taps. Long-presses that create a selection will set 737 // as well as 'regular' taps. Long-presses that create a selection will set
738 // |_newSelectionDisplaying| as well as populating _selectedText (this happens 738 // |_newSelectionDisplaying| as well as populating _selectedText (this happens
739 // in -handleScriptCommand:). 739 // in -handleScriptCommand:).
740 740
741 // If we just dismissed, do not consider this tap. 741 // If we just dismissed, do not consider this tap.
742 NSTimeInterval dismissTimeout = [_lastDismiss timeIntervalSinceNow] + 742 NSTimeInterval dismissTimeout = [_lastDismiss timeIntervalSinceNow] +
743 kPreventTriggerAfterDismissDelaySeconds; 743 kPreventTriggerAfterDismissDelaySeconds;
744 744
745 // If the panel is already displayed, just dismiss it and return, unless the 745 // If the panel is already displayed, just dismiss it and return, unless the
(...skipping 21 matching lines...) Expand all
767 CGPoint tapPoint = [recognizer locationInView:recognizer.view]; 767 CGPoint tapPoint = [recognizer locationInView:recognizer.view];
768 // tapPoint is the coordinate of the tap in the webView. If the view is 768 // tapPoint is the coordinate of the tap in the webView. If the view is
769 // currently offset because a header is displayed, offset the tapPoint. 769 // currently offset because a header is displayed, offset the tapPoint.
770 tapPoint.y -= [_controllerDelegate currentHeaderHeight]; 770 tapPoint.y -= [_controllerDelegate currentHeaderHeight];
771 771
772 // Handle tap asynchronously to monitor DOM modifications. See comment 772 // Handle tap asynchronously to monitor DOM modifications. See comment
773 // of |kDOMModificationDelaySeconds| for details. 773 // of |kDOMModificationDelaySeconds| for details.
774 dispatch_time_t dispatch = dispatch_time( 774 dispatch_time_t dispatch = dispatch_time(
775 DISPATCH_TIME_NOW, 775 DISPATCH_TIME_NOW,
776 static_cast<int64_t>(kDOMModificationDelaySeconds * NSEC_PER_SEC)); 776 static_cast<int64_t>(kDOMModificationDelaySeconds * NSEC_PER_SEC));
777 base::WeakNSObject<ContextualSearchController> weakSelf(self); 777 __weak ContextualSearchController* weakSelf = self;
778 dispatch_after(dispatch, dispatch_get_main_queue(), ^{ 778 dispatch_after(dispatch, dispatch_get_main_queue(), ^{
779 [weakSelf handleTapAtPoint:tapPoint]; 779 [weakSelf handleTapAtPoint:tapPoint];
780 }); 780 });
781 }; 781 };
782 DOMAlteringLock::FromWebState([self webState])->Acquire(self, lockAction); 782 DOMAlteringLock::FromWebState([self webState])->Acquire(self, lockAction);
783 } 783 }
784 784
785 - (void)handleLongPressFrom:(UIGestureRecognizer*)recognizer { 785 - (void)handleLongPressFrom:(UIGestureRecognizer*)recognizer {
786 DCHECK(recognizer == _copyGestureRecognizer.get()); 786 DCHECK(recognizer == _copyGestureRecognizer);
787 if (recognizer.state != UIGestureRecognizerStateEnded) 787 if (recognizer.state != UIGestureRecognizerStateEnded)
788 return; 788 return;
789 789
790 // Put the resolved search term (or the current selected text) into the 790 // Put the resolved search term (or the current selected text) into the
791 // pasteboard. 791 // pasteboard.
792 std::string text; 792 std::string text;
793 if (!_resolvedSearch.display_text.empty()) { 793 if (!_resolvedSearch.display_text.empty()) {
794 text = _resolvedSearch.display_text; 794 text = _resolvedSearch.display_text;
795 } 795 }
796 796
(...skipping 23 matching lines...) Expand all
820 std::string encoding = "UTF-8"; 820 std::string encoding = "UTF-8";
821 821
822 CGPoint relativeTapPoint = point; 822 CGPoint relativeTapPoint = point;
823 CGSize contentSize = [_webViewProxy scrollViewProxy].contentSize; 823 CGSize contentSize = [_webViewProxy scrollViewProxy].contentSize;
824 relativeTapPoint.x += [_webViewProxy scrollViewProxy].contentOffset.x; 824 relativeTapPoint.x += [_webViewProxy scrollViewProxy].contentOffset.x;
825 relativeTapPoint.y += [_webViewProxy scrollViewProxy].contentOffset.y; 825 relativeTapPoint.y += [_webViewProxy scrollViewProxy].contentOffset.y;
826 826
827 relativeTapPoint.x /= contentSize.width; 827 relativeTapPoint.x /= contentSize.width;
828 relativeTapPoint.y /= contentSize.height; 828 relativeTapPoint.y /= contentSize.height;
829 829
830 base::WeakNSProtocol<id<CRWWebViewProxy>> weakWebViewProxy( 830 __weak id<CRWWebViewProxy> weakWebViewProxy = _webViewProxy;
831 _webViewProxy.get());
832 void (^handler)(NSString*) = ^(NSString* result) { 831 void (^handler)(NSString*) = ^(NSString* result) {
833 [_tapRecognizer setEnabled:YES]; 832 [_tapRecognizer setEnabled:YES];
834 // If there has been an error in the javascript, return can be nil. 833 // If there has been an error in the javascript, return can be nil.
835 if (!result || _currentTapCancelled) 834 if (!result || _currentTapCancelled)
836 return; 835 return;
837 836
838 // Parse JSON. 837 // Parse JSON.
839 const std::string json = base::SysNSStringToUTF8(result); 838 const std::string json = base::SysNSStringToUTF8(result);
840 std::unique_ptr<base::Value> parsedResult( 839 std::unique_ptr<base::Value> parsedResult(
841 base::JSONReader::Read(json, false)); 840 base::JSONReader::Read(json, false));
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 1014
1016 if (_resolvedSearch.is_invalid) { 1015 if (_resolvedSearch.is_invalid) {
1017 [self dismissPane:ContextualSearch::UNKNOWN]; 1016 [self dismissPane:ContextualSearch::UNKNOWN];
1018 } else { 1017 } else {
1019 _searchTermResolved = YES; 1018 _searchTermResolved = YES;
1020 [_headerView 1019 [_headerView
1021 setSearchTerm:base::SysUTF8ToNSString(_resolvedSearch.display_text) 1020 setSearchTerm:base::SysUTF8ToNSString(_resolvedSearch.display_text)
1022 animated:[_panelView state] != ContextualSearch::DISMISSED]; 1021 animated:[_panelView state] != ContextualSearch::DISMISSED];
1023 if (_resolvedSearch.start_offset != -1 && 1022 if (_resolvedSearch.start_offset != -1 &&
1024 _resolvedSearch.end_offset != -1) { 1023 _resolvedSearch.end_offset != -1) {
1025 base::WeakNSObject<ContextualSearchController> weakSelf(self); 1024 __weak ContextualSearchController* weakSelf = self;
1026 [_contextualSearchJsManager 1025 [_contextualSearchJsManager
1027 expandHighlightToStartOffset:_resolvedSearch.start_offset 1026 expandHighlightToStartOffset:_resolvedSearch.start_offset
1028 endOffset:_resolvedSearch.end_offset 1027 endOffset:_resolvedSearch.end_offset
1029 completionHandler:^(id result, NSError* error) { 1028 completionHandler:^(id result, NSError* error) {
1030 [weakSelf handleHighlightJSResult:result 1029 [weakSelf handleHighlightJSResult:result
1031 withError:error]; 1030 withError:error];
1032 }]; 1031 }];
1033 } 1032 }
1034 GURL url = _delegate->GetURLForResolvedSearch(_resolvedSearch, true); 1033 GURL url = _delegate->GetURLForResolvedSearch(_resolvedSearch, true);
1035 [_searchResultsView createTabForSearch:url 1034 [_searchResultsView createTabForSearch:url
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 animated:[_panelView state] != ContextualSearch::DISMISSED]; 1068 animated:[_panelView state] != ContextualSearch::DISMISSED];
1070 } 1069 }
1071 } else { 1070 } else {
1072 ContextualSearch::RecordSelectionIsValid(false); 1071 ContextualSearch::RecordSelectionIsValid(false);
1073 [self dismissPane:ContextualSearch::INVALID_SELECTION]; 1072 [self dismissPane:ContextualSearch::INVALID_SELECTION];
1074 } 1073 }
1075 } 1074 }
1076 - (void)scrollToShowSelection:(CRWWebViewScrollViewProxy*)scrollView { 1075 - (void)scrollToShowSelection:(CRWWebViewScrollViewProxy*)scrollView {
1077 if (!scrollView || _preventScrollToShowSelection) 1076 if (!scrollView || _preventScrollToShowSelection)
1078 return; 1077 return;
1079 if (!_contextualHighlightView.get()) { 1078 if (!_contextualHighlightView) {
1080 return; 1079 return;
1081 } 1080 }
1082 CGRect highlightBoundingRect = [_contextualHighlightView boundingRect]; 1081 CGRect highlightBoundingRect = [_contextualHighlightView boundingRect];
1083 if (CGRectIsNull(highlightBoundingRect)) { 1082 if (CGRectIsNull(highlightBoundingRect)) {
1084 return; 1083 return;
1085 } 1084 }
1086 1085
1087 // Do the maths without the insets. 1086 // Do the maths without the insets.
1088 CGPoint scrollPoint = [scrollView contentOffset]; 1087 CGPoint scrollPoint = [scrollView contentOffset];
1089 scrollPoint.y += scrollView.contentInset.top; 1088 scrollPoint.y += scrollView.contentInset.top;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1157 1156
1158 scrollPoint.y -= scrollView.contentInset.top; 1157 scrollPoint.y -= scrollView.contentInset.top;
1159 scrollPoint.x -= scrollView.contentInset.left; 1158 scrollPoint.x -= scrollView.contentInset.left;
1160 [scrollView setContentOffset:scrollPoint animated:YES]; 1159 [scrollView setContentOffset:scrollPoint animated:YES];
1161 } 1160 }
1162 1161
1163 - (void)highlightRects:(NSArray*)rects { 1162 - (void)highlightRects:(NSArray*)rects {
1164 if (![self webState]) { 1163 if (![self webState]) {
1165 return; 1164 return;
1166 } 1165 }
1167 if (!_contextualHighlightView.get() && [rects count]) { 1166 if (!_contextualHighlightView && [rects count]) {
1168 CGRect frame = [[self webState]->GetWebViewProxy() frame]; 1167 CGRect frame = [[self webState]->GetWebViewProxy() frame];
1169 ContextualSearchHighlighterView* highlightView = 1168 ContextualSearchHighlighterView* highlightView =
1170 [[[ContextualSearchHighlighterView alloc] initWithFrame:frame 1169 [[ContextualSearchHighlighterView alloc] initWithFrame:frame
1171 delegate:self] 1170 delegate:self];
1172 autorelease]; 1171 _contextualHighlightView = highlightView;
1173 _contextualHighlightView.reset(highlightView);
1174 [[self webState]->GetWebViewProxy() addSubview:highlightView]; 1172 [[self webState]->GetWebViewProxy() addSubview:highlightView];
1175 } 1173 }
1176 CGPoint scroll = [[_webViewProxy scrollViewProxy] contentOffset]; 1174 CGPoint scroll = [[_webViewProxy scrollViewProxy] contentOffset];
1177 [_contextualHighlightView 1175 [_contextualHighlightView
1178 highlightRects:rects 1176 highlightRects:rects
1179 withOffset:[_controllerDelegate currentHeaderHeight] 1177 withOffset:[_controllerDelegate currentHeaderHeight]
1180 zoom:[[_webViewProxy scrollViewProxy] zoomScale] 1178 zoom:[[_webViewProxy scrollViewProxy] zoomScale]
1181 scroll:scroll]; 1179 scroll:scroll];
1182 } 1180 }
1183 1181
(...skipping 22 matching lines...) Expand all
1206 if (_closed) 1204 if (_closed)
1207 return; 1205 return;
1208 1206
1209 _closed = YES; 1207 _closed = YES;
1210 [self disableCurrentWebState]; 1208 [self disableCurrentWebState];
1211 [self setWebState:nil]; 1209 [self setWebState:nil];
1212 [_headerView removeGestureRecognizer:_copyGestureRecognizer]; 1210 [_headerView removeGestureRecognizer:_copyGestureRecognizer];
1213 [[_panelView window] removeGestureRecognizer:_dismissRecognizer]; 1211 [[_panelView window] removeGestureRecognizer:_dismissRecognizer];
1214 _delegate.reset(); 1212 _delegate.reset();
1215 [_searchResultsView setActive:NO]; 1213 [_searchResultsView setActive:NO];
1216 _searchResultsView.reset(); 1214 _searchResultsView = nil;
1217 } 1215 }
1218 1216
1219 #pragma mark - Promo view management 1217 #pragma mark - Promo view management
1220 1218
1221 - (void)userOptedInFromPromo:(BOOL)optIn { 1219 - (void)userOptedInFromPromo:(BOOL)optIn {
1222 if (optIn) { 1220 if (optIn) {
1223 self.permissions.preferenceState = TouchToSearch::ENABLED; 1221 self.permissions.preferenceState = TouchToSearch::ENABLED;
1224 [_promoView closeAnimated:YES]; 1222 [_promoView closeAnimated:YES];
1225 [_promoView setDisabled:YES]; 1223 [_promoView setDisabled:YES];
1226 } else { 1224 } else {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1282 // Dragged up. 1280 // Dragged up.
1283 [self coverPane:ContextualSearch::SWIPE]; 1281 [self coverPane:ContextualSearch::SWIPE];
1284 } 1282 }
1285 } 1283 }
1286 [self updateHighlight]; 1284 [self updateHighlight];
1287 } 1285 }
1288 1286
1289 - (void)panelWillPromote:(ContextualSearchPanelView*)panel { 1287 - (void)panelWillPromote:(ContextualSearchPanelView*)panel {
1290 DCHECK(panel == _panelView); 1288 DCHECK(panel == _panelView);
1291 [panel removeMotionObserver:self]; 1289 [panel removeMotionObserver:self];
1292 _panelView.reset(); 1290 _panelView = nil;
1293 [self setState:ContextualSearch::DISMISSED 1291 [self setState:ContextualSearch::DISMISSED
1294 reason:ContextualSearch::TAB_PROMOTION]; 1292 reason:ContextualSearch::TAB_PROMOTION];
1295 } 1293 }
1296 1294
1297 #pragma mark - ContextualSearchPanelTapHandler 1295 #pragma mark - ContextualSearchPanelTapHandler
1298 1296
1299 - (void)panelWasTapped:(UIGestureRecognizer*)gesture { 1297 - (void)panelWasTapped:(UIGestureRecognizer*)gesture {
1300 // Tapping when peeking switches to previewing. 1298 // Tapping when peeking switches to previewing.
1301 // Tapping otherwise turns the panel into a tab. 1299 // Tapping otherwise turns the panel into a tab.
1302 if ([_panelView state] == ContextualSearch::PEEKING) { 1300 if ([_panelView state] == ContextualSearch::PEEKING) {
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1416 - (void) 1414 - (void)
1417 dismissPaneWithJavascriptCompletionHandler:(ProceduralBlock)completionHandler 1415 dismissPaneWithJavascriptCompletionHandler:(ProceduralBlock)completionHandler
1418 reason:(ContextualSearch::StateChangeReason) 1416 reason:(ContextualSearch::StateChangeReason)
1419 reason { 1417 reason {
1420 [self cleanUpWebStateForDismissWithCompletion:completionHandler]; 1418 [self cleanUpWebStateForDismissWithCompletion:completionHandler];
1421 [self setState:ContextualSearch::DISMISSED reason:reason]; 1419 [self setState:ContextualSearch::DISMISSED reason:reason];
1422 } 1420 }
1423 1421
1424 - (void)cleanUpWebStateForDismissWithCompletion: 1422 - (void)cleanUpWebStateForDismissWithCompletion:
1425 (ProceduralBlock)completionHandler { 1423 (ProceduralBlock)completionHandler {
1426 _lastDismiss.reset([[NSDate date] retain]); 1424 _lastDismiss = [NSDate date];
1427 _currentTapCancelled = YES; 1425 _currentTapCancelled = YES;
1428 ContextualSearch::PanelState originalState = [_panelView state]; 1426 ContextualSearch::PanelState originalState = [_panelView state];
1429 if (originalState == ContextualSearch::DISMISSED) { 1427 if (originalState == ContextualSearch::DISMISSED) {
1430 DCHECK(![_searchResultsView active]); 1428 DCHECK(![_searchResultsView active]);
1431 if ([self webState]) { 1429 if ([self webState]) {
1432 DOMAlteringLock* lock = DOMAlteringLock::FromWebState([self webState]); 1430 DOMAlteringLock* lock = DOMAlteringLock::FromWebState([self webState]);
1433 if (lock) { 1431 if (lock) {
1434 lock->Release(self); 1432 lock->Release(self);
1435 } 1433 }
1436 } 1434 }
1437 if (completionHandler) 1435 if (completionHandler)
1438 completionHandler(); 1436 completionHandler();
1439 return; 1437 return;
1440 } 1438 }
1441 1439
1442 [_doubleTapRecognizer setEnabled:YES]; 1440 [_doubleTapRecognizer setEnabled:YES];
1443 _searchContext.reset(); 1441 _searchContext.reset();
1444 [_searchResultsView setActive:NO]; 1442 [_searchResultsView setActive:NO];
1445 _delegate->CancelSearchTermRequest(); 1443 _delegate->CancelSearchTermRequest();
1446 _selectedText = ""; 1444 _selectedText = "";
1447 1445
1448 ContextualSearchDelegate::SearchResolution blank; 1446 ContextualSearchDelegate::SearchResolution blank;
1449 _resolvedSearch = blank; 1447 _resolvedSearch = blank;
1450 if (completionHandler) { 1448 if (completionHandler) {
1451 base::WeakNSObject<ContextualSearchController> weakSelf(self); 1449 __weak ContextualSearchController* weakSelf = self;
1452 ProceduralBlock javaScriptCompletion = ^{ 1450 ProceduralBlock javaScriptCompletion = ^{
1453 if ([self webState]) { 1451 if ([weakSelf webState]) {
1454 DOMAlteringLock::FromWebState([self webState])->Release(self); 1452 DOMAlteringLock::FromWebState([weakSelf webState])->Release(weakSelf);
1455 completionHandler(); 1453 completionHandler();
1456 } 1454 }
1457 }; 1455 };
1458 [self highlightRects:nil]; 1456 [self highlightRects:nil];
1459 [_contextualSearchJsManager clearHighlight]; 1457 [_contextualSearchJsManager clearHighlight];
1460 javaScriptCompletion(); 1458 javaScriptCompletion();
1461 } else { 1459 } else {
1462 [self highlightRects:nil]; 1460 [self highlightRects:nil];
1463 [_contextualSearchJsManager clearHighlight]; 1461 [_contextualSearchJsManager clearHighlight];
1464 DOMAlteringLock::FromWebState([self webState])->Release(self); 1462 DOMAlteringLock::FromWebState([self webState])->Release(self);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1513 1511
1514 - (void)promoViewAcceptTapped { 1512 - (void)promoViewAcceptTapped {
1515 [self userOptedInFromPromo:YES]; 1513 [self userOptedInFromPromo:YES];
1516 } 1514 }
1517 1515
1518 - (void)promoViewDeclineTapped { 1516 - (void)promoViewDeclineTapped {
1519 [self userOptedInFromPromo:NO]; 1517 [self userOptedInFromPromo:NO];
1520 } 1518 }
1521 1519
1522 - (void)promoViewSettingsTapped { 1520 - (void)promoViewSettingsTapped {
1523 base::scoped_nsobject<GenericChromeCommand> command( 1521 GenericChromeCommand* command = [[GenericChromeCommand alloc]
1524 [[GenericChromeCommand alloc] 1522 initWithTag:IDC_SHOW_CONTEXTUAL_SEARCH_SETTINGS];
1525 initWithTag:IDC_SHOW_CONTEXTUAL_SEARCH_SETTINGS]);
1526 UIWindow* main_window = [[UIApplication sharedApplication] keyWindow]; 1523 UIWindow* main_window = [[UIApplication sharedApplication] keyWindow];
1527 [main_window chromeExecuteCommand:command]; 1524 [main_window chromeExecuteCommand:command];
1528 } 1525 }
1529 1526
1530 #pragma mark - ContextualSearchWebStateObserver methods 1527 #pragma mark - ContextualSearchWebStateObserver methods
1531 1528
1532 - (void)webState:(web::WebState*)webState 1529 - (void)webState:(web::WebState*)webState
1533 pageLoadedWithStatus:(web::PageLoadCompletionStatus)loadStatus { 1530 pageLoadedWithStatus:(web::PageLoadCompletionStatus)loadStatus {
1534 if (loadStatus != web::PageLoadCompletionStatus::SUCCESS) 1531 if (loadStatus != web::PageLoadCompletionStatus::SUCCESS)
1535 return; 1532 return;
1536 1533
1537 [self movePanelOffscreen]; 1534 [self movePanelOffscreen];
1538 _isScriptInjected = NO; 1535 _isScriptInjected = NO;
1539 [self enableCurrentWebState]; 1536 [self enableCurrentWebState];
1540 } 1537 }
1541 1538
1542 - (void)webStateDestroyed:(web::WebState*)webState { 1539 - (void)webStateDestroyed:(web::WebState*)webState {
1543 [self updateWebViewProxy:nil]; 1540 [self updateWebViewProxy:nil];
1544 } 1541 }
1545 1542
1546 #pragma mark - UIGestureRecognizerDelegate Methods 1543 #pragma mark - UIGestureRecognizerDelegate Methods
1547 1544
1548 // Ensures that |_tapRecognizer| and |_doubleTapRecognizer| cooperate with all 1545 // Ensures that |_tapRecognizer| and |_doubleTapRecognizer| cooperate with all
1549 // other gesture recognizers. 1546 // other gesture recognizers.
1550 - (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer 1547 - (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer
1551 shouldRecognizeSimultaneouslyWithGestureRecognizer: 1548 shouldRecognizeSimultaneouslyWithGestureRecognizer:
1552 (UIGestureRecognizer*)otherGestureRecognizer { 1549 (UIGestureRecognizer*)otherGestureRecognizer {
1553 return gestureRecognizer == _tapRecognizer.get() || 1550 return gestureRecognizer == _tapRecognizer ||
1554 gestureRecognizer == _doubleTapRecognizer.get(); 1551 gestureRecognizer == _doubleTapRecognizer;
1555 } 1552 }
1556 1553
1557 #pragma mark - CRWWebViewScrollViewObserver methods 1554 #pragma mark - CRWWebViewScrollViewObserver methods
1558 1555
1559 - (void)webViewScrollViewWillBeginDragging: 1556 - (void)webViewScrollViewWillBeginDragging:
1560 (CRWWebViewScrollViewProxy*)webViewScrollViewProxy { 1557 (CRWWebViewScrollViewProxy*)webViewScrollViewProxy {
1561 [self dismissPane:ContextualSearch::BASE_PAGE_SCROLL]; 1558 [self dismissPane:ContextualSearch::BASE_PAGE_SCROLL];
1562 [_tapRecognizer setEnabled:NO]; 1559 [_tapRecognizer setEnabled:NO];
1563 } 1560 }
1564 1561
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1616 1613
1617 - (void)touchToSearchPermissionsUpdated { 1614 - (void)touchToSearchPermissionsUpdated {
1618 // This method is already invoked asynchronously, so it's safe to 1615 // This method is already invoked asynchronously, so it's safe to
1619 // synchronously attempt to enable the feature. 1616 // synchronously attempt to enable the feature.
1620 [self enableContextualSearch:YES]; 1617 [self enableContextualSearch:YES];
1621 } 1618 }
1622 1619
1623 #pragma mark - ContextualSearchHighlighterDelegate methods 1620 #pragma mark - ContextualSearchHighlighterDelegate methods
1624 1621
1625 - (void)updateHighlight { 1622 - (void)updateHighlight {
1626 base::WeakNSObject<ContextualSearchController> weakSelf(self); 1623 __weak ContextualSearchController* weakSelf = self;
1627 [_contextualSearchJsManager 1624 [_contextualSearchJsManager
1628 highlightRectsWithCompletionHandler:^void(id result, NSError* error) { 1625 highlightRectsWithCompletionHandler:^void(id result, NSError* error) {
1629 [weakSelf handleHighlightJSResult:result withError:error]; 1626 [weakSelf handleHighlightJSResult:result withError:error];
1630 }]; 1627 }];
1631 } 1628 }
1632 1629
1633 @end 1630 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698