Chromium Code Reviews| 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 801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 812 | 812 |
| 813 // Do navigation-type specific actions. These will make and commit an entry. | 813 // Do navigation-type specific actions. These will make and commit an entry. |
| 814 details->type = ClassifyNavigation(rfh, params); | 814 details->type = ClassifyNavigation(rfh, params); |
| 815 | 815 |
| 816 // is_in_page must be computed before the entry gets committed. | 816 // is_in_page must be computed before the entry gets committed. |
| 817 details->is_in_page = IsURLInPageNavigation(params.url, params.origin, | 817 details->is_in_page = IsURLInPageNavigation(params.url, params.origin, |
| 818 params.was_within_same_page, rfh); | 818 params.was_within_same_page, rfh); |
| 819 | 819 |
| 820 switch (details->type) { | 820 switch (details->type) { |
| 821 case NAVIGATION_TYPE_NEW_PAGE: | 821 case NAVIGATION_TYPE_NEW_PAGE: |
| 822 RendererDidNavigateToNewPage(rfh, params, details->did_replace_entry); | 822 RendererDidNavigateToNewPage(rfh, params, details->is_in_page, |
| 823 details->did_replace_entry); | |
| 823 break; | 824 break; |
| 824 case NAVIGATION_TYPE_EXISTING_PAGE: | 825 case NAVIGATION_TYPE_EXISTING_PAGE: |
| 825 details->did_replace_entry = details->is_in_page; | 826 details->did_replace_entry = details->is_in_page; |
| 826 RendererDidNavigateToExistingPage(rfh, params); | 827 RendererDidNavigateToExistingPage(rfh, params); |
| 827 break; | 828 break; |
| 828 case NAVIGATION_TYPE_SAME_PAGE: | 829 case NAVIGATION_TYPE_SAME_PAGE: |
| 829 RendererDidNavigateToSamePage(rfh, params); | 830 RendererDidNavigateToSamePage(rfh, params); |
| 830 break; | 831 break; |
| 831 case NAVIGATION_TYPE_NEW_SUBFRAME: | 832 case NAVIGATION_TYPE_NEW_SUBFRAME: |
| 832 RendererDidNavigateNewSubframe(rfh, params, details->did_replace_entry); | 833 RendererDidNavigateNewSubframe(rfh, params, details->is_in_page, |
| 834 details->did_replace_entry); | |
| 833 break; | 835 break; |
| 834 case NAVIGATION_TYPE_AUTO_SUBFRAME: | 836 case NAVIGATION_TYPE_AUTO_SUBFRAME: |
| 835 if (!RendererDidNavigateAutoSubframe(rfh, params)) | 837 if (!RendererDidNavigateAutoSubframe(rfh, params)) |
| 836 return false; | 838 return false; |
| 837 break; | 839 break; |
| 838 case NAVIGATION_TYPE_NAV_IGNORE: | 840 case NAVIGATION_TYPE_NAV_IGNORE: |
| 839 // If a pending navigation was in progress, this canceled it. We should | 841 // If a pending navigation was in progress, this canceled it. We should |
| 840 // discard it and make sure it is removed from the URL bar. After that, | 842 // discard it and make sure it is removed from the URL bar. After that, |
| 841 // there is nothing we can do with this navigation, so we just return to | 843 // there is nothing we can do with this navigation, so we just return to |
| 842 // the caller that nothing has happened. | 844 // the caller that nothing has happened. |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1042 } | 1044 } |
| 1043 | 1045 |
| 1044 // Since we weeded out "new" navigations above, we know this is an existing | 1046 // Since we weeded out "new" navigations above, we know this is an existing |
| 1045 // (back/forward) navigation. | 1047 // (back/forward) navigation. |
| 1046 return NAVIGATION_TYPE_EXISTING_PAGE; | 1048 return NAVIGATION_TYPE_EXISTING_PAGE; |
| 1047 } | 1049 } |
| 1048 | 1050 |
| 1049 void NavigationControllerImpl::RendererDidNavigateToNewPage( | 1051 void NavigationControllerImpl::RendererDidNavigateToNewPage( |
| 1050 RenderFrameHostImpl* rfh, | 1052 RenderFrameHostImpl* rfh, |
| 1051 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, | 1053 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, |
| 1054 bool is_in_page, | |
| 1052 bool replace_entry) { | 1055 bool replace_entry) { |
| 1053 std::unique_ptr<NavigationEntryImpl> new_entry; | 1056 std::unique_ptr<NavigationEntryImpl> new_entry; |
| 1054 bool update_virtual_url; | 1057 bool update_virtual_url = false; |
| 1058 | |
| 1059 // First check if this is an in-page navigation. If so, clone the current | |
| 1060 // entry instead of looking at the pending entry, because the pending entry | |
| 1061 // does not have any subframe history items. | |
| 1062 if (is_in_page && GetLastCommittedEntry()) { | |
|
Avi (use Gerrit)
2016/07/26 15:03:58
Curious: how would we be in-page but not have a la
Charlie Reis
2016/07/26 15:30:45
Yeah, exactly. PushState on the initial blank pag
| |
| 1063 FrameNavigationEntry* frame_entry = new FrameNavigationEntry( | |
| 1064 params.frame_unique_name, params.item_sequence_number, | |
| 1065 params.document_sequence_number, rfh->GetSiteInstance(), nullptr, | |
| 1066 params.url, params.referrer, params.method, params.post_id); | |
| 1067 new_entry = GetLastCommittedEntry()->CloneAndReplace( | |
| 1068 frame_entry, true, rfh->frame_tree_node(), | |
| 1069 delegate_->GetFrameTree()->root()); | |
| 1070 | |
| 1071 // We expect |frame_entry| to be owned by |new_entry|. This should never | |
| 1072 // fail, because it's the main frame. | |
| 1073 CHECK(frame_entry->HasOneRef()); | |
| 1074 | |
| 1075 update_virtual_url = new_entry->update_virtual_url_with_url(); | |
| 1076 } | |
| 1077 | |
| 1055 // Only make a copy of the pending entry if it is appropriate for the new page | 1078 // Only make a copy of the pending entry if it is appropriate for the new page |
| 1056 // that was just loaded. Verify this by checking if the entry corresponds | 1079 // that was just loaded. Verify this by checking if the entry corresponds |
| 1057 // to the current navigation handle. Note that in some tests the render frame | 1080 // to the current navigation handle. Note that in some tests the render frame |
| 1058 // host does not have a valid handle. Additionally, coarsely check that: | 1081 // host does not have a valid handle. Additionally, coarsely check that: |
| 1059 // 1. The SiteInstance hasn't been assigned to something else. | 1082 // 1. The SiteInstance hasn't been assigned to something else. |
| 1060 // 2. The pending entry was intended as a new entry, rather than being a | 1083 // 2. The pending entry was intended as a new entry, rather than being a |
| 1061 // history navigation that was interrupted by an unrelated, | 1084 // history navigation that was interrupted by an unrelated, |
| 1062 // renderer-initiated navigation. | 1085 // renderer-initiated navigation. |
| 1063 // TODO(csharrison): Investigate whether we can remove some of the coarser | 1086 // TODO(csharrison): Investigate whether we can remove some of the coarser |
| 1064 // checks. | 1087 // checks. |
| 1065 NavigationHandleImpl* handle = rfh->navigation_handle(); | 1088 NavigationHandleImpl* handle = rfh->navigation_handle(); |
| 1066 DCHECK(handle); | 1089 DCHECK(handle); |
| 1067 if (PendingEntryMatchesHandle(handle) && pending_entry_index_ == -1 && | 1090 |
| 1091 if (!new_entry && | |
| 1092 PendingEntryMatchesHandle(handle) && pending_entry_index_ == -1 && | |
| 1068 (!pending_entry_->site_instance() || | 1093 (!pending_entry_->site_instance() || |
| 1069 pending_entry_->site_instance() == rfh->GetSiteInstance())) { | 1094 pending_entry_->site_instance() == rfh->GetSiteInstance())) { |
| 1070 new_entry = pending_entry_->Clone(); | 1095 new_entry = pending_entry_->Clone(); |
| 1071 | 1096 |
| 1072 update_virtual_url = new_entry->update_virtual_url_with_url(); | 1097 update_virtual_url = new_entry->update_virtual_url_with_url(); |
| 1073 } else { | 1098 } |
| 1099 | |
| 1100 // For non-in-page commits with no matching pending entry, create a new entry. | |
| 1101 if (!new_entry) { | |
| 1074 new_entry = base::WrapUnique(new NavigationEntryImpl); | 1102 new_entry = base::WrapUnique(new NavigationEntryImpl); |
| 1075 | 1103 |
| 1076 // Find out whether the new entry needs to update its virtual URL on URL | 1104 // Find out whether the new entry needs to update its virtual URL on URL |
| 1077 // change and set up the entry accordingly. This is needed to correctly | 1105 // change and set up the entry accordingly. This is needed to correctly |
| 1078 // update the virtual URL when replaceState is called after a pushState. | 1106 // update the virtual URL when replaceState is called after a pushState. |
| 1079 GURL url = params.url; | 1107 GURL url = params.url; |
| 1080 bool needs_update = false; | 1108 bool needs_update = false; |
| 1081 BrowserURLHandlerImpl::GetInstance()->RewriteURLIfNecessary( | 1109 BrowserURLHandlerImpl::GetInstance()->RewriteURLIfNecessary( |
| 1082 &url, browser_context_, &needs_update); | 1110 &url, browser_context_, &needs_update); |
| 1083 new_entry->set_update_virtual_url_with_url(needs_update); | 1111 new_entry->set_update_virtual_url_with_url(needs_update); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1108 // Update the FrameNavigationEntry for new main frame commits. | 1136 // Update the FrameNavigationEntry for new main frame commits. |
| 1109 FrameNavigationEntry* frame_entry = | 1137 FrameNavigationEntry* frame_entry = |
| 1110 new_entry->GetFrameEntry(rfh->frame_tree_node()); | 1138 new_entry->GetFrameEntry(rfh->frame_tree_node()); |
| 1111 frame_entry->set_frame_unique_name(params.frame_unique_name); | 1139 frame_entry->set_frame_unique_name(params.frame_unique_name); |
| 1112 frame_entry->set_item_sequence_number(params.item_sequence_number); | 1140 frame_entry->set_item_sequence_number(params.item_sequence_number); |
| 1113 frame_entry->set_document_sequence_number(params.document_sequence_number); | 1141 frame_entry->set_document_sequence_number(params.document_sequence_number); |
| 1114 frame_entry->set_method(params.method); | 1142 frame_entry->set_method(params.method); |
| 1115 frame_entry->set_post_id(params.post_id); | 1143 frame_entry->set_post_id(params.post_id); |
| 1116 | 1144 |
| 1117 // history.pushState() is classified as a navigation to a new page, but | 1145 // history.pushState() is classified as a navigation to a new page, but |
| 1118 // sets was_within_same_page to true. In this case, we already have the | 1146 // sets is_in_page to true. In this case, we already have the title and |
| 1119 // title and favicon available, so set them immediately. | 1147 // favicon available, so set them immediately. |
| 1120 if (params.was_within_same_page && GetLastCommittedEntry()) { | 1148 if (is_in_page && GetLastCommittedEntry()) { |
| 1121 new_entry->SetTitle(GetLastCommittedEntry()->GetTitle()); | 1149 new_entry->SetTitle(GetLastCommittedEntry()->GetTitle()); |
| 1122 new_entry->GetFavicon() = GetLastCommittedEntry()->GetFavicon(); | 1150 new_entry->GetFavicon() = GetLastCommittedEntry()->GetFavicon(); |
| 1123 } | 1151 } |
| 1124 | 1152 |
| 1125 DCHECK(!params.history_list_was_cleared || !replace_entry); | 1153 DCHECK(!params.history_list_was_cleared || !replace_entry); |
| 1126 // The browser requested to clear the session history when it initiated the | 1154 // The browser requested to clear the session history when it initiated the |
| 1127 // navigation. Now we know that the renderer has updated its state accordingly | 1155 // navigation. Now we know that the renderer has updated its state accordingly |
| 1128 // and it is safe to also clear the browser side history. | 1156 // and it is safe to also clear the browser side history. |
| 1129 if (params.history_list_was_cleared) { | 1157 if (params.history_list_was_cleared) { |
| 1130 DiscardNonCommittedEntriesInternal(); | 1158 DiscardNonCommittedEntriesInternal(); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1244 existing_entry->GetFrameEntry(rfh->frame_tree_node()); | 1272 existing_entry->GetFrameEntry(rfh->frame_tree_node()); |
| 1245 frame_entry->set_method(params.method); | 1273 frame_entry->set_method(params.method); |
| 1246 frame_entry->set_post_id(params.post_id); | 1274 frame_entry->set_post_id(params.post_id); |
| 1247 | 1275 |
| 1248 DiscardNonCommittedEntries(); | 1276 DiscardNonCommittedEntries(); |
| 1249 } | 1277 } |
| 1250 | 1278 |
| 1251 void NavigationControllerImpl::RendererDidNavigateNewSubframe( | 1279 void NavigationControllerImpl::RendererDidNavigateNewSubframe( |
| 1252 RenderFrameHostImpl* rfh, | 1280 RenderFrameHostImpl* rfh, |
| 1253 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, | 1281 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, |
| 1282 bool is_in_page, | |
| 1254 bool replace_entry) { | 1283 bool replace_entry) { |
| 1255 DCHECK(ui::PageTransitionCoreTypeIs(params.transition, | 1284 DCHECK(ui::PageTransitionCoreTypeIs(params.transition, |
| 1256 ui::PAGE_TRANSITION_MANUAL_SUBFRAME)); | 1285 ui::PAGE_TRANSITION_MANUAL_SUBFRAME)); |
| 1257 | 1286 |
| 1258 // Manual subframe navigations just get the current entry cloned so the user | 1287 // Manual subframe navigations just get the current entry cloned so the user |
| 1259 // can go back or forward to it. The actual subframe information will be | 1288 // can go back or forward to it. The actual subframe information will be |
| 1260 // stored in the page state for each of those entries. This happens out of | 1289 // stored in the page state for each of those entries. This happens out of |
| 1261 // band with the actual navigations. | 1290 // band with the actual navigations. |
| 1262 DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee " | 1291 DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee " |
| 1263 << "that a last committed entry exists."; | 1292 << "that a last committed entry exists."; |
| 1264 | 1293 |
| 1265 std::unique_ptr<NavigationEntryImpl> new_entry; | 1294 std::unique_ptr<NavigationEntryImpl> new_entry; |
| 1266 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { | 1295 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { |
| 1267 // Make sure we don't leak frame_entry if new_entry doesn't take ownership. | 1296 // Make sure we don't leak frame_entry if new_entry doesn't take ownership. |
| 1268 scoped_refptr<FrameNavigationEntry> frame_entry(new FrameNavigationEntry( | 1297 scoped_refptr<FrameNavigationEntry> frame_entry(new FrameNavigationEntry( |
| 1269 params.frame_unique_name, params.item_sequence_number, | 1298 params.frame_unique_name, params.item_sequence_number, |
| 1270 params.document_sequence_number, rfh->GetSiteInstance(), nullptr, | 1299 params.document_sequence_number, rfh->GetSiteInstance(), nullptr, |
| 1271 params.url, params.referrer, params.method, params.post_id)); | 1300 params.url, params.referrer, params.method, params.post_id)); |
| 1272 new_entry = GetLastCommittedEntry()->CloneAndReplace(rfh->frame_tree_node(), | 1301 new_entry = GetLastCommittedEntry()->CloneAndReplace( |
| 1273 frame_entry.get()); | 1302 frame_entry.get(), is_in_page, rfh->frame_tree_node(), |
| 1303 delegate_->GetFrameTree()->root()); | |
| 1274 | 1304 |
| 1275 // TODO(creis): Update this to add the frame_entry if we can't find the one | 1305 // TODO(creis): Update this to add the frame_entry if we can't find the one |
| 1276 // to replace, which can happen due to a unique name change. See | 1306 // to replace, which can happen due to a unique name change. See |
| 1277 // https://crbug.com/607205. For now, frame_entry will be deleted when it | 1307 // https://crbug.com/607205. For now, frame_entry will be deleted when it |
| 1278 // goes out of scope if it doesn't get used. | 1308 // goes out of scope if it doesn't get used. |
| 1279 } else { | 1309 } else { |
| 1280 new_entry = GetLastCommittedEntry()->Clone(); | 1310 new_entry = GetLastCommittedEntry()->Clone(); |
| 1281 } | 1311 } |
| 1282 | 1312 |
| 1283 new_entry->SetPageID(params.page_id); | 1313 new_entry->SetPageID(params.page_id); |
| (...skipping 785 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2069 } | 2099 } |
| 2070 } | 2100 } |
| 2071 } | 2101 } |
| 2072 | 2102 |
| 2073 void NavigationControllerImpl::SetGetTimestampCallbackForTest( | 2103 void NavigationControllerImpl::SetGetTimestampCallbackForTest( |
| 2074 const base::Callback<base::Time()>& get_timestamp_callback) { | 2104 const base::Callback<base::Time()>& get_timestamp_callback) { |
| 2075 get_timestamp_callback_ = get_timestamp_callback; | 2105 get_timestamp_callback_ = get_timestamp_callback; |
| 2076 } | 2106 } |
| 2077 | 2107 |
| 2078 } // namespace content | 2108 } // namespace content |
| OLD | NEW |