OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 /* | 5 /* |
6 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. | 6 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
7 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 7 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. | 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. |
9 * (http://www.torchmobile.com/) | 9 * (http://www.torchmobile.com/) |
10 * | 10 * |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 // Otherwise, we're clear of the last duplicate run, so reset the | 216 // Otherwise, we're clear of the last duplicate run, so reset the |
217 // water marks. | 217 // water marks. |
218 low_water_mark_ = high_water_mark_ = t; | 218 low_water_mark_ = high_water_mark_ = t; |
219 return t; | 219 return t; |
220 } | 220 } |
221 | 221 |
222 NavigationControllerImpl::NavigationControllerImpl( | 222 NavigationControllerImpl::NavigationControllerImpl( |
223 NavigationControllerDelegate* delegate, | 223 NavigationControllerDelegate* delegate, |
224 BrowserContext* browser_context) | 224 BrowserContext* browser_context) |
225 : browser_context_(browser_context), | 225 : browser_context_(browser_context), |
226 pending_entry_(NULL), | 226 pending_entry_(nullptr), |
227 failed_pending_entry_id_(0), | 227 failed_pending_entry_id_(0), |
228 failed_pending_entry_should_replace_(false), | 228 failed_pending_entry_should_replace_(false), |
229 last_committed_entry_index_(-1), | 229 last_committed_entry_index_(0), |
230 pending_entry_index_(-1), | 230 pending_entry_index_(-1), |
231 transient_entry_index_(-1), | 231 transient_entry_index_(-1), |
232 delegate_(delegate), | 232 delegate_(delegate), |
233 max_restored_page_id_(-1), | 233 max_restored_page_id_(-1), |
234 ssl_manager_(this), | 234 ssl_manager_(this), |
235 needs_reload_(false), | 235 needs_reload_(false), |
236 is_initial_navigation_(true), | 236 is_initial_navigation_(true), |
237 in_navigate_to_pending_entry_(false), | 237 in_navigate_to_pending_entry_(false), |
238 pending_reload_(NO_RELOAD), | 238 pending_reload_(NO_RELOAD), |
239 get_timestamp_callback_(base::Bind(&base::Time::Now)), | 239 get_timestamp_callback_(base::Bind(&base::Time::Now)), |
(...skipping 16 matching lines...) Expand all Loading... |
256 void NavigationControllerImpl::SetBrowserContext( | 256 void NavigationControllerImpl::SetBrowserContext( |
257 BrowserContext* browser_context) { | 257 BrowserContext* browser_context) { |
258 browser_context_ = browser_context; | 258 browser_context_ = browser_context; |
259 } | 259 } |
260 | 260 |
261 void NavigationControllerImpl::Restore( | 261 void NavigationControllerImpl::Restore( |
262 int selected_navigation, | 262 int selected_navigation, |
263 RestoreType type, | 263 RestoreType type, |
264 ScopedVector<NavigationEntry>* entries) { | 264 ScopedVector<NavigationEntry>* entries) { |
265 // Verify that this controller is unused and that the input is valid. | 265 // Verify that this controller is unused and that the input is valid. |
266 DCHECK(GetEntryCount() == 0 && !GetPendingEntry()); | 266 DCHECK(IsInitialBlankNavigation() && GetEntryCount() == 1 && |
| 267 !GetPendingEntry()); |
267 DCHECK(selected_navigation >= 0 && | 268 DCHECK(selected_navigation >= 0 && |
268 selected_navigation < static_cast<int>(entries->size())); | 269 selected_navigation < static_cast<int>(entries->size())); |
269 | 270 |
270 needs_reload_ = true; | 271 needs_reload_ = true; |
| 272 entries_.clear(); |
271 for (size_t i = 0; i < entries->size(); ++i) { | 273 for (size_t i = 0; i < entries->size(); ++i) { |
272 NavigationEntryImpl* entry = | 274 NavigationEntryImpl* entry = |
273 NavigationEntryImpl::FromNavigationEntry((*entries)[i]); | 275 NavigationEntryImpl::FromNavigationEntry((*entries)[i]); |
274 entries_.push_back(entry); | 276 entries_.push_back(entry); |
275 } | 277 } |
276 entries->weak_clear(); | 278 entries->weak_clear(); |
277 | 279 |
278 // And finish the restore. | 280 // And finish the restore. |
279 FinishRestore(selected_navigation, type); | 281 FinishRestore(selected_navigation, type); |
280 } | 282 } |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 } else { | 397 } else { |
396 ReloadInternal(false, pending_reload_); | 398 ReloadInternal(false, pending_reload_); |
397 pending_reload_ = NO_RELOAD; | 399 pending_reload_ = NO_RELOAD; |
398 } | 400 } |
399 } | 401 } |
400 | 402 |
401 bool NavigationControllerImpl::IsInitialNavigation() const { | 403 bool NavigationControllerImpl::IsInitialNavigation() const { |
402 return is_initial_navigation_; | 404 return is_initial_navigation_; |
403 } | 405 } |
404 | 406 |
| 407 bool NavigationControllerImpl::IsInitialBlankNavigation() const { |
| 408 // Only return true if the initial navigation is not marked as a restore, as |
| 409 // it is during a clone. |
| 410 return IsInitialNavigation() && |
| 411 GetEntryCount() == 1 && |
| 412 GetEntryAtIndex(0)->restore_type() == NavigationEntryImpl::RESTORE_NONE; |
| 413 } |
| 414 |
405 NavigationEntryImpl* NavigationControllerImpl::GetEntryWithPageID( | 415 NavigationEntryImpl* NavigationControllerImpl::GetEntryWithPageID( |
406 SiteInstance* instance, int32 page_id) const { | 416 SiteInstance* instance, int32 page_id) const { |
407 int index = GetEntryIndexWithPageID(instance, page_id); | 417 int index = GetEntryIndexWithPageID(instance, page_id); |
408 return (index != -1) ? entries_[index] : nullptr; | 418 return (index != -1) ? entries_[index] : nullptr; |
409 } | 419 } |
410 | 420 |
411 NavigationEntryImpl* | 421 NavigationEntryImpl* |
412 NavigationControllerImpl::GetEntryWithUniqueID(int nav_entry_id) const { | 422 NavigationControllerImpl::GetEntryWithUniqueID(int nav_entry_id) const { |
413 int index = GetEntryIndexWithUniqueID(nav_entry_id); | 423 int index = GetEntryIndexWithUniqueID(nav_entry_id); |
414 return (index != -1) ? entries_[index] : nullptr; | 424 return (index != -1) ? entries_[index] : nullptr; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 | 486 |
477 int NavigationControllerImpl::GetCurrentEntryIndex() const { | 487 int NavigationControllerImpl::GetCurrentEntryIndex() const { |
478 if (transient_entry_index_ != -1) | 488 if (transient_entry_index_ != -1) |
479 return transient_entry_index_; | 489 return transient_entry_index_; |
480 if (pending_entry_index_ != -1) | 490 if (pending_entry_index_ != -1) |
481 return pending_entry_index_; | 491 return pending_entry_index_; |
482 return last_committed_entry_index_; | 492 return last_committed_entry_index_; |
483 } | 493 } |
484 | 494 |
485 NavigationEntryImpl* NavigationControllerImpl::GetLastCommittedEntry() const { | 495 NavigationEntryImpl* NavigationControllerImpl::GetLastCommittedEntry() const { |
486 if (last_committed_entry_index_ == -1) | 496 DCHECK_GE(last_committed_entry_index_, 0); |
487 return NULL; | 497 DCHECK_LT(last_committed_entry_index_, GetEntryCount()); |
488 return entries_[last_committed_entry_index_]; | 498 return entries_[last_committed_entry_index_]; |
489 } | 499 } |
490 | 500 |
491 bool NavigationControllerImpl::CanViewSource() const { | 501 bool NavigationControllerImpl::CanViewSource() const { |
492 const std::string& mime_type = delegate_->GetContentsMimeType(); | 502 const std::string& mime_type = delegate_->GetContentsMimeType(); |
493 bool is_viewable_mime_type = | 503 bool is_viewable_mime_type = |
494 mime_util::IsSupportedNonImageMimeType(mime_type) && | 504 mime_util::IsSupportedNonImageMimeType(mime_type) && |
495 !media::IsSupportedMediaMimeType(mime_type); | 505 !media::IsSupportedMediaMimeType(mime_type); |
496 NavigationEntry* visible_entry = GetVisibleEntry(); | 506 NavigationEntry* visible_entry = GetVisibleEntry(); |
497 return visible_entry && !visible_entry->IsViewSourceMode() && | 507 return visible_entry && !visible_entry->IsViewSourceMode() && |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 break; | 795 break; |
786 }; | 796 }; |
787 | 797 |
788 LoadEntry(entry.Pass()); | 798 LoadEntry(entry.Pass()); |
789 } | 799 } |
790 | 800 |
791 bool NavigationControllerImpl::RendererDidNavigate( | 801 bool NavigationControllerImpl::RendererDidNavigate( |
792 RenderFrameHostImpl* rfh, | 802 RenderFrameHostImpl* rfh, |
793 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, | 803 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, |
794 LoadCommittedDetails* details) { | 804 LoadCommittedDetails* details) { |
795 is_initial_navigation_ = false; | |
796 | |
797 // Save the previous state before we clobber it. | 805 // Save the previous state before we clobber it. |
798 if (GetLastCommittedEntry()) { | 806 if (GetLastCommittedEntry()) { |
799 details->previous_url = GetLastCommittedEntry()->GetURL(); | 807 details->previous_url = GetLastCommittedEntry()->GetURL(); |
800 details->previous_entry_index = GetLastCommittedEntryIndex(); | 808 details->previous_entry_index = GetLastCommittedEntryIndex(); |
801 } else { | 809 } else { |
802 details->previous_url = GURL(); | 810 details->previous_url = GURL(); |
803 details->previous_entry_index = -1; | 811 details->previous_entry_index = -1; |
804 } | 812 } |
805 | 813 |
806 // If there is a pending entry at this point, it should have a SiteInstance, | 814 // If there is a pending entry at this point, it should have a SiteInstance, |
(...skipping 13 matching lines...) Expand all Loading... |
820 // If this is an error load, we may have already removed the pending entry | 828 // If this is an error load, we may have already removed the pending entry |
821 // when we got the notice of the load failure. If so, look at the copy of the | 829 // when we got the notice of the load failure. If so, look at the copy of the |
822 // pending parameters that were saved. | 830 // pending parameters that were saved. |
823 if (params.url_is_unreachable && failed_pending_entry_id_ != 0) { | 831 if (params.url_is_unreachable && failed_pending_entry_id_ != 0) { |
824 details->did_replace_entry = failed_pending_entry_should_replace_; | 832 details->did_replace_entry = failed_pending_entry_should_replace_; |
825 } else { | 833 } else { |
826 details->did_replace_entry = pending_entry_ && | 834 details->did_replace_entry = pending_entry_ && |
827 pending_entry_->should_replace_entry(); | 835 pending_entry_->should_replace_entry(); |
828 } | 836 } |
829 | 837 |
| 838 // If this is the first navigation after the initial about:blank page, then it |
| 839 // should replace the initial NavigationEntry, regardless of the checks above. |
| 840 if (IsInitialBlankNavigation()) |
| 841 details->did_replace_entry = true; |
| 842 is_initial_navigation_ = false; |
| 843 |
830 // Do navigation-type specific actions. These will make and commit an entry. | 844 // Do navigation-type specific actions. These will make and commit an entry. |
831 details->type = ClassifyNavigation(rfh, params); | 845 details->type = ClassifyNavigation(rfh, params); |
832 | 846 |
833 // is_in_page must be computed before the entry gets committed. | 847 // is_in_page must be computed before the entry gets committed. |
834 details->is_in_page = IsURLInPageNavigation( | 848 details->is_in_page = IsURLInPageNavigation( |
835 params.url, params.was_within_same_page, rfh); | 849 params.url, params.was_within_same_page, rfh); |
836 | 850 |
837 switch (details->type) { | 851 switch (details->type) { |
838 case NAVIGATION_TYPE_NEW_PAGE: | 852 case NAVIGATION_TYPE_NEW_PAGE: |
839 RendererDidNavigateToNewPage(rfh, params, details->did_replace_entry); | 853 RendererDidNavigateToNewPage(rfh, params, details->did_replace_entry); |
840 break; | 854 break; |
841 case NAVIGATION_TYPE_EXISTING_PAGE: | 855 case NAVIGATION_TYPE_EXISTING_PAGE: |
| 856 // TODO(creis): This is wrong. See |
| 857 // https://codereview.chromium.org/1214073005. Shouldn't touch this value |
| 858 // in most cases. |
842 details->did_replace_entry = details->is_in_page; | 859 details->did_replace_entry = details->is_in_page; |
843 RendererDidNavigateToExistingPage(rfh, params); | 860 RendererDidNavigateToExistingPage(rfh, params); |
844 break; | 861 break; |
845 case NAVIGATION_TYPE_SAME_PAGE: | 862 case NAVIGATION_TYPE_SAME_PAGE: |
846 RendererDidNavigateToSamePage(rfh, params); | 863 RendererDidNavigateToSamePage(rfh, params); |
847 break; | 864 break; |
848 case NAVIGATION_TYPE_NEW_SUBFRAME: | 865 case NAVIGATION_TYPE_NEW_SUBFRAME: |
849 RendererDidNavigateNewSubframe(rfh, params); | 866 RendererDidNavigateNewSubframe(rfh, params); |
850 break; | 867 break; |
851 case NAVIGATION_TYPE_AUTO_SUBFRAME: | 868 case NAVIGATION_TYPE_AUTO_SUBFRAME: |
852 if (!RendererDidNavigateAutoSubframe(rfh, params)) | 869 if (!RendererDidNavigateAutoSubframe(rfh, params)) |
853 return false; | 870 return false; |
854 break; | 871 break; |
855 case NAVIGATION_TYPE_NAV_IGNORE: | |
856 // If a pending navigation was in progress, this canceled it. We should | |
857 // discard it and make sure it is removed from the URL bar. After that, | |
858 // there is nothing we can do with this navigation, so we just return to | |
859 // the caller that nothing has happened. | |
860 if (pending_entry_) { | |
861 DiscardNonCommittedEntries(); | |
862 delegate_->NotifyNavigationStateChanged(INVALIDATE_TYPE_URL); | |
863 } | |
864 return false; | |
865 default: | 872 default: |
866 NOTREACHED(); | 873 NOTREACHED(); |
867 } | 874 } |
868 | 875 |
869 // At this point, we know that the navigation has just completed, so | 876 // At this point, we know that the navigation has just completed, so |
870 // record the time. | 877 // record the time. |
871 // | 878 // |
872 // TODO(akalin): Use "sane time" as described in | 879 // TODO(akalin): Use "sane time" as described in |
873 // http://www.chromium.org/developers/design-documents/sane-time . | 880 // http://www.chromium.org/developers/design-documents/sane-time . |
874 base::Time timestamp = | 881 base::Time timestamp = |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
946 | 953 |
947 return true; | 954 return true; |
948 } | 955 } |
949 | 956 |
950 NavigationType NavigationControllerImpl::ClassifyNavigation( | 957 NavigationType NavigationControllerImpl::ClassifyNavigation( |
951 RenderFrameHostImpl* rfh, | 958 RenderFrameHostImpl* rfh, |
952 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) const { | 959 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) const { |
953 if (params.did_create_new_entry) { | 960 if (params.did_create_new_entry) { |
954 // A new entry. We may or may not have a pending entry for the page, and | 961 // A new entry. We may or may not have a pending entry for the page, and |
955 // this may or may not be the main frame. | 962 // this may or may not be the main frame. |
956 if (!rfh->GetParent()) { | 963 return rfh->GetParent() ? |
957 return NAVIGATION_TYPE_NEW_PAGE; | 964 NAVIGATION_TYPE_NEW_SUBFRAME : |
958 } | 965 NAVIGATION_TYPE_NEW_PAGE; |
959 | |
960 // When this is a new subframe navigation, we should have a committed page | |
961 // in which it's a subframe. This may not be the case when an iframe is | |
962 // navigated on a popup navigated to about:blank (the iframe would be | |
963 // written into the popup by script on the main page). For these cases, | |
964 // there isn't any navigation stuff we can do, so just ignore it. | |
965 if (!GetLastCommittedEntry()) | |
966 return NAVIGATION_TYPE_NAV_IGNORE; | |
967 | |
968 // Valid subframe navigation. | |
969 return NAVIGATION_TYPE_NEW_SUBFRAME; | |
970 } | 966 } |
971 | 967 |
972 // We only clear the session history when navigating to a new page. | 968 // We only clear the session history when navigating to a new page. |
973 DCHECK(!params.history_list_was_cleared); | 969 DCHECK(!params.history_list_was_cleared); |
974 | 970 |
975 if (rfh->GetParent()) { | 971 if (rfh->GetParent()) { |
976 // All manual subframes would be did_create_new_entry and handled above, so | 972 // All manual subframes would be did_create_new_entry and handled above, so |
977 // we know this is auto. | 973 // we know this is auto. |
978 if (GetLastCommittedEntry()) { | 974 return NAVIGATION_TYPE_AUTO_SUBFRAME; |
979 return NAVIGATION_TYPE_AUTO_SUBFRAME; | |
980 } else { | |
981 // We ignore subframes created in non-committed pages; we'd appreciate if | |
982 // people stopped doing that. | |
983 return NAVIGATION_TYPE_NAV_IGNORE; | |
984 } | |
985 } | 975 } |
986 | 976 |
987 if (params.nav_entry_id == 0) { | 977 if (params.nav_entry_id == 0) { |
988 // This is a renderer-initiated navigation (nav_entry_id == 0), but didn't | 978 // This is a renderer-initiated navigation (nav_entry_id == 0), but didn't |
989 // create a new page. | 979 // create a new page. This happens for history.replaceState(), |
990 | 980 // history.reload(), or a client-side redirect. |
991 // Just like above in the did_create_new_entry case, it's possible to | |
992 // scribble onto an uncommitted page. Again, there isn't any navigation | |
993 // stuff that we can do, so ignore it here as well. | |
994 NavigationEntry* last_committed = GetLastCommittedEntry(); | |
995 if (!last_committed) | |
996 return NAVIGATION_TYPE_NAV_IGNORE; | |
997 | |
998 // This is history.replaceState(), history.reload(), or a client-side | |
999 // redirect. | |
1000 return NAVIGATION_TYPE_EXISTING_PAGE; | 981 return NAVIGATION_TYPE_EXISTING_PAGE; |
1001 } | 982 } |
1002 | 983 |
1003 if (pending_entry_ && pending_entry_index_ == -1 && | 984 if (pending_entry_ && pending_entry_index_ == -1 && |
1004 pending_entry_->GetUniqueID() == params.nav_entry_id) { | 985 pending_entry_->GetUniqueID() == params.nav_entry_id) { |
1005 // In this case, we have a pending entry for a load of a new URL but Blink | 986 // In this case, we have a pending entry for a load of a new URL but Blink |
1006 // didn't do a new navigation (params.did_create_new_entry). First check to | 987 // didn't do a new navigation (params.did_create_new_entry). First check to |
1007 // make sure Blink didn't treat a new cross-process navigation as inert, and | 988 // make sure Blink didn't treat a new cross-process navigation as inert, and |
1008 // thus set params.did_create_new_entry to false. In that case, we must | 989 // thus set params.did_create_new_entry to false. In that case, we must |
1009 // treat it as NEW since the SiteInstance doesn't match the entry. | 990 // treat it as NEW since the SiteInstance doesn't match the entry. |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1346 // and assume the renderer is malicious if a cross-origin navigation claims to | 1327 // and assume the renderer is malicious if a cross-origin navigation claims to |
1347 // be in-page. | 1328 // be in-page. |
1348 bool NavigationControllerImpl::IsURLInPageNavigation( | 1329 bool NavigationControllerImpl::IsURLInPageNavigation( |
1349 const GURL& url, | 1330 const GURL& url, |
1350 bool renderer_says_in_page, | 1331 bool renderer_says_in_page, |
1351 RenderFrameHost* rfh) const { | 1332 RenderFrameHost* rfh) const { |
1352 GURL last_committed_url; | 1333 GURL last_committed_url; |
1353 if (rfh->GetParent()) { | 1334 if (rfh->GetParent()) { |
1354 last_committed_url = rfh->GetLastCommittedURL(); | 1335 last_committed_url = rfh->GetLastCommittedURL(); |
1355 } else { | 1336 } else { |
1356 NavigationEntry* last_committed = GetLastCommittedEntry(); | 1337 last_committed_url = GetLastCommittedEntry()->GetURL(); |
1357 // There must be a last-committed entry to compare URLs to. TODO(avi): When | |
1358 // might Blink say that a navigation is in-page yet there be no last- | |
1359 // committed entry? | |
1360 if (!last_committed) | |
1361 return false; | |
1362 last_committed_url = last_committed->GetURL(); | |
1363 } | 1338 } |
1364 | 1339 |
1365 WebPreferences prefs = rfh->GetRenderViewHost()->GetWebkitPreferences(); | 1340 WebPreferences prefs = rfh->GetRenderViewHost()->GetWebkitPreferences(); |
1366 bool is_same_origin = last_committed_url.is_empty() || | 1341 bool is_same_origin = last_committed_url.is_empty() || |
1367 // TODO(japhet): We should only permit navigations | 1342 // TODO(japhet): We should only permit navigations |
1368 // originating from about:blank to be in-page if the | 1343 // originating from about:blank to be in-page if the |
1369 // about:blank is the first document that frame loaded. | 1344 // about:blank is the first document that frame loaded. |
1370 // We don't have sufficient information to identify | 1345 // We don't have sufficient information to identify |
1371 // that case at the moment, so always allow about:blank | 1346 // that case at the moment, so always allow about:blank |
1372 // for now. | 1347 // for now. |
1373 last_committed_url == GURL(url::kAboutBlankURL) || | 1348 last_committed_url == GURL(url::kAboutBlankURL) || |
1374 last_committed_url.GetOrigin() == url.GetOrigin() || | 1349 last_committed_url.GetOrigin() == url.GetOrigin() || |
1375 !prefs.web_security_enabled || | 1350 !prefs.web_security_enabled || |
1376 (prefs.allow_universal_access_from_file_urls && | 1351 (prefs.allow_universal_access_from_file_urls && |
1377 last_committed_url.SchemeIs(url::kFileScheme)); | 1352 last_committed_url.SchemeIs(url::kFileScheme)); |
1378 if (!is_same_origin && renderer_says_in_page) { | 1353 if (!is_same_origin && renderer_says_in_page) { |
1379 bad_message::ReceivedBadMessage(rfh->GetProcess(), | 1354 bad_message::ReceivedBadMessage(rfh->GetProcess(), |
1380 bad_message::NC_IN_PAGE_NAVIGATION); | 1355 bad_message::NC_IN_PAGE_NAVIGATION); |
1381 } | 1356 } |
1382 return is_same_origin && renderer_says_in_page; | 1357 return is_same_origin && renderer_says_in_page; |
1383 } | 1358 } |
1384 | 1359 |
1385 void NavigationControllerImpl::CopyStateFrom( | 1360 void NavigationControllerImpl::CopyStateFrom( |
1386 const NavigationController& temp) { | 1361 const NavigationController& temp) { |
1387 const NavigationControllerImpl& source = | 1362 const NavigationControllerImpl& source = |
1388 static_cast<const NavigationControllerImpl&>(temp); | 1363 static_cast<const NavigationControllerImpl&>(temp); |
1389 // Verify that we look new. | 1364 // Verify that we look new. |
1390 DCHECK(GetEntryCount() == 0 && !GetPendingEntry()); | 1365 DCHECK(IsInitialBlankNavigation() && GetEntryCount() == 1 && |
1391 | 1366 !GetPendingEntry()); |
1392 if (source.GetEntryCount() == 0) | 1367 DCHECK_GT(source.GetEntryCount(), 0); |
1393 return; // Nothing new to do. | |
1394 | 1368 |
1395 needs_reload_ = true; | 1369 needs_reload_ = true; |
| 1370 // Drop the initial entry first. |
| 1371 entries_.pop_back(); |
1396 InsertEntriesFrom(source, source.GetEntryCount()); | 1372 InsertEntriesFrom(source, source.GetEntryCount()); |
1397 | 1373 |
1398 for (SessionStorageNamespaceMap::const_iterator it = | 1374 for (SessionStorageNamespaceMap::const_iterator it = |
1399 source.session_storage_namespace_map_.begin(); | 1375 source.session_storage_namespace_map_.begin(); |
1400 it != source.session_storage_namespace_map_.end(); | 1376 it != source.session_storage_namespace_map_.end(); |
1401 ++it) { | 1377 ++it) { |
1402 SessionStorageNamespaceImpl* source_namespace = | 1378 SessionStorageNamespaceImpl* source_namespace = |
1403 static_cast<SessionStorageNamespaceImpl*>(it->second.get()); | 1379 static_cast<SessionStorageNamespaceImpl*>(it->second.get()); |
1404 session_storage_namespace_map_[it->first] = source_namespace->Clone(); | 1380 session_storage_namespace_map_[it->first] = source_namespace->Clone(); |
1405 } | 1381 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1462 delegate_->CopyMaxPageIDsFrom(source->delegate()->GetWebContents()); | 1438 delegate_->CopyMaxPageIDsFrom(source->delegate()->GetWebContents()); |
1463 delegate_->UpdateMaxPageIDForSiteInstance(last_committed->site_instance(), | 1439 delegate_->UpdateMaxPageIDForSiteInstance(last_committed->site_instance(), |
1464 site_max_page_id); | 1440 site_max_page_id); |
1465 max_restored_page_id_ = source->max_restored_page_id_; | 1441 max_restored_page_id_ = source->max_restored_page_id_; |
1466 } | 1442 } |
1467 | 1443 |
1468 bool NavigationControllerImpl::CanPruneAllButLastCommitted() { | 1444 bool NavigationControllerImpl::CanPruneAllButLastCommitted() { |
1469 // If there is no last committed entry, we cannot prune. Even if there is a | 1445 // If there is no last committed entry, we cannot prune. Even if there is a |
1470 // pending entry, it may not commit, leaving this WebContents blank, despite | 1446 // pending entry, it may not commit, leaving this WebContents blank, despite |
1471 // possibly giving it new entries via CopyStateFromAndPrune. | 1447 // possibly giving it new entries via CopyStateFromAndPrune. |
1472 if (last_committed_entry_index_ == -1) | 1448 if (IsInitialBlankNavigation()) |
1473 return false; | 1449 return false; |
1474 | 1450 |
1475 // We cannot prune if there is a pending entry at an existing entry index. | 1451 // We cannot prune if there is a pending entry at an existing entry index. |
1476 // It may not commit, so we have to keep the last committed entry, and thus | 1452 // It may not commit, so we have to keep the last committed entry, and thus |
1477 // there is no sensible place to keep the pending entry. It is ok to have | 1453 // there is no sensible place to keep the pending entry. It is ok to have |
1478 // a new pending entry, which can optionally commit as a new navigation. | 1454 // a new pending entry, which can optionally commit as a new navigation. |
1479 if (pending_entry_index_ != -1) | 1455 if (pending_entry_index_ != -1) |
1480 return false; | 1456 return false; |
1481 | 1457 |
1482 // We should not prune if we are currently showing a transient entry. | 1458 // We should not prune if we are currently showing a transient entry. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1530 } | 1506 } |
1531 | 1507 |
1532 void NavigationControllerImpl::SetMaxRestoredPageID(int32 max_id) { | 1508 void NavigationControllerImpl::SetMaxRestoredPageID(int32 max_id) { |
1533 max_restored_page_id_ = max_id; | 1509 max_restored_page_id_ = max_id; |
1534 } | 1510 } |
1535 | 1511 |
1536 int32 NavigationControllerImpl::GetMaxRestoredPageID() const { | 1512 int32 NavigationControllerImpl::GetMaxRestoredPageID() const { |
1537 return max_restored_page_id_; | 1513 return max_restored_page_id_; |
1538 } | 1514 } |
1539 | 1515 |
| 1516 void NavigationControllerImpl::Init(SiteInstance* instance) { |
| 1517 DCHECK(IsInitialNavigation()); |
| 1518 |
| 1519 // Start with an entry for the initial about:blank page, which will be |
| 1520 // replaced on first navigation. |
| 1521 scoped_ptr<NavigationEntryImpl> initial_entry = |
| 1522 make_scoped_ptr(new NavigationEntryImpl( |
| 1523 static_cast<SiteInstanceImpl*>(instance), -1, |
| 1524 GURL(url::kAboutBlankURL), Referrer(), base::string16(), |
| 1525 ui::PAGE_TRANSITION_LINK, false)); |
| 1526 |
| 1527 // Make sure the initial RenderFrameHost knows about it. |
| 1528 RenderFrameHostImpl* main_frame = |
| 1529 delegate_->GetFrameTree()->root()->current_frame_host(); |
| 1530 static_cast<RenderViewHostImpl*>(main_frame->GetRenderViewHost())-> |
| 1531 set_nav_entry_id(initial_entry->GetUniqueID()); |
| 1532 |
| 1533 entries_.push_back(initial_entry.Pass()); |
| 1534 } |
| 1535 |
1540 bool NavigationControllerImpl::IsUnmodifiedBlankTab() const { | 1536 bool NavigationControllerImpl::IsUnmodifiedBlankTab() const { |
1541 return IsInitialNavigation() && | 1537 return IsInitialBlankNavigation() && |
1542 !GetLastCommittedEntry() && | |
1543 !delegate_->HasAccessedInitialDocument(); | 1538 !delegate_->HasAccessedInitialDocument(); |
1544 } | 1539 } |
1545 | 1540 |
1546 SessionStorageNamespace* | 1541 SessionStorageNamespace* |
1547 NavigationControllerImpl::GetSessionStorageNamespace(SiteInstance* instance) { | 1542 NavigationControllerImpl::GetSessionStorageNamespace(SiteInstance* instance) { |
1548 std::string partition_id; | 1543 std::string partition_id; |
1549 if (instance) { | 1544 if (instance) { |
1550 // TODO(ajwong): When GetDefaultSessionStorageNamespace() goes away, remove | 1545 // TODO(ajwong): When GetDefaultSessionStorageNamespace() goes away, remove |
1551 // this if statement so |instance| must not be NULL. | 1546 // this if statement so |instance| must not be NULL. |
1552 partition_id = | 1547 partition_id = |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1980 NavigationEntryImpl* NavigationControllerImpl::GetTransientEntry() const { | 1975 NavigationEntryImpl* NavigationControllerImpl::GetTransientEntry() const { |
1981 if (transient_entry_index_ == -1) | 1976 if (transient_entry_index_ == -1) |
1982 return NULL; | 1977 return NULL; |
1983 return entries_[transient_entry_index_]; | 1978 return entries_[transient_entry_index_]; |
1984 } | 1979 } |
1985 | 1980 |
1986 void NavigationControllerImpl::SetTransientEntry( | 1981 void NavigationControllerImpl::SetTransientEntry( |
1987 scoped_ptr<NavigationEntry> entry) { | 1982 scoped_ptr<NavigationEntry> entry) { |
1988 // Discard any current transient entry, we can only have one at a time. | 1983 // Discard any current transient entry, we can only have one at a time. |
1989 int index = 0; | 1984 int index = 0; |
1990 if (last_committed_entry_index_ != -1) | 1985 index = last_committed_entry_index_ + 1; |
1991 index = last_committed_entry_index_ + 1; | |
1992 DiscardTransientEntry(); | 1986 DiscardTransientEntry(); |
1993 entries_.insert(entries_.begin() + index, | 1987 entries_.insert(entries_.begin() + index, |
1994 NavigationEntryImpl::FromNavigationEntry(entry.release())); | 1988 NavigationEntryImpl::FromNavigationEntry(entry.release())); |
1995 transient_entry_index_ = index; | 1989 transient_entry_index_ = index; |
1996 delegate_->NotifyNavigationStateChanged(INVALIDATE_TYPE_ALL); | 1990 delegate_->NotifyNavigationStateChanged(INVALIDATE_TYPE_ALL); |
1997 } | 1991 } |
1998 | 1992 |
1999 void NavigationControllerImpl::InsertEntriesFrom( | 1993 void NavigationControllerImpl::InsertEntriesFrom( |
2000 const NavigationControllerImpl& source, | 1994 const NavigationControllerImpl& source, |
2001 int max_index) { | 1995 int max_index) { |
(...skipping 10 matching lines...) Expand all Loading... |
2012 } | 2006 } |
2013 } | 2007 } |
2014 } | 2008 } |
2015 | 2009 |
2016 void NavigationControllerImpl::SetGetTimestampCallbackForTest( | 2010 void NavigationControllerImpl::SetGetTimestampCallbackForTest( |
2017 const base::Callback<base::Time()>& get_timestamp_callback) { | 2011 const base::Callback<base::Time()>& get_timestamp_callback) { |
2018 get_timestamp_callback_ = get_timestamp_callback; | 2012 get_timestamp_callback_ = get_timestamp_callback; |
2019 } | 2013 } |
2020 | 2014 |
2021 } // namespace content | 2015 } // namespace content |
OLD | NEW |