summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browser.cc64
1 files changed, 37 insertions, 27 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index b3de4f6..36e0d2c 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -667,6 +667,24 @@ void Browser::ReplaceContents(TabContents* source, TabContents* new_contents) {
int index = tabstrip_model_.GetIndexOfTabContents(source);
tabstrip_model_.ReplaceTabContentsAt(index, new_contents);
+
+ if (is_attempting_to_close_browser_) {
+ // Need to do this asynchronously as it will close the tab, which is
+ // currently on the call stack above us.
+ MessageLoop::current()->PostTask(FROM_HERE,
+ method_factory_.NewRunnableMethod(&Browser::ClearUnloadStateOnCrash,
+ Source<TabContents>(source).ptr()));
+ }
+ // Need to remove ourselves as an observer for disconnection on the replaced
+ // TabContents, since we only care to fire onbeforeunload handlers on active
+ // Tabs. Make sure an observer is added for the replacement TabContents.
+ NotificationService::current()->
+ RemoveObserver(this, NOTIFY_WEB_CONTENTS_DISCONNECTED,
+ Source<TabContents>(source));
+ NotificationService::current()->
+ AddObserver(this, NOTIFY_WEB_CONTENTS_DISCONNECTED,
+ Source<TabContents>(new_contents));
+
}
void Browser::AddNewContents(TabContents* source,
@@ -815,11 +833,13 @@ void Browser::Observe(NotificationType type,
}
}
} else if (type == NOTIFY_WEB_CONTENTS_DISCONNECTED) {
- // Need to do this asynchronously as it will close the tab, which is
- // currently on the call stack above us.
- MessageLoop::current()->PostTask(FROM_HERE,
- method_factory_.NewRunnableMethod(&Browser::ClearUnloadStateOnCrash,
- Source<TabContents>(source).ptr()));
+ if (is_attempting_to_close_browser_) {
+ // Need to do this asynchronously as it will close the tab, which is
+ // currently on the call stack above us.
+ MessageLoop::current()->PostTask(FROM_HERE,
+ method_factory_.NewRunnableMethod(&Browser::ClearUnloadStateOnCrash,
+ Source<TabContents>(source).ptr()));
+ }
} else {
NOTREACHED() << "Got a notification we didn't register for.";
}
@@ -1025,13 +1045,6 @@ bool Browser::ShouldCloseWindow() {
for (int i = 0; i < tab_count(); ++i) {
if (tabstrip_model_.TabHasUnloadListener(i)) {
TabContents* tab = GetTabContentsAt(i);
-
- // If the tab crashes in the beforeunload or unload handler, it won't be
- // able to ack. But we know we can close it.
- NotificationService::current()->
- AddObserver(this, NOTIFY_WEB_CONTENTS_DISCONNECTED,
- Source<TabContents>(tab));
-
tabs_needing_before_unload_fired_.push_back(tab);
}
}
@@ -1088,21 +1101,8 @@ void Browser::CancelWindowClose() {
// So there had better be a tab that we think needs beforeunload fired.
DCHECK(!tabs_needing_before_unload_fired_.empty());
- while (!tabs_needing_before_unload_fired_.empty()) {
- TabContents* tab = tabs_needing_before_unload_fired_.back();
- NotificationService::current()->
- RemoveObserver(this, NOTIFY_WEB_CONTENTS_DISCONNECTED,
- Source<TabContents>(tab));
- tabs_needing_before_unload_fired_.pop_back();
- }
-
- while (!tabs_needing_unload_fired_.empty()) {
- TabContents* tab = tabs_needing_unload_fired_.back();
- NotificationService::current()->
- RemoveObserver(this, NOTIFY_WEB_CONTENTS_DISCONNECTED,
- Source<TabContents>(tab));
- tabs_needing_unload_fired_.pop_back();
- }
+ tabs_needing_before_unload_fired_.clear();
+ tabs_needing_unload_fired_.clear();
is_attempting_to_close_browser_ = false;
}
@@ -1367,6 +1367,12 @@ void Browser::TabInsertedAt(TabContents* contents,
// parent of the Find window (if the parent is already correctly set this
// does nothing).
AdoptFindWindow(contents);
+
+ // If the tab crashes in the beforeunload or unload handler, it won't be
+ // able to ack. But we know we can close it.
+ NotificationService::current()->
+ AddObserver(this, NOTIFY_WEB_CONTENTS_DISCONNECTED,
+ Source<TabContents>(contents));
}
void Browser::TabClosingAt(TabContents* contents, int index) {
@@ -1400,6 +1406,10 @@ void Browser::TabDetachedAt(TabContents* contents, int index) {
SyncHistoryWithTabs(0);
RemoveScheduledUpdatesFor(contents);
+
+ NotificationService::current()->
+ RemoveObserver(this, NOTIFY_WEB_CONTENTS_DISCONNECTED,
+ Source<TabContents>(contents));
}
void Browser::TabSelectedAt(TabContents* old_contents,