Chromium Code Reviews| 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*)headerViews { |
| 2651 std::vector<HeaderDefinition> results; | 2699 NSMutableArray* results = [[NSMutableArray alloc] init]; |
|
marq (ping after 24h)
2017/04/06 14:58:16
NSMutableArray<HeaderDefinition*>*
(also in the
stkhapugin
2017/04/10 15:15:47
Done.
| |
| 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; |
|
marq (ping after 24h)
2017/04/06 14:58:16
[results copy]
stkhapugin
2017/04/10 15:15:47
Done.
| |
| 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 |