Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: content/browser/frame_host/navigation_controller_impl.cc

Issue 2161393002: Clone children of FrameNavigationEntries for in-page navigations. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix test. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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()) {
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698