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

Side by Side Diff: chrome/browser/extensions/extension_shelf_model.cc

Issue 3129003: remove toolstrips (Closed)
Patch Set: merge Created 10 years, 4 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/extensions/extension_shelf_model.h"
6
7 #include "base/stl_util-inl.h"
8 #include "chrome/browser/browser.h"
9 #include "chrome/browser/profile.h"
10 #include "chrome/browser/extensions/extension_host.h"
11 #include "chrome/browser/extensions/extension_process_manager.h"
12 #include "chrome/browser/extensions/extension_toolstrip_api.h"
13 #include "chrome/browser/extensions/extensions_service.h"
14 #include "chrome/browser/renderer_host/render_view_host.h"
15 #include "chrome/common/extensions/extension.h"
16 #include "chrome/common/notification_service.h"
17
18 ExtensionShelfModel::ExtensionShelfModel(Browser* browser)
19 : browser_(browser), ready_(false) {
20 // Watch extensions loaded and unloaded notifications.
21 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
22 NotificationService::AllSources());
23 registrar_.Add(this, NotificationType::EXTENSION_LOADED,
24 NotificationService::AllSources());
25 registrar_.Add(this, NotificationType::EXTENSIONS_READY,
26 NotificationService::AllSources());
27
28 // Add any already-loaded extensions now, since we missed the notification for
29 // those.
30 ExtensionsService* service = browser_->profile()->GetExtensionsService();
31 if (service) { // This can be null in unit tests.
32 prefs_ = browser_->profile()->GetExtensionsService()->extension_prefs();
33 registrar_.Add(this, NotificationType::EXTENSION_SHELF_MODEL_CHANGED,
34 Source<ExtensionPrefs>(prefs_));
35 ready_ = service->is_ready();
36 if (ready_) {
37 AddExtensions(service->extensions());
38 SortToolstrips();
39 }
40 }
41 }
42
43 ExtensionShelfModel::~ExtensionShelfModel() {
44 FOR_EACH_OBSERVER(ExtensionShelfModelObserver, observers_,
45 ShelfModelDeleting());
46
47 observers_.Clear();
48
49 for (iterator t = toolstrips_.begin(); t != toolstrips_.end(); ++t)
50 delete t->host;
51 toolstrips_.clear();
52 }
53
54 void ExtensionShelfModel::AddObserver(ExtensionShelfModelObserver* observer) {
55 observers_.AddObserver(observer);
56 }
57
58 void ExtensionShelfModel::RemoveObserver(
59 ExtensionShelfModelObserver* observer) {
60 observers_.RemoveObserver(observer);
61 }
62
63 void ExtensionShelfModel::AppendToolstrip(const ToolstripItem& toolstrip) {
64 InsertToolstripAt(count(), toolstrip);
65 }
66
67 void ExtensionShelfModel::InsertToolstripAt(int index,
68 const ToolstripItem& toolstrip) {
69 toolstrips_.insert(toolstrips_.begin() + index, toolstrip);
70 if (ready_) {
71 FOR_EACH_OBSERVER(ExtensionShelfModelObserver, observers_,
72 ToolstripInsertedAt(toolstrip.host, index));
73 }
74 }
75
76 void ExtensionShelfModel::RemoveToolstripAt(int index) {
77 ExtensionHost* host = ToolstripAt(index).host;
78 FOR_EACH_OBSERVER(ExtensionShelfModelObserver, observers_,
79 ToolstripRemovingAt(host, index));
80 toolstrips_.erase(toolstrips_.begin() + index);
81 delete host;
82 }
83
84 void ExtensionShelfModel::MoveToolstripAt(int index, int to_index) {
85 DCHECK(index >= 0);
86 DCHECK(to_index >= 0);
87 if (index == to_index)
88 return;
89
90 ToolstripItem toolstrip = toolstrips_[index];
91 toolstrips_.erase(toolstrips_.begin() + index);
92 toolstrips_.insert(toolstrips_.begin() + to_index, toolstrip);
93
94 FOR_EACH_OBSERVER(ExtensionShelfModelObserver, observers_,
95 ToolstripMoved(toolstrip.host, index, to_index));
96
97 UpdatePrefs();
98 }
99
100 int ExtensionShelfModel::IndexOfHost(ExtensionHost* host) {
101 for (iterator i = toolstrips_.begin(); i != toolstrips_.end(); ++i) {
102 if (i->host == host)
103 return i - toolstrips_.begin();
104 }
105 return -1;
106 }
107
108 ExtensionShelfModel::iterator ExtensionShelfModel::ToolstripForHost(
109 ExtensionHost* host) {
110 for (iterator i = toolstrips_.begin(); i != toolstrips_.end(); ++i) {
111 if (i->host == host)
112 return i;
113 }
114 return toolstrips_.end();
115 }
116
117 const ExtensionShelfModel::ToolstripItem& ExtensionShelfModel::ToolstripAt(
118 int index) {
119 DCHECK(index >= 0);
120 return toolstrips_[index];
121 }
122
123 void ExtensionShelfModel::SetToolstripDataAt(int index, void* data) {
124 DCHECK(index >= 0);
125 toolstrips_[index].data = data;
126 }
127
128 void ExtensionShelfModel::ExpandToolstrip(iterator toolstrip,
129 const GURL& url, int height) {
130 if (toolstrip == end())
131 return;
132 toolstrip->height = height;
133 toolstrip->url = url;
134 FOR_EACH_OBSERVER(ExtensionShelfModelObserver, observers_,
135 ToolstripChanged(toolstrip));
136 int routing_id = toolstrip->host->render_view_host()->routing_id();
137 ToolstripEventRouter::OnToolstripExpanded(browser_->profile(),
138 routing_id,
139 url, height);
140 toolstrip->host->SetRenderViewType(ViewType::EXTENSION_MOLE);
141 }
142
143 void ExtensionShelfModel::CollapseToolstrip(iterator toolstrip,
144 const GURL& url) {
145 if (toolstrip == end())
146 return;
147 toolstrip->height = 0;
148 toolstrip->url = url;
149 FOR_EACH_OBSERVER(ExtensionShelfModelObserver, observers_,
150 ToolstripChanged(toolstrip));
151 int routing_id = toolstrip->host->render_view_host()->routing_id();
152 ToolstripEventRouter::OnToolstripCollapsed(browser_->profile(),
153 routing_id,
154 url);
155 toolstrip->host->SetRenderViewType(ViewType::EXTENSION_TOOLSTRIP);
156 }
157
158 void ExtensionShelfModel::Observe(NotificationType type,
159 const NotificationSource& source,
160 const NotificationDetails& details) {
161 switch (type.value) {
162 case NotificationType::EXTENSION_LOADED:
163 if (ready_)
164 AddExtension(Details<Extension>(details).ptr());
165 break;
166 case NotificationType::EXTENSION_UNLOADED:
167 RemoveExtension(Details<Extension>(details).ptr());
168 break;
169 case NotificationType::EXTENSIONS_READY:
170 if (browser_->profile()->GetExtensionsService()) {
171 AddExtensions(
172 browser_->profile()->GetExtensionsService()->extensions());
173 SortToolstrips();
174 }
175 ready_ = true;
176 break;
177 case NotificationType::EXTENSION_SHELF_MODEL_CHANGED:
178 // Ignore changes that this model originated.
179 if (Details<ExtensionShelfModel>(details).ptr() != this)
180 SortToolstrips();
181 break;
182 default:
183 DCHECK(false) << "Unhandled notification of type: " << type.value;
184 break;
185 }
186 }
187
188 void ExtensionShelfModel::AddExtension(Extension* extension) {
189 ExtensionProcessManager* manager =
190 browser_->profile()->GetExtensionProcessManager();
191 DCHECK(manager);
192 if (!manager)
193 return;
194
195 for (std::vector<Extension::ToolstripInfo>::const_iterator toolstrip =
196 extension->toolstrips().begin();
197 toolstrip != extension->toolstrips().end(); ++toolstrip) {
198 GURL url = toolstrip->toolstrip;
199 ToolstripItem item;
200 item.host = manager->CreateToolstrip(extension, url, browser_);
201 item.info = *toolstrip;
202 item.data = NULL;
203 item.height = 0;
204 AppendToolstrip(item);
205 }
206 }
207
208 void ExtensionShelfModel::AddExtensions(const ExtensionList* extensions) {
209 if (extensions->size()) {
210 ExtensionList::const_iterator extension = extensions->begin();
211 for (; extension != extensions->end(); ++extension)
212 AddExtension(*extension);
213 }
214 }
215
216 void ExtensionShelfModel::RemoveExtension(Extension* extension) {
217 bool changed = false;
218 for (int i = count() - 1; i >= 0; --i) {
219 ExtensionHost* t = ToolstripAt(i).host;
220 if (t->extension()->id() == extension->id()) {
221 changed = true;
222 RemoveToolstripAt(i);
223
224 // There can be more than one toolstrip per extension, so we have to keep
225 // looping even after finding a match.
226 }
227 }
228 if (changed)
229 UpdatePrefs();
230 }
231
232 void ExtensionShelfModel::UpdatePrefs() {
233 if (!prefs_)
234 return;
235
236 // It's easiest to just rebuild the list each time.
237 ExtensionPrefs::URLList urls;
238 for (int i = 0; i < count(); ++i)
239 urls.push_back(ToolstripAt(i).host->GetURL());
240 prefs_->SetShelfToolstripOrder(urls);
241
242 NotificationService::current()->Notify(
243 NotificationType::EXTENSION_SHELF_MODEL_CHANGED,
244 Source<ExtensionPrefs>(prefs_),
245 Details<ExtensionShelfModel>(this));
246 }
247
248 void ExtensionShelfModel::SortToolstrips() {
249 ExtensionPrefs::URLList urls = prefs_->GetShelfToolstripOrder();
250 ToolstripList copy =
251 ToolstripList(toolstrips_.begin(), toolstrips_.end());
252 toolstrips_.clear();
253
254 // Go through the urls and find the matching toolstrip, re-adding it to the
255 // new list in the proper order.
256 for (size_t i = 0; i < urls.size(); ++i) {
257 GURL& url = urls[i];
258 for (iterator toolstrip = copy.begin();
259 toolstrip != copy.end(); ++toolstrip) {
260 if (url == toolstrip->host->GetURL()) {
261 // Note that it's technically possible for the same URL to appear in
262 // multiple toolstrips, so we don't do any testing for uniqueness.
263 toolstrips_.push_back(*toolstrip);
264
265 // Remove the toolstrip from the list so we don't have to iterate over
266 // it next time.
267 copy.erase(toolstrip);
268 break;
269 }
270 }
271 }
272
273 // Any toolstrips remaining in |copy| were somehow missing from the prefs,
274 // so just append them to the end.
275 for (iterator toolstrip = copy.begin();
276 toolstrip != copy.end(); ++toolstrip) {
277 toolstrips_.push_back(*toolstrip);
278 }
279
280 FOR_EACH_OBSERVER(ExtensionShelfModelObserver, observers_,
281 ShelfModelReloaded());
282 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_shelf_model.h ('k') | chrome/browser/extensions/extension_shelf_model_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698