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()) { |
| 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 |