Index: chrome/browser/ui/unload_controller.cc |
diff --git a/chrome/browser/ui/unload_controller.cc b/chrome/browser/ui/unload_controller.cc |
index 8da59883131c958fbd7a16fe9daa400225b43eb7..e9b7104644ca6fcd412ace22633ca091b9c5e78b 100644 |
--- a/chrome/browser/ui/unload_controller.cc |
+++ b/chrome/browser/ui/unload_controller.cc |
@@ -12,6 +12,7 @@ |
#include "chrome/browser/ui/browser.h" |
#include "chrome/browser/ui/browser_tabstrip.h" |
#include "chrome/browser/ui/tabs/tab_strip_model.h" |
+#include "chrome/browser/ui/unload_controller_web_contents_delegate.h" |
#include "content/public/browser/notification_service.h" |
#include "content/public/browser/notification_source.h" |
#include "content/public/browser/notification_types.h" |
@@ -120,7 +121,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 +164,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_before_unload_event, |
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 +181,11 @@ bool UnloadController::CallBeforeUnloadHandlers( |
is_attempting_to_close_browser_ = true; |
on_close_confirmed_ = on_close_confirmed; |
- ProcessPendingTabs(); |
+ ProcessPendingTabs(skip_before_unload_event); |
return true; |
} |
-void UnloadController::ResetBeforeUnloadHandlers() { |
+void UnloadController::ResetTryToCloseWindow() { |
if (!is_calling_before_unload_handlers()) |
return; |
CancelWindowClose(); |
@@ -290,7 +292,7 @@ void UnloadController::TabDetachedImpl(content::WebContents* contents) { |
content::Source<content::WebContents>(contents)); |
} |
-void UnloadController::ProcessPendingTabs() { |
+void UnloadController::ProcessPendingTabs(bool skip_before_unload_event) { |
if (!is_attempting_to_close_browser_) { |
// Because we might invoke this after a delay it's possible for the value of |
// is_attempting_to_close_browser_ to have changed since we scheduled the |
@@ -305,6 +307,20 @@ void UnloadController::ProcessPendingTabs() { |
return; |
} |
+ if (skip_before_unload_event) { |
+ tabs_needing_unload_fired_.insert(tabs_needing_before_unload_fired_.begin(), |
+ tabs_needing_before_unload_fired_.end()); |
+ if (!web_contents_delegate_) |
+ web_contents_delegate_.reset(new UnloadControllerWebContentsDelegate()); |
+ for (UnloadListenerSet::iterator it = tabs_needing_unload_fired_.begin(); |
+ it != tabs_needing_unload_fired_.end(); ++it) { |
+ content::WebContents* contents = *it; |
+ if (contents->GetRenderViewHost()) |
+ contents->SetDelegate(web_contents_delegate_.get()); |
+ } |
+ 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()) { |
@@ -377,11 +393,11 @@ 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 { |
base::ThreadTaskRunnerHandle::Get()->PostTask( |
FROM_HERE, base::Bind(&UnloadController::ProcessPendingTabs, |
- weak_factory_.GetWeakPtr())); |
+ weak_factory_.GetWeakPtr(), false)); |
} |
} |
} |