Index: content/renderer/render_frame_impl.cc |
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc |
index 9fb4467fa3001951d3bbc3694a09ca2bc32629fe..99caf805b48678c144f0dbc0881b17f830128036 100644 |
--- a/content/renderer/render_frame_impl.cc |
+++ b/content/renderer/render_frame_impl.cc |
@@ -578,11 +578,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); |
@@ -1118,6 +1115,7 @@ RenderFrameImpl::RenderFrameImpl(const CreateParams& params) |
pepper_last_mouse_event_target_(nullptr), |
#endif |
frame_binding_(this), |
+ has_accessed_initial_document_(false), |
weak_factory_(this) { |
// We don't have a shell::Connection at this point, so use nullptr. |
// TODO(beng): We should fix this, so we can apply policy about which |
@@ -2772,13 +2770,14 @@ RenderFrameImpl::createServiceWorkerProvider() { |
} |
void RenderFrameImpl::didAccessInitialDocument() { |
+ DCHECK(!frame_->parent()); |
// NOTE: Do not call back into JavaScript here, since this call is made from a |
// V8 security check. |
// 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.) |
- if (!frame_->parent()) { |
+ if (!has_accessed_initial_document_) { |
DocumentState* document_state = |
DocumentState::FromDataSource(frame_->dataSource()); |
NavigationStateImpl* navigation_state = |
@@ -2788,6 +2787,8 @@ void RenderFrameImpl::didAccessInitialDocument() { |
Send(new FrameHostMsg_DidAccessInitialDocument(routing_id_)); |
} |
} |
+ |
+ has_accessed_initial_document_ = true; |
} |
blink::WebFrame* RenderFrameImpl::createChildFrame( |
@@ -5072,14 +5073,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 = |
clamy
2016/08/17 13:03:55
I think we may be missing the case where the navig
Alexander Semashko
2016/08/17 17:10:25
How can this occur without a redirect? If |is_redi
|
+ 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. |
+ (has_accessed_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(); |
@@ -5089,6 +5097,13 @@ 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. |
@@ -5445,13 +5460,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. |
@@ -5590,11 +5603,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 = |
@@ -6041,12 +6049,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 |