OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/ntp/google_landing_view_controller.h" | 5 #import "ios/chrome/browser/ui/ntp/google_landing_view_controller.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/mac/foundation_util.h" | 9 #include "base/mac/foundation_util.h" |
10 #include "base/metrics/user_metrics.h" | 10 #include "base/metrics/user_metrics.h" |
(...skipping 17 matching lines...) Expand all Loading... |
28 #import "ios/chrome/browser/ui/url_loader.h" | 28 #import "ios/chrome/browser/ui/url_loader.h" |
29 #include "ios/chrome/common/string_util.h" | 29 #include "ios/chrome/common/string_util.h" |
30 #include "ios/chrome/grit/ios_strings.h" | 30 #include "ios/chrome/grit/ios_strings.h" |
31 #import "ios/third_party/material_components_ios/src/components/Snackbar/src/Mat
erialSnackbar.h" | 31 #import "ios/third_party/material_components_ios/src/components/Snackbar/src/Mat
erialSnackbar.h" |
32 #import "ios/third_party/material_components_ios/src/components/Typography/src/M
aterialTypography.h" | 32 #import "ios/third_party/material_components_ios/src/components/Typography/src/M
aterialTypography.h" |
33 #import "ios/web/public/web_state/context_menu_params.h" | 33 #import "ios/web/public/web_state/context_menu_params.h" |
34 #import "net/base/mac/url_conversions.h" | 34 #import "net/base/mac/url_conversions.h" |
35 #include "ui/base/l10n/l10n_util.h" | 35 #include "ui/base/l10n/l10n_util.h" |
36 #include "ui/base/page_transition_types.h" | 36 #include "ui/base/page_transition_types.h" |
37 | 37 |
| 38 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 39 #error "This file requires ARC support." |
| 40 #endif |
| 41 |
38 using base::UserMetricsAction; | 42 using base::UserMetricsAction; |
39 | 43 |
40 namespace { | 44 namespace { |
41 | 45 |
42 enum { | 46 enum { |
43 SectionWithOmnibox, | 47 SectionWithOmnibox, |
44 SectionWithMostVisited, | 48 SectionWithMostVisited, |
45 NumberOfCollectionViewSections, | 49 NumberOfCollectionViewSections, |
46 }; | 50 }; |
47 | 51 |
48 const UIEdgeInsets kSearchBoxStretchInsets = {3, 3, 3, 3}; | 52 const UIEdgeInsets kSearchBoxStretchInsets = {3, 3, 3, 3}; |
49 | 53 |
50 const CGFloat kHintLabelSidePadding = 12; | 54 const CGFloat kHintLabelSidePadding = 12; |
51 const CGFloat kWhatsNewHeaderHiddenHeight = 8; | 55 const CGFloat kWhatsNewHeaderHiddenHeight = 8; |
52 const NSInteger kMaxNumMostVisitedFaviconRows = 2; | 56 const NSInteger kMaxNumMostVisitedFaviconRows = 2; |
53 const CGFloat kShiftTilesDownAnimationDuration = 0.2; | 57 const CGFloat kShiftTilesDownAnimationDuration = 0.2; |
54 | 58 |
55 } // namespace | 59 } // namespace |
56 | 60 |
57 @interface GoogleLandingViewController ()<OverscrollActionsControllerDelegate, | 61 @interface GoogleLandingViewController ()<OverscrollActionsControllerDelegate, |
58 UICollectionViewDataSource, | 62 UICollectionViewDataSource, |
59 UICollectionViewDelegate, | 63 UICollectionViewDelegate, |
60 UICollectionViewDelegateFlowLayout, | 64 UICollectionViewDelegateFlowLayout, |
61 UIGestureRecognizerDelegate, | 65 UIGestureRecognizerDelegate, |
62 WhatsNewHeaderViewDelegate> { | 66 WhatsNewHeaderViewDelegate> { |
63 // Fake omnibox. | 67 // Fake omnibox. |
64 base::scoped_nsobject<UIButton> _searchTapTarget; | 68 UIButton* _searchTapTarget; |
65 | 69 |
66 // A collection view for the most visited sites. | 70 // A collection view for the most visited sites. |
67 base::scoped_nsobject<UICollectionView> _mostVisitedView; | 71 UICollectionView* _mostVisitedView; |
68 | 72 |
69 // The overscroll actions controller managing accelerators over the toolbar. | 73 // The overscroll actions controller managing accelerators over the toolbar. |
70 base::scoped_nsobject<OverscrollActionsController> | 74 OverscrollActionsController* _overscrollActionsController; |
71 _overscrollActionsController; | |
72 | 75 |
73 // |YES| when notifications indicate the omnibox is focused. | 76 // |YES| when notifications indicate the omnibox is focused. |
74 BOOL _omniboxFocused; | 77 BOOL _omniboxFocused; |
75 | 78 |
76 // Tap and swipe gesture recognizers when the omnibox is focused. | 79 // Tap and swipe gesture recognizers when the omnibox is focused. |
77 base::scoped_nsobject<UITapGestureRecognizer> _tapGestureRecognizer; | 80 UITapGestureRecognizer* _tapGestureRecognizer; |
78 base::scoped_nsobject<UISwipeGestureRecognizer> _swipeGestureRecognizer; | 81 UISwipeGestureRecognizer* _swipeGestureRecognizer; |
79 | 82 |
80 // Handles displaying the context menu for all form factors. | 83 // Handles displaying the context menu for all form factors. |
81 base::scoped_nsobject<ContextMenuCoordinator> _contextMenuCoordinator; | 84 ContextMenuCoordinator* _contextMenuCoordinator; |
82 | 85 |
83 // URL of the last deleted most viewed entry. If present the UI to restore it | 86 // URL of the last deleted most viewed entry. If present the UI to restore it |
84 // is shown. | 87 // is shown. |
85 base::scoped_nsobject<NSURL> _deletedUrl; | 88 NSURL* _deletedUrl; |
86 | 89 |
87 // |YES| if the view has finished its first layout. This is useful when | 90 // |YES| if the view has finished its first layout. This is useful when |
88 // determining if the view has sized itself for tablet. | 91 // determining if the view has sized itself for tablet. |
89 BOOL _viewLoaded; | 92 BOOL _viewLoaded; |
90 | 93 |
91 // |YES| if the fakebox header should be animated on scroll. | 94 // |YES| if the fakebox header should be animated on scroll. |
92 BOOL _animateHeader; | 95 BOOL _animateHeader; |
93 | 96 |
94 // |YES| if the collection scrollView is scrolled all the way to the top. Used | 97 // |YES| if the collection scrollView is scrolled all the way to the top. Used |
95 // to lock this position in place on various frame changes. | 98 // to lock this position in place on various frame changes. |
96 BOOL _scrolledToTop; | 99 BOOL _scrolledToTop; |
97 | 100 |
98 // |YES| if this NTP panel is visible. When set to |NO| various UI updates | 101 // |YES| if this NTP panel is visible. When set to |NO| various UI updates |
99 // are ignored. | 102 // are ignored. |
100 BOOL _isShowing; | 103 BOOL _isShowing; |
101 | 104 |
102 CFTimeInterval _shiftTilesDownStartTime; | 105 CFTimeInterval _shiftTilesDownStartTime; |
103 CGSize _mostVisitedCellSize; | 106 CGSize _mostVisitedCellSize; |
104 base::scoped_nsobject<NSLayoutConstraint> _hintLabelLeadingConstraint; | 107 NSLayoutConstraint* _hintLabelLeadingConstraint; |
105 base::scoped_nsobject<NSLayoutConstraint> _voiceTapTrailingConstraint; | 108 NSLayoutConstraint* _voiceTapTrailingConstraint; |
106 base::scoped_nsobject<NSLayoutConstraint> _doodleHeightConstraint; | 109 NSLayoutConstraint* _doodleHeightConstraint; |
107 base::scoped_nsobject<NSLayoutConstraint> _doodleTopMarginConstraint; | 110 NSLayoutConstraint* _doodleTopMarginConstraint; |
108 base::scoped_nsobject<NSLayoutConstraint> _searchFieldWidthConstraint; | 111 NSLayoutConstraint* _searchFieldWidthConstraint; |
109 base::scoped_nsobject<NSLayoutConstraint> _searchFieldHeightConstraint; | 112 NSLayoutConstraint* _searchFieldHeightConstraint; |
110 base::scoped_nsobject<NSLayoutConstraint> _searchFieldTopMarginConstraint; | 113 NSLayoutConstraint* _searchFieldTopMarginConstraint; |
111 base::scoped_nsobject<NewTabPageHeaderView> _headerView; | 114 NewTabPageHeaderView* _headerView; |
112 base::scoped_nsobject<WhatsNewHeaderView> _promoHeaderView; | 115 WhatsNewHeaderView* _promoHeaderView; |
113 base::WeakNSProtocol<id<GoogleLandingDataSource>> _dataSource; | 116 __weak id<GoogleLandingDataSource> _dataSource; |
114 base::WeakNSProtocol<id<UrlLoader, OmniboxFocuser>> _dispatcher; | 117 __weak id<UrlLoader, OmniboxFocuser> _dispatcher; |
115 } | 118 } |
116 | 119 |
117 // Whether the Google logo or doodle is being shown. | 120 // Whether the Google logo or doodle is being shown. |
118 @property(nonatomic, assign) BOOL logoIsShowing; | 121 @property(nonatomic, assign) BOOL logoIsShowing; |
119 | 122 |
120 // Exposes view and methods to drive the doodle. | 123 // Exposes view and methods to drive the doodle. |
121 @property(nonatomic, assign) id<LogoVendor> logoVendor; | 124 @property(nonatomic, weak) id<LogoVendor> logoVendor; |
122 | 125 |
123 // |YES| if this consumer is has voice search enabled. | 126 // |YES| if this consumer is has voice search enabled. |
124 @property(nonatomic, assign) BOOL voiceSearchIsEnabled; | 127 @property(nonatomic, assign) BOOL voiceSearchIsEnabled; |
125 | 128 |
126 // Gets the maximum number of sites shown. | 129 // Gets the maximum number of sites shown. |
127 @property(nonatomic, assign) NSUInteger maximumMostVisitedSitesShown; | 130 @property(nonatomic, assign) NSUInteger maximumMostVisitedSitesShown; |
128 | 131 |
129 // Gets the text of a what's new promo. | 132 // Gets the text of a what's new promo. |
130 @property(nonatomic, retain) NSString* promoText; | 133 @property(nonatomic, strong) NSString* promoText; |
131 | 134 |
132 // Gets the icon of a what's new promo. | 135 // Gets the icon of a what's new promo. |
133 // TODO(crbug.com/694750): This should not be WhatsNewIcon. | 136 // TODO(crbug.com/694750): This should not be WhatsNewIcon. |
134 @property(nonatomic, assign) WhatsNewIcon promoIcon; | 137 @property(nonatomic, assign) WhatsNewIcon promoIcon; |
135 | 138 |
136 // |YES| if a what's new promo can be displayed. | 139 // |YES| if a what's new promo can be displayed. |
137 @property(nonatomic, assign) BOOL promoCanShow; | 140 @property(nonatomic, assign) BOOL promoCanShow; |
138 | 141 |
139 // The number of tabs to show in the google landing fake toolbar. | 142 // The number of tabs to show in the google landing fake toolbar. |
140 @property(nonatomic, assign) int tabCount; | 143 @property(nonatomic, assign) int tabCount; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 UIViewAutoresizingFlexibleWidth]; | 224 UIViewAutoresizingFlexibleWidth]; |
222 | 225 |
223 // Initialise |shiftTilesDownStartTime| to a sentinel value to indicate that | 226 // Initialise |shiftTilesDownStartTime| to a sentinel value to indicate that |
224 // the animation has not yet started. | 227 // the animation has not yet started. |
225 _shiftTilesDownStartTime = -1; | 228 _shiftTilesDownStartTime = -1; |
226 _mostVisitedCellSize = [self mostVisitedCellSize]; | 229 _mostVisitedCellSize = [self mostVisitedCellSize]; |
227 _isShowing = YES; | 230 _isShowing = YES; |
228 _scrolledToTop = NO; | 231 _scrolledToTop = NO; |
229 _animateHeader = YES; | 232 _animateHeader = YES; |
230 | 233 |
231 _tapGestureRecognizer.reset([[UITapGestureRecognizer alloc] | 234 _tapGestureRecognizer = |
232 initWithTarget:self | 235 [[UITapGestureRecognizer alloc] initWithTarget:self |
233 action:@selector(blurOmnibox)]); | 236 action:@selector(blurOmnibox)]; |
234 [_tapGestureRecognizer setDelegate:self]; | 237 [_tapGestureRecognizer setDelegate:self]; |
235 _swipeGestureRecognizer.reset([[UISwipeGestureRecognizer alloc] | 238 _swipeGestureRecognizer = |
236 initWithTarget:self | 239 [[UISwipeGestureRecognizer alloc] initWithTarget:self |
237 action:@selector(blurOmnibox)]); | 240 action:@selector(blurOmnibox)]; |
238 [_swipeGestureRecognizer setDirection:UISwipeGestureRecognizerDirectionDown]; | 241 [_swipeGestureRecognizer setDirection:UISwipeGestureRecognizerDirectionDown]; |
239 | 242 |
240 self.leftMargin = | 243 self.leftMargin = |
241 content_suggestions::centeredTilesMarginForWidth([self viewWidth]); | 244 content_suggestions::centeredTilesMarginForWidth([self viewWidth]); |
242 | 245 |
243 [self addSearchField]; | 246 [self addSearchField]; |
244 [self addMostVisited]; | 247 [self addMostVisited]; |
245 [self addOverscrollActions]; | 248 [self addOverscrollActions]; |
246 [self reload]; | 249 [self reload]; |
247 _viewLoaded = YES; | 250 _viewLoaded = YES; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 // Invalidate layout to handle the cases where the layout is changed when the | 299 // Invalidate layout to handle the cases where the layout is changed when the |
297 // NTP is not presented (e.g. tab backgrounded). | 300 // NTP is not presented (e.g. tab backgrounded). |
298 [[_mostVisitedView collectionViewLayout] invalidateLayout]; | 301 [[_mostVisitedView collectionViewLayout] invalidateLayout]; |
299 } | 302 } |
300 | 303 |
301 - (void)dealloc { | 304 - (void)dealloc { |
302 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 305 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
303 [_mostVisitedView setDelegate:nil]; | 306 [_mostVisitedView setDelegate:nil]; |
304 [_mostVisitedView setDataSource:nil]; | 307 [_mostVisitedView setDataSource:nil]; |
305 [_overscrollActionsController invalidate]; | 308 [_overscrollActionsController invalidate]; |
306 [super dealloc]; | |
307 } | 309 } |
308 | 310 |
309 #pragma mark - Properties | 311 #pragma mark - Properties |
310 | 312 |
311 - (id<GoogleLandingDataSource>)dataSource { | 313 - (id<GoogleLandingDataSource>)dataSource { |
312 return _dataSource; | 314 return _dataSource; |
313 } | 315 } |
314 | 316 |
315 - (void)setDataSource:(id<GoogleLandingDataSource>)dataSource { | 317 - (void)setDataSource:(id<GoogleLandingDataSource>)dataSource { |
316 _dataSource.reset(dataSource); | 318 _dataSource = dataSource; |
317 } | 319 } |
318 | 320 |
319 - (id<UrlLoader, OmniboxFocuser>)dispatcher { | 321 - (id<UrlLoader, OmniboxFocuser>)dispatcher { |
320 return _dispatcher; | 322 return _dispatcher; |
321 } | 323 } |
322 | 324 |
323 - (void)setDispatcher:(id<UrlLoader, OmniboxFocuser>)dispatcher { | 325 - (void)setDispatcher:(id<UrlLoader, OmniboxFocuser>)dispatcher { |
324 _dispatcher.reset(dispatcher); | 326 _dispatcher = dispatcher; |
325 } | 327 } |
326 | 328 |
327 #pragma mark - Private | 329 #pragma mark - Private |
328 | 330 |
329 - (CGSize)mostVisitedCellSize { | 331 - (CGSize)mostVisitedCellSize { |
330 if (IsIPadIdiom()) { | 332 if (IsIPadIdiom()) { |
331 // On iPads, split-screen and slide-over may require showing smaller cells. | 333 // On iPads, split-screen and slide-over may require showing smaller cells. |
332 CGSize maximumCellSize = [MostVisitedCell maximumSize]; | 334 CGSize maximumCellSize = [MostVisitedCell maximumSize]; |
333 CGSize viewSize = self.view.bounds.size; | 335 CGSize viewSize = self.view.bounds.size; |
334 CGFloat smallestDimension = | 336 CGFloat smallestDimension = |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 setConstant:content_suggestions::doodleHeight(self.logoIsShowing)]; | 377 setConstant:content_suggestions::doodleHeight(self.logoIsShowing)]; |
376 } | 378 } |
377 if (IsIPadIdiom()) | 379 if (IsIPadIdiom()) |
378 [_searchTapTarget setHidden:!self.logoIsShowing]; | 380 [_searchTapTarget setHidden:!self.logoIsShowing]; |
379 [[_mostVisitedView collectionViewLayout] invalidateLayout]; | 381 [[_mostVisitedView collectionViewLayout] invalidateLayout]; |
380 } | 382 } |
381 } | 383 } |
382 | 384 |
383 // Initialize and add a search field tap target and a voice search button. | 385 // Initialize and add a search field tap target and a voice search button. |
384 - (void)addSearchField { | 386 - (void)addSearchField { |
385 _searchTapTarget.reset([[UIButton alloc] init]); | 387 _searchTapTarget = [[UIButton alloc] init]; |
386 if (IsIPadIdiom()) { | 388 if (IsIPadIdiom()) { |
387 UIImage* searchBoxImage = [[UIImage imageNamed:@"ntp_google_search_box"] | 389 UIImage* searchBoxImage = [[UIImage imageNamed:@"ntp_google_search_box"] |
388 resizableImageWithCapInsets:kSearchBoxStretchInsets]; | 390 resizableImageWithCapInsets:kSearchBoxStretchInsets]; |
389 [_searchTapTarget setBackgroundImage:searchBoxImage | 391 [_searchTapTarget setBackgroundImage:searchBoxImage |
390 forState:UIControlStateNormal]; | 392 forState:UIControlStateNormal]; |
391 } | 393 } |
392 [_searchTapTarget setAdjustsImageWhenHighlighted:NO]; | 394 [_searchTapTarget setAdjustsImageWhenHighlighted:NO]; |
393 [_searchTapTarget addTarget:self | 395 [_searchTapTarget addTarget:self |
394 action:@selector(searchFieldTapped:) | 396 action:@selector(searchFieldTapped:) |
395 forControlEvents:UIControlEventTouchUpInside]; | 397 forControlEvents:UIControlEventTouchUpInside]; |
396 [_searchTapTarget | 398 [_searchTapTarget |
397 setAccessibilityLabel:l10n_util::GetNSString(IDS_OMNIBOX_EMPTY_HINT)]; | 399 setAccessibilityLabel:l10n_util::GetNSString(IDS_OMNIBOX_EMPTY_HINT)]; |
398 // Set isAccessibilityElement to NO so that Voice Search button is accessible. | 400 // Set isAccessibilityElement to NO so that Voice Search button is accessible. |
399 [_searchTapTarget setIsAccessibilityElement:NO]; | 401 [_searchTapTarget setIsAccessibilityElement:NO]; |
400 | 402 |
401 // Set up fakebox hint label. | 403 // Set up fakebox hint label. |
402 UILabel* searchHintLabel = [[[UILabel alloc] init] autorelease]; | 404 UILabel* searchHintLabel = [[UILabel alloc] init]; |
403 content_suggestions::configureSearchHintLabel(searchHintLabel, | 405 content_suggestions::configureSearchHintLabel(searchHintLabel, |
404 _searchTapTarget.get()); | 406 _searchTapTarget); |
405 | 407 |
406 _hintLabelLeadingConstraint.reset([[searchHintLabel.leadingAnchor | 408 _hintLabelLeadingConstraint = [searchHintLabel.leadingAnchor |
407 constraintEqualToAnchor:[_searchTapTarget leadingAnchor] | 409 constraintEqualToAnchor:[_searchTapTarget leadingAnchor] |
408 constant:kHintLabelSidePadding] retain]); | 410 constant:kHintLabelSidePadding]; |
409 [_hintLabelLeadingConstraint setActive:YES]; | 411 [_hintLabelLeadingConstraint setActive:YES]; |
410 | 412 |
411 // Add a voice search button. | 413 // Add a voice search button. |
412 UIButton* voiceTapTarget = [[[UIButton alloc] init] autorelease]; | 414 UIButton* voiceTapTarget = [[UIButton alloc] init]; |
413 content_suggestions::configureVoiceSearchButton(voiceTapTarget, | 415 content_suggestions::configureVoiceSearchButton(voiceTapTarget, |
414 _searchTapTarget.get()); | 416 _searchTapTarget); |
415 | 417 |
416 _voiceTapTrailingConstraint.reset([[voiceTapTarget.trailingAnchor | 418 _voiceTapTrailingConstraint = [voiceTapTarget.trailingAnchor |
417 constraintEqualToAnchor:[_searchTapTarget trailingAnchor]] retain]); | 419 constraintEqualToAnchor:[_searchTapTarget trailingAnchor]]; |
418 [NSLayoutConstraint activateConstraints:@[ | 420 [NSLayoutConstraint activateConstraints:@[ |
419 [searchHintLabel.trailingAnchor | 421 [searchHintLabel.trailingAnchor |
420 constraintEqualToAnchor:voiceTapTarget.leadingAnchor], | 422 constraintEqualToAnchor:voiceTapTarget.leadingAnchor], |
421 _voiceTapTrailingConstraint | 423 _voiceTapTrailingConstraint |
422 ]]; | 424 ]]; |
423 | 425 |
424 if (self.voiceSearchIsEnabled) { | 426 if (self.voiceSearchIsEnabled) { |
425 [voiceTapTarget addTarget:self | 427 [voiceTapTarget addTarget:self |
426 action:@selector(loadVoiceSearch:) | 428 action:@selector(loadVoiceSearch:) |
427 forControlEvents:UIControlEventTouchUpInside]; | 429 forControlEvents:UIControlEventTouchUpInside]; |
(...skipping 12 matching lines...) Expand all Loading... |
440 } | 442 } |
441 | 443 |
442 - (void)preloadVoiceSearch:(id)sender { | 444 - (void)preloadVoiceSearch:(id)sender { |
443 DCHECK(self.voiceSearchIsEnabled); | 445 DCHECK(self.voiceSearchIsEnabled); |
444 [sender removeTarget:self | 446 [sender removeTarget:self |
445 action:@selector(preloadVoiceSearch:) | 447 action:@selector(preloadVoiceSearch:) |
446 forControlEvents:UIControlEventTouchDown]; | 448 forControlEvents:UIControlEventTouchDown]; |
447 | 449 |
448 // Use a GenericChromeCommand because |sender| already has a tag set for a | 450 // Use a GenericChromeCommand because |sender| already has a tag set for a |
449 // different command. | 451 // different command. |
450 base::scoped_nsobject<GenericChromeCommand> command( | 452 GenericChromeCommand* command = |
451 [[GenericChromeCommand alloc] initWithTag:IDC_PRELOAD_VOICE_SEARCH]); | 453 [[GenericChromeCommand alloc] initWithTag:IDC_PRELOAD_VOICE_SEARCH]; |
452 [sender chromeExecuteCommand:command]; | 454 [sender chromeExecuteCommand:command]; |
453 } | 455 } |
454 | 456 |
455 // Initialize and add a panel with most visited sites. | 457 // Initialize and add a panel with most visited sites. |
456 - (void)addMostVisited { | 458 - (void)addMostVisited { |
457 CGRect mostVisitedFrame = [self.view bounds]; | 459 CGRect mostVisitedFrame = [self.view bounds]; |
458 base::scoped_nsobject<UICollectionViewFlowLayout> flowLayout; | 460 UICollectionViewFlowLayout* flowLayout; |
459 if (IsIPadIdiom()) | 461 if (IsIPadIdiom()) |
460 flowLayout.reset([[UICollectionViewFlowLayout alloc] init]); | 462 flowLayout = [[UICollectionViewFlowLayout alloc] init]; |
461 else | 463 else |
462 flowLayout.reset([[MostVisitedLayout alloc] init]); | 464 flowLayout = [[MostVisitedLayout alloc] init]; |
463 | 465 |
464 [flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical]; | 466 [flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical]; |
465 [flowLayout setItemSize:_mostVisitedCellSize]; | 467 [flowLayout setItemSize:_mostVisitedCellSize]; |
466 [flowLayout setMinimumInteritemSpacing:8]; | 468 [flowLayout setMinimumInteritemSpacing:8]; |
467 [flowLayout setMinimumLineSpacing:content_suggestions::spacingBetweenTiles()]; | 469 [flowLayout setMinimumLineSpacing:content_suggestions::spacingBetweenTiles()]; |
468 DCHECK(!_mostVisitedView); | 470 DCHECK(!_mostVisitedView); |
469 _mostVisitedView.reset([[UICollectionView alloc] | 471 _mostVisitedView = [[UICollectionView alloc] initWithFrame:mostVisitedFrame |
470 initWithFrame:mostVisitedFrame | 472 collectionViewLayout:flowLayout]; |
471 collectionViewLayout:flowLayout]); | |
472 [_mostVisitedView setAutoresizingMask:UIViewAutoresizingFlexibleHeight | | 473 [_mostVisitedView setAutoresizingMask:UIViewAutoresizingFlexibleHeight | |
473 UIViewAutoresizingFlexibleWidth]; | 474 UIViewAutoresizingFlexibleWidth]; |
474 [_mostVisitedView setDelegate:self]; | 475 [_mostVisitedView setDelegate:self]; |
475 [_mostVisitedView setDataSource:self]; | 476 [_mostVisitedView setDataSource:self]; |
476 [_mostVisitedView registerClass:[MostVisitedCell class] | 477 [_mostVisitedView registerClass:[MostVisitedCell class] |
477 forCellWithReuseIdentifier:@"classCell"]; | 478 forCellWithReuseIdentifier:@"classCell"]; |
478 [_mostVisitedView setBackgroundColor:[UIColor clearColor]]; | 479 [_mostVisitedView setBackgroundColor:[UIColor clearColor]]; |
479 [_mostVisitedView setBounces:YES]; | 480 [_mostVisitedView setBounces:YES]; |
480 [_mostVisitedView setShowsHorizontalScrollIndicator:NO]; | 481 [_mostVisitedView setShowsHorizontalScrollIndicator:NO]; |
481 [_mostVisitedView setShowsVerticalScrollIndicator:NO]; | 482 [_mostVisitedView setShowsVerticalScrollIndicator:NO]; |
(...skipping 12 matching lines...) Expand all Loading... |
494 [_headerView updateSearchFieldWidth:_searchFieldWidthConstraint | 495 [_headerView updateSearchFieldWidth:_searchFieldWidthConstraint |
495 height:_searchFieldHeightConstraint | 496 height:_searchFieldHeightConstraint |
496 topMargin:_searchFieldTopMarginConstraint | 497 topMargin:_searchFieldTopMarginConstraint |
497 subviewConstraints:constraints | 498 subviewConstraints:constraints |
498 logoIsShowing:self.logoIsShowing | 499 logoIsShowing:self.logoIsShowing |
499 forOffset:[_mostVisitedView contentOffset].y]; | 500 forOffset:[_mostVisitedView contentOffset].y]; |
500 } | 501 } |
501 | 502 |
502 - (void)addOverscrollActions { | 503 - (void)addOverscrollActions { |
503 if (!IsIPadIdiom()) { | 504 if (!IsIPadIdiom()) { |
504 _overscrollActionsController.reset([[OverscrollActionsController alloc] | 505 _overscrollActionsController = [[OverscrollActionsController alloc] |
505 initWithScrollView:_mostVisitedView]); | 506 initWithScrollView:_mostVisitedView]; |
506 [_overscrollActionsController setStyle:OverscrollStyle::NTP_NON_INCOGNITO]; | 507 [_overscrollActionsController setStyle:OverscrollStyle::NTP_NON_INCOGNITO]; |
507 [_overscrollActionsController setDelegate:self]; | 508 [_overscrollActionsController setDelegate:self]; |
508 } | 509 } |
509 } | 510 } |
510 | 511 |
511 // Check to see if the promo label should be hidden. | 512 // Check to see if the promo label should be hidden. |
512 - (void)hideWhatsNewIfNecessary { | 513 - (void)hideWhatsNewIfNecessary { |
513 if (![_promoHeaderView isHidden] && !self.promoCanShow) { | 514 if (![_promoHeaderView isHidden] && !self.promoCanShow) { |
514 [_promoHeaderView setHidden:YES]; | 515 [_promoHeaderView setHidden:YES]; |
515 [self.view setNeedsLayout]; | 516 [self.view setNeedsLayout]; |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
648 // -numberOfItems increases enough to add a new row and change the height | 649 // -numberOfItems increases enough to add a new row and change the height |
649 // of _mostVisitedView. | 650 // of _mostVisitedView. |
650 [_mostVisitedView reloadData]; | 651 [_mostVisitedView reloadData]; |
651 [[_mostVisitedView collectionViewLayout] invalidateLayout]; | 652 [[_mostVisitedView collectionViewLayout] invalidateLayout]; |
652 [self.view setNeedsLayout]; | 653 [self.view setNeedsLayout]; |
653 } | 654 } |
654 | 655 |
655 - (void)addConstraintsForLogoView:(UIView*)logoView | 656 - (void)addConstraintsForLogoView:(UIView*)logoView |
656 searchField:(UIView*)searchField | 657 searchField:(UIView*)searchField |
657 andHeaderView:(UIView*)headerView { | 658 andHeaderView:(UIView*)headerView { |
658 _doodleTopMarginConstraint.reset([[logoView.topAnchor | 659 _doodleTopMarginConstraint = [logoView.topAnchor |
659 constraintEqualToAnchor:headerView.topAnchor | 660 constraintEqualToAnchor:headerView.topAnchor |
660 constant:content_suggestions::doodleTopMargin()] retain]); | 661 constant:content_suggestions::doodleTopMargin()]; |
661 _doodleHeightConstraint.reset([[logoView.heightAnchor | 662 _doodleHeightConstraint = [logoView.heightAnchor |
662 constraintEqualToConstant:content_suggestions::doodleHeight( | 663 constraintEqualToConstant:content_suggestions::doodleHeight( |
663 self.logoIsShowing)] retain]); | 664 self.logoIsShowing)]; |
664 _searchFieldWidthConstraint.reset([[searchField.widthAnchor | 665 _searchFieldWidthConstraint = [searchField.widthAnchor |
665 constraintEqualToConstant:content_suggestions::searchFieldWidth( | 666 constraintEqualToConstant:content_suggestions::searchFieldWidth( |
666 [self viewWidth])] retain]); | 667 [self viewWidth])]; |
667 _searchFieldHeightConstraint.reset([[searchField.heightAnchor | 668 _searchFieldHeightConstraint = [searchField.heightAnchor |
668 constraintEqualToConstant:content_suggestions::kSearchFieldHeight] | 669 constraintEqualToConstant:content_suggestions::kSearchFieldHeight]; |
669 retain]); | 670 _searchFieldTopMarginConstraint = [searchField.topAnchor |
670 _searchFieldTopMarginConstraint.reset([[searchField.topAnchor | |
671 constraintEqualToAnchor:logoView.bottomAnchor | 671 constraintEqualToAnchor:logoView.bottomAnchor |
672 constant:content_suggestions::searchFieldTopMargin()] | 672 constant:content_suggestions::searchFieldTopMargin()]; |
673 retain]); | |
674 [NSLayoutConstraint activateConstraints:@[ | 673 [NSLayoutConstraint activateConstraints:@[ |
675 _doodleTopMarginConstraint, | 674 _doodleTopMarginConstraint, |
676 _doodleHeightConstraint.get(), | 675 _doodleHeightConstraint, |
677 _searchFieldWidthConstraint.get(), | 676 _searchFieldWidthConstraint, |
678 _searchFieldHeightConstraint.get(), | 677 _searchFieldHeightConstraint, |
679 _searchFieldTopMarginConstraint.get(), | 678 _searchFieldTopMarginConstraint, |
680 [logoView.widthAnchor constraintEqualToAnchor:headerView.widthAnchor], | 679 [logoView.widthAnchor constraintEqualToAnchor:headerView.widthAnchor], |
681 [logoView.leadingAnchor constraintEqualToAnchor:headerView.leadingAnchor], | 680 [logoView.leadingAnchor constraintEqualToAnchor:headerView.leadingAnchor], |
682 [searchField.centerXAnchor | 681 [searchField.centerXAnchor |
683 constraintEqualToAnchor:headerView.centerXAnchor], | 682 constraintEqualToAnchor:headerView.centerXAnchor], |
684 ]]; | 683 ]]; |
685 } | 684 } |
686 | 685 |
687 - (void)updateConstraintsForWidth:(CGFloat)width { | 686 - (void)updateConstraintsForWidth:(CGFloat)width { |
688 [_promoHeaderView | 687 [_promoHeaderView |
689 setSideMargin:content_suggestions::centeredTilesMarginForWidth(width) | 688 setSideMargin:content_suggestions::centeredTilesMarginForWidth(width) |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 - (void)collectionView:(UICollectionView*)collectionView | 743 - (void)collectionView:(UICollectionView*)collectionView |
745 didSelectItemAtIndexPath:(NSIndexPath*)indexPath { | 744 didSelectItemAtIndexPath:(NSIndexPath*)indexPath { |
746 MostVisitedCell* cell = | 745 MostVisitedCell* cell = |
747 (MostVisitedCell*)[collectionView cellForItemAtIndexPath:indexPath]; | 746 (MostVisitedCell*)[collectionView cellForItemAtIndexPath:indexPath]; |
748 | 747 |
749 // Keep the UICollectionView alive for one second while the screen | 748 // Keep the UICollectionView alive for one second while the screen |
750 // reader does its thing. | 749 // reader does its thing. |
751 // TODO(jif): This needs a radar, since it is almost certainly a | 750 // TODO(jif): This needs a radar, since it is almost certainly a |
752 // UIKit accessibility bug. crbug.com/529271 | 751 // UIKit accessibility bug. crbug.com/529271 |
753 if (UIAccessibilityIsVoiceOverRunning()) { | 752 if (UIAccessibilityIsVoiceOverRunning()) { |
754 UICollectionView* blockView = [_mostVisitedView retain]; | 753 __block UICollectionView* blockView = _mostVisitedView; |
755 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, | 754 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, |
756 static_cast<int64_t>(1 * NSEC_PER_SEC)), | 755 static_cast<int64_t>(1 * NSEC_PER_SEC)), |
757 dispatch_get_main_queue(), ^{ | 756 dispatch_get_main_queue(), ^{ |
758 [blockView release]; | 757 blockView = nil; |
759 }); | 758 }); |
760 } | 759 } |
761 | 760 |
762 const NSUInteger visitedIndex = indexPath.row; | 761 const NSUInteger visitedIndex = indexPath.row; |
763 [self blurOmnibox]; | 762 [self blurOmnibox]; |
764 DCHECK(visitedIndex < [self numberOfItems]); | 763 DCHECK(visitedIndex < [self numberOfItems]); |
765 [self.dataSource logMostVisitedClick:visitedIndex tileType:cell.tileType]; | 764 [self.dataSource logMostVisitedClick:visitedIndex tileType:cell.tileType]; |
766 [self.dispatcher loadURL:[self urlForIndex:visitedIndex] | 765 [self.dispatcher loadURL:[self urlForIndex:visitedIndex] |
767 referrer:web::Referrer() | 766 referrer:web::Referrer() |
768 transition:ui::PAGE_TRANSITION_AUTO_BOOKMARK | 767 transition:ui::PAGE_TRANSITION_AUTO_BOOKMARK |
769 rendererInitiated:NO]; | 768 rendererInitiated:NO]; |
770 } | 769 } |
771 | 770 |
772 #pragma mark - UICollectionViewDataSource | 771 #pragma mark - UICollectionViewDataSource |
773 | 772 |
774 - (UICollectionReusableView*)collectionView:(UICollectionView*)collectionView | 773 - (UICollectionReusableView*)collectionView:(UICollectionView*)collectionView |
775 viewForSupplementaryElementOfKind:(NSString*)kind | 774 viewForSupplementaryElementOfKind:(NSString*)kind |
776 atIndexPath:(NSIndexPath*)indexPath { | 775 atIndexPath:(NSIndexPath*)indexPath { |
777 DCHECK(kind == UICollectionElementKindSectionHeader); | 776 DCHECK(kind == UICollectionElementKindSectionHeader); |
778 | 777 |
779 if (indexPath.section == SectionWithOmnibox) { | 778 if (indexPath.section == SectionWithOmnibox) { |
780 UICollectionReusableView* reusableView = | 779 UICollectionReusableView* reusableView = |
781 [collectionView dequeueReusableSupplementaryViewOfKind: | 780 [collectionView dequeueReusableSupplementaryViewOfKind: |
782 UICollectionElementKindSectionHeader | 781 UICollectionElementKindSectionHeader |
783 withReuseIdentifier:@"header" | 782 withReuseIdentifier:@"header" |
784 forIndexPath:indexPath]; | 783 forIndexPath:indexPath]; |
785 if (!_headerView) { | 784 if (!_headerView) { |
786 _headerView.reset([[NewTabPageHeaderView alloc] init]); | 785 _headerView = [[NewTabPageHeaderView alloc] init]; |
787 [_headerView addSubview:[self.logoVendor view]]; | 786 [_headerView addSubview:[self.logoVendor view]]; |
788 [_headerView addSubview:_searchTapTarget]; | 787 [_headerView addSubview:_searchTapTarget]; |
789 self.logoVendor.view.translatesAutoresizingMaskIntoConstraints = NO; | 788 self.logoVendor.view.translatesAutoresizingMaskIntoConstraints = NO; |
790 [_searchTapTarget setTranslatesAutoresizingMaskIntoConstraints:NO]; | 789 [_searchTapTarget setTranslatesAutoresizingMaskIntoConstraints:NO]; |
791 | 790 |
792 [self addConstraintsForLogoView:self.logoVendor.view | 791 [self addConstraintsForLogoView:self.logoVendor.view |
793 searchField:_searchTapTarget | 792 searchField:_searchTapTarget |
794 andHeaderView:_headerView]; | 793 andHeaderView:_headerView]; |
795 | 794 |
796 [_headerView addViewsToSearchField:_searchTapTarget]; | 795 [_headerView addViewsToSearchField:_searchTapTarget]; |
(...skipping 16 matching lines...) Expand all Loading... |
813 return reusableView; | 812 return reusableView; |
814 } | 813 } |
815 | 814 |
816 if (indexPath.section == SectionWithMostVisited) { | 815 if (indexPath.section == SectionWithMostVisited) { |
817 UICollectionReusableView* reusableView = | 816 UICollectionReusableView* reusableView = |
818 [collectionView dequeueReusableSupplementaryViewOfKind: | 817 [collectionView dequeueReusableSupplementaryViewOfKind: |
819 UICollectionElementKindSectionHeader | 818 UICollectionElementKindSectionHeader |
820 withReuseIdentifier:@"header" | 819 withReuseIdentifier:@"header" |
821 forIndexPath:indexPath]; | 820 forIndexPath:indexPath]; |
822 if (!_promoHeaderView) { | 821 if (!_promoHeaderView) { |
823 _promoHeaderView.reset([[WhatsNewHeaderView alloc] init]); | 822 _promoHeaderView = [[WhatsNewHeaderView alloc] init]; |
824 [_promoHeaderView | 823 [_promoHeaderView |
825 setSideMargin:content_suggestions::centeredTilesMarginForWidth( | 824 setSideMargin:content_suggestions::centeredTilesMarginForWidth( |
826 [self viewWidth]) | 825 [self viewWidth]) |
827 forWidth:[self viewWidth]]; | 826 forWidth:[self viewWidth]]; |
828 [_promoHeaderView setDelegate:self]; | 827 [_promoHeaderView setDelegate:self]; |
829 if (self.promoCanShow) { | 828 if (self.promoCanShow) { |
830 [_promoHeaderView setText:self.promoText]; | 829 [_promoHeaderView setText:self.promoText]; |
831 [_promoHeaderView setIcon:self.promoIcon]; | 830 [_promoHeaderView setIcon:self.promoIcon]; |
832 [self.dataSource promoViewed]; | 831 [self.dataSource promoViewed]; |
833 } | 832 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
880 } | 879 } |
881 return cell; | 880 return cell; |
882 } | 881 } |
883 | 882 |
884 const ntp_tiles::NTPTile& ntpTile = | 883 const ntp_tiles::NTPTile& ntpTile = |
885 [self.dataSource mostVisitedAtIndex:indexPath.row]; | 884 [self.dataSource mostVisitedAtIndex:indexPath.row]; |
886 NSString* title = base::SysUTF16ToNSString(ntpTile.title); | 885 NSString* title = base::SysUTF16ToNSString(ntpTile.title); |
887 | 886 |
888 [cell setupWithURL:ntpTile.url title:title dataSource:self.dataSource]; | 887 [cell setupWithURL:ntpTile.url title:title dataSource:self.dataSource]; |
889 | 888 |
890 base::scoped_nsobject<UILongPressGestureRecognizer> longPress( | 889 UILongPressGestureRecognizer* longPress = |
891 [[UILongPressGestureRecognizer alloc] | 890 [[UILongPressGestureRecognizer alloc] |
892 initWithTarget:self | 891 initWithTarget:self |
893 action:@selector(handleMostVisitedLongPress:)]); | 892 action:@selector(handleMostVisitedLongPress:)]; |
894 [cell addGestureRecognizer:longPress]; | 893 [cell addGestureRecognizer:longPress]; |
895 | 894 |
896 return cell; | 895 return cell; |
897 } | 896 } |
898 | 897 |
899 #pragma mark - Context Menu | 898 #pragma mark - Context Menu |
900 | 899 |
901 // Called when a user does a long press on a most visited item. | 900 // Called when a user does a long press on a most visited item. |
902 - (void)handleMostVisitedLongPress:(UILongPressGestureRecognizer*)sender { | 901 - (void)handleMostVisitedLongPress:(UILongPressGestureRecognizer*)sender { |
903 if (sender.state == UIGestureRecognizerStateBegan) { | 902 if (sender.state == UIGestureRecognizerStateBegan) { |
904 // Only one long press at a time. | 903 // Only one long press at a time. |
905 if ([_contextMenuCoordinator isVisible]) { | 904 if ([_contextMenuCoordinator isVisible]) { |
906 return; | 905 return; |
907 } | 906 } |
908 | 907 |
909 NSIndexPath* indexPath = [_mostVisitedView | 908 NSIndexPath* indexPath = [_mostVisitedView |
910 indexPathForCell:static_cast<UICollectionViewCell*>(sender.view)]; | 909 indexPathForCell:static_cast<UICollectionViewCell*>(sender.view)]; |
911 const NSUInteger index = indexPath.row; | 910 const NSUInteger index = indexPath.row; |
912 | 911 |
913 // A long press occured on one of the most visited button. Popup a context | 912 // A long press occured on one of the most visited button. Popup a context |
914 // menu. | 913 // menu. |
915 DCHECK(index < [self numberOfItems]); | 914 DCHECK(index < [self numberOfItems]); |
916 | 915 |
917 web::ContextMenuParams params; | 916 web::ContextMenuParams params; |
918 // Get view coordinates in local space. | 917 // Get view coordinates in local space. |
919 params.location = [sender locationInView:self.view]; | 918 params.location = [sender locationInView:self.view]; |
920 params.view.reset([self.view retain]); | 919 params.view.reset(self.view); |
921 | 920 |
922 // Present sheet/popover using controller that is added to view hierarchy. | 921 // Present sheet/popover using controller that is added to view hierarchy. |
923 UIViewController* topController = [params.view window].rootViewController; | 922 UIViewController* topController = [params.view window].rootViewController; |
924 while (topController.presentedViewController) | 923 while (topController.presentedViewController) |
925 topController = topController.presentedViewController; | 924 topController = topController.presentedViewController; |
926 | 925 |
927 _contextMenuCoordinator.reset([[ContextMenuCoordinator alloc] | 926 _contextMenuCoordinator = |
928 initWithBaseViewController:topController | 927 [[ContextMenuCoordinator alloc] initWithBaseViewController:topController |
929 params:params]); | 928 params:params]; |
930 | 929 |
931 ProceduralBlock action; | 930 ProceduralBlock action; |
932 | 931 |
933 // Open In New Tab. | 932 // Open In New Tab. |
934 GURL url = [self urlForIndex:index]; | 933 GURL url = [self urlForIndex:index]; |
935 base::WeakNSObject<GoogleLandingViewController> weakSelf(self); | 934 __weak GoogleLandingViewController* weakSelf = self; |
936 action = ^{ | 935 action = ^{ |
937 base::scoped_nsobject<GoogleLandingViewController> strongSelf( | 936 GoogleLandingViewController* strongSelf = weakSelf; |
938 [weakSelf retain]); | |
939 if (!strongSelf) | 937 if (!strongSelf) |
940 return; | 938 return; |
941 MostVisitedCell* cell = (MostVisitedCell*)sender.view; | 939 MostVisitedCell* cell = (MostVisitedCell*)sender.view; |
942 [[strongSelf dataSource] logMostVisitedClick:index | 940 [[strongSelf dataSource] logMostVisitedClick:index |
943 tileType:cell.tileType]; | 941 tileType:cell.tileType]; |
944 [[strongSelf dispatcher] webPageOrderedOpen:url | 942 [[strongSelf dispatcher] webPageOrderedOpen:url |
945 referrer:web::Referrer() | 943 referrer:web::Referrer() |
946 inBackground:YES | 944 inBackground:YES |
947 appendTo:kCurrentTab]; | 945 appendTo:kCurrentTab]; |
948 }; | 946 }; |
949 [_contextMenuCoordinator | 947 [_contextMenuCoordinator |
950 addItemWithTitle:l10n_util::GetNSStringWithFixup( | 948 addItemWithTitle:l10n_util::GetNSStringWithFixup( |
951 IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB) | 949 IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB) |
952 action:action]; | 950 action:action]; |
953 | 951 |
954 // Open in Incognito Tab. | 952 // Open in Incognito Tab. |
955 action = ^{ | 953 action = ^{ |
956 base::scoped_nsobject<GoogleLandingViewController> strongSelf( | 954 GoogleLandingViewController* strongSelf = weakSelf; |
957 [weakSelf retain]); | |
958 if (!strongSelf) | 955 if (!strongSelf) |
959 return; | 956 return; |
960 MostVisitedCell* cell = (MostVisitedCell*)sender.view; | 957 MostVisitedCell* cell = (MostVisitedCell*)sender.view; |
961 [[strongSelf dataSource] logMostVisitedClick:index | 958 [[strongSelf dataSource] logMostVisitedClick:index |
962 tileType:cell.tileType]; | 959 tileType:cell.tileType]; |
963 [[strongSelf dispatcher] webPageOrderedOpen:url | 960 [[strongSelf dispatcher] webPageOrderedOpen:url |
964 referrer:web::Referrer() | 961 referrer:web::Referrer() |
965 inIncognito:YES | 962 inIncognito:YES |
966 inBackground:NO | 963 inBackground:NO |
967 appendTo:kCurrentTab]; | 964 appendTo:kCurrentTab]; |
968 }; | 965 }; |
969 [_contextMenuCoordinator | 966 [_contextMenuCoordinator |
970 addItemWithTitle:l10n_util::GetNSStringWithFixup( | 967 addItemWithTitle:l10n_util::GetNSStringWithFixup( |
971 IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWINCOGNITOTAB) | 968 IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWINCOGNITOTAB) |
972 action:action]; | 969 action:action]; |
973 | 970 |
974 // Remove the most visited url. | 971 // Remove the most visited url. |
975 NSString* title = | 972 NSString* title = |
976 l10n_util::GetNSStringWithFixup(IDS_BOOKMARK_BUBBLE_REMOVE_BOOKMARK); | 973 l10n_util::GetNSStringWithFixup(IDS_BOOKMARK_BUBBLE_REMOVE_BOOKMARK); |
977 action = ^{ | 974 action = ^{ |
978 base::scoped_nsobject<GoogleLandingViewController> strongSelf( | 975 GoogleLandingViewController* strongSelf = weakSelf; |
979 [weakSelf retain]); | |
980 // Early return if the controller has been deallocated. | 976 // Early return if the controller has been deallocated. |
981 if (!strongSelf) | 977 if (!strongSelf) |
982 return; | 978 return; |
983 base::RecordAction(UserMetricsAction("MostVisited_UrlBlacklisted")); | 979 base::RecordAction(UserMetricsAction("MostVisited_UrlBlacklisted")); |
984 [[strongSelf dataSource] addBlacklistedURL:url]; | 980 [[strongSelf dataSource] addBlacklistedURL:url]; |
985 [strongSelf showMostVisitedUndoForURL:net::NSURLWithGURL(url)]; | 981 [strongSelf showMostVisitedUndoForURL:net::NSURLWithGURL(url)]; |
986 }; | 982 }; |
987 [_contextMenuCoordinator addItemWithTitle:title action:action]; | 983 [_contextMenuCoordinator addItemWithTitle:title action:action]; |
988 | 984 |
989 [_contextMenuCoordinator start]; | 985 [_contextMenuCoordinator start]; |
990 | 986 |
991 if (IsIPadIdiom()) | 987 if (IsIPadIdiom()) |
992 [self blurOmnibox]; | 988 [self blurOmnibox]; |
993 } | 989 } |
994 } | 990 } |
995 | 991 |
996 - (void)showMostVisitedUndoForURL:(NSURL*)url { | 992 - (void)showMostVisitedUndoForURL:(NSURL*)url { |
997 _deletedUrl.reset([url retain]); | 993 _deletedUrl = url; |
998 | 994 |
999 MDCSnackbarMessageAction* action = | 995 MDCSnackbarMessageAction* action = [[MDCSnackbarMessageAction alloc] init]; |
1000 [[[MDCSnackbarMessageAction alloc] init] autorelease]; | 996 __weak GoogleLandingViewController* weakSelf = self; |
1001 base::WeakNSObject<GoogleLandingViewController> weakSelf(self); | |
1002 action.handler = ^{ | 997 action.handler = ^{ |
1003 base::scoped_nsobject<GoogleLandingViewController> strongSelf( | 998 GoogleLandingViewController* strongSelf = weakSelf; |
1004 [weakSelf retain]); | |
1005 if (!strongSelf) | 999 if (!strongSelf) |
1006 return; | 1000 return; |
1007 [[strongSelf dataSource] | 1001 [[strongSelf dataSource] |
1008 removeBlacklistedURL:net::GURLWithNSURL(_deletedUrl)]; | 1002 removeBlacklistedURL:net::GURLWithNSURL(_deletedUrl)]; |
1009 }; | 1003 }; |
1010 action.title = l10n_util::GetNSString(IDS_NEW_TAB_UNDO_THUMBNAIL_REMOVE); | 1004 action.title = l10n_util::GetNSString(IDS_NEW_TAB_UNDO_THUMBNAIL_REMOVE); |
1011 action.accessibilityIdentifier = @"Undo"; | 1005 action.accessibilityIdentifier = @"Undo"; |
1012 | 1006 |
1013 TriggerHapticFeedbackForNotification(UINotificationFeedbackTypeSuccess); | 1007 TriggerHapticFeedbackForNotification(UINotificationFeedbackTypeSuccess); |
1014 MDCSnackbarMessage* message = [MDCSnackbarMessage | 1008 MDCSnackbarMessage* message = [MDCSnackbarMessage |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1219 - (BOOL)animateHeader { | 1213 - (BOOL)animateHeader { |
1220 return _animateHeader; | 1214 return _animateHeader; |
1221 } | 1215 } |
1222 | 1216 |
1223 #pragma mark - OverscrollActionsControllerDelegate | 1217 #pragma mark - OverscrollActionsControllerDelegate |
1224 | 1218 |
1225 - (void)overscrollActionsController:(OverscrollActionsController*)controller | 1219 - (void)overscrollActionsController:(OverscrollActionsController*)controller |
1226 didTriggerAction:(OverscrollAction)action { | 1220 didTriggerAction:(OverscrollAction)action { |
1227 switch (action) { | 1221 switch (action) { |
1228 case OverscrollAction::NEW_TAB: { | 1222 case OverscrollAction::NEW_TAB: { |
1229 base::scoped_nsobject<GenericChromeCommand> command( | 1223 GenericChromeCommand* command = |
1230 [[GenericChromeCommand alloc] initWithTag:IDC_NEW_TAB]); | 1224 [[GenericChromeCommand alloc] initWithTag:IDC_NEW_TAB]; |
1231 [[self view] chromeExecuteCommand:command]; | 1225 [[self view] chromeExecuteCommand:command]; |
1232 } break; | 1226 } break; |
1233 case OverscrollAction::CLOSE_TAB: { | 1227 case OverscrollAction::CLOSE_TAB: { |
1234 base::scoped_nsobject<GenericChromeCommand> command( | 1228 GenericChromeCommand* command = |
1235 [[GenericChromeCommand alloc] initWithTag:IDC_CLOSE_TAB]); | 1229 [[GenericChromeCommand alloc] initWithTag:IDC_CLOSE_TAB]; |
1236 [[self view] chromeExecuteCommand:command]; | 1230 [[self view] chromeExecuteCommand:command]; |
1237 } break; | 1231 } break; |
1238 case OverscrollAction::REFRESH: | 1232 case OverscrollAction::REFRESH: |
1239 [self reload]; | 1233 [self reload]; |
1240 break; | 1234 break; |
1241 case OverscrollAction::NONE: | 1235 case OverscrollAction::NONE: |
1242 NOTREACHED(); | 1236 NOTREACHED(); |
1243 break; | 1237 break; |
1244 } | 1238 } |
1245 } | 1239 } |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1311 - (void)setCanGoForward:(BOOL)canGoForward { | 1305 - (void)setCanGoForward:(BOOL)canGoForward { |
1312 _canGoForward = canGoForward; | 1306 _canGoForward = canGoForward; |
1313 [_headerView setCanGoForward:self.canGoForward]; | 1307 [_headerView setCanGoForward:self.canGoForward]; |
1314 } | 1308 } |
1315 | 1309 |
1316 - (void)setCanGoBack:(BOOL)canGoBack { | 1310 - (void)setCanGoBack:(BOOL)canGoBack { |
1317 _canGoBack = canGoBack; | 1311 _canGoBack = canGoBack; |
1318 [_headerView setCanGoBack:self.canGoBack]; | 1312 [_headerView setCanGoBack:self.canGoBack]; |
1319 } | 1313 } |
1320 @end | 1314 @end |
OLD | NEW |