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 #include "content/browser/frame_host/navigator_impl.h" | 5 #include "content/browser/frame_host/navigator_impl.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/metrics/histogram_macros.h" | 10 #include "base/metrics/histogram_macros.h" |
(...skipping 28 matching lines...) Expand all Loading... | |
39 #include "content/public/browser/page_navigator.h" | 39 #include "content/public/browser/page_navigator.h" |
40 #include "content/public/browser/render_view_host.h" | 40 #include "content/public/browser/render_view_host.h" |
41 #include "content/public/browser/stream_handle.h" | 41 #include "content/public/browser/stream_handle.h" |
42 #include "content/public/browser/user_metrics.h" | 42 #include "content/public/browser/user_metrics.h" |
43 #include "content/public/common/bindings_policy.h" | 43 #include "content/public/common/bindings_policy.h" |
44 #include "content/public/common/browser_side_navigation_policy.h" | 44 #include "content/public/common/browser_side_navigation_policy.h" |
45 #include "content/public/common/content_client.h" | 45 #include "content/public/common/content_client.h" |
46 #include "content/public/common/content_constants.h" | 46 #include "content/public/common/content_constants.h" |
47 #include "content/public/common/resource_response.h" | 47 #include "content/public/common/resource_response.h" |
48 #include "net/base/net_errors.h" | 48 #include "net/base/net_errors.h" |
49 #include "net/base/url_util.h" | |
49 #include "url/gurl.h" | 50 #include "url/gurl.h" |
50 | 51 |
51 namespace content { | 52 namespace content { |
52 | 53 |
53 namespace { | 54 namespace { |
54 | 55 |
55 FrameMsg_Navigate_Type::Value GetNavigationType( | 56 FrameMsg_Navigate_Type::Value GetNavigationType( |
56 BrowserContext* browser_context, | 57 const GURL& old_url, |
58 const GURL& new_url, | |
59 ReloadType reload_type, | |
60 bool is_history_navigation, | |
61 bool is_same_document_history_load, | |
57 const NavigationEntryImpl& entry, | 62 const NavigationEntryImpl& entry, |
58 ReloadType reload_type) { | 63 std::string method) { |
64 // Reload navigations | |
59 switch (reload_type) { | 65 switch (reload_type) { |
60 case ReloadType::NORMAL: | 66 case ReloadType::NORMAL: |
61 return FrameMsg_Navigate_Type::RELOAD; | 67 return FrameMsg_Navigate_Type::RELOAD; |
62 case ReloadType::BYPASSING_CACHE: | 68 case ReloadType::BYPASSING_CACHE: |
63 case ReloadType::DISABLE_LOFI_MODE: | 69 case ReloadType::DISABLE_LOFI_MODE: |
64 return FrameMsg_Navigate_Type::RELOAD_BYPASSING_CACHE; | 70 return FrameMsg_Navigate_Type::RELOAD_BYPASSING_CACHE; |
65 case ReloadType::ORIGINAL_REQUEST_URL: | 71 case ReloadType::ORIGINAL_REQUEST_URL: |
66 return FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL; | 72 return FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL; |
67 case ReloadType::NONE: | 73 case ReloadType::NONE: |
68 break; // Fall through to rest of function. | 74 break; // Fall through to rest of function. |
69 } | 75 } |
70 | 76 |
71 // |RenderViewImpl::PopulateStateFromPendingNavigationParams| differentiates | 77 // |RenderViewImpl::PopulateStateFromPendingNavigationParams| differentiates |
72 // between |RESTORE_WITH_POST| and |RESTORE|. | 78 // between |RESTORE_WITH_POST| and |RESTORE|. |
73 if (entry.restore_type() == RestoreType::LAST_SESSION_EXITED_CLEANLY) { | 79 if (entry.restore_type() == RestoreType::LAST_SESSION_EXITED_CLEANLY) { |
74 if (entry.GetHasPostData()) | 80 if (entry.GetHasPostData()) |
75 return FrameMsg_Navigate_Type::RESTORE_WITH_POST; | 81 return FrameMsg_Navigate_Type::RESTORE_WITH_POST; |
76 return FrameMsg_Navigate_Type::RESTORE; | 82 return FrameMsg_Navigate_Type::RESTORE; |
77 } | 83 } |
78 | 84 |
79 return FrameMsg_Navigate_Type::NORMAL; | 85 // History navigations. |
86 if (is_history_navigation) { | |
87 if (is_same_document_history_load) | |
88 return FrameMsg_Navigate_Type::HISTORY_SAME_DOCUMENT; | |
89 else | |
90 return FrameMsg_Navigate_Type::HISTORY_DIFFERENT_DOCUMENT; | |
91 } | |
92 | |
93 // A same-document fragment-navigation happens when the only part of the url | |
94 // that is modified is after the '#' character. | |
95 // | |
96 // Be careful not to consider history navigations. For instance, if the | |
97 // history is: 'A#bar' -> 'B' -> 'A#foo'. Then an history navigation from | |
98 // 'A#foo' to 'A#bar' is not a same-document navigation, but a | |
99 // different-document one! The two FrameNavigationEntry doesn't share the same | |
100 // document_sequence_number. | |
101 // | |
102 // When modifying this condition, please take a look at: | |
103 // FrameLoader::shouldPerformFragmentNavigation. | |
104 if (net::IsFragmentAddedOrUpdated(old_url, new_url) && method == "GET") | |
105 return FrameMsg_Navigate_Type::SAME_DOCUMENT; | |
106 else | |
107 return FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT; | |
80 } | 108 } |
81 | 109 |
82 } // namespace | 110 } // namespace |
83 | 111 |
84 struct NavigatorImpl::NavigationMetricsData { | 112 struct NavigatorImpl::NavigationMetricsData { |
85 NavigationMetricsData(base::TimeTicks start_time, | 113 NavigationMetricsData(base::TimeTicks start_time, |
86 GURL url, | 114 GURL url, |
87 RestoreType restore_type) | 115 RestoreType restore_type) |
88 : start_time_(start_time), url_(url) { | 116 : start_time_(start_time), url_(url) { |
89 is_restoring_from_last_session_ = | 117 is_restoring_from_last_session_ = |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
395 dest_render_frame_host->set_is_loading(true); | 423 dest_render_frame_host->set_is_loading(true); |
396 | 424 |
397 // A session history navigation should have been accompanied by state. | 425 // A session history navigation should have been accompanied by state. |
398 // TODO(creis): This is known to be failing in UseSubframeNavigationEntries | 426 // TODO(creis): This is known to be failing in UseSubframeNavigationEntries |
399 // in https://crbug.com/568703, when the PageState on a FrameNavigationEntry | 427 // in https://crbug.com/568703, when the PageState on a FrameNavigationEntry |
400 // is unexpectedly empty. Until the cause is found, keep this as a DCHECK | 428 // is unexpectedly empty. Until the cause is found, keep this as a DCHECK |
401 // and load the URL without PageState. | 429 // and load the URL without PageState. |
402 if (is_pending_entry && controller_->GetPendingEntryIndex() != -1) | 430 if (is_pending_entry && controller_->GetPendingEntryIndex() != -1) |
403 DCHECK(frame_entry.page_state().IsValid()); | 431 DCHECK(frame_entry.page_state().IsValid()); |
404 | 432 |
433 bool is_history_navigation = frame_entry.page_state().IsValid(); | |
434 | |
405 // Navigate in the desired RenderFrameHost. | 435 // Navigate in the desired RenderFrameHost. |
406 // We can skip this step in the rare case that this is a transfer navigation | 436 // We can skip this step in the rare case that this is a transfer navigation |
407 // which began in the chosen RenderFrameHost, since the request has already | 437 // which began in the chosen RenderFrameHost, since the request has already |
408 // been issued. In that case, simply resume the response. | 438 // been issued. In that case, simply resume the response. |
409 bool is_transfer_to_same = | 439 bool is_transfer_to_same = |
410 is_transfer && | 440 is_transfer && |
411 entry.transferred_global_request_id().child_id == | 441 entry.transferred_global_request_id().child_id == |
412 dest_render_frame_host->GetProcess()->GetID(); | 442 dest_render_frame_host->GetProcess()->GetID(); |
413 if (!is_transfer_to_same) { | 443 if (!is_transfer_to_same) { |
414 navigation_data_.reset(new NavigationMetricsData( | 444 navigation_data_.reset(new NavigationMetricsData( |
415 navigation_start, dest_url, entry.restore_type())); | 445 navigation_start, dest_url, entry.restore_type())); |
416 // Create the navigation parameters. | 446 // Create the navigation parameters. |
417 FrameMsg_Navigate_Type::Value navigation_type = GetNavigationType( | 447 FrameMsg_Navigate_Type::Value navigation_type = GetNavigationType( |
418 controller_->GetBrowserContext(), entry, reload_type); | 448 frame_tree_node->current_url(), // old_url |
449 dest_url, // new_url | |
450 reload_type, // reload_type | |
451 is_history_navigation, // is_history_navigation | |
nasko
2017/01/19 00:43:35
Maybe pass the FrameNavigationEntry, as we can ext
arthursonzogni
2017/01/19 17:49:21
Perfect!
| |
452 is_same_document_history_load, // is_same_document_history_load | |
453 entry, // entry | |
454 frame_entry.method()); // method | |
455 | |
419 dest_render_frame_host->Navigate( | 456 dest_render_frame_host->Navigate( |
420 entry.ConstructCommonNavigationParams( | 457 entry.ConstructCommonNavigationParams( |
421 frame_entry, post_body, dest_url, dest_referrer, navigation_type, | 458 frame_entry, post_body, dest_url, dest_referrer, navigation_type, |
422 previews_state, navigation_start), | 459 previews_state, navigation_start), |
423 entry.ConstructStartNavigationParams(), | 460 entry.ConstructStartNavigationParams(), |
424 entry.ConstructRequestNavigationParams( | 461 entry.ConstructRequestNavigationParams( |
425 frame_entry, is_same_document_history_load, | 462 frame_entry, is_history_navigation_in_new_child, |
426 is_history_navigation_in_new_child, | |
427 entry.GetSubframeUniqueNames(frame_tree_node), | 463 entry.GetSubframeUniqueNames(frame_tree_node), |
428 frame_tree_node->has_committed_real_load(), | 464 frame_tree_node->has_committed_real_load(), |
429 controller_->GetPendingEntryIndex() == -1, | 465 controller_->GetPendingEntryIndex() == -1, |
430 controller_->GetIndexOfEntry(&entry), | 466 controller_->GetIndexOfEntry(&entry), |
431 controller_->GetLastCommittedEntryIndex(), | 467 controller_->GetLastCommittedEntryIndex(), |
432 controller_->GetEntryCount())); | 468 controller_->GetEntryCount())); |
433 } else { | 469 } else { |
434 dest_render_frame_host->navigation_handle()->set_is_transferring(false); | 470 dest_render_frame_host->navigation_handle()->set_is_transferring(false); |
435 } | 471 } |
436 } | 472 } |
(...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1125 bool is_history_navigation_in_new_child, | 1161 bool is_history_navigation_in_new_child, |
1126 base::TimeTicks navigation_start) { | 1162 base::TimeTicks navigation_start) { |
1127 CHECK(IsBrowserSideNavigationEnabled()); | 1163 CHECK(IsBrowserSideNavigationEnabled()); |
1128 DCHECK(frame_tree_node); | 1164 DCHECK(frame_tree_node); |
1129 | 1165 |
1130 // This value must be set here because creating a NavigationRequest might | 1166 // This value must be set here because creating a NavigationRequest might |
1131 // change the renderer live/non-live status and change this result. | 1167 // change the renderer live/non-live status and change this result. |
1132 bool should_dispatch_beforeunload = | 1168 bool should_dispatch_beforeunload = |
1133 !is_same_document_history_load && | 1169 !is_same_document_history_load && |
1134 frame_tree_node->current_frame_host()->ShouldDispatchBeforeUnload(); | 1170 frame_tree_node->current_frame_host()->ShouldDispatchBeforeUnload(); |
1135 FrameMsg_Navigate_Type::Value navigation_type = | 1171 bool is_history_navigation = frame_entry.page_state().IsValid(); |
1136 GetNavigationType(controller_->GetBrowserContext(), entry, reload_type); | 1172 FrameMsg_Navigate_Type::Value navigation_type = GetNavigationType( |
1173 frame_tree_node->current_url(), // old_url | |
1174 dest_url, // new_url | |
1175 reload_type, // reload_type | |
1176 is_history_navigation, // is_history_navigation | |
1177 is_same_document_history_load, // is_same_document_history_load | |
1178 entry, // entry | |
1179 frame_entry.method()); // method | |
1137 std::unique_ptr<NavigationRequest> scoped_request = | 1180 std::unique_ptr<NavigationRequest> scoped_request = |
1138 NavigationRequest::CreateBrowserInitiated( | 1181 NavigationRequest::CreateBrowserInitiated( |
1139 frame_tree_node, dest_url, dest_referrer, frame_entry, entry, | 1182 frame_tree_node, dest_url, dest_referrer, frame_entry, entry, |
1140 navigation_type, previews_state, is_same_document_history_load, | 1183 navigation_type, previews_state, is_same_document_history_load, |
1141 is_history_navigation_in_new_child, navigation_start, controller_); | 1184 is_history_navigation_in_new_child, navigation_start, controller_); |
1142 NavigationRequest* navigation_request = scoped_request.get(); | 1185 NavigationRequest* navigation_request = scoped_request.get(); |
1143 | 1186 |
1144 // Navigation to a javascript URL is not a "real" navigation so there is no | 1187 // Navigation to a javascript URL is not a "real" navigation so there is no |
1145 // need to create a NavigationHandle. The navigation commits immediately and | 1188 // need to create a NavigationHandle. The navigation commits immediately and |
1146 // the NavigationRequest is not assigned to the FrameTreeNode as navigating to | 1189 // the NavigationRequest is not assigned to the FrameTreeNode as navigating to |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1265 if (navigation_handle) | 1308 if (navigation_handle) |
1266 navigation_handle->update_entry_id_for_transfer(entry->GetUniqueID()); | 1309 navigation_handle->update_entry_id_for_transfer(entry->GetUniqueID()); |
1267 | 1310 |
1268 controller_->SetPendingEntry(std::move(entry)); | 1311 controller_->SetPendingEntry(std::move(entry)); |
1269 if (delegate_) | 1312 if (delegate_) |
1270 delegate_->NotifyChangedNavigationState(content::INVALIDATE_TYPE_URL); | 1313 delegate_->NotifyChangedNavigationState(content::INVALIDATE_TYPE_URL); |
1271 } | 1314 } |
1272 } | 1315 } |
1273 | 1316 |
1274 } // namespace content | 1317 } // namespace content |
OLD | NEW |