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..ad936d54965639a55537f2d03a9c7e5895d0fb91 100644 |
--- a/chrome/browser/ui/unload_controller.cc |
+++ b/chrome/browser/ui/unload_controller.cc |
@@ -43,6 +43,11 @@ bool UnloadController::CanCloseContents(content::WebContents* contents) { |
// static |
bool UnloadController::RunUnloadEventsHelper(content::WebContents* contents) { |
+ // If there's a devtools window attached to the web contents, |
+ // then we would like to run its beforeunload handlers first. |
+ 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 +65,9 @@ bool UnloadController::RunUnloadEventsHelper(content::WebContents* contents) { |
bool UnloadController::BeforeUnloadFired(content::WebContents* contents, |
bool proceed) { |
+ if (!proceed) |
+ DevToolsWindow::PageClosingCanceled(contents); |
+ |
if (!is_attempting_to_close_browser_) { |
if (!proceed) |
contents->SetClosedByUserGesture(false); |
@@ -90,6 +98,11 @@ bool UnloadController::ShouldCloseWindow() { |
if (HasCompletedUnloadProcessing()) |
return true; |
+ if (browser_->is_devtools() && |
+ DevToolsWindow::ShouldCloseDevToolsBrowser(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 +130,10 @@ bool UnloadController::ShouldCloseWindow() { |
bool UnloadController::CallBeforeUnloadHandlers( |
const base::Callback<void(bool)>& on_close_confirmed) { |
- if (HasCompletedUnloadProcessing() || !TabsNeedBeforeUnloadFired()) |
+ // DevTools browser will get its beforeunload events triggered on |
+ // inspected tab closing |
+ if (browser_->is_devtools() || HasCompletedUnloadProcessing() || |
+ !TabsNeedBeforeUnloadFired()) |
return false; |
is_attempting_to_close_browser_ = true; |
@@ -139,7 +155,8 @@ bool UnloadController::TabsNeedBeforeUnloadFired() { |
content::WebContents* contents = |
browser_->tab_strip_model()->GetWebContentsAt(i); |
if (!ContainsKey(tabs_needing_unload_fired_, contents) && |
- contents->NeedToFireBeforeUnload()) { |
+ (contents->NeedToFireBeforeUnload() || |
+ DevToolsWindow::NeedToFireBeforeUnload(contents))) { |
tabs_needing_before_unload_fired_.insert(contents); |
} |
} |
@@ -236,7 +253,8 @@ 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 (!DevToolsWindow::InterceptPageBeforeUnload(web_contents)) |
+ web_contents->GetRenderViewHost()->FirePageBeforeUnload(false); |
} else { |
ClearUnloadState(web_contents, true); |
} |
@@ -274,6 +292,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::PageClosingCanceled(*it); |
+ } |
tabs_needing_unload_fired_.clear(); |
if (is_calling_before_unload_handlers()) { |
base::Callback<void(bool)> on_close_confirmed = on_close_confirmed_; |