Index: chrome/browser/ui/unload_controller.cc |
diff --git a/chrome/browser/ui/unload_controller.cc b/chrome/browser/ui/unload_controller.cc |
index 7a30244ff82a5b5d2a596bc747714e12bc18e913..c838992ef6116f0cb6ab3a604c2539db2cbd0ee2 100644 |
--- a/chrome/browser/ui/unload_controller.cc |
+++ b/chrome/browser/ui/unload_controller.cc |
@@ -120,7 +120,7 @@ bool UnloadController::BeforeUnloadFired(content::WebContents* contents, |
// Now that beforeunload has fired, put the tab on the queue to fire |
// unload. |
tabs_needing_unload_fired_.insert(contents); |
- ProcessPendingTabs(); |
+ ProcessPendingTabs(false); |
// We want to handle firing the unload event ourselves since we want to |
// fire all the beforeunload events before attempting to fire the unload |
// events should the user cancel closing the browser. |
@@ -163,11 +163,12 @@ bool UnloadController::ShouldCloseWindow() { |
// Cases 2 and 3. |
on_close_confirmed_.Reset(); |
- ProcessPendingTabs(); |
+ ProcessPendingTabs(false); |
return false; |
} |
-bool UnloadController::CallBeforeUnloadHandlers( |
+bool UnloadController::TryToCloseWindow( |
+ bool skip_beforeunload, |
const base::Callback<void(bool)>& on_close_confirmed) { |
// The devtools browser gets its beforeunload events as the results of |
// intercepting events from the inspected tab, so don't send them here as |
@@ -179,11 +180,11 @@ bool UnloadController::CallBeforeUnloadHandlers( |
is_attempting_to_close_browser_ = true; |
on_close_confirmed_ = on_close_confirmed; |
- ProcessPendingTabs(); |
- return true; |
+ ProcessPendingTabs(skip_beforeunload); |
+ return !skip_beforeunload; |
} |
-void UnloadController::ResetBeforeUnloadHandlers() { |
+void UnloadController::ResetTryToCloseWindow() { |
if (!is_calling_before_unload_handlers()) |
return; |
CancelWindowClose(); |
@@ -290,7 +291,7 @@ void UnloadController::TabDetachedImpl(content::WebContents* contents) { |
content::Source<content::WebContents>(contents)); |
} |
-void UnloadController::ProcessPendingTabs() { |
+void UnloadController::ProcessPendingTabs(bool skip_beforeunload) { |
// Cancel posted/queued ProcessPendingTabs task if there is any. |
weak_factory_.InvalidateWeakPtrs(); |
@@ -308,6 +309,12 @@ void UnloadController::ProcessPendingTabs() { |
return; |
} |
+ if (skip_beforeunload) { |
+ tabs_needing_unload_fired_.insert(tabs_needing_before_unload_fired_.begin(), |
+ tabs_needing_before_unload_fired_.end()); |
+ tabs_needing_before_unload_fired_.clear(); |
+ } |
+ |
// Process beforeunload tabs first. When that queue is empty, process |
// unload tabs. |
if (!tabs_needing_before_unload_fired_.empty()) { |
@@ -332,7 +339,8 @@ void UnloadController::ProcessPendingTabs() { |
// is complete. |
if (tabs_needing_unload_fired_.empty()) |
on_close_confirmed_.Reset(); |
- on_close_confirmed.Run(true); |
+ if (!skip_beforeunload) |
+ on_close_confirmed.Run(true); |
} else if (!tabs_needing_unload_fired_.empty()) { |
// We've finished firing all beforeunload events and can proceed with unload |
// events. |
@@ -380,14 +388,14 @@ void UnloadController::ClearUnloadState(content::WebContents* web_contents, |
RemoveFromSet(&tabs_needing_before_unload_fired_, web_contents); |
RemoveFromSet(&tabs_needing_unload_fired_, web_contents); |
if (process_now) { |
- ProcessPendingTabs(); |
+ ProcessPendingTabs(false); |
} else { |
// Do not post a new task if there is already any. |
if (weak_factory_.HasWeakPtrs()) |
return; |
base::ThreadTaskRunnerHandle::Get()->PostTask( |
FROM_HERE, base::Bind(&UnloadController::ProcessPendingTabs, |
- weak_factory_.GetWeakPtr())); |
+ weak_factory_.GetWeakPtr(), false)); |
} |
} |
} |