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/web/navigation/crw_session_controller.h" | 5 #import "ios/web/navigation/crw_session_controller.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 125 - (void)discardTransientEntry; | 125 - (void)discardTransientEntry; |
| 126 // Create a new autoreleased session entry. | 126 // Create a new autoreleased session entry. |
| 127 - (CRWSessionEntry*)sessionEntryWithURL:(const GURL&)url | 127 - (CRWSessionEntry*)sessionEntryWithURL:(const GURL&)url |
| 128 referrer:(const web::Referrer&)referrer | 128 referrer:(const web::Referrer&)referrer |
| 129 transition:(ui::PageTransition)transition | 129 transition:(ui::PageTransition)transition |
| 130 useDesktopUserAgent:(BOOL)useDesktopUserAgent | 130 useDesktopUserAgent:(BOOL)useDesktopUserAgent |
| 131 rendererInitiated:(BOOL)rendererInitiated; | 131 rendererInitiated:(BOOL)rendererInitiated; |
| 132 // Return the PageTransition for the underlying navigationItem at |index| in | 132 // Return the PageTransition for the underlying navigationItem at |index| in |
| 133 // |entries_| | 133 // |entries_| |
| 134 - (ui::PageTransition)transitionForIndex:(NSUInteger)index; | 134 - (ui::PageTransition)transitionForIndex:(NSUInteger)index; |
| 135 // Returns YES if the PageTransition for the underlying navigationItem at | |
| 136 // |index| in |entries_| has ui::PAGE_TRANSITION_IS_REDIRECT_MASK. | |
| 137 - (BOOL)isRedirectTransitionForEntryAtIndex:(NSInteger)index; | |
| 135 @end | 138 @end |
| 136 | 139 |
| 137 @implementation CRWSessionController | 140 @implementation CRWSessionController |
| 138 | 141 |
| 139 @synthesize tabId = _tabId; | 142 @synthesize tabId = _tabId; |
| 140 @synthesize currentNavigationIndex = _currentNavigationIndex; | 143 @synthesize currentNavigationIndex = _currentNavigationIndex; |
| 141 @synthesize previousNavigationIndex = _previousNavigationIndex; | 144 @synthesize previousNavigationIndex = _previousNavigationIndex; |
| 142 @synthesize entries = _entries; | 145 @synthesize entries = _entries; |
| 143 @synthesize windowName = _windowName; | 146 @synthesize windowName = _windowName; |
| 144 @synthesize lastVisitedTimestamp = _lastVisitedTimestamp; | 147 @synthesize lastVisitedTimestamp = _lastVisitedTimestamp; |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 605 } | 608 } |
| 606 } | 609 } |
| 607 DCHECK_LT((NSUInteger)_currentNavigationIndex, [_entries count]); | 610 DCHECK_LT((NSUInteger)_currentNavigationIndex, [_entries count]); |
| 608 } | 611 } |
| 609 | 612 |
| 610 - (ui::PageTransition)transitionForIndex:(NSUInteger)index { | 613 - (ui::PageTransition)transitionForIndex:(NSUInteger)index { |
| 611 return [[_entries objectAtIndex:index] navigationItem]->GetTransitionType(); | 614 return [[_entries objectAtIndex:index] navigationItem]->GetTransitionType(); |
| 612 } | 615 } |
| 613 | 616 |
| 614 - (BOOL)canGoBack { | 617 - (BOOL)canGoBack { |
| 615 if ([_entries count] == 0) | 618 return [self canGoDelta:-1]; |
| 616 return NO; | |
| 617 | |
| 618 // A transient entry behaves from a user perspective in most ways like a | |
| 619 // committed entry, so allow going back from a transient entry since this | |
| 620 // object already has at least one committed entry. | |
| 621 if (_transientEntry) | |
| 622 return YES; | |
| 623 | |
| 624 NSInteger lastNonRedirectedIndex = _currentNavigationIndex; | |
| 625 while (lastNonRedirectedIndex >= 0 && | |
| 626 ui::PageTransitionIsRedirect( | |
| 627 [self transitionForIndex:lastNonRedirectedIndex])) { | |
| 628 --lastNonRedirectedIndex; | |
| 629 } | |
| 630 | |
| 631 return lastNonRedirectedIndex > 0; | |
| 632 } | 619 } |
| 633 | 620 |
| 634 - (BOOL)canGoForward { | 621 - (BOOL)canGoForward { |
| 635 // In case there are pending entries return no since when the entry will be | 622 return [self canGoDelta:1]; |
| 636 // committed the history will be cleared from that point forward. | 623 } |
| 637 if (_pendingEntry) | 624 |
| 638 return NO; | 625 - (BOOL)canGoDelta:(int)delta { |
| 639 // If the current index is less than the last element, there are entries to | 626 NSInteger index = [self indexOfEntryForDelta:delta]; |
| 640 // go forward to. | 627 return 0 <= index && static_cast<NSUInteger>(index) < _entries.count; |
| 641 const NSInteger count = [_entries count]; | |
| 642 return count && _currentNavigationIndex < (count - 1); | |
| 643 } | 628 } |
| 644 | 629 |
| 645 - (void)goBack { | 630 - (void)goBack { |
| 646 if (![self canGoBack]) | 631 [self goDelta:-1]; |
| 647 return; | |
| 648 | |
| 649 BOOL hadTransientEntry = _transientEntry != nil; | |
| 650 | |
| 651 [self discardNonCommittedEntries]; | |
| 652 | |
| 653 // Going back from a transient entry doesn't require anything beyond | |
| 654 // discarding the pending entry. | |
| 655 if (hadTransientEntry) | |
| 656 return; | |
| 657 | |
| 658 base::RecordAction(UserMetricsAction("Back")); | |
| 659 _previousNavigationIndex = _currentNavigationIndex; | |
| 660 // To stop the user getting 'stuck' on redirecting pages they weren't even | |
| 661 // aware existed, it is necessary to pass over pages that would immediately | |
| 662 // result in a redirect (the entry *before* the redirected page). | |
| 663 while (_currentNavigationIndex && | |
| 664 [self transitionForIndex:_currentNavigationIndex] & | |
| 665 ui::PAGE_TRANSITION_IS_REDIRECT_MASK) { | |
| 666 --_currentNavigationIndex; | |
| 667 } | |
| 668 | |
| 669 if (_currentNavigationIndex) | |
| 670 --_currentNavigationIndex; | |
| 671 } | 632 } |
| 672 | 633 |
| 673 - (void)goForward { | 634 - (void)goForward { |
| 674 [self discardTransientEntry]; | 635 [self goDelta:1]; |
| 675 | |
| 676 base::RecordAction(UserMetricsAction("Forward")); | |
| 677 if (_currentNavigationIndex + 1 < static_cast<NSInteger>([_entries count])) { | |
| 678 _previousNavigationIndex = _currentNavigationIndex; | |
| 679 ++_currentNavigationIndex; | |
| 680 } | |
| 681 // To reduce the chance of a redirect kicking in (truncating the history | |
| 682 // stack) we skip over any pages that might do this; we detect this by | |
| 683 // looking for when the *next* page had rediection transition type (was | |
| 684 // auto redirected to). | |
| 685 while (_currentNavigationIndex + 1 < | |
| 686 (static_cast<NSInteger>([_entries count])) && | |
| 687 ([self transitionForIndex:_currentNavigationIndex + 1] & | |
| 688 ui::PAGE_TRANSITION_IS_REDIRECT_MASK)) { | |
| 689 ++_currentNavigationIndex; | |
| 690 } | |
| 691 } | 636 } |
| 692 | 637 |
| 693 - (void)goDelta:(int)delta { | 638 - (void)goDelta:(int)delta { |
| 694 // Store the navigation index at the start of this function, as |-goForward| | 639 if (delta == 0 || ![self canGoDelta:delta]) |
| 695 // and |-goBack| will incrementally reset |_previousNavigationIndex| each time | 640 return; |
| 696 // they are called. | 641 |
| 697 NSInteger previousNavigationIndex = self.currentNavigationIndex; | 642 NSInteger oldNavigationIndex = self.currentNavigationIndex; |
| 643 NSInteger newNavigationIndex = [self indexOfEntryForDelta:delta]; | |
| 644 | |
| 698 if (delta < 0) { | 645 if (delta < 0) { |
| 699 while ([self canGoBack] && delta < 0) { | 646 [self discardNonCommittedEntries]; |
| 700 [self goBack]; | 647 for (int i = delta; i < 0; i++) { |
| 701 ++delta; | 648 base::RecordAction(UserMetricsAction("Back")); |
| 702 } | 649 } |
| 703 } else { | 650 } else if (delta > 0) { |
| 704 while ([self canGoForward] && delta > 0) { | 651 [self discardTransientEntry]; |
| 705 [self goForward]; | 652 for (int i = 0; i < delta; i++) { |
| 706 --delta; | 653 base::RecordAction(UserMetricsAction("Forward")); |
| 707 } | 654 } |
| 708 } | 655 } |
| 709 _previousNavigationIndex = previousNavigationIndex; | 656 |
| 657 _currentNavigationIndex = newNavigationIndex; | |
| 658 _previousNavigationIndex = oldNavigationIndex; | |
| 710 } | 659 } |
| 711 | 660 |
| 712 - (void)goToEntry:(CRWSessionEntry*)entry { | 661 - (void)goToEntry:(CRWSessionEntry*)entry { |
| 713 DCHECK(entry); | 662 DCHECK(entry); |
| 714 | 663 |
| 715 [self discardTransientEntry]; | 664 [self discardTransientEntry]; |
| 716 | 665 |
| 717 // Check that |entries_| still contains |entry|. |entry| could have been | 666 // Check that |entries_| still contains |entry|. |entry| could have been |
| 718 // removed by -clearForwardEntries. | 667 // removed by -clearForwardEntries. |
| 719 if ([_entries containsObject:entry]) { | 668 if ([_entries containsObject:entry]) { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 837 return [_entries objectAtIndex:index]; | 786 return [_entries objectAtIndex:index]; |
| 838 } | 787 } |
| 839 | 788 |
| 840 - (void)useDesktopUserAgentForNextPendingEntry { | 789 - (void)useDesktopUserAgentForNextPendingEntry { |
| 841 if (_pendingEntry) | 790 if (_pendingEntry) |
| 842 [_pendingEntry navigationItem]->SetIsOverridingUserAgent(true); | 791 [_pendingEntry navigationItem]->SetIsOverridingUserAgent(true); |
| 843 else | 792 else |
| 844 _useDesktopUserAgentForNextPendingEntry = YES; | 793 _useDesktopUserAgentForNextPendingEntry = YES; |
| 845 } | 794 } |
| 846 | 795 |
| 796 - (NSInteger)indexOfEntryForDelta:(int)delta { | |
| 797 NSInteger result = _currentNavigationIndex; | |
| 798 if (delta < 0) { | |
| 799 if (_transientEntry) { | |
| 800 // Going back from transient entry is a matter of discarding it and there | |
| 801 // is no need to move navigation index back. | |
| 802 delta++; | |
| 803 } | |
| 804 | |
| 805 while (delta < 0) { | |
| 806 // To stop the user getting 'stuck' on redirecting pages they weren't | |
| 807 // even aware existed, it is necessary to pass over pages that would | |
| 808 // immediately result in a redirect (the entry *before* the redirected | |
| 809 // page). | |
| 810 while (result > 0 && [self isRedirectTransitionForEntryAtIndex:result]) { | |
| 811 --result; | |
| 812 } | |
| 813 --result; | |
| 814 ++delta; | |
| 815 } | |
| 816 } else if (delta > 0) { | |
| 817 NSInteger count = static_cast<NSInteger>([_entries count]); | |
| 818 if (_pendingEntry) { | |
| 819 // Chrome for iOS does not allow forward navigation if there is another | |
| 820 // pending navigation in progress. Returning invalid index indicates that | |
| 821 // forward navigation will not be allowed (and |NSNotFound| works for | |
| 822 // that). This is different from other platforms which allow forward | |
| 823 // navigation if pending entry exist. | |
| 824 // TODO(crbug.com/661858): Remove this once back-forward navigation uses | |
| 825 // pending index. | |
| 826 return NSNotFound; | |
| 827 } | |
| 828 | |
| 829 while (delta > 0) { | |
| 830 ++result; | |
| 831 --delta; | |
| 832 // As with going back, skip over redirects. | |
| 833 while (result + 1 < count && | |
| 834 [self isRedirectTransitionForEntryAtIndex:result + 1]) { | |
| 835 ++result; | |
| 836 } | |
| 837 } | |
| 838 } | |
| 839 | |
| 840 return result; | |
| 841 } | |
| 842 | |
| 847 #pragma mark - | 843 #pragma mark - |
| 848 #pragma mark Private methods | 844 #pragma mark Private methods |
| 849 | 845 |
| 850 - (NSString*)uniqueID { | 846 - (NSString*)uniqueID { |
| 851 CFUUIDRef uuidRef = CFUUIDCreate(NULL); | 847 CFUUIDRef uuidRef = CFUUIDCreate(NULL); |
| 852 CFStringRef uuidStringRef = CFUUIDCreateString(NULL, uuidRef); | 848 CFStringRef uuidStringRef = CFUUIDCreateString(NULL, uuidRef); |
| 853 CFRelease(uuidRef); | 849 CFRelease(uuidRef); |
| 854 | 850 |
| 855 NSString* uuid = | 851 NSString* uuid = |
| 856 [NSString stringWithString:base::mac::ObjCCastStrict<NSString>( | 852 [NSString stringWithString:base::mac::ObjCCastStrict<NSString>( |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 879 } | 875 } |
| 880 std::unique_ptr<web::NavigationItemImpl> item(new web::NavigationItemImpl()); | 876 std::unique_ptr<web::NavigationItemImpl> item(new web::NavigationItemImpl()); |
| 881 item->SetURL(loaded_url); | 877 item->SetURL(loaded_url); |
| 882 item->SetReferrer(referrer); | 878 item->SetReferrer(referrer); |
| 883 item->SetTransitionType(transition); | 879 item->SetTransitionType(transition); |
| 884 item->SetIsOverridingUserAgent(useDesktopUserAgent); | 880 item->SetIsOverridingUserAgent(useDesktopUserAgent); |
| 885 item->set_is_renderer_initiated(rendererInitiated); | 881 item->set_is_renderer_initiated(rendererInitiated); |
| 886 return [[CRWSessionEntry alloc] initWithNavigationItem:std::move(item)]; | 882 return [[CRWSessionEntry alloc] initWithNavigationItem:std::move(item)]; |
| 887 } | 883 } |
| 888 | 884 |
| 885 - (BOOL)isRedirectTransitionForEntryAtIndex:(NSInteger)index { | |
| 886 ui::PageTransition transition = [self transitionForIndex:index]; | |
| 887 return (transition & ui::PAGE_TRANSITION_IS_REDIRECT_MASK) ? YES : NO; | |
|
Eugene But (OOO till 7-30)
2016/11/08 04:03:01
https://google.github.io/styleguide/objcguide.xml#
| |
| 888 } | |
| 889 | |
| 889 @end | 890 @end |
| OLD | NEW |