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