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

Side by Side Diff: ios/web/navigation/crw_session_controller.mm

Issue 2488553004: Revert of [ios] Refactored back-forward navigation in CRWSessionController. (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 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
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;
138 @end 135 @end
139 136
140 @implementation CRWSessionController 137 @implementation CRWSessionController
141 138
142 @synthesize tabId = _tabId; 139 @synthesize tabId = _tabId;
143 @synthesize currentNavigationIndex = _currentNavigationIndex; 140 @synthesize currentNavigationIndex = _currentNavigationIndex;
144 @synthesize previousNavigationIndex = _previousNavigationIndex; 141 @synthesize previousNavigationIndex = _previousNavigationIndex;
145 @synthesize entries = _entries; 142 @synthesize entries = _entries;
146 @synthesize windowName = _windowName; 143 @synthesize windowName = _windowName;
147 @synthesize lastVisitedTimestamp = _lastVisitedTimestamp; 144 @synthesize lastVisitedTimestamp = _lastVisitedTimestamp;
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 } 605 }
609 } 606 }
610 DCHECK_LT((NSUInteger)_currentNavigationIndex, [_entries count]); 607 DCHECK_LT((NSUInteger)_currentNavigationIndex, [_entries count]);
611 } 608 }
612 609
613 - (ui::PageTransition)transitionForIndex:(NSUInteger)index { 610 - (ui::PageTransition)transitionForIndex:(NSUInteger)index {
614 return [[_entries objectAtIndex:index] navigationItem]->GetTransitionType(); 611 return [[_entries objectAtIndex:index] navigationItem]->GetTransitionType();
615 } 612 }
616 613
617 - (BOOL)canGoBack { 614 - (BOOL)canGoBack {
618 return [self canGoDelta:-1]; 615 if ([_entries count] == 0)
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;
619 } 632 }
620 633
621 - (BOOL)canGoForward { 634 - (BOOL)canGoForward {
622 return [self canGoDelta:1]; 635 // In case there are pending entries return no since when the entry will be
623 } 636 // committed the history will be cleared from that point forward.
624 637 if (_pendingEntry)
625 - (BOOL)canGoDelta:(int)delta { 638 return NO;
626 NSInteger index = [self indexOfEntryForDelta:delta]; 639 // If the current index is less than the last element, there are entries to
627 return 0 <= index && static_cast<NSUInteger>(index) < _entries.count; 640 // go forward to.
641 const NSInteger count = [_entries count];
642 return count && _currentNavigationIndex < (count - 1);
628 } 643 }
629 644
630 - (void)goBack { 645 - (void)goBack {
631 [self goDelta:-1]; 646 if (![self canGoBack])
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;
632 } 671 }
633 672
634 - (void)goForward { 673 - (void)goForward {
635 [self goDelta:1]; 674 [self discardTransientEntry];
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 }
636 } 691 }
637 692
638 - (void)goDelta:(int)delta { 693 - (void)goDelta:(int)delta {
639 if (delta == 0 || ![self canGoDelta:delta]) 694 // Store the navigation index at the start of this function, as |-goForward|
640 return; 695 // and |-goBack| will incrementally reset |_previousNavigationIndex| each time
641 696 // they are called.
642 NSInteger oldNavigationIndex = self.currentNavigationIndex; 697 NSInteger previousNavigationIndex = self.currentNavigationIndex;
643 NSInteger newNavigationIndex = [self indexOfEntryForDelta:delta];
644
645 if (delta < 0) { 698 if (delta < 0) {
646 [self discardNonCommittedEntries]; 699 while ([self canGoBack] && delta < 0) {
647 for (int i = delta; i < 0; i++) { 700 [self goBack];
648 base::RecordAction(UserMetricsAction("Back")); 701 ++delta;
649 } 702 }
650 } else if (delta > 0) { 703 } else {
651 [self discardTransientEntry]; 704 while ([self canGoForward] && delta > 0) {
652 for (int i = 0; i < delta; i++) { 705 [self goForward];
653 base::RecordAction(UserMetricsAction("Forward")); 706 --delta;
654 } 707 }
655 } 708 }
656 709 _previousNavigationIndex = previousNavigationIndex;
657 _currentNavigationIndex = newNavigationIndex;
658 _previousNavigationIndex = oldNavigationIndex;
659 } 710 }
660 711
661 - (void)goToEntry:(CRWSessionEntry*)entry { 712 - (void)goToEntry:(CRWSessionEntry*)entry {
662 DCHECK(entry); 713 DCHECK(entry);
663 714
664 [self discardTransientEntry]; 715 [self discardTransientEntry];
665 716
666 // Check that |entries_| still contains |entry|. |entry| could have been 717 // Check that |entries_| still contains |entry|. |entry| could have been
667 // removed by -clearForwardEntries. 718 // removed by -clearForwardEntries.
668 if ([_entries containsObject:entry]) { 719 if ([_entries containsObject:entry]) {
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
786 return [_entries objectAtIndex:index]; 837 return [_entries objectAtIndex:index];
787 } 838 }
788 839
789 - (void)useDesktopUserAgentForNextPendingEntry { 840 - (void)useDesktopUserAgentForNextPendingEntry {
790 if (_pendingEntry) 841 if (_pendingEntry)
791 [_pendingEntry navigationItem]->SetIsOverridingUserAgent(true); 842 [_pendingEntry navigationItem]->SetIsOverridingUserAgent(true);
792 else 843 else
793 _useDesktopUserAgentForNextPendingEntry = YES; 844 _useDesktopUserAgentForNextPendingEntry = YES;
794 } 845 }
795 846
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
843 #pragma mark - 847 #pragma mark -
844 #pragma mark Private methods 848 #pragma mark Private methods
845 849
846 - (NSString*)uniqueID { 850 - (NSString*)uniqueID {
847 CFUUIDRef uuidRef = CFUUIDCreate(NULL); 851 CFUUIDRef uuidRef = CFUUIDCreate(NULL);
848 CFStringRef uuidStringRef = CFUUIDCreateString(NULL, uuidRef); 852 CFStringRef uuidStringRef = CFUUIDCreateString(NULL, uuidRef);
849 CFRelease(uuidRef); 853 CFRelease(uuidRef);
850 854
851 NSString* uuid = 855 NSString* uuid =
852 [NSString stringWithString:base::mac::ObjCCastStrict<NSString>( 856 [NSString stringWithString:base::mac::ObjCCastStrict<NSString>(
(...skipping 22 matching lines...) Expand all
875 } 879 }
876 std::unique_ptr<web::NavigationItemImpl> item(new web::NavigationItemImpl()); 880 std::unique_ptr<web::NavigationItemImpl> item(new web::NavigationItemImpl());
877 item->SetURL(loaded_url); 881 item->SetURL(loaded_url);
878 item->SetReferrer(referrer); 882 item->SetReferrer(referrer);
879 item->SetTransitionType(transition); 883 item->SetTransitionType(transition);
880 item->SetIsOverridingUserAgent(useDesktopUserAgent); 884 item->SetIsOverridingUserAgent(useDesktopUserAgent);
881 item->set_is_renderer_initiated(rendererInitiated); 885 item->set_is_renderer_initiated(rendererInitiated);
882 return [[CRWSessionEntry alloc] initWithNavigationItem:std::move(item)]; 886 return [[CRWSessionEntry alloc] initWithNavigationItem:std::move(item)];
883 } 887 }
884 888
885 - (BOOL)isRedirectTransitionForEntryAtIndex:(NSInteger)index {
886 return [self transitionForIndex:index] & ui::PAGE_TRANSITION_IS_REDIRECT_MASK;
887 }
888
889 @end 889 @end
OLDNEW
« no previous file with comments | « ios/web/navigation/crw_session_controller.h ('k') | ios/web/navigation/crw_session_controller_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698