Index: content/browser/web_contents/web_contents_impl.cc |
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc |
index c98f895e8b3844f9bdde6806aedfda13818ba985..4a983f591132d840c630625c69da4ff55a544fb7 100644 |
--- a/content/browser/web_contents/web_contents_impl.cc |
+++ b/content/browser/web_contents/web_contents_impl.cc |
@@ -307,6 +307,14 @@ class WebContentsImpl::DestructionObserver : public WebContentsObserver { |
// WebContentsImpl ------------------------------------------------------------- |
+WebContentsImpl::PendingNavigationParams::PendingNavigationParams() { |
+} |
+ |
+WebContentsImpl::PendingNavigationParams::PendingNavigationParams( |
+ const GlobalRequestID& global_request_id) |
+ : global_request_id(global_request_id) { |
+} |
+ |
WebContentsImpl::WebContentsImpl( |
BrowserContext* browser_context, |
WebContentsImpl* opener) |
@@ -3033,9 +3041,44 @@ void WebContentsImpl::Close(RenderViewHost* rvh) { |
delegate_->CloseContents(this); |
} |
+void WebContentsImpl::OnCrossSiteResponse( |
+ RenderViewHost* pending_render_view_host, |
+ const GlobalRequestID& global_request_id) { |
+ // This should be called when the pending RVH is ready to commit. |
+ DCHECK_EQ(pending_render_view_host, |
+ render_manager_.pending_render_view_host()); |
+ |
+ // Remember the request ID until the unload handler has run. |
+ pending_nav_params_.reset(new PendingNavigationParams(global_request_id)); |
+ |
+ // Run the unload handler of the current page. |
+ render_manager_.SwapOutOldPage(); |
+} |
+ |
void WebContentsImpl::SwappedOut(RenderViewHost* rvh) { |
- if (delegate_ && rvh == GetRenderViewHost()) |
+ if (rvh != GetRenderViewHost()) { |
+ pending_nav_params_.reset(); |
+ return; |
+ } |
+ |
+ if (delegate_) |
delegate_->SwappedOut(this); |
+ |
+ // Make sure we have a pending navigation from OnCrossSiteResponse above. |
+ // If not (e.g., for data URLs that don't make network requests), just return |
+ // early and ignore. |
+ if (!pending_nav_params_.get()) |
+ return; |
+ |
+ // Now that the unload handler has run, we need to resume the paused response. |
+ if (render_manager_.pending_render_view_host()) { |
+ RenderProcessHostImpl* pending_process = |
+ static_cast<RenderProcessHostImpl*>( |
+ render_manager_.pending_render_view_host()->GetProcess()); |
+ pending_process->ResumeDeferredNavigation( |
+ pending_nav_params_->global_request_id); |
+ } |
+ pending_nav_params_.reset(); |
} |
void WebContentsImpl::RequestMove(const gfx::Rect& new_bounds) { |