| 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 0c34b760f629ae56c9c4c8fa0b69852949bee897..a1723a94ce5514fd60d037ce4e352025d5fe82a9 100644
|
| --- a/content/browser/frame_host/navigator_impl.cc
|
| +++ b/content/browser/frame_host/navigator_impl.cc
|
| @@ -47,15 +47,20 @@
|
| #include "content/public/common/resource_response.h"
|
| #include "net/base/net_errors.h"
|
| #include "url/gurl.h"
|
| +#include "url/url_util.h"
|
|
|
| namespace content {
|
|
|
| namespace {
|
|
|
| FrameMsg_Navigate_Type::Value GetNavigationType(
|
| - BrowserContext* browser_context,
|
| + const GURL& old_url,
|
| + const GURL& new_url,
|
| + ReloadType reload_type,
|
| const NavigationEntryImpl& entry,
|
| - ReloadType reload_type) {
|
| + const FrameNavigationEntry& frame_entry,
|
| + bool is_same_document_history_load) {
|
| + // Reload navigations
|
| switch (reload_type) {
|
| case ReloadType::NORMAL:
|
| return FrameMsg_Navigate_Type::RELOAD;
|
| @@ -73,10 +78,36 @@ FrameMsg_Navigate_Type::Value GetNavigationType(
|
| if (entry.restore_type() == RestoreType::LAST_SESSION_EXITED_CLEANLY) {
|
| if (entry.GetHasPostData())
|
| return FrameMsg_Navigate_Type::RESTORE_WITH_POST;
|
| - return FrameMsg_Navigate_Type::RESTORE;
|
| + else
|
| + return FrameMsg_Navigate_Type::RESTORE;
|
| + }
|
| +
|
| + // History navigations.
|
| + if (frame_entry.page_state().IsValid()) {
|
| + if (is_same_document_history_load)
|
| + return FrameMsg_Navigate_Type::HISTORY_SAME_DOCUMENT;
|
| + else
|
| + return FrameMsg_Navigate_Type::HISTORY_DIFFERENT_DOCUMENT;
|
| }
|
| + DCHECK(!is_same_document_history_load);
|
|
|
| - return FrameMsg_Navigate_Type::NORMAL;
|
| + // 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 (new_url.has_ref() && old_url.EqualsIgnoringRef(new_url) &&
|
| + frame_entry.method() == "GET") {
|
| + return FrameMsg_Navigate_Type::SAME_DOCUMENT;
|
| + } else {
|
| + return FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT;
|
| + }
|
| }
|
|
|
| } // namespace
|
| @@ -417,15 +448,20 @@ 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
|
| + entry, // entry
|
| + frame_entry, // frame_entry
|
| + is_same_document_history_load); // is_same_document_history_load
|
| +
|
| 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,
|
| @@ -1133,8 +1169,13 @@ 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);
|
| + FrameMsg_Navigate_Type::Value navigation_type = GetNavigationType(
|
| + frame_tree_node->current_url(), // old_url
|
| + dest_url, // new_url
|
| + reload_type, // reload_type
|
| + entry, // entry
|
| + frame_entry, // frame_entry
|
| + is_same_document_history_load); // is_same_document_history_load
|
| std::unique_ptr<NavigationRequest> scoped_request =
|
| NavigationRequest::CreateBrowserInitiated(
|
| frame_tree_node, dest_url, dest_referrer, frame_entry, entry,
|
|
|