Index: content/renderer/render_frame_impl.cc |
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc |
index db7242bce67a9b0995cde3fe8a29c56a4d2fa453..bf257133128d4accca05a0c81db9109cbf04274c 100644 |
--- a/content/renderer/render_frame_impl.cc |
+++ b/content/renderer/render_frame_impl.cc |
@@ -565,11 +565,8 @@ WebURLRequest CreateURLRequestForNavigation( |
// clamping it to renderer_navigation_start, initialized earlier in the call |
// stack. |
base::TimeTicks SanitizeNavigationTiming( |
- blink::WebFrameLoadType load_type, |
const base::TimeTicks& browser_navigation_start, |
const base::TimeTicks& renderer_navigation_start) { |
- if (load_type != blink::WebFrameLoadType::Standard) |
- return base::TimeTicks(); |
DCHECK(!browser_navigation_start.is_null()); |
base::TimeTicks navigation_start = |
std::min(browser_navigation_start, renderer_navigation_start); |
@@ -1063,6 +1060,7 @@ RenderFrameImpl::RenderFrameImpl(const CreateParams& params) |
render_view_(params.render_view->AsWeakPtr()), |
routing_id_(params.routing_id), |
proxy_routing_id_(MSG_ROUTING_NONE), |
+ did_access_initial_document_(false), |
#if defined(ENABLE_PLUGINS) |
plugin_power_saver_helper_(nullptr), |
plugin_find_handler_(nullptr), |
@@ -2756,6 +2754,8 @@ RenderFrameImpl::createServiceWorkerProvider() { |
} |
void RenderFrameImpl::didAccessInitialDocument() { |
+ did_access_initial_document_ = true; |
+ |
// If the request hasn't yet committed, notify the browser process that it is |
// no longer safe to show the pending URL of the main frame, since a URL spoof |
// is now possible. (If the request has committed, the browser already knows.) |
@@ -3376,6 +3376,7 @@ void RenderFrameImpl::didCommitProvisionalLoad( |
// Update the current history item for this frame (both in default Chrome and |
// subframe FrameNavigationEntry modes). |
current_history_item_ = item; |
+ did_access_initial_document_ = false; |
InternalDocumentStateData* internal_data = |
InternalDocumentStateData::FromDocumentState(document_state); |
@@ -5040,14 +5041,21 @@ WebNavigationPolicy RenderFrameImpl::decidePolicyForNavigation( |
return blink::WebNavigationPolicyIgnore; |
} |
- // Execute the BeforeUnload event. If asked not to proceed or the frame is |
- // destroyed, ignore the navigation. There is no need to execute the |
- // BeforeUnload event during a redirect, since it was already executed at the |
- // start of the navigation. |
- // PlzNavigate: this is not executed when commiting the navigation. |
- if (info.defaultPolicy == blink::WebNavigationPolicyCurrentTab && |
- !is_redirect && (!IsBrowserSideNavigationEnabled() || |
- info.urlRequest.checkForBrowserSideNavigation())) { |
+ bool should_dispatch_before_unload = |
+ info.defaultPolicy == blink::WebNavigationPolicyCurrentTab && |
+ // There is no need to execute the BeforeUnload event during a redirect, |
+ // since it was already executed at the start of the navigation. |
+ !is_redirect && |
+ // PlzNavigate: this should not be executed when commiting the navigation. |
+ (!IsBrowserSideNavigationEnabled() || |
+ info.urlRequest.checkForBrowserSideNavigation()) && |
+ // No need to dispatch beforeunload if the frame has not committed a |
+ // navigation and contains an empty initial document. |
+ (did_access_initial_document_ || !current_history_item_.isNull()); |
+ |
+ if (should_dispatch_before_unload) { |
+ // Execute the BeforeUnload event. If asked not to proceed or the frame is |
+ // destroyed, ignore the navigation. |
// Keep a WeakPtr to this RenderFrameHost to detect if executing the |
// BeforeUnload event destriyed this frame. |
base::WeakPtr<RenderFrameImpl> weak_self = weak_factory_.GetWeakPtr(); |
@@ -5057,6 +5065,12 @@ WebNavigationPolicy RenderFrameImpl::decidePolicyForNavigation( |
!weak_self) { |
return blink::WebNavigationPolicyIgnore; |
} |
+ // navigation_start must be recorded immediately after dispatching the |
+ // beforeunload event. |
+ if (pending_navigation_params_) { |
+ pending_navigation_params_->common_params.navigation_start = |
+ base::TimeTicks::Now(); |
+ } |
} |
// PlzNavigate: if the navigation is not synchronous, send it to the browser. |
@@ -5454,13 +5468,11 @@ void RenderFrameImpl::NavigateInternal( |
pending_navigation_params_.reset( |
new NavigationParams(common_params, start_params, request_params)); |
- // Unless the load is a WebFrameLoadType::Standard, this should remain |
- // uninitialized. It will be updated when the load type is determined to be |
- // Standard, or after the previous document's unload handler has been |
- // triggered. This occurs in UpdateNavigationState. |
- // TODO(csharrison) See if we can always use the browser timestamp. |
+ // Sanitize navigation start and store in |pending_navigation_params_|. |
+ // It will be picked up in UpdateNavigationState. |
pending_navigation_params_->common_params.navigation_start = |
- base::TimeTicks(); |
+ SanitizeNavigationTiming(common_params.navigation_start, |
+ renderer_navigation_start); |
// Create parameters for a standard navigation, indicating whether it should |
// replace the current NavigationEntry. |
@@ -5583,11 +5595,6 @@ void RenderFrameImpl::NavigateInternal( |
} |
if (should_load_request) { |
- // Sanitize navigation start now that we know the load_type. |
- pending_navigation_params_->common_params.navigation_start = |
- SanitizeNavigationTiming(load_type, common_params.navigation_start, |
- renderer_navigation_start); |
- |
// PlzNavigate: check if the navigation being committed originated as a |
// client redirect. |
bool is_client_redirect = |
@@ -6027,12 +6034,7 @@ void RenderFrameImpl::UpdateNavigationState(DocumentState* document_state, |
return; |
} |
- // If this is a browser-initiated load that doesn't override |
- // navigation_start, set it here. |
- if (pending_navigation_params_->common_params.navigation_start.is_null()) { |
- pending_navigation_params_->common_params.navigation_start = |
- base::TimeTicks::Now(); |
- } |
+ DCHECK(!pending_navigation_params_->common_params.navigation_start.is_null()); |
document_state->set_navigation_state(CreateNavigationStateFromPending()); |
// The |set_was_load_data_with_base_url_request| state should not change for |