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

Unified Diff: chrome/browser/ui/tabs/tab_strip_model.cc

Issue 15896023: Makes TabStripModel deal handle the case of the TabStripModel (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Incorporate Avi's feedback Created 7 years, 7 months 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
« no previous file with comments | « chrome/browser/ui/tabs/tab_strip_model.h ('k') | chrome/browser/ui/tabs/tab_strip_model_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/ui/tabs/tab_strip_model.cc
diff --git a/chrome/browser/ui/tabs/tab_strip_model.cc b/chrome/browser/ui/tabs/tab_strip_model.cc
index da4302a9707f818b363d7e0fc77c6ad60449d138..78c8f0e1fa9620c82c4bac5195361223f1d84cdb 100644
--- a/chrome/browser/ui/tabs/tab_strip_model.cc
+++ b/chrome/browser/ui/tabs/tab_strip_model.cc
@@ -45,6 +45,67 @@ bool ShouldForgetOpenersForTransition(content::PageTransition transition) {
transition == content::PAGE_TRANSITION_AUTO_TOPLEVEL;
}
+// CloseTracker is used when closing a set of WebContents. It listens for
+// deletions of the WebContents and removes from the internal set any time one
+// is deleted.
+class CloseTracker : public content::NotificationObserver {
+ public:
+ typedef std::vector<WebContents*> Contents;
+
+ explicit CloseTracker(const Contents& contents);
+ virtual ~CloseTracker();
+
+ // Returns true if there is another WebContents in the Tracker.
+ bool HasNext() const;
+
+ // Returns the next WebContents, or NULL if there are no more.
+ WebContents* Next();
+
+ private:
+ // NotificationObserver:
+ virtual void Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) OVERRIDE;
+
+ Contents contents_;
+
+ content::NotificationRegistrar registrar_;
+
+ DISALLOW_COPY_AND_ASSIGN(CloseTracker);
+};
+
+CloseTracker::CloseTracker(const Contents& contents)
+ : contents_(contents) {
+ registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
+ content::NotificationService::AllBrowserContextsAndSources());
+}
+
+CloseTracker::~CloseTracker() {
+}
+
+bool CloseTracker::HasNext() const {
+ return !contents_.empty();
+}
+
+WebContents* CloseTracker::Next() {
+ if (contents_.empty())
+ return NULL;
+
+ WebContents* web_contents = contents_[0];
+ contents_.erase(contents_.begin());
+ return web_contents;
+}
+
+void CloseTracker::Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ WebContents* web_contents = content::Source<WebContents>(source).ptr();
+ Contents::iterator i =
+ std::find(contents_.begin(), contents_.end(), web_contents);
+ if (i != contents_.end())
+ contents_.erase(i);
+}
+
} // namespace
///////////////////////////////////////////////////////////////////////////////
@@ -960,6 +1021,14 @@ bool TabStripModel::ContextMenuCommandToBrowserCommand(int cmd_id,
///////////////////////////////////////////////////////////////////////////////
// TabStripModel, private:
+std::vector<WebContents*> TabStripModel::GetWebContentsFromIndices(
+ const std::vector<int>& indices) const {
+ std::vector<WebContents*> contents;
+ for (size_t i = 0; i < indices.size(); ++i)
+ contents.push_back(GetWebContentsAtImpl(indices[i]));
+ return contents;
+}
+
void TabStripModel::GetIndicesWithSameDomain(int index,
std::vector<int>* indices) {
std::string domain = GetWebContentsAt(index)->GetURL().host();
@@ -1014,12 +1083,7 @@ bool TabStripModel::InternalCloseTabs(const std::vector<int>& indices,
if (indices.empty())
return true;
- // Map the indices to WebContentses, that way if deleting a tab deletes
- // other tabs we're ok. Crashes seem to indicate during tab deletion other
- // tabs are getting removed.
- std::vector<WebContents*> closing_contentses;
- for (size_t i = 0; i < indices.size(); ++i)
- closing_contentses.push_back(GetWebContentsAtImpl(indices[i]));
+ CloseTracker close_tracker(GetWebContentsFromIndices(indices));
// We only try the fast shutdown path if the whole browser process is *not*
// shutting down. Fast shutdown during browser termination is handled in
@@ -1044,8 +1108,8 @@ bool TabStripModel::InternalCloseTabs(const std::vector<int>& indices,
// We now return to our regularly scheduled shutdown procedure.
bool retval = true;
- for (size_t i = 0; i < closing_contentses.size(); ++i) {
- WebContents* closing_contents = closing_contentses[i];
+ while (close_tracker.HasNext()) {
+ WebContents* closing_contents = close_tracker.Next();
int index = GetIndexOfWebContents(closing_contents);
// Make sure we still contain the tab.
if (index == kNoTab)
« no previous file with comments | « chrome/browser/ui/tabs/tab_strip_model.h ('k') | chrome/browser/ui/tabs/tab_strip_model_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698