Chromium Code Reviews| Index: chrome/browser/ui/unload_controller.cc |
| diff --git a/chrome/browser/ui/unload_controller.cc b/chrome/browser/ui/unload_controller.cc |
| index dc55a5f89444178a848d950f67f63e4324e45e41..6d76a9767fb59653a0a7e98677f49677611ae09f 100644 |
| --- a/chrome/browser/ui/unload_controller.cc |
| +++ b/chrome/browser/ui/unload_controller.cc |
| @@ -42,7 +42,23 @@ bool UnloadController::CanCloseContents(content::WebContents* contents) { |
| } |
| // static |
| +bool UnloadController::ShouldRunUnloadEventsHelper( |
| + content::WebContents* contents) { |
| + // If |contents| is being inspected, DevTools needs to intercept beforeunload |
| + // events. |
| + return DevToolsWindow::GetInstanceForInspectedRenderViewHost( |
| + contents->GetRenderViewHost()) != NULL; |
| +} |
| + |
| +// static |
| bool UnloadController::RunUnloadEventsHelper(content::WebContents* contents) { |
| + // If there's a devtools window attached to |contents|, |
| + // we would like devtools to call its own beforeunload handlers first, |
| + // and then call beforeunload handlers for |contents|. |
| + // See DevToolsWindow::InterceptPageBeforeUnload for details. |
| + if (DevToolsWindow::InterceptPageBeforeUnload(contents)) { |
| + return true; |
| + } |
| // If the WebContents is not connected yet, then there's no unload |
| // handler we can fire even if the WebContents has an unload listener. |
| // One case where we hit this is in a tab that has an infinite loop |
| @@ -60,6 +76,9 @@ bool UnloadController::RunUnloadEventsHelper(content::WebContents* contents) { |
| bool UnloadController::BeforeUnloadFired(content::WebContents* contents, |
| bool proceed) { |
| + if (!proceed) |
| + DevToolsWindow::OnPageCloseCanceled(contents); |
| + |
| if (!is_attempting_to_close_browser_) { |
| if (!proceed) |
| contents->SetClosedByUserGesture(false); |
| @@ -90,6 +109,14 @@ bool UnloadController::ShouldCloseWindow() { |
| if (HasCompletedUnloadProcessing()) |
| return true; |
| + // Special case for when we quit an application. The Devtools window can |
| + // close if it's beforeunload event has already fired which will happen due |
| + // to the interception of it's content's beforeunload. |
| + if (browser_->is_devtools() && |
| + DevToolsWindow::HasFiredBeforeUnloadEventForDevToolsBrowser(browser_)) { |
| + return true; |
| + } |
| + |
| // The behavior followed here varies based on the current phase of the |
| // operation and whether a batched shutdown is in progress. |
| // |
| @@ -117,7 +144,11 @@ bool UnloadController::ShouldCloseWindow() { |
| bool UnloadController::CallBeforeUnloadHandlers( |
| const base::Callback<void(bool)>& on_close_confirmed) { |
| - if (HasCompletedUnloadProcessing() || !TabsNeedBeforeUnloadFired()) |
| + // The DevTools browser gets its beforeunload events as the results of |
| + // intercepting events from the inspected tab, so don't send them here as |
| + // well. |
| + if (browser_->is_devtools() || HasCompletedUnloadProcessing() || |
| + !TabsNeedBeforeUnloadFired()) |
| return false; |
| is_attempting_to_close_browser_ = true; |
| @@ -138,8 +169,10 @@ bool UnloadController::TabsNeedBeforeUnloadFired() { |
| for (int i = 0; i < browser_->tab_strip_model()->count(); ++i) { |
| content::WebContents* contents = |
| browser_->tab_strip_model()->GetWebContentsAt(i); |
| + bool should_fire_beforeunload = contents->NeedToFireBeforeUnload() || |
| + DevToolsWindow::NeedsToInterceptBeforeUnload(contents); |
| if (!ContainsKey(tabs_needing_unload_fired_, contents) && |
| - contents->NeedToFireBeforeUnload()) { |
| + should_fire_beforeunload) { |
| tabs_needing_before_unload_fired_.insert(contents); |
| } |
| } |
| @@ -236,7 +269,12 @@ void UnloadController::ProcessPendingTabs() { |
| // Null check render_view_host here as this gets called on a PostTask and |
| // the tab's render_view_host may have been nulled out. |
| if (web_contents->GetRenderViewHost()) { |
| - web_contents->GetRenderViewHost()->FirePageBeforeUnload(false); |
| + // If there's a devtools window attached to |web_contents|, |
| + // we would like devtools to call its own beforeunload handlers first, |
|
jeremy
2013/11/14 08:53:13
nit: devtools capitalization here and throughout *
lushnikov
2013/11/14 09:49:39
Oops, just checked other usages of "devtools" word
|
| + // and then call beforeunload handlers for |web_contents|. |
| + // See DevToolsWindow::InterceptPageBeforeUnload for details. |
| + if (!DevToolsWindow::InterceptPageBeforeUnload(web_contents)) |
| + web_contents->GetRenderViewHost()->FirePageBeforeUnload(false); |
| } else { |
| ClearUnloadState(web_contents, true); |
| } |
| @@ -274,6 +312,10 @@ void UnloadController::CancelWindowClose() { |
| // Closing of window can be canceled from a beforeunload handler. |
| DCHECK(is_attempting_to_close_browser_); |
| tabs_needing_before_unload_fired_.clear(); |
| + for (UnloadListenerSet::iterator it = tabs_needing_unload_fired_.begin(); |
| + it != tabs_needing_unload_fired_.end(); ++it) { |
| + DevToolsWindow::OnPageCloseCanceled(*it); |
| + } |
| tabs_needing_unload_fired_.clear(); |
| if (is_calling_before_unload_handlers()) { |
| base::Callback<void(bool)> on_close_confirmed = on_close_confirmed_; |