Chromium Code Reviews| 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, |