diff options
Diffstat (limited to 'content/renderer/render_view.cc')
-rw-r--r-- | content/renderer/render_view.cc | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/content/renderer/render_view.cc b/content/renderer/render_view.cc index 63c36b4..62b1e99 100644 --- a/content/renderer/render_view.cc +++ b/content/renderer/render_view.cc @@ -632,6 +632,7 @@ bool RenderView::OnMessageReceived(const IPC::Message& message) { OnEnumerateDirectoryResponse) IPC_MESSAGE_HANDLER(ViewMsg_RunFileChooserResponse, OnFileChooserResponse) IPC_MESSAGE_HANDLER(ViewMsg_ShouldClose, OnShouldClose) + IPC_MESSAGE_HANDLER(ViewMsg_SwapOut, OnSwapOut) IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage) IPC_MESSAGE_HANDLER(ViewMsg_ThemeChanged, OnThemeChanged) IPC_MESSAGE_HANDLER(ViewMsg_DisassociateFromPopupCount, @@ -685,6 +686,10 @@ void RenderView::OnNavigate(const ViewMsg_Navigate_Params& params) { if (!webview()) return; + // Swap this renderer back in if necessary. + if (is_swapped_out_) + SetSwappedOut(false); + history_list_offset_ = params.current_history_list_offset; history_list_length_ = params.current_history_list_length; @@ -1564,6 +1569,12 @@ bool RenderView::runModalPromptDialog( bool RenderView::runModalBeforeUnloadDialog( WebFrame* frame, const WebString& message) { + // If we are swapping out, we have already run the beforeunload handler. + // TODO(creis): Fix OnSwapOut to clear the frame without running beforeunload + // at all, to avoid running it twice. + if (is_swapped_out_) + return true; + bool success = false; // This is an ignored return value, but is included so we can accept the same // response as RunJavaScriptMessage. @@ -1926,6 +1937,12 @@ void RenderView::loadURLExternally( WebNavigationPolicy RenderView::decidePolicyForNavigation( WebFrame* frame, const WebURLRequest& request, WebNavigationType type, const WebNode&, WebNavigationPolicy default_policy, bool is_redirect) { + // TODO(creis): Remove this when we fix OnSwapOut to not need a navigation. + if (is_swapped_out_) { + DCHECK(request.url() == GURL("about:swappedout")); + return default_policy; + } + // Webkit is asking whether to navigate to a new URL. // This is fine normally, except if we're showing UI from one security // context and they're trying to navigate to a different context. @@ -3510,7 +3527,38 @@ void RenderView::OnShouldClose() { Send(new ViewHostMsg_ShouldClose_ACK(routing_id_, should_close)); } -void RenderView::OnClosePage(const ViewMsg_ClosePage_Params& params) { +void RenderView::OnSwapOut(const ViewMsg_SwapOut_Params& params) { + if (is_swapped_out_) + return; + + // Swap this RenderView out so the tab can navigate to a page rendered by a + // different process. This involves running the unload handler and clearing + // the page. Once WasSwappedOut is called, we also allow this process to exit + // if there are no other active RenderViews in it. + + // Send an UpdateState message before we get swapped out. + SyncNavigationState(); + + // Synchronously run the unload handler before sending the ACK. + webview()->dispatchUnloadEvent(); + + // Swap out and stop sending any IPC messages that are not ACKs. + SetSwappedOut(true); + + // Replace the page with a blank dummy URL. The unload handler will not be + // run a second time, thanks to a check in FrameLoader::stopLoading. + // TODO(creis): Need to add a better way to do this that avoids running the + // beforeunload handler. For now, we just run it a second time silently. + webview()->mainFrame()->loadHTMLString(std::string(), + GURL("about:swappedout"), + GURL("about:swappedout"), + false); + + // Just echo back the params in the ACK. + Send(new ViewHostMsg_SwapOut_ACK(routing_id_, params)); +} + +void RenderView::OnClosePage() { // TODO(creis): We'd rather use webview()->Close() here, but that currently // sets the WebView's delegate_ to NULL, preventing any JavaScript dialogs // in the onunload handler from appearing. For now, we're bypassing that and @@ -3520,8 +3568,7 @@ void RenderView::OnClosePage(const ViewMsg_ClosePage_Params& params) { // http://b/issue?id=753080. webview()->dispatchUnloadEvent(); - // Just echo back the params in the ACK. - Send(new ViewHostMsg_ClosePage_ACK(routing_id_, params)); + Send(new ViewHostMsg_ClosePage_ACK(routing_id_)); } void RenderView::OnThemeChanged() { |