Index: content/browser/frame_host/navigator_impl.cc |
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc |
index 09d7ed98c8fd17451c99e81d4af0b1bcba6a6be1..862b90e5c5b4277b0252d321ab5a8669a57e35e9 100644 |
--- a/content/browser/frame_host/navigator_impl.cc |
+++ b/content/browser/frame_host/navigator_impl.cc |
@@ -46,6 +46,7 @@ |
#include "content/public/common/content_constants.h" |
#include "content/public/common/resource_response.h" |
#include "net/base/net_errors.h" |
+#include "net/base/url_util.h" |
#include "url/gurl.h" |
namespace content { |
@@ -53,9 +54,14 @@ namespace content { |
namespace { |
FrameMsg_Navigate_Type::Value GetNavigationType( |
- BrowserContext* browser_context, |
+ const GURL& old_url, |
+ const GURL& new_url, |
+ ReloadType reload_type, |
+ bool is_history_navigation, |
+ bool is_same_document_history_load, |
const NavigationEntryImpl& entry, |
- ReloadType reload_type) { |
+ std::string method) { |
+ // Reload navigations |
switch (reload_type) { |
case ReloadType::NORMAL: |
return FrameMsg_Navigate_Type::RELOAD; |
@@ -76,7 +82,29 @@ FrameMsg_Navigate_Type::Value GetNavigationType( |
return FrameMsg_Navigate_Type::RESTORE; |
} |
- return FrameMsg_Navigate_Type::NORMAL; |
+ // History navigations. |
+ if (is_history_navigation) { |
+ if (is_same_document_history_load) |
+ return FrameMsg_Navigate_Type::HISTORY_SAME_DOCUMENT; |
+ else |
+ return FrameMsg_Navigate_Type::HISTORY_DIFFERENT_DOCUMENT; |
+ } |
+ |
+ // A same-document fragment-navigation happens when the only part of the url |
+ // that is modified is after the '#' character. |
+ // |
+ // Be careful not to consider history navigations. For instance, if the |
+ // history is: 'A#bar' -> 'B' -> 'A#foo'. Then an history navigation from |
+ // 'A#foo' to 'A#bar' is not a same-document navigation, but a |
+ // different-document one! The two FrameNavigationEntry doesn't share the same |
+ // document_sequence_number. |
+ // |
+ // When modifying this condition, please take a look at: |
+ // FrameLoader::shouldPerformFragmentNavigation. |
+ if (net::IsFragmentAddedOrUpdated(old_url, new_url) && method == "GET") |
+ return FrameMsg_Navigate_Type::SAME_DOCUMENT; |
+ else |
+ return FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT; |
} |
} // namespace |
@@ -402,6 +430,8 @@ bool NavigatorImpl::NavigateToEntry( |
if (is_pending_entry && controller_->GetPendingEntryIndex() != -1) |
DCHECK(frame_entry.page_state().IsValid()); |
+ bool is_history_navigation = frame_entry.page_state().IsValid(); |
+ |
// Navigate in the desired RenderFrameHost. |
// We can skip this step in the rare case that this is a transfer navigation |
// which began in the chosen RenderFrameHost, since the request has already |
@@ -415,15 +445,21 @@ bool NavigatorImpl::NavigateToEntry( |
navigation_start, dest_url, entry.restore_type())); |
// Create the navigation parameters. |
FrameMsg_Navigate_Type::Value navigation_type = GetNavigationType( |
- controller_->GetBrowserContext(), entry, reload_type); |
+ frame_tree_node->current_url(), // old_url |
+ dest_url, // new_url |
+ reload_type, // reload_type |
+ 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!
|
+ is_same_document_history_load, // is_same_document_history_load |
+ entry, // entry |
+ frame_entry.method()); // method |
+ |
dest_render_frame_host->Navigate( |
entry.ConstructCommonNavigationParams( |
frame_entry, post_body, dest_url, dest_referrer, navigation_type, |
previews_state, navigation_start), |
entry.ConstructStartNavigationParams(), |
entry.ConstructRequestNavigationParams( |
- frame_entry, is_same_document_history_load, |
- is_history_navigation_in_new_child, |
+ frame_entry, is_history_navigation_in_new_child, |
entry.GetSubframeUniqueNames(frame_tree_node), |
frame_tree_node->has_committed_real_load(), |
controller_->GetPendingEntryIndex() == -1, |
@@ -1132,8 +1168,15 @@ void NavigatorImpl::RequestNavigation(FrameTreeNode* frame_tree_node, |
bool should_dispatch_beforeunload = |
!is_same_document_history_load && |
frame_tree_node->current_frame_host()->ShouldDispatchBeforeUnload(); |
- FrameMsg_Navigate_Type::Value navigation_type = |
- GetNavigationType(controller_->GetBrowserContext(), entry, reload_type); |
+ bool is_history_navigation = frame_entry.page_state().IsValid(); |
+ FrameMsg_Navigate_Type::Value navigation_type = GetNavigationType( |
+ frame_tree_node->current_url(), // old_url |
+ dest_url, // new_url |
+ reload_type, // reload_type |
+ is_history_navigation, // is_history_navigation |
+ is_same_document_history_load, // is_same_document_history_load |
+ entry, // entry |
+ frame_entry.method()); // method |
std::unique_ptr<NavigationRequest> scoped_request = |
NavigationRequest::CreateBrowserInitiated( |
frame_tree_node, dest_url, dest_referrer, frame_entry, entry, |