| 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 |