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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 | 70 |
71 // Stores the certificate policies decided by the user. | 71 // Stores the certificate policies decided by the user. |
72 CRWSessionCertificatePolicyManager* _sessionCertificatePolicyManager; | 72 CRWSessionCertificatePolicyManager* _sessionCertificatePolicyManager; |
73 | 73 |
74 // The timestamp of the last time this tab is visited, represented in time | 74 // The timestamp of the last time this tab is visited, represented in time |
75 // interval since 1970. | 75 // interval since 1970. |
76 NSTimeInterval _lastVisitedTimestamp; | 76 NSTimeInterval _lastVisitedTimestamp; |
77 | 77 |
78 // If |YES|, override |currentEntry.useDesktopUserAgent| and create the | 78 // If |YES|, override |currentEntry.useDesktopUserAgent| and create the |
79 // pending entry using the desktop user agent. | 79 // pending entry using the desktop user agent. |
80 BOOL _useDesktopUserAgentForNextPendingEntry; | 80 BOOL _useDesktopUserAgentForNextPendingItem; |
81 | 81 |
82 // The browser state associated with this CRWSessionController; | 82 // The browser state associated with this CRWSessionController; |
83 web::BrowserState* _browserState; // weak | 83 web::BrowserState* _browserState; // weak |
84 | 84 |
85 // Time smoother for navigation entry timestamps; see comment in | 85 // Time smoother for navigation entry timestamps; see comment in |
86 // navigation_controller_impl.h | 86 // navigation_controller_impl.h |
87 web::TimeSmoother _timeSmoother; | 87 web::TimeSmoother _timeSmoother; |
88 } | 88 } |
89 | 89 |
90 // Redefine as readwrite. | 90 // Redefine as readwrite. |
91 @property(nonatomic, readwrite, assign) NSInteger currentNavigationIndex; | 91 @property(nonatomic, readwrite, assign) NSInteger currentNavigationIndex; |
92 | 92 |
93 // TODO(rohitrao): These properties must be redefined readwrite to work around a | 93 // TODO(rohitrao): These properties must be redefined readwrite to work around a |
94 // clang bug. crbug.com/228650 | 94 // clang bug. crbug.com/228650 |
95 @property(nonatomic, readwrite, copy) NSString* tabId; | 95 @property(nonatomic, readwrite, copy) NSString* tabId; |
96 @property(nonatomic, readwrite, strong) NSArray* entries; | 96 @property(nonatomic, readwrite, strong) NSArray* entries; |
97 @property(nonatomic, readwrite, strong) | 97 @property(nonatomic, readwrite, strong) |
98 CRWSessionCertificatePolicyManager* sessionCertificatePolicyManager; | 98 CRWSessionCertificatePolicyManager* sessionCertificatePolicyManager; |
99 | 99 |
100 // Expose setters for serialization properties. These are exposed in a category | 100 // Expose setters for serialization properties. These are exposed in a category |
101 // in NavigationManagerStorageBuilder, and will be removed as ownership of | 101 // in NavigationManagerStorageBuilder, and will be removed as ownership of |
102 // their backing ivars moves to NavigationManagerImpl. | 102 // their backing ivars moves to NavigationManagerImpl. |
103 @property(nonatomic, readwrite, copy) NSString* openerId; | 103 @property(nonatomic, readwrite, copy) NSString* openerId; |
104 @property(nonatomic, readwrite, getter=isOpenedByDOM) BOOL openedByDOM; | 104 @property(nonatomic, readwrite, getter=isOpenedByDOM) BOOL openedByDOM; |
105 @property(nonatomic, readwrite, assign) NSInteger openerNavigationIndex; | 105 @property(nonatomic, readwrite, assign) NSInteger openerNavigationIndex; |
106 @property(nonatomic, readwrite, assign) NSInteger previousNavigationIndex; | 106 @property(nonatomic, readwrite, assign) NSInteger previousNavigationIndex; |
107 | 107 |
108 - (NSString*)uniqueID; | 108 - (NSString*)uniqueID; |
109 // Removes all entries after currentNavigationIndex_. | 109 // Removes all entries after currentNavigationIndex_. |
110 - (void)clearForwardEntries; | 110 - (void)clearForwardItems; |
111 // Discards the transient entry, if any. | 111 // Discards the transient entry, if any. |
112 - (void)discardTransientEntry; | 112 - (void)discardTransientItem; |
113 // Create a new autoreleased session entry. | 113 // Create a new autoreleased session entry. |
114 - (CRWSessionEntry*)sessionEntryWithURL:(const GURL&)url | 114 - (CRWSessionEntry*)sessionEntryWithURL:(const GURL&)url |
115 referrer:(const web::Referrer&)referrer | 115 referrer:(const web::Referrer&)referrer |
116 transition:(ui::PageTransition)transition | 116 transition:(ui::PageTransition)transition |
117 useDesktopUserAgent:(BOOL)useDesktopUserAgent | 117 useDesktopUserAgent:(BOOL)useDesktopUserAgent |
118 rendererInitiated:(BOOL)rendererInitiated; | 118 rendererInitiated:(BOOL)rendererInitiated; |
119 // Returns YES if the PageTransition for the underlying navigationItem at | 119 // Returns YES if the PageTransition for the underlying navigationItem at |
120 // |index| in |entries_| has ui::PAGE_TRANSITION_IS_REDIRECT_MASK. | 120 // |index| in |entries_| has ui::PAGE_TRANSITION_IS_REDIRECT_MASK. |
121 - (BOOL)isRedirectTransitionForEntryAtIndex:(NSInteger)index; | 121 - (BOOL)isRedirectTransitionForItemAtIndex:(NSInteger)index; |
| 122 // Returns a NavigationItemList containing the NavigationItems from |entries|. |
| 123 - (web::NavigationItemList)itemListForEntryList:(NSArray*)entries; |
122 @end | 124 @end |
123 | 125 |
124 @implementation CRWSessionController | 126 @implementation CRWSessionController |
125 | 127 |
126 @synthesize tabId = _tabId; | 128 @synthesize tabId = _tabId; |
127 @synthesize currentNavigationIndex = _currentNavigationIndex; | 129 @synthesize currentNavigationIndex = _currentNavigationIndex; |
128 @synthesize previousNavigationIndex = _previousNavigationIndex; | 130 @synthesize previousNavigationIndex = _previousNavigationIndex; |
129 @synthesize pendingEntryIndex = _pendingEntryIndex; | 131 @synthesize pendingItemIndex = _pendingItemIndex; |
130 @synthesize entries = _entries; | 132 @synthesize entries = _entries; |
131 @synthesize windowName = _windowName; | 133 @synthesize windowName = _windowName; |
132 @synthesize lastVisitedTimestamp = _lastVisitedTimestamp; | 134 @synthesize lastVisitedTimestamp = _lastVisitedTimestamp; |
133 @synthesize openerId = _openerId; | 135 @synthesize openerId = _openerId; |
134 @synthesize openedByDOM = _openedByDOM; | 136 @synthesize openedByDOM = _openedByDOM; |
135 @synthesize openerNavigationIndex = _openerNavigationIndex; | 137 @synthesize openerNavigationIndex = _openerNavigationIndex; |
136 @synthesize sessionCertificatePolicyManager = _sessionCertificatePolicyManager; | 138 @synthesize sessionCertificatePolicyManager = _sessionCertificatePolicyManager; |
137 | 139 |
138 - (id)initWithWindowName:(NSString*)windowName | 140 - (id)initWithWindowName:(NSString*)windowName |
139 openerId:(NSString*)openerId | 141 openerId:(NSString*)openerId |
140 openedByDOM:(BOOL)openedByDOM | 142 openedByDOM:(BOOL)openedByDOM |
141 openerNavigationIndex:(NSInteger)openerIndex | 143 openerNavigationIndex:(NSInteger)openerIndex |
142 browserState:(web::BrowserState*)browserState { | 144 browserState:(web::BrowserState*)browserState { |
143 self = [super init]; | 145 self = [super init]; |
144 if (self) { | 146 if (self) { |
145 self.windowName = windowName; | 147 self.windowName = windowName; |
146 _tabId = [[self uniqueID] copy]; | 148 _tabId = [[self uniqueID] copy]; |
147 _openerId = [openerId copy]; | 149 _openerId = [openerId copy]; |
148 _openedByDOM = openedByDOM; | 150 _openedByDOM = openedByDOM; |
149 _openerNavigationIndex = openerIndex; | 151 _openerNavigationIndex = openerIndex; |
150 _browserState = browserState; | 152 _browserState = browserState; |
151 _entries = [NSMutableArray array]; | 153 _entries = [NSMutableArray array]; |
152 _lastVisitedTimestamp = [[NSDate date] timeIntervalSince1970]; | 154 _lastVisitedTimestamp = [[NSDate date] timeIntervalSince1970]; |
153 _currentNavigationIndex = -1; | 155 _currentNavigationIndex = -1; |
154 _previousNavigationIndex = -1; | 156 _previousNavigationIndex = -1; |
155 _pendingEntryIndex = -1; | 157 _pendingItemIndex = -1; |
156 _sessionCertificatePolicyManager = | 158 _sessionCertificatePolicyManager = |
157 [[CRWSessionCertificatePolicyManager alloc] init]; | 159 [[CRWSessionCertificatePolicyManager alloc] init]; |
158 } | 160 } |
159 return self; | 161 return self; |
160 } | 162 } |
161 | 163 |
162 - (id)initWithNavigationItems: | 164 - (id)initWithNavigationItems: |
163 (std::vector<std::unique_ptr<web::NavigationItem>>)items | 165 (std::vector<std::unique_ptr<web::NavigationItem>>)items |
164 currentIndex:(NSUInteger)currentIndex | 166 currentIndex:(NSUInteger)currentIndex |
165 browserState:(web::BrowserState*)browserState { | 167 browserState:(web::BrowserState*)browserState { |
(...skipping 12 matching lines...) Expand all Loading... |
178 [_entries addObject:entry]; | 180 [_entries addObject:entry]; |
179 } | 181 } |
180 self.currentNavigationIndex = currentIndex; | 182 self.currentNavigationIndex = currentIndex; |
181 // Prior to M34, 0 was used as "no index" instead of -1; adjust for that. | 183 // Prior to M34, 0 was used as "no index" instead of -1; adjust for that. |
182 if (![_entries count]) | 184 if (![_entries count]) |
183 self.currentNavigationIndex = -1; | 185 self.currentNavigationIndex = -1; |
184 if (_currentNavigationIndex >= static_cast<NSInteger>(items.size())) { | 186 if (_currentNavigationIndex >= static_cast<NSInteger>(items.size())) { |
185 self.currentNavigationIndex = static_cast<NSInteger>(items.size()) - 1; | 187 self.currentNavigationIndex = static_cast<NSInteger>(items.size()) - 1; |
186 } | 188 } |
187 _previousNavigationIndex = -1; | 189 _previousNavigationIndex = -1; |
188 _pendingEntryIndex = -1; | 190 _pendingItemIndex = -1; |
189 _lastVisitedTimestamp = [[NSDate date] timeIntervalSince1970]; | 191 _lastVisitedTimestamp = [[NSDate date] timeIntervalSince1970]; |
190 _sessionCertificatePolicyManager = | 192 _sessionCertificatePolicyManager = |
191 [[CRWSessionCertificatePolicyManager alloc] init]; | 193 [[CRWSessionCertificatePolicyManager alloc] init]; |
192 } | 194 } |
193 return self; | 195 return self; |
194 } | 196 } |
195 | 197 |
196 - (id)copyWithZone:(NSZone*)zone { | 198 - (id)copyWithZone:(NSZone*)zone { |
197 CRWSessionController* copy = [[[self class] alloc] init]; | 199 CRWSessionController* copy = [[[self class] alloc] init]; |
198 copy->_tabId = [_tabId copy]; | 200 copy->_tabId = [_tabId copy]; |
199 copy->_openerId = [_openerId copy]; | 201 copy->_openerId = [_openerId copy]; |
200 copy->_openedByDOM = _openedByDOM; | 202 copy->_openedByDOM = _openedByDOM; |
201 copy->_openerNavigationIndex = _openerNavigationIndex; | 203 copy->_openerNavigationIndex = _openerNavigationIndex; |
202 copy.windowName = self.windowName; | 204 copy.windowName = self.windowName; |
203 copy->_currentNavigationIndex = _currentNavigationIndex; | 205 copy->_currentNavigationIndex = _currentNavigationIndex; |
204 copy->_previousNavigationIndex = _previousNavigationIndex; | 206 copy->_previousNavigationIndex = _previousNavigationIndex; |
205 copy->_pendingEntryIndex = _pendingEntryIndex; | 207 copy->_pendingItemIndex = _pendingItemIndex; |
206 copy->_lastVisitedTimestamp = _lastVisitedTimestamp; | 208 copy->_lastVisitedTimestamp = _lastVisitedTimestamp; |
207 copy->_entries = | 209 copy->_entries = |
208 [[NSMutableArray alloc] initWithArray:_entries copyItems:YES]; | 210 [[NSMutableArray alloc] initWithArray:_entries copyItems:YES]; |
209 copy->_sessionCertificatePolicyManager = | 211 copy->_sessionCertificatePolicyManager = |
210 [_sessionCertificatePolicyManager copy]; | 212 [_sessionCertificatePolicyManager copy]; |
211 return copy; | 213 return copy; |
212 } | 214 } |
213 | 215 |
214 - (void)setCurrentNavigationIndex:(NSInteger)currentNavigationIndex { | 216 - (void)setCurrentNavigationIndex:(NSInteger)currentNavigationIndex { |
215 if (_currentNavigationIndex != currentNavigationIndex) { | 217 if (_currentNavigationIndex != currentNavigationIndex) { |
216 _currentNavigationIndex = currentNavigationIndex; | 218 _currentNavigationIndex = currentNavigationIndex; |
217 if (_navigationManager) | 219 if (_navigationManager) |
218 _navigationManager->RemoveTransientURLRewriters(); | 220 _navigationManager->RemoveTransientURLRewriters(); |
219 } | 221 } |
220 } | 222 } |
221 | 223 |
222 - (void)setPendingEntryIndex:(NSInteger)index { | 224 - (void)setPendingItemIndex:(NSInteger)index { |
223 DCHECK_GE(index, -1); | 225 DCHECK_GE(index, -1); |
224 DCHECK_LT(index, static_cast<NSInteger>(_entries.count)); | 226 DCHECK_LT(index, static_cast<NSInteger>(_entries.count)); |
225 _pendingEntryIndex = index; | 227 _pendingItemIndex = index; |
226 CRWSessionEntry* entry = index != -1 ? _entries[index] : nil; | 228 CRWSessionEntry* entry = index != -1 ? _entries[index] : nil; |
227 _pendingEntry.reset(entry); | 229 _pendingEntry.reset(entry); |
228 DCHECK(_pendingEntryIndex == -1 || _pendingEntry); | 230 DCHECK(_pendingItemIndex == -1 || _pendingEntry); |
229 } | 231 } |
230 | 232 |
231 - (void)setNavigationManager:(web::NavigationManagerImpl*)navigationManager { | 233 - (void)setNavigationManager:(web::NavigationManagerImpl*)navigationManager { |
232 _navigationManager = navigationManager; | 234 _navigationManager = navigationManager; |
233 if (_navigationManager) { | 235 if (_navigationManager) { |
234 // _browserState will be nullptr if CRWSessionController has been | 236 // _browserState will be nullptr if CRWSessionController has been |
235 // initialized with -initWithCoder: method. Take _browserState from | 237 // initialized with -initWithCoder: method. Take _browserState from |
236 // NavigationManagerImpl if that's the case. | 238 // NavigationManagerImpl if that's the case. |
237 if (!_browserState) { | 239 if (!_browserState) { |
238 _browserState = _navigationManager->GetBrowserState(); | 240 _browserState = _navigationManager->GetBrowserState(); |
239 } | 241 } |
240 DCHECK_EQ(_browserState, _navigationManager->GetBrowserState()); | 242 DCHECK_EQ(_browserState, _navigationManager->GetBrowserState()); |
241 } | 243 } |
242 } | 244 } |
243 | 245 |
244 - (void)setBrowserState:(web::BrowserState*)browserState { | 246 - (void)setBrowserState:(web::BrowserState*)browserState { |
245 _browserState = browserState; | 247 _browserState = browserState; |
246 DCHECK(!_navigationManager || | 248 DCHECK(!_navigationManager || |
247 _navigationManager->GetBrowserState() == _browserState); | 249 _navigationManager->GetBrowserState() == _browserState); |
248 } | 250 } |
249 | 251 |
250 - (NSString*)description { | 252 - (NSString*)description { |
251 return [NSString | 253 return [NSString |
252 stringWithFormat: | 254 stringWithFormat: |
253 @"id: %@\nname: %@\nlast visit: %f\ncurrent index: %" PRIdNS | 255 @"id: %@\nname: %@\nlast visit: %f\ncurrent index: %" PRIdNS |
254 @"\nprevious index: %" PRIdNS @"\npending index: %" PRIdNS | 256 @"\nprevious index: %" PRIdNS @"\npending index: %" PRIdNS |
255 @"\n%@\npending: %@\ntransient: %@\n", | 257 @"\n%@\npending: %@\ntransient: %@\n", |
256 _tabId, self.windowName, _lastVisitedTimestamp, | 258 _tabId, self.windowName, _lastVisitedTimestamp, |
257 _currentNavigationIndex, _previousNavigationIndex, _pendingEntryIndex, | 259 _currentNavigationIndex, _previousNavigationIndex, _pendingItemIndex, |
258 _entries, _pendingEntry.get(), _transientEntry.get()]; | 260 _entries, _pendingEntry.get(), _transientEntry.get()]; |
259 } | 261 } |
260 | 262 |
| 263 - (web::NavigationItemList)items { |
| 264 return [self itemListForEntryList:self.entries]; |
| 265 } |
| 266 |
| 267 - (web::NavigationItemImpl*)currentItem { |
| 268 return self.currentEntry.navigationItemImpl; |
| 269 } |
| 270 |
| 271 - (web::NavigationItemImpl*)visibleItem { |
| 272 return self.visibleEntry.navigationItemImpl; |
| 273 } |
| 274 |
| 275 - (web::NavigationItemImpl*)pendingItem { |
| 276 return self.pendingEntry.navigationItemImpl; |
| 277 } |
| 278 |
| 279 - (web::NavigationItemImpl*)transientItem { |
| 280 return self.transientEntry.navigationItemImpl; |
| 281 } |
| 282 |
| 283 - (web::NavigationItemImpl*)lastCommittedItem { |
| 284 return self.lastCommittedEntry.navigationItemImpl; |
| 285 } |
| 286 |
| 287 - (web::NavigationItemImpl*)previousItem { |
| 288 return self.previousEntry.navigationItemImpl; |
| 289 } |
| 290 |
| 291 - (web::NavigationItemImpl*)lastUserItem { |
| 292 return self.lastUserEntry.navigationItemImpl; |
| 293 } |
| 294 |
| 295 - (web::NavigationItemList)backwardItems { |
| 296 return [self itemListForEntryList:self.backwardEntries]; |
| 297 } |
| 298 |
| 299 - (web::NavigationItemList)forwardItems { |
| 300 return [self itemListForEntryList:self.forwardEntries]; |
| 301 } |
| 302 |
261 // Returns the current entry in the session list, or the pending entry if there | 303 // Returns the current entry in the session list, or the pending entry if there |
262 // is a navigation in progress. | 304 // is a navigation in progress. |
263 - (CRWSessionEntry*)currentEntry { | 305 - (CRWSessionEntry*)currentEntry { |
264 if (_transientEntry) | 306 if (_transientEntry) |
265 return _transientEntry.get(); | 307 return _transientEntry.get(); |
266 if (_pendingEntry) | 308 if (_pendingEntry) |
267 return _pendingEntry.get(); | 309 return _pendingEntry.get(); |
268 return [self lastCommittedEntry]; | 310 return [self lastCommittedEntry]; |
269 } | 311 } |
270 | 312 |
271 // See NavigationController::GetVisibleEntry for the motivation for this | 313 // See NavigationController::GetVisibleEntry for the motivation for this |
272 // distinction. | 314 // distinction. |
273 - (CRWSessionEntry*)visibleEntry { | 315 - (CRWSessionEntry*)visibleEntry { |
274 if (_transientEntry) | 316 if (_transientEntry) |
275 return _transientEntry.get(); | 317 return _transientEntry.get(); |
276 // Only return the pending_entry for new (non-history), browser-initiated | 318 // Only return the pending_entry for new (non-history), browser-initiated |
277 // navigations in order to prevent URL spoof attacks. | 319 // navigations in order to prevent URL spoof attacks. |
278 web::NavigationItemImpl* pendingItem = [_pendingEntry navigationItemImpl]; | 320 web::NavigationItemImpl* pendingItem = [_pendingEntry navigationItemImpl]; |
279 bool safeToShowPending = pendingItem && | 321 bool safeToShowPending = pendingItem && |
280 !pendingItem->is_renderer_initiated() && | 322 !pendingItem->is_renderer_initiated() && |
281 _pendingEntryIndex == -1; | 323 _pendingItemIndex == -1; |
282 if (safeToShowPending) { | 324 if (safeToShowPending) { |
283 return _pendingEntry.get(); | 325 return _pendingEntry.get(); |
284 } | 326 } |
285 return [self lastCommittedEntry]; | 327 return [self lastCommittedEntry]; |
286 } | 328 } |
287 | 329 |
288 - (CRWSessionEntry*)pendingEntry { | 330 - (CRWSessionEntry*)pendingEntry { |
289 return _pendingEntry.get(); | 331 return _pendingEntry.get(); |
290 } | 332 } |
291 | 333 |
292 - (CRWSessionEntry*)transientEntry { | 334 - (CRWSessionEntry*)transientEntry { |
293 return _transientEntry.get(); | 335 return _transientEntry.get(); |
294 } | 336 } |
295 | 337 |
296 - (CRWSessionEntry*)lastCommittedEntry { | 338 - (CRWSessionEntry*)lastCommittedEntry { |
297 if (_currentNavigationIndex == -1) | 339 if (_currentNavigationIndex == -1) |
298 return nil; | 340 return nil; |
299 return [_entries objectAtIndex:_currentNavigationIndex]; | 341 return [_entries objectAtIndex:_currentNavigationIndex]; |
300 } | 342 } |
301 | 343 |
302 // Returns the previous entry in the session list, or nil if there isn't any. | 344 // Returns the previous entry in the session list, or nil if there isn't any. |
303 - (CRWSessionEntry*)previousEntry { | 345 - (CRWSessionEntry*)previousEntry { |
304 if ((_previousNavigationIndex < 0) || (![_entries count])) | 346 if ((_previousNavigationIndex < 0) || (![_entries count])) |
305 return nil; | 347 return nil; |
306 return [_entries objectAtIndex:_previousNavigationIndex]; | 348 return [_entries objectAtIndex:_previousNavigationIndex]; |
307 } | 349 } |
308 | 350 |
309 - (void)addPendingEntry:(const GURL&)url | 351 - (void)addPendingItem:(const GURL&)url |
310 referrer:(const web::Referrer&)ref | 352 referrer:(const web::Referrer&)ref |
311 transition:(ui::PageTransition)trans | 353 transition:(ui::PageTransition)trans |
312 rendererInitiated:(BOOL)rendererInitiated { | 354 rendererInitiated:(BOOL)rendererInitiated { |
313 [self discardTransientEntry]; | 355 [self discardTransientItem]; |
314 _pendingEntryIndex = -1; | 356 _pendingItemIndex = -1; |
315 | 357 |
316 // Don't create a new entry if it's already the same as the current entry, | 358 // Don't create a new entry if it's already the same as the current entry, |
317 // allowing this routine to be called multiple times in a row without issue. | 359 // allowing this routine to be called multiple times in a row without issue. |
318 // Note: CRWSessionController currently has the responsibility to distinguish | 360 // Note: CRWSessionController currently has the responsibility to distinguish |
319 // between new navigations and history stack navigation, hence the inclusion | 361 // between new navigations and history stack navigation, hence the inclusion |
320 // of specific transiton type logic here, in order to make it reliable with | 362 // of specific transiton type logic here, in order to make it reliable with |
321 // real-world observed behavior. | 363 // real-world observed behavior. |
322 // TODO(crbug.com/676129): Fix the way changes are detected/reported elsewhere | 364 // TODO(crbug.com/676129): Fix the way changes are detected/reported elsewhere |
323 // in the web layer so that this hack can be removed. | 365 // in the web layer so that this hack can be removed. |
324 // Remove the workaround code from -presentSafeBrowsingWarningForResource:. | 366 // Remove the workaround code from -presentSafeBrowsingWarningForResource:. |
325 CRWSessionEntry* currentEntry = self.currentEntry; | 367 CRWSessionEntry* currentEntry = self.currentEntry; |
326 if (currentEntry) { | 368 if (currentEntry) { |
327 web::NavigationItem* item = [currentEntry navigationItem]; | 369 web::NavigationItem* item = [currentEntry navigationItem]; |
328 if (item->GetURL() == url && | 370 if (item->GetURL() == url && |
329 (!PageTransitionCoreTypeIs(trans, ui::PAGE_TRANSITION_FORM_SUBMIT) || | 371 (!PageTransitionCoreTypeIs(trans, ui::PAGE_TRANSITION_FORM_SUBMIT) || |
330 PageTransitionCoreTypeIs(item->GetTransitionType(), | 372 PageTransitionCoreTypeIs(item->GetTransitionType(), |
331 ui::PAGE_TRANSITION_FORM_SUBMIT))) { | 373 ui::PAGE_TRANSITION_FORM_SUBMIT))) { |
332 // Send the notification anyway, to preserve old behavior. It's unknown | 374 // Send the notification anyway, to preserve old behavior. It's unknown |
333 // whether anything currently relies on this, but since both this whole | 375 // whether anything currently relies on this, but since both this whole |
334 // hack and the content facade will both be going away, it's not worth | 376 // hack and the content facade will both be going away, it's not worth |
335 // trying to unwind. | 377 // trying to unwind. |
336 if (_navigationManager && _navigationManager->GetFacadeDelegate()) { | 378 if (_navigationManager && _navigationManager->GetFacadeDelegate()) { |
337 _navigationManager->GetFacadeDelegate()->OnNavigationItemPending(); | 379 _navigationManager->GetFacadeDelegate()->OnNavigationItemPending(); |
338 } | 380 } |
339 return; | 381 return; |
340 } | 382 } |
341 } | 383 } |
342 | 384 |
343 BOOL useDesktopUserAgent = | 385 BOOL useDesktopUserAgent = |
344 _useDesktopUserAgentForNextPendingEntry || | 386 _useDesktopUserAgentForNextPendingItem || |
345 (self.currentEntry.navigationItem && | 387 (self.currentEntry.navigationItem && |
346 self.currentEntry.navigationItem->IsOverridingUserAgent()); | 388 self.currentEntry.navigationItem->IsOverridingUserAgent()); |
347 _useDesktopUserAgentForNextPendingEntry = NO; | 389 _useDesktopUserAgentForNextPendingItem = NO; |
348 _pendingEntry.reset([self sessionEntryWithURL:url | 390 _pendingEntry.reset([self sessionEntryWithURL:url |
349 referrer:ref | 391 referrer:ref |
350 transition:trans | 392 transition:trans |
351 useDesktopUserAgent:useDesktopUserAgent | 393 useDesktopUserAgent:useDesktopUserAgent |
352 rendererInitiated:rendererInitiated]); | 394 rendererInitiated:rendererInitiated]); |
353 | 395 |
354 if (_navigationManager && _navigationManager->GetFacadeDelegate()) { | 396 if (_navigationManager && _navigationManager->GetFacadeDelegate()) { |
355 _navigationManager->GetFacadeDelegate()->OnNavigationItemPending(); | 397 _navigationManager->GetFacadeDelegate()->OnNavigationItemPending(); |
356 } | 398 } |
357 } | 399 } |
358 | 400 |
359 - (void)updatePendingEntry:(const GURL&)url { | 401 - (void)updatePendingItem:(const GURL&)url { |
360 // If there is no pending entry, navigation is probably happening within the | 402 // If there is no pending entry, navigation is probably happening within the |
361 // session history. Don't modify the entry list. | 403 // session history. Don't modify the entry list. |
362 if (!_pendingEntry) | 404 if (!_pendingEntry) |
363 return; | 405 return; |
364 | 406 |
365 web::NavigationItemImpl* item = [_pendingEntry navigationItemImpl]; | 407 web::NavigationItemImpl* item = [_pendingEntry navigationItemImpl]; |
366 if (url != item->GetURL()) { | 408 if (url != item->GetURL()) { |
367 // Assume a redirection, and discard any transient entry. | 409 // Assume a redirection, and discard any transient entry. |
368 // TODO(stuartmorgan): Once the current safe browsing code is gone, | 410 // TODO(stuartmorgan): Once the current safe browsing code is gone, |
369 // consider making this a DCHECK that there's no transient entry. | 411 // consider making this a DCHECK that there's no transient entry. |
370 [self discardTransientEntry]; | 412 [self discardTransientItem]; |
371 | 413 |
372 item->SetURL(url); | 414 item->SetURL(url); |
373 item->SetVirtualURL(url); | 415 item->SetVirtualURL(url); |
374 // Redirects (3xx response code), or client side navigation must change | 416 // Redirects (3xx response code), or client side navigation must change |
375 // POST requests to GETs. | 417 // POST requests to GETs. |
376 item->SetPostData(nil); | 418 item->SetPostData(nil); |
377 item->ResetHttpRequestHeaders(); | 419 item->ResetHttpRequestHeaders(); |
378 } | 420 } |
379 | 421 |
380 // This should probably not be sent if the URLs matched, but that's what was | 422 // This should probably not be sent if the URLs matched, but that's what was |
381 // done before, so preserve behavior in case something relies on it. | 423 // done before, so preserve behavior in case something relies on it. |
382 if (_navigationManager && _navigationManager->GetFacadeDelegate()) { | 424 if (_navigationManager && _navigationManager->GetFacadeDelegate()) { |
383 _navigationManager->GetFacadeDelegate()->OnNavigationItemPending(); | 425 _navigationManager->GetFacadeDelegate()->OnNavigationItemPending(); |
384 } | 426 } |
385 } | 427 } |
386 | 428 |
387 - (void)clearForwardEntries { | 429 - (void)clearForwardItems { |
388 DCHECK_EQ(_pendingEntryIndex, -1); | 430 DCHECK_EQ(_pendingItemIndex, -1); |
389 [self discardTransientEntry]; | 431 [self discardTransientItem]; |
390 | 432 |
391 NSInteger forwardEntryStartIndex = _currentNavigationIndex + 1; | 433 NSInteger forwardItemStartIndex = _currentNavigationIndex + 1; |
392 DCHECK(forwardEntryStartIndex >= 0); | 434 DCHECK(forwardItemStartIndex >= 0); |
393 | 435 |
394 if (forwardEntryStartIndex >= static_cast<NSInteger>([_entries count])) | 436 if (forwardItemStartIndex >= static_cast<NSInteger>([_entries count])) |
395 return; | 437 return; |
396 | 438 |
397 NSRange remove = NSMakeRange(forwardEntryStartIndex, | 439 NSRange remove = NSMakeRange(forwardItemStartIndex, |
398 [_entries count] - forwardEntryStartIndex); | 440 [_entries count] - forwardItemStartIndex); |
399 // Store removed items in temporary NSArray so they can be deallocated after | 441 // Store removed items in temporary NSArray so they can be deallocated after |
400 // their facades. | 442 // their facades. |
401 base::scoped_nsobject<NSArray> removedItems( | 443 base::scoped_nsobject<NSArray> removedItems( |
402 [_entries subarrayWithRange:remove]); | 444 [_entries subarrayWithRange:remove]); |
403 [_entries removeObjectsInRange:remove]; | 445 [_entries removeObjectsInRange:remove]; |
404 if (_previousNavigationIndex >= forwardEntryStartIndex) | 446 if (_previousNavigationIndex >= forwardItemStartIndex) |
405 _previousNavigationIndex = -1; | 447 _previousNavigationIndex = -1; |
406 if (_navigationManager) { | 448 if (_navigationManager) { |
407 _navigationManager->OnNavigationItemsPruned(remove.length); | 449 _navigationManager->OnNavigationItemsPruned(remove.length); |
408 } | 450 } |
409 } | 451 } |
410 | 452 |
411 - (void)commitPendingEntry { | 453 - (void)commitPendingItem { |
412 if (_pendingEntry) { | 454 if (_pendingEntry) { |
413 NSInteger newNavigationIndex = _pendingEntryIndex; | 455 NSInteger newNavigationIndex = _pendingItemIndex; |
414 if (_pendingEntryIndex == -1) { | 456 if (_pendingItemIndex == -1) { |
415 [self clearForwardEntries]; | 457 [self clearForwardItems]; |
416 // Add the new entry at the end. | 458 // Add the new entry at the end. |
417 [_entries addObject:_pendingEntry]; | 459 [_entries addObject:_pendingEntry]; |
418 newNavigationIndex = [_entries count] - 1; | 460 newNavigationIndex = [_entries count] - 1; |
419 } | 461 } |
420 _previousNavigationIndex = _currentNavigationIndex; | 462 _previousNavigationIndex = _currentNavigationIndex; |
421 self.currentNavigationIndex = newNavigationIndex; | 463 self.currentNavigationIndex = newNavigationIndex; |
422 // Once an entry is committed it's not renderer-initiated any more. (Matches | 464 // Once an entry is committed it's not renderer-initiated any more. (Matches |
423 // the implementation in NavigationController.) | 465 // the implementation in NavigationController.) |
424 [_pendingEntry navigationItemImpl]->ResetForCommit(); | 466 [_pendingEntry navigationItemImpl]->ResetForCommit(); |
425 _pendingEntry.reset(); | 467 _pendingEntry.reset(); |
426 _pendingEntryIndex = -1; | 468 _pendingItemIndex = -1; |
427 } | 469 } |
428 | 470 |
429 CRWSessionEntry* currentEntry = self.currentEntry; | 471 CRWSessionEntry* currentEntry = self.currentEntry; |
430 web::NavigationItem* item = currentEntry.navigationItem; | 472 web::NavigationItem* item = currentEntry.navigationItem; |
431 // Update the navigation timestamp now that it's actually happened. | 473 // Update the navigation timestamp now that it's actually happened. |
432 if (item) | 474 if (item) |
433 item->SetTimestamp(_timeSmoother.GetSmoothedTime(base::Time::Now())); | 475 item->SetTimestamp(_timeSmoother.GetSmoothedTime(base::Time::Now())); |
434 | 476 |
435 if (_navigationManager && item) | 477 if (_navigationManager && item) |
436 _navigationManager->OnNavigationItemCommitted(); | 478 _navigationManager->OnNavigationItemCommitted(); |
437 DCHECK_EQ(_pendingEntryIndex, -1); | 479 DCHECK_EQ(_pendingItemIndex, -1); |
438 } | 480 } |
439 | 481 |
440 - (void)addTransientEntryWithURL:(const GURL&)URL { | 482 - (void)addTransientItemWithURL:(const GURL&)URL { |
441 _transientEntry.reset([self | 483 _transientEntry.reset([self |
442 sessionEntryWithURL:URL | 484 sessionEntryWithURL:URL |
443 referrer:web::Referrer() | 485 referrer:web::Referrer() |
444 transition:ui::PAGE_TRANSITION_CLIENT_REDIRECT | 486 transition:ui::PAGE_TRANSITION_CLIENT_REDIRECT |
445 useDesktopUserAgent:NO | 487 useDesktopUserAgent:NO |
446 rendererInitiated:NO]); | 488 rendererInitiated:NO]); |
447 | 489 |
448 web::NavigationItem* navigationItem = [_transientEntry navigationItem]; | 490 web::NavigationItem* navigationItem = [_transientEntry navigationItem]; |
449 DCHECK(navigationItem); | 491 DCHECK(navigationItem); |
450 navigationItem->SetTimestamp( | 492 navigationItem->SetTimestamp( |
451 _timeSmoother.GetSmoothedTime(base::Time::Now())); | 493 _timeSmoother.GetSmoothedTime(base::Time::Now())); |
452 } | 494 } |
453 | 495 |
454 - (void)pushNewEntryWithURL:(const GURL&)URL | 496 - (void)pushNewItemWithURL:(const GURL&)URL |
455 stateObject:(NSString*)stateObject | 497 stateObject:(NSString*)stateObject |
456 transition:(ui::PageTransition)transition { | 498 transition:(ui::PageTransition)transition { |
457 DCHECK(![self pendingEntry]); | 499 DCHECK(![self pendingEntry]); |
458 DCHECK([self currentEntry]); | 500 DCHECK([self currentEntry]); |
459 web::NavigationItem* item = [self currentEntry].navigationItem; | 501 web::NavigationItem* item = [self currentEntry].navigationItem; |
460 CHECK( | 502 CHECK( |
461 web::history_state_util::IsHistoryStateChangeValid(item->GetURL(), URL)); | 503 web::history_state_util::IsHistoryStateChangeValid(item->GetURL(), URL)); |
462 web::Referrer referrer(item->GetURL(), web::ReferrerPolicyDefault); | 504 web::Referrer referrer(item->GetURL(), web::ReferrerPolicyDefault); |
463 bool overrideUserAgent = | 505 bool overrideUserAgent = |
464 self.currentEntry.navigationItem->IsOverridingUserAgent(); | 506 self.currentEntry.navigationItem->IsOverridingUserAgent(); |
465 base::scoped_nsobject<CRWSessionEntry> pushedEntry([self | 507 base::scoped_nsobject<CRWSessionEntry> pushedEntry([self |
466 sessionEntryWithURL:URL | 508 sessionEntryWithURL:URL |
467 referrer:referrer | 509 referrer:referrer |
468 transition:transition | 510 transition:transition |
469 useDesktopUserAgent:overrideUserAgent | 511 useDesktopUserAgent:overrideUserAgent |
470 rendererInitiated:NO]); | 512 rendererInitiated:NO]); |
471 web::NavigationItemImpl* pushedItem = [pushedEntry navigationItemImpl]; | 513 web::NavigationItemImpl* pushedItem = [pushedEntry navigationItemImpl]; |
472 pushedItem->SetSerializedStateObject(stateObject); | 514 pushedItem->SetSerializedStateObject(stateObject); |
473 pushedItem->SetIsCreatedFromPushState(true); | 515 pushedItem->SetIsCreatedFromPushState(true); |
474 web::SSLStatus& sslStatus = [self currentEntry].navigationItem->GetSSL(); | 516 web::SSLStatus& sslStatus = [self currentEntry].navigationItem->GetSSL(); |
475 pushedEntry.get().navigationItem->GetSSL() = sslStatus; | 517 pushedEntry.get().navigationItem->GetSSL() = sslStatus; |
476 | 518 |
477 [self clearForwardEntries]; | 519 [self clearForwardItems]; |
478 // Add the new entry at the end. | 520 // Add the new entry at the end. |
479 [_entries addObject:pushedEntry]; | 521 [_entries addObject:pushedEntry]; |
480 _previousNavigationIndex = _currentNavigationIndex; | 522 _previousNavigationIndex = _currentNavigationIndex; |
481 self.currentNavigationIndex = [_entries count] - 1; | 523 self.currentNavigationIndex = [_entries count] - 1; |
482 | 524 |
483 if (_navigationManager) | 525 if (_navigationManager) |
484 _navigationManager->OnNavigationItemCommitted(); | 526 _navigationManager->OnNavigationItemCommitted(); |
485 } | 527 } |
486 | 528 |
487 - (void)updateCurrentEntryWithURL:(const GURL&)url | 529 - (void)updateCurrentItemWithURL:(const GURL&)url |
488 stateObject:(NSString*)stateObject { | 530 stateObject:(NSString*)stateObject { |
489 DCHECK(!_transientEntry); | 531 DCHECK(!_transientEntry); |
490 CRWSessionEntry* currentEntry = self.currentEntry; | 532 CRWSessionEntry* currentEntry = self.currentEntry; |
491 web::NavigationItemImpl* currentItem = self.currentEntry.navigationItemImpl; | 533 web::NavigationItemImpl* currentItem = self.currentEntry.navigationItemImpl; |
492 currentItem->SetURL(url); | 534 currentItem->SetURL(url); |
493 currentItem->SetSerializedStateObject(stateObject); | 535 currentItem->SetSerializedStateObject(stateObject); |
494 currentItem->SetHasStateBeenReplaced(true); | 536 currentItem->SetHasStateBeenReplaced(true); |
495 currentItem->SetPostData(nil); | 537 currentItem->SetPostData(nil); |
496 currentEntry.navigationItem->SetURL(url); | 538 currentEntry.navigationItem->SetURL(url); |
497 // If the change is to a committed entry, notify interested parties. | 539 // If the change is to a committed entry, notify interested parties. |
498 if (currentEntry != self.pendingEntry && _navigationManager) | 540 if (currentEntry != self.pendingEntry && _navigationManager) |
499 _navigationManager->OnNavigationItemChanged(); | 541 _navigationManager->OnNavigationItemChanged(); |
500 } | 542 } |
501 | 543 |
502 - (void)discardNonCommittedEntries { | 544 - (void)discardNonCommittedItems { |
503 [self discardTransientEntry]; | 545 [self discardTransientItem]; |
504 _pendingEntry.reset(); | 546 _pendingEntry.reset(); |
505 _pendingEntryIndex = -1; | 547 _pendingItemIndex = -1; |
506 } | 548 } |
507 | 549 |
508 - (void)discardTransientEntry { | 550 - (void)discardTransientItem { |
509 // Keep the entry alive temporarily. There are flows that get the current | 551 // Keep the entry alive temporarily. There are flows that get the current |
510 // entry, do some navigation operation, and then try to use that old current | 552 // entry, do some navigation operation, and then try to use that old current |
511 // entry; since navigations clear the transient entry, these flows might | 553 // entry; since navigations clear the transient entry, these flows might |
512 // crash. (This should be removable once more session management is handled | 554 // crash. (This should be removable once more session management is handled |
513 // within this class and/or NavigationManager). | 555 // within this class and/or NavigationManager). |
514 _transientEntry.reset(); | 556 _transientEntry.reset(); |
515 } | 557 } |
516 | 558 |
517 - (BOOL)hasPendingEntry { | |
518 return _pendingEntry != nil; | |
519 } | |
520 | |
521 - (void)insertStateFromSessionController:(CRWSessionController*)sourceSession { | 559 - (void)insertStateFromSessionController:(CRWSessionController*)sourceSession { |
522 DCHECK(sourceSession); | 560 DCHECK(sourceSession); |
523 self.windowName = sourceSession.windowName; | 561 self.windowName = sourceSession.windowName; |
524 | 562 |
525 // The other session may not have any entries, in which case there is nothing | 563 // The other session may not have any entries, in which case there is nothing |
526 // to insert. The other session's currentNavigationEntry will be bogus | 564 // to insert. The other session's currentNavigationEntry will be bogus |
527 // in such cases, so ignore it and return early. | 565 // in such cases, so ignore it and return early. |
528 NSArray* sourceEntries = sourceSession.entries; | 566 NSArray* sourceEntries = sourceSession.entries; |
529 if (!sourceEntries.count) | 567 if (!sourceEntries.count) |
530 return; | 568 return; |
531 | 569 |
532 // Cycle through the entries from the other session and insert them before any | 570 // Cycle through the entries from the other session and insert them before any |
533 // entries from this session. Do not copy anything that comes after the other | 571 // entries from this session. Do not copy anything that comes after the other |
534 // session's current entry. | 572 // session's current entry. |
535 NSInteger lastIndexToCopy = sourceSession.currentNavigationIndex; | 573 NSInteger lastIndexToCopy = sourceSession.currentNavigationIndex; |
536 for (NSInteger i = 0; i <= lastIndexToCopy; ++i) { | 574 for (NSInteger i = 0; i <= lastIndexToCopy; ++i) { |
537 [_entries insertObject:sourceEntries[i] atIndex:i]; | 575 [_entries insertObject:sourceEntries[i] atIndex:i]; |
538 } | 576 } |
539 | 577 |
540 _previousNavigationIndex = -1; | 578 _previousNavigationIndex = -1; |
541 _currentNavigationIndex += lastIndexToCopy + 1; | 579 _currentNavigationIndex += lastIndexToCopy + 1; |
542 if (_pendingEntryIndex != -1) | 580 if (_pendingItemIndex != -1) |
543 _pendingEntryIndex += lastIndexToCopy + 1; | 581 _pendingItemIndex += lastIndexToCopy + 1; |
544 | 582 |
545 DCHECK_LT(static_cast<NSUInteger>(_currentNavigationIndex), _entries.count); | 583 DCHECK_LT(static_cast<NSUInteger>(_currentNavigationIndex), _entries.count); |
546 DCHECK(_pendingEntryIndex == -1 || _pendingEntry); | 584 DCHECK(_pendingItemIndex == -1 || _pendingEntry); |
547 } | 585 } |
548 | 586 |
549 - (void)goToEntryAtIndex:(NSInteger)index { | 587 - (void)goToItemAtIndex:(NSInteger)index { |
550 if (index < 0 || static_cast<NSUInteger>(index) >= _entries.count) | 588 if (index < 0 || static_cast<NSUInteger>(index) >= _entries.count) |
551 return; | 589 return; |
552 | 590 |
553 if (index < _currentNavigationIndex) { | 591 if (index < _currentNavigationIndex) { |
554 // Going back. | 592 // Going back. |
555 [self discardNonCommittedEntries]; | 593 [self discardNonCommittedItems]; |
556 } else if (_currentNavigationIndex < index) { | 594 } else if (_currentNavigationIndex < index) { |
557 // Going forward. | 595 // Going forward. |
558 [self discardTransientEntry]; | 596 [self discardTransientItem]; |
559 } else { | 597 } else { |
560 // |delta| is 0, no need to change current navigation index. | 598 // |delta| is 0, no need to change current navigation index. |
561 return; | 599 return; |
562 } | 600 } |
563 | 601 |
564 _previousNavigationIndex = _currentNavigationIndex; | 602 _previousNavigationIndex = _currentNavigationIndex; |
565 _currentNavigationIndex = index; | 603 _currentNavigationIndex = index; |
566 } | 604 } |
567 | 605 |
568 - (void)removeEntryAtIndex:(NSInteger)index { | 606 - (void)removeItemAtIndex:(NSInteger)index { |
569 DCHECK(index < static_cast<NSInteger>([_entries count])); | 607 DCHECK(index < static_cast<NSInteger>([_entries count])); |
570 DCHECK(index != _currentNavigationIndex); | 608 DCHECK(index != _currentNavigationIndex); |
571 DCHECK(index >= 0); | 609 DCHECK(index >= 0); |
572 | 610 |
573 [self discardNonCommittedEntries]; | 611 [self discardNonCommittedItems]; |
574 | 612 |
575 [_entries removeObjectAtIndex:index]; | 613 [_entries removeObjectAtIndex:index]; |
576 if (_currentNavigationIndex > index) | 614 if (_currentNavigationIndex > index) |
577 _currentNavigationIndex--; | 615 _currentNavigationIndex--; |
578 if (_previousNavigationIndex >= index) | 616 if (_previousNavigationIndex >= index) |
579 _previousNavigationIndex--; | 617 _previousNavigationIndex--; |
580 } | 618 } |
581 | 619 |
582 - (NSArray*)backwardEntries { | 620 - (NSArray*)backwardEntries { |
583 NSMutableArray* entries = [NSMutableArray array]; | 621 NSMutableArray* entries = [NSMutableArray array]; |
584 for (NSInteger index = _currentNavigationIndex; index > 0; --index) { | 622 for (NSInteger index = _currentNavigationIndex; index > 0; --index) { |
585 if (![self isRedirectTransitionForEntryAtIndex:index]) | 623 if (![self isRedirectTransitionForItemAtIndex:index]) |
586 [entries addObject:_entries[index - 1]]; | 624 [entries addObject:_entries[index - 1]]; |
587 } | 625 } |
588 return entries; | 626 return entries; |
589 } | 627 } |
590 | 628 |
591 - (NSArray*)forwardEntries { | 629 - (NSArray*)forwardEntries { |
592 NSMutableArray* entries = [NSMutableArray array]; | 630 NSMutableArray* entries = [NSMutableArray array]; |
593 NSUInteger lastNonRedirectedIndex = _currentNavigationIndex + 1; | 631 NSUInteger lastNonRedirectedIndex = _currentNavigationIndex + 1; |
594 while (lastNonRedirectedIndex < [_entries count]) { | 632 while (lastNonRedirectedIndex < [_entries count]) { |
595 CRWSessionEntry* entry = [_entries objectAtIndex:lastNonRedirectedIndex]; | 633 CRWSessionEntry* entry = [_entries objectAtIndex:lastNonRedirectedIndex]; |
596 if (!ui::PageTransitionIsRedirect( | 634 if (!ui::PageTransitionIsRedirect( |
597 entry.navigationItem->GetTransitionType())) { | 635 entry.navigationItem->GetTransitionType())) { |
598 [entries addObject:entry]; | 636 [entries addObject:entry]; |
599 } | 637 } |
600 ++lastNonRedirectedIndex; | 638 ++lastNonRedirectedIndex; |
601 } | 639 } |
602 return entries; | 640 return entries; |
603 } | 641 } |
604 | 642 |
605 - (BOOL)isSameDocumentNavigationBetweenEntry:(CRWSessionEntry*)firstEntry | 643 - (BOOL)isSameDocumentNavigationBetweenItem:(web::NavigationItem*)firstItem |
606 andEntry:(CRWSessionEntry*)secondEntry { | 644 andItem:(web::NavigationItem*)secondItem { |
607 if (!firstEntry || !secondEntry || firstEntry == secondEntry) | 645 if (!firstItem || !secondItem || firstItem == secondItem) |
608 return NO; | 646 return NO; |
609 NSUInteger firstIndex = [_entries indexOfObject:firstEntry]; | 647 NSUInteger firstIndex = [self indexOfItem:firstItem]; |
610 NSUInteger secondIndex = [_entries indexOfObject:secondEntry]; | 648 NSUInteger secondIndex = [self indexOfItem:secondItem]; |
611 if (firstIndex == NSNotFound || secondIndex == NSNotFound) | 649 if (firstIndex == NSNotFound || secondIndex == NSNotFound) |
612 return NO; | 650 return NO; |
613 NSUInteger startIndex = firstIndex < secondIndex ? firstIndex : secondIndex; | 651 NSUInteger startIndex = firstIndex < secondIndex ? firstIndex : secondIndex; |
614 NSUInteger endIndex = firstIndex < secondIndex ? secondIndex : firstIndex; | 652 NSUInteger endIndex = firstIndex < secondIndex ? secondIndex : firstIndex; |
615 | 653 |
616 for (NSUInteger i = startIndex + 1; i <= endIndex; i++) { | 654 for (NSUInteger i = startIndex + 1; i <= endIndex; i++) { |
617 web::NavigationItemImpl* item = [_entries[i] navigationItemImpl]; | 655 web::NavigationItemImpl* item = [_entries[i] navigationItemImpl]; |
618 // Every entry in the sequence has to be created from a hash change or | 656 // Every entry in the sequence has to be created from a hash change or |
619 // pushState() call. | 657 // pushState() call. |
620 if (!item->IsCreatedFromPushState() && !item->IsCreatedFromHashChange()) | 658 if (!item->IsCreatedFromPushState() && !item->IsCreatedFromHashChange()) |
621 return NO; | 659 return NO; |
622 // Every entry in the sequence has to have a URL that could have been | 660 // Every entry in the sequence has to have a URL that could have been |
623 // created from a pushState() call. | 661 // created from a pushState() call. |
624 if (!web::history_state_util::IsHistoryStateChangeValid( | 662 if (!web::history_state_util::IsHistoryStateChangeValid(firstItem->GetURL(), |
625 firstEntry.navigationItem->GetURL(), item->GetURL())) | 663 item->GetURL())) |
626 return NO; | 664 return NO; |
627 } | 665 } |
628 return YES; | 666 return YES; |
629 } | 667 } |
630 | 668 |
631 - (CRWSessionEntry*)lastUserEntry { | 669 - (CRWSessionEntry*)lastUserEntry { |
632 if (![_entries count]) | 670 if (![_entries count]) |
633 return nil; | 671 return nil; |
634 | 672 |
635 NSInteger index = _currentNavigationIndex; | 673 NSInteger index = _currentNavigationIndex; |
636 // This will return the first session entry if all other entries are | 674 // This will return the first session entry if all other entries are |
637 // redirects, regardless of the transition state of the first entry. | 675 // redirects, regardless of the transition state of the first entry. |
638 while (index > 0 && [self isRedirectTransitionForEntryAtIndex:index]) { | 676 while (index > 0 && [self isRedirectTransitionForItemAtIndex:index]) { |
639 --index; | 677 --index; |
640 } | 678 } |
641 return [_entries objectAtIndex:index]; | 679 return [_entries objectAtIndex:index]; |
642 } | 680 } |
643 | 681 |
644 - (void)useDesktopUserAgentForNextPendingEntry { | 682 - (void)useDesktopUserAgentForNextPendingItem { |
645 if (_pendingEntry) | 683 if (_pendingEntry) |
646 [_pendingEntry navigationItem]->SetIsOverridingUserAgent(true); | 684 [_pendingEntry navigationItem]->SetIsOverridingUserAgent(true); |
647 else | 685 else |
648 _useDesktopUserAgentForNextPendingEntry = YES; | 686 _useDesktopUserAgentForNextPendingItem = YES; |
| 687 } |
| 688 |
| 689 - (NSInteger)indexOfItem:(web::NavigationItem*)item { |
| 690 web::NavigationItemList items = self.items; |
| 691 for (NSInteger i = 0; i < static_cast<NSInteger>(items.size()); ++i) { |
| 692 if (items[i] == item) |
| 693 return i; |
| 694 } |
| 695 return NSNotFound; |
649 } | 696 } |
650 | 697 |
651 #pragma mark - | 698 #pragma mark - |
652 #pragma mark Private methods | 699 #pragma mark Private methods |
653 | 700 |
654 - (NSString*)uniqueID { | 701 - (NSString*)uniqueID { |
655 CFUUIDRef uuidRef = CFUUIDCreate(NULL); | 702 CFUUIDRef uuidRef = CFUUIDCreate(NULL); |
656 CFStringRef uuidStringRef = CFUUIDCreateString(NULL, uuidRef); | 703 CFStringRef uuidStringRef = CFUUIDCreateString(NULL, uuidRef); |
657 CFRelease(uuidRef); | 704 CFRelease(uuidRef); |
658 | 705 |
(...skipping 25 matching lines...) Expand all Loading... |
684 std::unique_ptr<web::NavigationItemImpl> item(new web::NavigationItemImpl()); | 731 std::unique_ptr<web::NavigationItemImpl> item(new web::NavigationItemImpl()); |
685 item->SetOriginalRequestURL(loaded_url); | 732 item->SetOriginalRequestURL(loaded_url); |
686 item->SetURL(loaded_url); | 733 item->SetURL(loaded_url); |
687 item->SetReferrer(referrer); | 734 item->SetReferrer(referrer); |
688 item->SetTransitionType(transition); | 735 item->SetTransitionType(transition); |
689 item->SetIsOverridingUserAgent(useDesktopUserAgent); | 736 item->SetIsOverridingUserAgent(useDesktopUserAgent); |
690 item->set_is_renderer_initiated(rendererInitiated); | 737 item->set_is_renderer_initiated(rendererInitiated); |
691 return [[CRWSessionEntry alloc] initWithNavigationItem:std::move(item)]; | 738 return [[CRWSessionEntry alloc] initWithNavigationItem:std::move(item)]; |
692 } | 739 } |
693 | 740 |
694 - (BOOL)isRedirectTransitionForEntryAtIndex:(NSInteger)index { | 741 - (BOOL)isRedirectTransitionForItemAtIndex:(NSInteger)index { |
695 ui::PageTransition transition = | 742 ui::PageTransition transition = |
696 [_entries[index] navigationItem]->GetTransitionType(); | 743 [_entries[index] navigationItem]->GetTransitionType(); |
697 return (transition & ui::PAGE_TRANSITION_IS_REDIRECT_MASK) ? YES : NO; | 744 return (transition & ui::PAGE_TRANSITION_IS_REDIRECT_MASK) ? YES : NO; |
698 } | 745 } |
699 | 746 |
| 747 - (web::NavigationItemList)itemListForEntryList:(NSArray*)entries { |
| 748 web::NavigationItemList list(entries.count); |
| 749 for (size_t index = 0; index < entries.count; ++index) |
| 750 list[index] = [entries[index] navigationItem]; |
| 751 return list; |
| 752 } |
| 753 |
700 @end | 754 @end |
OLD | NEW |