| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/tabs/tab_strip_model.h" | 5 #include "chrome/browser/tabs/tab_strip_model.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 842 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 tab->web_contents())) { | 853 tab->web_contents())) { |
| 854 tab->web_contents()->GetController().Reload(true); | 854 tab->web_contents()->GetController().Reload(true); |
| 855 } | 855 } |
| 856 } | 856 } |
| 857 break; | 857 break; |
| 858 } | 858 } |
| 859 | 859 |
| 860 case CommandDuplicate: { | 860 case CommandDuplicate: { |
| 861 content::RecordAction(UserMetricsAction("TabContextMenu_Duplicate")); | 861 content::RecordAction(UserMetricsAction("TabContextMenu_Duplicate")); |
| 862 std::vector<int> indices = GetIndicesForCommand(context_index); | 862 std::vector<int> indices = GetIndicesForCommand(context_index); |
| 863 // Copy the TabContents off as the indices will change as tabs are | 863 // Copy the TabContentsWrapper off as the indices will change as tabs are |
| 864 // duplicated. | 864 // duplicated. |
| 865 std::vector<TabContentsWrapper*> tabs; | 865 std::vector<TabContentsWrapper*> tabs; |
| 866 for (size_t i = 0; i < indices.size(); ++i) | 866 for (size_t i = 0; i < indices.size(); ++i) |
| 867 tabs.push_back(GetTabContentsAt(indices[i])); | 867 tabs.push_back(GetTabContentsAt(indices[i])); |
| 868 for (size_t i = 0; i < tabs.size(); ++i) { | 868 for (size_t i = 0; i < tabs.size(); ++i) { |
| 869 int index = GetIndexOfTabContents(tabs[i]); | 869 int index = GetIndexOfTabContents(tabs[i]); |
| 870 if (index != -1 && delegate_->CanDuplicateContentsAt(index)) | 870 if (index != -1 && delegate_->CanDuplicateContentsAt(index)) |
| 871 delegate_->DuplicateContentsAt(index); | 871 delegate_->DuplicateContentsAt(index); |
| 872 } | 872 } |
| 873 break; | 873 break; |
| 874 } | 874 } |
| 875 | 875 |
| 876 case CommandCloseTab: { | 876 case CommandCloseTab: { |
| 877 content::RecordAction(UserMetricsAction("TabContextMenu_CloseTab")); | 877 content::RecordAction(UserMetricsAction("TabContextMenu_CloseTab")); |
| 878 std::vector<int> indices = GetIndicesForCommand(context_index); | 878 std::vector<int> indices = GetIndicesForCommand(context_index); |
| 879 // Copy the TabContents off as the indices will change as we remove | 879 // Copy the TabContentsWrapper off as the indices will change as we remove |
| 880 // things. | 880 // things. |
| 881 std::vector<TabContentsWrapper*> tabs; | 881 std::vector<TabContentsWrapper*> tabs; |
| 882 for (size_t i = 0; i < indices.size(); ++i) | 882 for (size_t i = 0; i < indices.size(); ++i) |
| 883 tabs.push_back(GetTabContentsAt(indices[i])); | 883 tabs.push_back(GetTabContentsAt(indices[i])); |
| 884 for (size_t i = 0; i < tabs.size() && delegate_->CanCloseTab(); ++i) { | 884 for (size_t i = 0; i < tabs.size() && delegate_->CanCloseTab(); ++i) { |
| 885 int index = GetIndexOfTabContents(tabs[i]); | 885 int index = GetIndexOfTabContents(tabs[i]); |
| 886 if (index != -1) { | 886 if (index != -1) { |
| 887 CloseTabContentsAt(index, | 887 CloseTabContentsAt(index, |
| 888 CLOSE_CREATE_HISTORICAL_TAB | CLOSE_USER_GESTURE); | 888 CLOSE_CREATE_HISTORICAL_TAB | CLOSE_USER_GESTURE); |
| 889 } | 889 } |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1000 } | 1000 } |
| 1001 | 1001 |
| 1002 /////////////////////////////////////////////////////////////////////////////// | 1002 /////////////////////////////////////////////////////////////////////////////// |
| 1003 // TabStripModel, content::NotificationObserver implementation: | 1003 // TabStripModel, content::NotificationObserver implementation: |
| 1004 | 1004 |
| 1005 void TabStripModel::Observe(int type, | 1005 void TabStripModel::Observe(int type, |
| 1006 const content::NotificationSource& source, | 1006 const content::NotificationSource& source, |
| 1007 const content::NotificationDetails& details) { | 1007 const content::NotificationDetails& details) { |
| 1008 switch (type) { | 1008 switch (type) { |
| 1009 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: { | 1009 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: { |
| 1010 // Sometimes, on qemu, it seems like a TabContents object can be destroyed | 1010 // Sometimes, on qemu, it seems like a WebContents object can be destroyed |
| 1011 // while we still have a reference to it. We need to break this reference | 1011 // while we still have a reference to it. We need to break this reference |
| 1012 // here so we don't crash later. | 1012 // here so we don't crash later. |
| 1013 int index = GetWrapperIndex(content::Source<WebContents>(source).ptr()); | 1013 int index = GetWrapperIndex(content::Source<WebContents>(source).ptr()); |
| 1014 if (index != TabStripModel::kNoTab) { | 1014 if (index != TabStripModel::kNoTab) { |
| 1015 // Note that we only detach the contents here, not close it - it's | 1015 // Note that we only detach the contents here, not close it - it's |
| 1016 // already been closed. We just want to undo our bookkeeping. | 1016 // already been closed. We just want to undo our bookkeeping. |
| 1017 DetachTabContentsAt(index); | 1017 DetachTabContentsAt(index); |
| 1018 } | 1018 } |
| 1019 break; | 1019 break; |
| 1020 } | 1020 } |
| 1021 | 1021 |
| 1022 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { | 1022 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { |
| 1023 const Extension* extension = | 1023 const Extension* extension = |
| 1024 content::Details<UnloadedExtensionInfo>(details)->extension; | 1024 content::Details<UnloadedExtensionInfo>(details)->extension; |
| 1025 // Iterate backwards as we may remove items while iterating. | 1025 // Iterate backwards as we may remove items while iterating. |
| 1026 for (int i = count() - 1; i >= 0; i--) { | 1026 for (int i = count() - 1; i >= 0; i--) { |
| 1027 TabContentsWrapper* contents = GetTabContentsAt(i); | 1027 TabContentsWrapper* contents = GetTabContentsAt(i); |
| 1028 if (contents->extension_tab_helper()->extension_app() == extension) { | 1028 if (contents->extension_tab_helper()->extension_app() == extension) { |
| 1029 // The extension an app tab was created from has been nuked. Delete | 1029 // The extension an app tab was created from has been nuked. Delete |
| 1030 // the TabContents. Deleting a TabContents results in a notification | 1030 // the WebContents. Deleting a WebContents results in a notification |
| 1031 // of type TAB_CONTENTS_DESTROYED; we do the necessary cleanup in | 1031 // of type NOTIFICATION_WEB_CONTENTS_DESTROYED; we do the necessary |
| 1032 // handling that notification. | 1032 // cleanup in handling that notification. |
| 1033 | 1033 |
| 1034 InternalCloseTab(contents, i, false); | 1034 InternalCloseTab(contents, i, false); |
| 1035 } | 1035 } |
| 1036 } | 1036 } |
| 1037 break; | 1037 break; |
| 1038 } | 1038 } |
| 1039 | 1039 |
| 1040 default: | 1040 default: |
| 1041 NOTREACHED(); | 1041 NOTREACHED(); |
| 1042 } | 1042 } |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1129 bool TabStripModel::InternalCloseTabs(const std::vector<int>& in_indices, | 1129 bool TabStripModel::InternalCloseTabs(const std::vector<int>& in_indices, |
| 1130 uint32 close_types) { | 1130 uint32 close_types) { |
| 1131 if (in_indices.empty()) | 1131 if (in_indices.empty()) |
| 1132 return true; | 1132 return true; |
| 1133 | 1133 |
| 1134 std::vector<int> indices(in_indices); | 1134 std::vector<int> indices(in_indices); |
| 1135 bool retval = delegate_->CanCloseContents(&indices); | 1135 bool retval = delegate_->CanCloseContents(&indices); |
| 1136 if (indices.empty()) | 1136 if (indices.empty()) |
| 1137 return retval; | 1137 return retval; |
| 1138 | 1138 |
| 1139 // Map the indices to TabContents, that way if deleting a tab deletes other | 1139 // Map the indices to TabContentsWrapper, that way if deleting a tab deletes |
| 1140 // tabs we're ok. Crashes seem to indicate during tab deletion other tabs are | 1140 // other tabs we're ok. Crashes seem to indicate during tab deletion other |
| 1141 // getting removed. | 1141 // tabs are getting removed. |
| 1142 std::vector<TabContentsWrapper*> tabs; | 1142 std::vector<TabContentsWrapper*> tabs; |
| 1143 for (size_t i = 0; i < indices.size(); ++i) | 1143 for (size_t i = 0; i < indices.size(); ++i) |
| 1144 tabs.push_back(GetContentsAt(indices[i])); | 1144 tabs.push_back(GetContentsAt(indices[i])); |
| 1145 | 1145 |
| 1146 // We only try the fast shutdown path if the whole browser process is *not* | 1146 // We only try the fast shutdown path if the whole browser process is *not* |
| 1147 // shutting down. Fast shutdown during browser termination is handled in | 1147 // shutting down. Fast shutdown during browser termination is handled in |
| 1148 // BrowserShutdown. | 1148 // BrowserShutdown. |
| 1149 if (browser_shutdown::GetShutdownType() == browser_shutdown::NOT_VALID) { | 1149 if (browser_shutdown::GetShutdownType() == browser_shutdown::NOT_VALID) { |
| 1150 // Construct a map of processes to the number of associated tabs that are | 1150 // Construct a map of processes to the number of associated tabs that are |
| 1151 // closing. | 1151 // closing. |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1206 int index, | 1206 int index, |
| 1207 bool create_historical_tabs) { | 1207 bool create_historical_tabs) { |
| 1208 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, | 1208 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, |
| 1209 TabClosingAt(this, contents, index)); | 1209 TabClosingAt(this, contents, index)); |
| 1210 | 1210 |
| 1211 // Ask the delegate to save an entry for this tab in the historical tab | 1211 // Ask the delegate to save an entry for this tab in the historical tab |
| 1212 // database if applicable. | 1212 // database if applicable. |
| 1213 if (create_historical_tabs) | 1213 if (create_historical_tabs) |
| 1214 delegate_->CreateHistoricalTab(contents); | 1214 delegate_->CreateHistoricalTab(contents); |
| 1215 | 1215 |
| 1216 // Deleting the TabContents will call back to us via NotificationObserver | 1216 // Deleting the TabContentsWrapper will call back to us via |
| 1217 // and detach it. | 1217 // NotificationObserver and detach it. |
| 1218 delete contents; | 1218 delete contents; |
| 1219 } | 1219 } |
| 1220 | 1220 |
| 1221 TabContentsWrapper* TabStripModel::GetContentsAt(int index) const { | 1221 TabContentsWrapper* TabStripModel::GetContentsAt(int index) const { |
| 1222 CHECK(ContainsIndex(index)) << | 1222 CHECK(ContainsIndex(index)) << |
| 1223 "Failed to find: " << index << " in: " << count() << " entries."; | 1223 "Failed to find: " << index << " in: " << count() << " entries."; |
| 1224 return contents_data_.at(index)->contents; | 1224 return contents_data_.at(index)->contents; |
| 1225 } | 1225 } |
| 1226 | 1226 |
| 1227 void TabStripModel::NotifyIfTabDeactivated(TabContentsWrapper* contents) { | 1227 void TabStripModel::NotifyIfTabDeactivated(TabContentsWrapper* contents) { |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1344 void TabStripModel::ForgetOpenersAndGroupsReferencing( | 1344 void TabStripModel::ForgetOpenersAndGroupsReferencing( |
| 1345 const NavigationController* tab) { | 1345 const NavigationController* tab) { |
| 1346 for (TabContentsDataVector::const_iterator i = contents_data_.begin(); | 1346 for (TabContentsDataVector::const_iterator i = contents_data_.begin(); |
| 1347 i != contents_data_.end(); ++i) { | 1347 i != contents_data_.end(); ++i) { |
| 1348 if ((*i)->group == tab) | 1348 if ((*i)->group == tab) |
| 1349 (*i)->group = NULL; | 1349 (*i)->group = NULL; |
| 1350 if ((*i)->opener == tab) | 1350 if ((*i)->opener == tab) |
| 1351 (*i)->opener = NULL; | 1351 (*i)->opener = NULL; |
| 1352 } | 1352 } |
| 1353 } | 1353 } |
| OLD | NEW |