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 1bb37874fe17199af3b6370eb673a0b99eac87df..3e45e5f9ebb6b37563a8a3742d75dcc4e446d193 100644 |
--- a/ios/web/navigation/crw_session_controller.mm |
+++ b/ios/web/navigation/crw_session_controller.mm |
@@ -152,6 +152,11 @@ - (void)setPendingItemIndex:(NSInteger)pendingItemIndex { |
DCHECK(_pendingItemIndex == -1 || self.pendingItem); |
} |
+- (BOOL)canPruneAllButLastCommittedItem { |
+ return self.currentNavigationIndex != -1 && self.pendingItemIndex == -1 && |
+ !self.transientItem; |
+} |
+ |
- (const web::ScopedNavigationItemImplList&)items { |
return _items; |
} |
@@ -486,35 +491,41 @@ - (void)discardTransientItem { |
_transientItem.reset(); |
} |
-- (void)insertStateFromSessionController:(CRWSessionController*)sourceSession { |
- DCHECK(sourceSession); |
+- (void)copyStateFromSessionControllerAndPrune:(CRWSessionController*)source { |
+ DCHECK(source); |
+ if (!self.canPruneAllButLastCommittedItem) |
+ return; |
// The other session may not have any items, in which case there is nothing |
- // to insert. The other session's currentItem will be bogus in such cases, so |
- // ignore it and return early. |
- web::ScopedNavigationItemImplList& sourceItems = sourceSession->_items; |
+ // to insert. |
+ const web::ScopedNavigationItemImplList& sourceItems = source->_items; |
if (sourceItems.empty()) |
return; |
- // Cycle through the items from the other session and insert them before any |
- // items from this session. Do not copy anything that comes after the other |
- // session's current item. |
- NSInteger lastIndexToCopy = sourceSession.currentNavigationIndex; |
- for (NSInteger i = 0; i <= lastIndexToCopy; ++i) { |
- std::unique_ptr<web::NavigationItemImpl> sourceItemCopy = |
- base::MakeUnique<web::NavigationItemImpl>(*sourceItems[i]); |
- _items.insert(_items.begin() + i, std::move(sourceItemCopy)); |
+ // Early return if there's no committed source item. |
+ if (!source.lastCommittedItem) |
+ return; |
Eugene But (OOO till 7-30)
2017/03/15 19:54:51
Can we even get here? if there is no |lastCommitte
kkhorimoto
2017/03/15 21:04:38
We're checking |canPruneAllButLastCommittedItem| o
|
+ |
+ // Copy |sourceItems| into a new NavigationItemList. |
+ DCHECK_GT(source.currentNavigationIndex, -1); |
+ size_t sourceCurrentIndex = |
+ static_cast<size_t>(source.currentNavigationIndex); |
+ web::ScopedNavigationItemImplList mergedItems(sourceCurrentIndex + 2); |
Eugene But (OOO till 7-30)
2017/03/15 19:54:51
Why +2 ?
kkhorimoto
2017/03/15 21:04:38
Big enough for |source|'s session up to and includ
|
+ for (size_t index = 0; index <= sourceCurrentIndex; ++index) { |
+ mergedItems[index] = |
+ base::MakeUnique<web::NavigationItemImpl>(*sourceItems[index]); |
} |
+ mergedItems.back() = std::move(_items[self.currentNavigationIndex]); |
+ |
+ // Use |mergedItems| as the session history. |
+ std::swap(mergedItems, _items); |
// Update state to reflect inserted NavigationItems. |
_previousNavigationIndex = -1; |
- _currentNavigationIndex += lastIndexToCopy + 1; |
- if (self.pendingItemIndex != -1) |
- self.pendingItemIndex += lastIndexToCopy + 1; |
+ _currentNavigationIndex = self.items.size() - 1; |
DCHECK_LT(static_cast<NSUInteger>(_currentNavigationIndex), |
self.items.size()); |
- DCHECK(self.pendingItemIndex == -1 || self.pendingItem); |
} |
- (void)goToItemAtIndex:(NSInteger)index { |