Index: chrome/browser/ui/unload_controller.h |
diff --git a/chrome/browser/ui/unload_controller.h b/chrome/browser/ui/unload_controller.h |
index 512217a96b5e3aadd01c7340b86ddfb97c7d88d0..a2ba5aaedf7a75e6a983f296bf28ec3ee9c41017 100644 |
--- a/chrome/browser/ui/unload_controller.h |
+++ b/chrome/browser/ui/unload_controller.h |
@@ -7,6 +7,7 @@ |
#include <set> |
+#include "base/memory/scoped_ptr.h" |
#include "base/memory/weak_ptr.h" |
#include "chrome/browser/ui/tabs/tab_strip_model_observer.h" |
#include "content/public/browser/notification_observer.h" |
@@ -23,7 +24,36 @@ class WebContents; |
} |
namespace chrome { |
- |
+class UnloadDetachedHandler; |
+ |
+// UnloadController manages closing tabs and windows -- especially in |
+// regards to beforeunload handlers (proceed/cancel dialogs) and |
+// unload handlers (no user interaction). |
+// |
+// Typical flow of closing a tab: |
+// 1. Browser calls |CanCloseContents()|. |
+// If true, browser calls contents::CloseWebContents(). |
+// 2. WebContents notifies us via its delegate and BeforeUnloadFired() |
+// that the beforeunload handler was run. If the user allowed the |
+// close to continue, we hand-off running the unload handler to |
+// UnloadDetachedHandler. The tab is removed from the tab strip at |
+// this point. |
+// |
+// Typical flow of closing a window: |
+// 1. BrowserView::CanClose() calls TabsNeedBeforeUnloadFired(). |
+// If beforeunload/unload handlers need to run, UnloadController returns |
+// true and calls ProcessPendingTabs() (private method). |
+// 2. For each tab with a beforeunload/unload handler, ProcessPendingTabs() |
+// calls |web_contents->OnCloseStarted()| |
+// and |web_contents->GetRenderViewHost()->FirePageBeforeUnload()|. |
+// 3. If the user allowed the close to continue, we hand-off all the tabs with |
+// unload handlers to UnloadDetachedHandler. All the tabs are removed |
+// from the tab strip. |
+// 4. The browser gets notified that the tab strip is empty and calls |
+// CloseFrame where the empty tab strip causes the window to hide. |
+// Once the detached tabs finish, the browser calls CloseFrame again and |
+// the window is finally closed. |
+// |
class UnloadController : public content::NotificationObserver, |
public TabStripModelObserver { |
public: |
@@ -115,11 +145,11 @@ class UnloadController : public content::NotificationObserver, |
content::NotificationRegistrar registrar_; |
- // Tracks tabs that need there beforeunload event fired before we can |
+ // Tracks tabs that need their beforeunload event fired before we can |
// close the browser. Only gets populated when we try to close the browser. |
UnloadListenerSet tabs_needing_before_unload_fired_; |
- // Tracks tabs that need there unload event fired before we can |
+ // Tracks tabs that need their unload event fired before we can |
// close the browser. Only gets populated when we try to close the browser. |
UnloadListenerSet tabs_needing_unload_fired_; |
@@ -129,6 +159,9 @@ class UnloadController : public content::NotificationObserver, |
// Browser window isn't just immediately closed. |
bool is_attempting_to_close_browser_; |
+ // Allow unload handlers to run without holding up the UI. |
+ scoped_ptr<UnloadDetachedHandler> unload_detached_handler_; |
+ |
base::WeakPtrFactory<UnloadController> weak_factory_; |
DISALLOW_COPY_AND_ASSIGN(UnloadController); |