Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2103)

Unified Diff: chrome/browser/ui/unload_controller.cc

Issue 23835007: DevTools: Do not close devtools if there are dirty files in workspace (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressing final Jeremy's comments Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« chrome/browser/ui/browser.h ('K') | « chrome/browser/ui/unload_controller.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..db8b2476ddda62c63ab6d73e2d85685df8acb5c4 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,
+ // 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_;
« chrome/browser/ui/browser.h ('K') | « chrome/browser/ui/unload_controller.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698