Index: ios/web/navigation/crw_session_controller.mm |
diff --git a/ios/web/navigation/crw_session_controller.mm b/ios/web/navigation/crw_session_controller.mm |
index c867f5e999900319a3a1d7c5b9899928e3fe48c6..2c29cf1120911c0caf2d1ad1da740e74e13d1c0f 100644 |
--- a/ios/web/navigation/crw_session_controller.mm |
+++ b/ios/web/navigation/crw_session_controller.mm |
@@ -80,6 +80,21 @@ - (void)discardTransientItem; |
// |index| in |items| has ui::PAGE_TRANSITION_IS_REDIRECT_MASK. |
- (BOOL)isRedirectTransitionForItemAtIndex:(size_t)index; |
+// Should create a new pending item if the new pending item is not a duplicate |
+// of the last added or commited item. Returns YES if one of the following rules |
+// apply: |
+// 1. There is no last added or committed item. |
+// 2. The new item has different url from the last added or commited item. |
+// 3. Url is the same, but the new item is a form submission resulted from the |
+// last added or committed item. |
+// 4. Url is the same, but new item is a reload with different user agent type |
+// resulted from last added or commited item. |
+- (BOOL)shouldCreatePendingItemWithURL:(const GURL&)URL |
+ transition:(ui::PageTransition)transition |
+ userAgentOverrideOption: |
+ (web::NavigationManager::UserAgentOverrideOption) |
+ userAgentOverrideOption; |
+ |
@end |
@implementation CRWSessionController |
@@ -268,9 +283,11 @@ - (void)setBrowserState:(web::BrowserState*)browserState { |
} |
- (void)addPendingItem:(const GURL&)url |
- referrer:(const web::Referrer&)ref |
- transition:(ui::PageTransition)trans |
- initiationType:(web::NavigationInitiationType)initiationType { |
+ referrer:(const web::Referrer&)ref |
+ transition:(ui::PageTransition)trans |
+ initiationType:(web::NavigationInitiationType)initiationType |
+ userAgentOverrideOption:(web::NavigationManager::UserAgentOverrideOption) |
+ userAgentOverrideOption { |
// Server side redirects are handled by updating existing pending item instead |
// of adding a new item. |
DCHECK((trans & ui::PAGE_TRANSITION_SERVER_REDIRECT) == 0); |
@@ -278,8 +295,33 @@ - (void)addPendingItem:(const GURL&)url |
[self discardTransientItem]; |
self.pendingItemIndex = -1; |
- // Don't create a new item if it's already the same as the current item, |
- // allowing this routine to be called multiple times in a row without issue. |
+ if (![self shouldCreatePendingItemWithURL:url |
+ transition:trans |
+ userAgentOverrideOption:userAgentOverrideOption]) { |
+ // Send the notification anyway, to preserve old behavior. It's unknown |
+ // whether anything currently relies on this, but since both this whole |
+ // hack and the content facade will both be going away, it's not worth |
+ // trying to unwind. |
+ if (_navigationManager && _navigationManager->GetFacadeDelegate()) |
+ _navigationManager->GetFacadeDelegate()->OnNavigationItemPending(); |
+ return; |
+ } |
+ |
+ _pendingItem = [self itemWithURL:url |
+ referrer:ref |
+ transition:trans |
+ initiationType:initiationType]; |
+ |
+ if (_navigationManager && _navigationManager->GetFacadeDelegate()) |
+ _navigationManager->GetFacadeDelegate()->OnNavigationItemPending(); |
+ DCHECK_EQ(-1, self.pendingItemIndex); |
+} |
+ |
+- (BOOL)shouldCreatePendingItemWithURL:(const GURL&)URL |
+ transition:(ui::PageTransition)transition |
+ userAgentOverrideOption: |
+ (web::NavigationManager::UserAgentOverrideOption) |
+ userAgentOverrideOption { |
// Note: CRWSessionController currently has the responsibility to distinguish |
// between new navigations and history stack navigation, hence the inclusion |
// of specific transiton type logic here, in order to make it reliable with |
@@ -288,35 +330,49 @@ - (void)addPendingItem:(const GURL&)url |
// in the web layer so that this hack can be removed. |
// Remove the workaround code from -presentSafeBrowsingWarningForResource:. |
web::NavigationItemImpl* currentItem = self.currentItem; |
- if (currentItem) { |
- BOOL hasSameURL = currentItem->GetURL() == url; |
- BOOL isPendingTransitionFormSubmit = |
- PageTransitionCoreTypeIs(trans, ui::PAGE_TRANSITION_FORM_SUBMIT); |
- BOOL isCurrentTransitionFormSubmit = PageTransitionCoreTypeIs( |
- currentItem->GetTransitionType(), ui::PAGE_TRANSITION_FORM_SUBMIT); |
- BOOL shouldCreatePendingItem = |
- !hasSameURL || |
- (isPendingTransitionFormSubmit && !isCurrentTransitionFormSubmit); |
- |
- if (!shouldCreatePendingItem) { |
- // Send the notification anyway, to preserve old behavior. It's unknown |
- // whether anything currently relies on this, but since both this whole |
- // hack and the content facade will both be going away, it's not worth |
- // trying to unwind. |
- if (_navigationManager && _navigationManager->GetFacadeDelegate()) |
- _navigationManager->GetFacadeDelegate()->OnNavigationItemPending(); |
- return; |
- } |
+ if (!currentItem) |
+ return YES; |
+ |
+ // User agent override option should always be different from the user agent |
+ // type of the pending item, or the last committed item if pending doesn't |
+ // exist. |
+ DCHECK(userAgentOverrideOption != |
+ web::NavigationManager::UserAgentOverrideOption::DESKTOP || |
+ currentItem->GetUserAgentType() != web::UserAgentType::DESKTOP); |
+ DCHECK(userAgentOverrideOption != |
+ web::NavigationManager::UserAgentOverrideOption::MOBILE || |
+ currentItem->GetUserAgentType() != web::UserAgentType::MOBILE); |
+ |
+ BOOL hasSameURL = self.currentItem->GetURL() == URL; |
+ if (!hasSameURL) { |
+ // Different url indicates that it's not a duplicate item. |
+ return YES; |
} |
- _pendingItem = [self itemWithURL:url |
- referrer:ref |
- transition:trans |
- initiationType:initiationType]; |
+ BOOL isPendingTransitionFormSubmit = |
+ PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_FORM_SUBMIT); |
+ BOOL isCurrentTransitionFormSubmit = PageTransitionCoreTypeIs( |
+ currentItem->GetTransitionType(), ui::PAGE_TRANSITION_FORM_SUBMIT); |
+ if (isPendingTransitionFormSubmit && !isCurrentTransitionFormSubmit) { |
+ // |isPendingTransitionFormSubmit| indicates that the new item is a form |
+ // submission resulted from the last added or commited item, and |
+ // |!isCurrentTransitionFormSubmit| shows that the form submission is not |
+ // counted multiple times. |
+ return YES; |
+ } |
- if (_navigationManager && _navigationManager->GetFacadeDelegate()) |
- _navigationManager->GetFacadeDelegate()->OnNavigationItemPending(); |
- DCHECK_EQ(-1, self.pendingItemIndex); |
+ BOOL isPendingTransitionReload = |
+ PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_RELOAD); |
+ BOOL isInheritingUserAgentType = |
+ userAgentOverrideOption == |
+ web::NavigationManager::UserAgentOverrideOption::INHERIT; |
+ if (isPendingTransitionReload && !isInheritingUserAgentType) { |
+ // Overriding user agent type to MOBILE or DESKTOP indicates that the new |
+ // new item is a reload with different user agent type. |
+ return YES; |
+ } |
+ |
+ return NO; |
} |
- (void)updatePendingItem:(const GURL&)url { |