OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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/browser_view_controller.h" | 5 #import "ios/chrome/browser/ui/browser_view_controller.h" |
6 | 6 |
7 #import <AssetsLibrary/AssetsLibrary.h> | 7 #import <AssetsLibrary/AssetsLibrary.h> |
8 #import <MobileCoreServices/MobileCoreServices.h> | 8 #import <MobileCoreServices/MobileCoreServices.h> |
9 #import <PassKit/PassKit.h> | 9 #import <PassKit/PassKit.h> |
10 #import <Photos/Photos.h> | 10 #import <Photos/Photos.h> |
11 #import <QuartzCore/QuartzCore.h> | 11 #import <QuartzCore/QuartzCore.h> |
12 | 12 |
13 #include <stdint.h> | 13 #include <stdint.h> |
14 #include <cmath> | 14 #include <cmath> |
15 #include <memory> | 15 #include <memory> |
16 | 16 |
17 #include "base/base64.h" | 17 #include "base/base64.h" |
18 #include "base/command_line.h" | 18 #include "base/command_line.h" |
19 #include "base/files/file_path.h" | 19 #include "base/files/file_path.h" |
20 #include "base/format_macros.h" | 20 #include "base/format_macros.h" |
21 #include "base/i18n/rtl.h" | 21 #include "base/i18n/rtl.h" |
22 #include "base/ios/block_types.h" | 22 #include "base/ios/block_types.h" |
23 #include "base/ios/ios_util.h" | 23 #include "base/ios/ios_util.h" |
24 #include "base/logging.h" | 24 #include "base/logging.h" |
25 #include "base/mac/bind_objc_block.h" | 25 #include "base/mac/bind_objc_block.h" |
26 #include "base/mac/bundle_locations.h" | 26 #include "base/mac/bundle_locations.h" |
27 #include "base/mac/foundation_util.h" | 27 #include "base/mac/foundation_util.h" |
28 #import "base/mac/scoped_nsobject.h" | |
29 #include "base/macros.h" | 28 #include "base/macros.h" |
30 #include "base/memory/ptr_util.h" | 29 #include "base/memory/ptr_util.h" |
31 #include "base/metrics/histogram_macros.h" | 30 #include "base/metrics/histogram_macros.h" |
32 #include "base/metrics/user_metrics.h" | 31 #include "base/metrics/user_metrics.h" |
33 #include "base/metrics/user_metrics_action.h" | 32 #include "base/metrics/user_metrics_action.h" |
34 #include "base/strings/sys_string_conversions.h" | 33 #include "base/strings/sys_string_conversions.h" |
35 #include "base/strings/utf_string_conversions.h" | 34 #include "base/strings/utf_string_conversions.h" |
36 #include "base/threading/sequenced_worker_pool.h" | 35 #include "base/threading/sequenced_worker_pool.h" |
37 #include "components/bookmarks/browser/base_bookmark_model_observer.h" | 36 #include "components/bookmarks/browser/base_bookmark_model_observer.h" |
38 #include "components/bookmarks/browser/bookmark_model.h" | 37 #include "components/bookmarks/browser/bookmark_model.h" |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 | 262 |
264 enum HeaderBehaviour { | 263 enum HeaderBehaviour { |
265 // The header moves completely out of the screen. | 264 // The header moves completely out of the screen. |
266 Hideable = 0, | 265 Hideable = 0, |
267 // This header stays on screen and doesn't overlap with the content. | 266 // This header stays on screen and doesn't overlap with the content. |
268 Visible, | 267 Visible, |
269 // This header stay on screen and covers part of the content. | 268 // This header stay on screen and covers part of the content. |
270 Overlap | 269 Overlap |
271 }; | 270 }; |
272 | 271 |
273 struct HeaderDefinition { | |
274 // The header view. | |
275 base::scoped_nsobject<UIView> view; | |
276 // How to place the view, and its behaviour when the headers move. | |
277 HeaderBehaviour behaviour; | |
278 // Reduces the height of a header to adjust for shadows. | |
279 CGFloat heightAdjustement; | |
280 // Nudges that particular header up by this number of points. | |
281 CGFloat inset; | |
282 }; | |
283 | |
284 const CGFloat kIPadFindBarOverlap = 11; | 272 const CGFloat kIPadFindBarOverlap = 11; |
285 | 273 |
286 bool IsURLAllowedInIncognito(const GURL& url) { | 274 bool IsURLAllowedInIncognito(const GURL& url) { |
287 // Most URLs are allowed in incognito; the following are exceptions. | 275 // Most URLs are allowed in incognito; the following are exceptions. |
288 if (!url.SchemeIs(kChromeUIScheme)) | 276 if (!url.SchemeIs(kChromeUIScheme)) |
289 return true; | 277 return true; |
290 std::string url_host = url.host(); | 278 std::string url_host = url.host(); |
291 return url_host != kChromeUIHistoryHost && | 279 return url_host != kChromeUIHistoryHost && |
292 url_host != kChromeUIHistoryFrameHost; | 280 url_host != kChromeUIHistoryFrameHost; |
293 } | 281 } |
294 | 282 |
295 // Temporary key to use when storing native controllers vended to tabs before | 283 // Temporary key to use when storing native controllers vended to tabs before |
296 // they are added to the tab model. | 284 // they are added to the tab model. |
297 NSString* const kNativeControllerTemporaryKey = @"NativeControllerTemporaryKey"; | 285 NSString* const kNativeControllerTemporaryKey = @"NativeControllerTemporaryKey"; |
298 | 286 |
299 } // namespace | 287 } // namespace |
300 | 288 |
| 289 #pragma mark - HeaderDefinition helper |
| 290 |
| 291 @interface HeaderDefinition : NSObject |
| 292 |
| 293 // The header view. |
| 294 @property(nonatomic, strong) UIView* view; |
| 295 // How to place the view, and its behaviour when the headers move. |
| 296 @property(nonatomic, assign) HeaderBehaviour behaviour; |
| 297 // Reduces the height of a header to adjust for shadows. |
| 298 @property(nonatomic, assign) CGFloat heightAdjustement; |
| 299 // Nudges that particular header up by this number of points. |
| 300 @property(nonatomic, assign) CGFloat inset; |
| 301 |
| 302 - (instancetype)initWithView:(UIView*)view |
| 303 headerBehaviour:(HeaderBehaviour)behaviour |
| 304 heightAdjustment:(CGFloat)heightAdjustment |
| 305 inset:(CGFloat)inset; |
| 306 |
| 307 + (instancetype)definitionWithView:(UIView*)view |
| 308 headerBehaviour:(HeaderBehaviour)behaviour |
| 309 heightAdjustment:(CGFloat)heightAdjustment |
| 310 inset:(CGFloat)inset; |
| 311 |
| 312 @end |
| 313 |
| 314 @implementation HeaderDefinition |
| 315 @synthesize view = _view; |
| 316 @synthesize behaviour = _behaviour; |
| 317 @synthesize heightAdjustement = _heightAdjustement; |
| 318 @synthesize inset = _inset; |
| 319 |
| 320 + (instancetype)definitionWithView:(UIView*)view |
| 321 headerBehaviour:(HeaderBehaviour)behaviour |
| 322 heightAdjustment:(CGFloat)heightAdjustment |
| 323 inset:(CGFloat)inset { |
| 324 return [[self alloc] initWithView:view |
| 325 headerBehaviour:behaviour |
| 326 heightAdjustment:heightAdjustment |
| 327 inset:inset]; |
| 328 } |
| 329 |
| 330 - (instancetype)initWithView:(UIView*)view |
| 331 headerBehaviour:(HeaderBehaviour)behaviour |
| 332 heightAdjustment:(CGFloat)heightAdjustment |
| 333 inset:(CGFloat)inset { |
| 334 self = [super init]; |
| 335 if (self) { |
| 336 _view = view; |
| 337 _behaviour = behaviour; |
| 338 _heightAdjustement = heightAdjustment; |
| 339 _inset = inset; |
| 340 } |
| 341 return self; |
| 342 } |
| 343 |
| 344 @end |
| 345 |
| 346 #pragma mark - BVC |
| 347 |
301 @interface BrowserViewController ()<AppRatingPromptDelegate, | 348 @interface BrowserViewController ()<AppRatingPromptDelegate, |
302 ContextualSearchControllerDelegate, | 349 ContextualSearchControllerDelegate, |
303 ContextualSearchPanelMotionObserver, | 350 ContextualSearchPanelMotionObserver, |
304 CRWNativeContentProvider, | 351 CRWNativeContentProvider, |
305 CRWWebStateDelegate, | 352 CRWWebStateDelegate, |
306 DialogPresenterDelegate, | 353 DialogPresenterDelegate, |
307 FullScreenControllerDelegate, | 354 FullScreenControllerDelegate, |
308 KeyCommandsPlumbing, | 355 KeyCommandsPlumbing, |
309 MFMailComposeViewControllerDelegate, | 356 MFMailComposeViewControllerDelegate, |
310 NewTabPageControllerObserver, | 357 NewTabPageControllerObserver, |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 @property(nonatomic, readonly) BOOL shouldShowVoiceSearchBar; | 572 @property(nonatomic, readonly) BOOL shouldShowVoiceSearchBar; |
526 // Coordinator for displaying a modal overlay with activity indicator to prevent | 573 // Coordinator for displaying a modal overlay with activity indicator to prevent |
527 // the user from interacting with the browser view. | 574 // the user from interacting with the browser view. |
528 @property(nonatomic, strong) | 575 @property(nonatomic, strong) |
529 ActivityOverlayCoordinator* activityOverlayCoordinator; | 576 ActivityOverlayCoordinator* activityOverlayCoordinator; |
530 | 577 |
531 // The user agent type used to load the currently visible page. User agent type | 578 // The user agent type used to load the currently visible page. User agent type |
532 // is NONE if there is no visible page or visible page is a native page. | 579 // is NONE if there is no visible page or visible page is a native page. |
533 @property(nonatomic, assign, readonly) web::UserAgentType userAgentType; | 580 @property(nonatomic, assign, readonly) web::UserAgentType userAgentType; |
534 | 581 |
| 582 // Returns the header views, all the chrome on top of the page, including the |
| 583 // ones that cannot be scrolled off screen by full screen. |
| 584 @property(nonatomic, strong, readonly) NSArray<HeaderDefinition*>* headerViews; |
| 585 |
535 // BVC initialization: | 586 // BVC initialization: |
536 // If the BVC is initialized with a valid browser state & tab model immediately, | 587 // If the BVC is initialized with a valid browser state & tab model immediately, |
537 // the path is straightforward: functionality is enabled, and the UI is built | 588 // the path is straightforward: functionality is enabled, and the UI is built |
538 // when -viewDidLoad is called. | 589 // when -viewDidLoad is called. |
539 // If the BVC is initialized without a browser state or tab model, the tab model | 590 // If the BVC is initialized without a browser state or tab model, the tab model |
540 // and browser state may or may not be provided before -viewDidLoad is called. | 591 // and browser state may or may not be provided before -viewDidLoad is called. |
541 // In most cases, they will not, to improve startup performance. | 592 // In most cases, they will not, to improve startup performance. |
542 // In order to handle this, initialization of various aspects of BVC have been | 593 // In order to handle this, initialization of various aspects of BVC have been |
543 // broken out into the following functions, which have expectations (enforced | 594 // broken out into the following functions, which have expectations (enforced |
544 // with DCHECKs) regarding |_browserState|, |_model|, and [self isViewLoaded]. | 595 // with DCHECKs) regarding |_browserState|, |_model|, and [self isViewLoaded]. |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 - (CGFloat)voiceSearchOverlayYOffsetForTab:(Tab*)tab; | 777 - (CGFloat)voiceSearchOverlayYOffsetForTab:(Tab*)tab; |
727 // Lazily instantiates |_voiceSearchController|. | 778 // Lazily instantiates |_voiceSearchController|. |
728 - (void)ensureVoiceSearchControllerCreated; | 779 - (void)ensureVoiceSearchControllerCreated; |
729 // Lazily instantiates |_voiceSearchBar| and adds it to the view. | 780 // Lazily instantiates |_voiceSearchBar| and adds it to the view. |
730 - (void)ensureVoiceSearchBarCreated; | 781 - (void)ensureVoiceSearchBarCreated; |
731 // Shows/hides the voice search bar. | 782 // Shows/hides the voice search bar. |
732 - (void)updateVoiceSearchBarVisibilityAnimated:(BOOL)animated; | 783 - (void)updateVoiceSearchBarVisibilityAnimated:(BOOL)animated; |
733 // The LogoAnimationControllerOwner to be used for the next logo transition | 784 // The LogoAnimationControllerOwner to be used for the next logo transition |
734 // animation. | 785 // animation. |
735 - (id<LogoAnimationControllerOwner>)currentLogoAnimationControllerOwner; | 786 - (id<LogoAnimationControllerOwner>)currentLogoAnimationControllerOwner; |
736 // Returns the header views, all the chrome on top of the page, including the | |
737 // ones that cannot be scrolled off screen by full screen. | |
738 - (const std::vector<HeaderDefinition>)headerViews; | |
739 // Returns the footer view if one exists (e.g. the voice search bar). | 787 // Returns the footer view if one exists (e.g. the voice search bar). |
740 - (UIView*)footerView; | 788 - (UIView*)footerView; |
741 // Returns the height of the header view for the tab model's current tab. | 789 // Returns the height of the header view for the tab model's current tab. |
742 - (CGFloat)headerHeight; | 790 - (CGFloat)headerHeight; |
743 // Sets the frame for the headers. | 791 // Sets the frame for the headers. |
744 - (void)setFramesForHeaders:(const std::vector<HeaderDefinition>)headers | 792 - (void)setFramesForHeaders:(NSArray<HeaderDefinition*>*)headers |
745 atOffset:(CGFloat)headerOffset; | 793 atOffset:(CGFloat)headerOffset; |
746 // Returns the y coordinate for the footer's frame when animating the footer | 794 // Returns the y coordinate for the footer's frame when animating the footer |
747 // in/out of fullscreen. | 795 // in/out of fullscreen. |
748 - (CGFloat)footerYForHeaderOffset:(CGFloat)headerOffset; | 796 - (CGFloat)footerYForHeaderOffset:(CGFloat)headerOffset; |
749 // Called when the animation for setting the header view's offset is finished. | 797 // Called when the animation for setting the header view's offset is finished. |
750 // |completed| should indicate if the animation finished completely or was | 798 // |completed| should indicate if the animation finished completely or was |
751 // interrupted. |offset| should indicate the header offset after the animation. | 799 // interrupted. |offset| should indicate the header offset after the animation. |
752 // |dragged| should indicate if the header moved due to the user dragging. | 800 // |dragged| should indicate if the header moved due to the user dragging. |
753 - (void)fullScreenController:(FullScreenController*)controller | 801 - (void)fullScreenController:(FullScreenController*)controller |
754 headerAnimationCompleted:(BOOL)completed | 802 headerAnimationCompleted:(BOOL)completed |
(...skipping 1885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2640 } | 2688 } |
2641 | 2689 |
2642 #pragma mark - FullScreenControllerDelegate methods | 2690 #pragma mark - FullScreenControllerDelegate methods |
2643 | 2691 |
2644 - (CGFloat)headerOffset { | 2692 - (CGFloat)headerOffset { |
2645 if (IsIPadIdiom()) | 2693 if (IsIPadIdiom()) |
2646 return StatusBarHeight(); | 2694 return StatusBarHeight(); |
2647 return 0.0; | 2695 return 0.0; |
2648 } | 2696 } |
2649 | 2697 |
2650 - (const std::vector<HeaderDefinition>)headerViews { | 2698 - (NSArray<HeaderDefinition*>*)headerViews { |
2651 std::vector<HeaderDefinition> results; | 2699 NSMutableArray<HeaderDefinition*>* results = [[NSMutableArray alloc] init]; |
2652 if (![self isViewLoaded]) | 2700 if (![self isViewLoaded]) |
2653 return results; | 2701 return results; |
2654 | 2702 |
2655 if (!IsIPadIdiom()) { | 2703 if (!IsIPadIdiom()) { |
2656 if ([_toolbarController view]) { | 2704 if ([_toolbarController view]) { |
2657 HeaderDefinition header = { | 2705 [results addObject:[HeaderDefinition |
2658 base::scoped_nsobject<UIView>([_toolbarController view]), Hideable, | 2706 definitionWithView:[_toolbarController view] |
2659 [ToolbarController toolbarDropShadowHeight], 0.0, | 2707 headerBehaviour:Hideable |
2660 }; | 2708 heightAdjustment:[ToolbarController |
2661 results.push_back(header); | 2709 toolbarDropShadowHeight] |
| 2710 inset:0.0]]; |
2662 } | 2711 } |
2663 } else { | 2712 } else { |
2664 if ([_tabStripController view]) { | 2713 if ([_tabStripController view]) { |
2665 HeaderDefinition header = { | 2714 [results addObject:[HeaderDefinition |
2666 base::scoped_nsobject<UIView>([_tabStripController view]), Hideable, | 2715 definitionWithView:[_tabStripController view] |
2667 0.0, 0.0, | 2716 headerBehaviour:Hideable |
2668 }; | 2717 heightAdjustment:0.0 |
2669 results.push_back(header); | 2718 inset:0.0]]; |
2670 } | 2719 } |
2671 if ([_toolbarController view]) { | 2720 if ([_toolbarController view]) { |
2672 HeaderDefinition header = { | 2721 [results addObject:[HeaderDefinition |
2673 base::scoped_nsobject<UIView>([_toolbarController view]), Hideable, | 2722 definitionWithView:[_toolbarController view] |
2674 [ToolbarController toolbarDropShadowHeight], 0.0, | 2723 headerBehaviour:Hideable |
2675 }; | 2724 heightAdjustment:[ToolbarController |
2676 results.push_back(header); | 2725 toolbarDropShadowHeight] |
| 2726 inset:0.0]]; |
2677 } | 2727 } |
2678 if ([_findBarController view]) { | 2728 if ([_findBarController view]) { |
2679 HeaderDefinition header = { | 2729 [results addObject:[HeaderDefinition |
2680 base::scoped_nsobject<UIView>([_findBarController view]), Overlap, | 2730 definitionWithView:[_findBarController view] |
2681 0.0, kIPadFindBarOverlap, | 2731 headerBehaviour:Overlap |
2682 }; | 2732 heightAdjustment:0.0 |
2683 results.push_back(header); | 2733 inset:kIPadFindBarOverlap]]; |
2684 } | 2734 } |
2685 } | 2735 } |
2686 return results; | 2736 return [results copy]; |
2687 } | 2737 } |
2688 | 2738 |
2689 - (UIView*)footerView { | 2739 - (UIView*)footerView { |
2690 return _voiceSearchBar; | 2740 return _voiceSearchBar; |
2691 } | 2741 } |
2692 | 2742 |
2693 - (CGFloat)headerHeight { | 2743 - (CGFloat)headerHeight { |
2694 return [self headerHeightForTab:[_model currentTab]]; | 2744 return [self headerHeightForTab:[_model currentTab]]; |
2695 } | 2745 } |
2696 | 2746 |
2697 - (CGFloat)headerHeightForTab:(Tab*)tab { | 2747 - (CGFloat)headerHeightForTab:(Tab*)tab { |
2698 id nativeController = [self nativeControllerForTab:tab]; | 2748 id nativeController = [self nativeControllerForTab:tab]; |
2699 if ([nativeController conformsToProtocol:@protocol(ToolbarOwner)] && | 2749 if ([nativeController conformsToProtocol:@protocol(ToolbarOwner)] && |
2700 [nativeController respondsToSelector:@selector(toolbarHeight)] && | 2750 [nativeController respondsToSelector:@selector(toolbarHeight)] && |
2701 [nativeController toolbarHeight] > 0.0 && !IsIPadIdiom()) { | 2751 [nativeController toolbarHeight] > 0.0 && !IsIPadIdiom()) { |
2702 // On iPhone, don't add any header height for ToolbarOwner native | 2752 // On iPhone, don't add any header height for ToolbarOwner native |
2703 // controllers when they're displaying their own toolbar. | 2753 // controllers when they're displaying their own toolbar. |
2704 return 0; | 2754 return 0; |
2705 } | 2755 } |
2706 | 2756 |
2707 const std::vector<HeaderDefinition> views = [self headerViews]; | 2757 NSArray<HeaderDefinition*>* views = [self headerViews]; |
2708 | 2758 |
2709 CGFloat height = [self headerOffset]; | 2759 CGFloat height = [self headerOffset]; |
2710 for (const auto& header : views) { | 2760 for (HeaderDefinition* header in views) { |
2711 if (header.view && header.behaviour == Hideable) { | 2761 if (header.view && header.behaviour == Hideable) { |
2712 height += CGRectGetHeight([header.view frame]) - | 2762 height += CGRectGetHeight([header.view frame]) - |
2713 header.heightAdjustement - header.inset; | 2763 header.heightAdjustement - header.inset; |
2714 } | 2764 } |
2715 } | 2765 } |
2716 | 2766 |
2717 return height - StatusBarHeight(); | 2767 return height - StatusBarHeight(); |
2718 } | 2768 } |
2719 | 2769 |
2720 - (BOOL)isTabWithIDCurrent:(NSString*)sessionID { | 2770 - (BOOL)isTabWithIDCurrent:(NSString*)sessionID { |
2721 return self.visible && [sessionID isEqualToString:[_model currentTab].tabId]; | 2771 return self.visible && [sessionID isEqualToString:[_model currentTab].tabId]; |
2722 } | 2772 } |
2723 | 2773 |
2724 - (CGFloat)currentHeaderOffset { | 2774 - (CGFloat)currentHeaderOffset { |
2725 const std::vector<HeaderDefinition> headers = [self headerViews]; | 2775 NSArray<HeaderDefinition*>* headers = [self headerViews]; |
2726 if (!headers.size()) | 2776 if (!headers.count) |
2727 return 0.0; | 2777 return 0.0; |
2728 | 2778 |
2729 // Prerender tab does not have a toolbar, return |headerHeight| as promised by | 2779 // Prerender tab does not have a toolbar, return |headerHeight| as promised by |
2730 // API documentation. | 2780 // API documentation. |
2731 if ([[[self tabModel] currentTab] isPrerenderTab]) | 2781 if ([[[self tabModel] currentTab] isPrerenderTab]) |
2732 return [self headerHeight]; | 2782 return [self headerHeight]; |
2733 | 2783 |
2734 UIView* topHeader = headers[0].view; | 2784 UIView* topHeader = headers[0].view; |
2735 return -(topHeader.frame.origin.y - [self headerOffset]); | 2785 return -(topHeader.frame.origin.y - [self headerOffset]); |
2736 } | 2786 } |
2737 | 2787 |
2738 - (CGFloat)footerYForHeaderOffset:(CGFloat)headerOffset { | 2788 - (CGFloat)footerYForHeaderOffset:(CGFloat)headerOffset { |
2739 UIView* footer = [self footerView]; | 2789 UIView* footer = [self footerView]; |
2740 CGFloat headerHeight = [self headerHeight]; | 2790 CGFloat headerHeight = [self headerHeight]; |
2741 if (!footer || headerHeight == 0) | 2791 if (!footer || headerHeight == 0) |
2742 return 0.0; | 2792 return 0.0; |
2743 | 2793 |
2744 CGFloat footerHeight = CGRectGetHeight(footer.frame); | 2794 CGFloat footerHeight = CGRectGetHeight(footer.frame); |
2745 CGFloat offset = headerOffset * footerHeight / headerHeight; | 2795 CGFloat offset = headerOffset * footerHeight / headerHeight; |
2746 return std::ceil(CGRectGetHeight(self.view.bounds) - footerHeight + offset); | 2796 return std::ceil(CGRectGetHeight(self.view.bounds) - footerHeight + offset); |
2747 } | 2797 } |
2748 | 2798 |
2749 - (void)fullScreenController:(FullScreenController*)controller | 2799 - (void)fullScreenController:(FullScreenController*)controller |
2750 headerAnimationCompleted:(BOOL)completed | 2800 headerAnimationCompleted:(BOOL)completed |
2751 offset:(CGFloat)offset { | 2801 offset:(CGFloat)offset { |
2752 if (completed) | 2802 if (completed) |
2753 [controller setToolbarInsetsForHeaderOffset:offset]; | 2803 [controller setToolbarInsetsForHeaderOffset:offset]; |
2754 } | 2804 } |
2755 | 2805 |
2756 - (void)setFramesForHeaders:(const std::vector<HeaderDefinition>)headers | 2806 - (void)setFramesForHeaders:(NSArray<HeaderDefinition*>*)headers |
2757 atOffset:(CGFloat)headerOffset { | 2807 atOffset:(CGFloat)headerOffset { |
2758 CGFloat height = [self headerOffset]; | 2808 CGFloat height = [self headerOffset]; |
2759 for (const auto& header : headers) { | 2809 for (HeaderDefinition* header in headers) { |
2760 CGRect frame = [header.view frame]; | 2810 CGRect frame = [header.view frame]; |
2761 frame.origin.y = height - headerOffset - header.inset; | 2811 frame.origin.y = height - headerOffset - header.inset; |
2762 [header.view setFrame:frame]; | 2812 [header.view setFrame:frame]; |
2763 if (header.behaviour != Overlap) | 2813 if (header.behaviour != Overlap) |
2764 height += CGRectGetHeight(frame); | 2814 height += CGRectGetHeight(frame); |
2765 } | 2815 } |
2766 } | 2816 } |
2767 | 2817 |
2768 - (void)fullScreenController:(FullScreenController*)fullScreenController | 2818 - (void)fullScreenController:(FullScreenController*)fullScreenController |
2769 drawHeaderViewFromOffset:(CGFloat)headerOffset | 2819 drawHeaderViewFromOffset:(CGFloat)headerOffset |
2770 animate:(BOOL)animate { | 2820 animate:(BOOL)animate { |
2771 if ([_sideSwipeController inSwipe]) | 2821 if ([_sideSwipeController inSwipe]) |
2772 return; | 2822 return; |
2773 | 2823 |
2774 CGRect footerFrame = CGRectZero; | 2824 CGRect footerFrame = CGRectZero; |
2775 UIView* footer = nil; | 2825 UIView* footer = nil; |
2776 // Only animate the voice search bar if the tab is a voice search results tab. | 2826 // Only animate the voice search bar if the tab is a voice search results tab. |
2777 if ([_model currentTab].isVoiceSearchResultsTab) { | 2827 if ([_model currentTab].isVoiceSearchResultsTab) { |
2778 footer = [self footerView]; | 2828 footer = [self footerView]; |
2779 footerFrame = footer.frame; | 2829 footerFrame = footer.frame; |
2780 footerFrame.origin.y = [self footerYForHeaderOffset:headerOffset]; | 2830 footerFrame.origin.y = [self footerYForHeaderOffset:headerOffset]; |
2781 } | 2831 } |
2782 | 2832 |
2783 const std::vector<HeaderDefinition> headers = [self headerViews]; | 2833 NSArray<HeaderDefinition*>* headers = [self headerViews]; |
2784 void (^block)(void) = ^{ | 2834 void (^block)(void) = ^{ |
2785 [self setFramesForHeaders:headers atOffset:headerOffset]; | 2835 [self setFramesForHeaders:headers atOffset:headerOffset]; |
2786 footer.frame = footerFrame; | 2836 footer.frame = footerFrame; |
2787 }; | 2837 }; |
2788 void (^completion)(BOOL) = ^(BOOL finished) { | 2838 void (^completion)(BOOL) = ^(BOOL finished) { |
2789 [self fullScreenController:fullScreenController | 2839 [self fullScreenController:fullScreenController |
2790 headerAnimationCompleted:finished | 2840 headerAnimationCompleted:finished |
2791 offset:headerOffset]; | 2841 offset:headerOffset]; |
2792 }; | 2842 }; |
2793 if (animate) { | 2843 if (animate) { |
(...skipping 19 matching lines...) Expand all Loading... |
2813 | 2863 |
2814 CGRect footerFrame; | 2864 CGRect footerFrame; |
2815 UIView* footer = nil; | 2865 UIView* footer = nil; |
2816 // Only animate the voice search bar if the tab is a voice search results tab. | 2866 // Only animate the voice search bar if the tab is a voice search results tab. |
2817 if ([_model currentTab].isVoiceSearchResultsTab) { | 2867 if ([_model currentTab].isVoiceSearchResultsTab) { |
2818 footer = [self footerView]; | 2868 footer = [self footerView]; |
2819 footerFrame = footer.frame; | 2869 footerFrame = footer.frame; |
2820 footerFrame.origin.y = [self footerYForHeaderOffset:headerOffset]; | 2870 footerFrame.origin.y = [self footerYForHeaderOffset:headerOffset]; |
2821 } | 2871 } |
2822 | 2872 |
2823 const std::vector<HeaderDefinition> headers = [self headerViews]; | 2873 NSArray<HeaderDefinition*>* headers = [self headerViews]; |
2824 void (^block)(void) = ^{ | 2874 void (^block)(void) = ^{ |
2825 [self setFramesForHeaders:headers atOffset:headerOffset]; | 2875 [self setFramesForHeaders:headers atOffset:headerOffset]; |
2826 footer.frame = footerFrame; | 2876 footer.frame = footerFrame; |
2827 webViewProxy.scrollViewProxy.contentOffset = CGPointMake( | 2877 webViewProxy.scrollViewProxy.contentOffset = CGPointMake( |
2828 webViewProxy.scrollViewProxy.contentOffset.x, contentOffset); | 2878 webViewProxy.scrollViewProxy.contentOffset.x, contentOffset); |
2829 if (changeTopContentPadding) | 2879 if (changeTopContentPadding) |
2830 webViewProxy.topContentPadding = contentOffset; | 2880 webViewProxy.topContentPadding = contentOffset; |
2831 }; | 2881 }; |
2832 void (^completion)(BOOL) = ^(BOOL finished) { | 2882 void (^completion)(BOOL) = ^(BOOL finished) { |
2833 [self fullScreenController:fullScreenController | 2883 [self fullScreenController:fullScreenController |
(...skipping 2291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5125 | 5175 |
5126 - (UIView*)voiceSearchButton { | 5176 - (UIView*)voiceSearchButton { |
5127 return _voiceSearchButton; | 5177 return _voiceSearchButton; |
5128 } | 5178 } |
5129 | 5179 |
5130 - (id<LogoAnimationControllerOwner>)logoAnimationControllerOwner { | 5180 - (id<LogoAnimationControllerOwner>)logoAnimationControllerOwner { |
5131 return [self currentLogoAnimationControllerOwner]; | 5181 return [self currentLogoAnimationControllerOwner]; |
5132 } | 5182 } |
5133 | 5183 |
5134 @end | 5184 @end |
OLD | NEW |