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/extensions/extension_toolbar_model.h" | 5 #include "chrome/browser/extensions/extension_toolbar_model.h" |
6 | 6 |
7 #include "chrome/browser/extensions/extension_browser_event_router.h" | 7 #include "chrome/browser/extensions/extension_browser_event_router.h" |
8 #include "chrome/browser/extensions/extension_prefs.h" | 8 #include "chrome/browser/extensions/extension_prefs.h" |
9 #include "chrome/browser/extensions/extension_service.h" | 9 #include "chrome/browser/extensions/extension_service.h" |
10 #include "chrome/browser/extensions/extension_tab_helper.h" | 10 #include "chrome/browser/extensions/extension_tab_helper.h" |
11 #include "chrome/browser/extensions/extension_tab_util.h" | 11 #include "chrome/browser/extensions/extension_tab_util.h" |
12 #include "chrome/browser/prefs/pref_service.h" | 12 #include "chrome/browser/prefs/pref_service.h" |
13 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
14 #include "chrome/browser/ui/browser.h" | 14 #include "chrome/browser/ui/browser.h" |
15 #include "chrome/browser/ui/tab_contents/tab_contents.h" | 15 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
16 #include "chrome/common/chrome_notification_types.h" | 16 #include "chrome/common/chrome_notification_types.h" |
17 #include "chrome/common/extensions/extension.h" | 17 #include "chrome/common/extensions/extension.h" |
18 #include "chrome/common/extensions/extension_switch_utils.h" | |
18 #include "chrome/common/pref_names.h" | 19 #include "chrome/common/pref_names.h" |
19 #include "content/public/browser/notification_details.h" | 20 #include "content/public/browser/notification_details.h" |
20 #include "content/public/browser/notification_source.h" | 21 #include "content/public/browser/notification_source.h" |
21 #include "content/public/browser/web_contents.h" | 22 #include "content/public/browser/web_contents.h" |
22 | 23 |
23 using extensions::Extension; | 24 using extensions::Extension; |
24 using extensions::ExtensionList; | 25 using extensions::ExtensionList; |
25 | 26 |
26 ExtensionToolbarModel::ExtensionToolbarModel(ExtensionService* service) | 27 ExtensionToolbarModel::ExtensionToolbarModel(ExtensionService* service) |
27 : service_(service), | 28 : service_(service), |
(...skipping 25 matching lines...) Expand all Loading... | |
53 observers_.RemoveObserver(observer); | 54 observers_.RemoveObserver(observer); |
54 } | 55 } |
55 | 56 |
56 void ExtensionToolbarModel::MoveBrowserAction(const Extension* extension, | 57 void ExtensionToolbarModel::MoveBrowserAction(const Extension* extension, |
57 int index) { | 58 int index) { |
58 ExtensionList::iterator pos = std::find(begin(), end(), extension); | 59 ExtensionList::iterator pos = std::find(begin(), end(), extension); |
59 if (pos == end()) { | 60 if (pos == end()) { |
60 NOTREACHED(); | 61 NOTREACHED(); |
61 return; | 62 return; |
62 } | 63 } |
63 toolitems_.erase(pos); | 64 toolbar_items_.erase(pos); |
64 | 65 |
65 int i = 0; | 66 int i = 0; |
66 bool inserted = false; | 67 bool inserted = false; |
67 for (ExtensionList::iterator iter = begin(); iter != end(); ++iter, ++i) { | 68 for (ExtensionList::iterator iter = begin(); iter != end(); ++iter, ++i) { |
68 if (i == index) { | 69 if (i == index) { |
69 toolitems_.insert(iter, make_scoped_refptr(extension)); | 70 toolbar_items_.insert(iter, make_scoped_refptr(extension)); |
70 inserted = true; | 71 inserted = true; |
71 break; | 72 break; |
72 } | 73 } |
73 } | 74 } |
74 | 75 |
75 if (!inserted) { | 76 if (!inserted) { |
76 DCHECK_EQ(index, static_cast<int>(toolitems_.size())); | 77 DCHECK_EQ(index, static_cast<int>(toolbar_items_.size())); |
77 index = toolitems_.size(); | 78 index = toolbar_items_.size(); |
78 | 79 |
79 toolitems_.push_back(make_scoped_refptr(extension)); | 80 toolbar_items_.push_back(make_scoped_refptr(extension)); |
80 } | 81 } |
81 | 82 |
82 FOR_EACH_OBSERVER(Observer, observers_, BrowserActionMoved(extension, index)); | 83 FOR_EACH_OBSERVER(Observer, observers_, BrowserActionMoved(extension, index)); |
83 | 84 |
84 UpdatePrefs(); | 85 UpdatePrefs(); |
85 } | 86 } |
86 | 87 |
87 ExtensionToolbarModel::Action ExtensionToolbarModel::ExecuteBrowserAction( | 88 ExtensionToolbarModel::Action ExtensionToolbarModel::ExecuteBrowserAction( |
88 const Extension* extension, | 89 const Extension* extension, |
89 Browser* browser, | 90 Browser* browser, |
(...skipping 24 matching lines...) Expand all Loading... | |
114 void ExtensionToolbarModel::SetVisibleIconCount(int count) { | 115 void ExtensionToolbarModel::SetVisibleIconCount(int count) { |
115 visible_icon_count_ = count == static_cast<int>(size()) ? -1 : count; | 116 visible_icon_count_ = count == static_cast<int>(size()) ? -1 : count; |
116 prefs_->SetInteger(prefs::kExtensionToolbarSize, visible_icon_count_); | 117 prefs_->SetInteger(prefs::kExtensionToolbarSize, visible_icon_count_); |
117 } | 118 } |
118 | 119 |
119 void ExtensionToolbarModel::Observe( | 120 void ExtensionToolbarModel::Observe( |
120 int type, | 121 int type, |
121 const content::NotificationSource& source, | 122 const content::NotificationSource& source, |
122 const content::NotificationDetails& details) { | 123 const content::NotificationDetails& details) { |
123 if (type == chrome::NOTIFICATION_EXTENSIONS_READY) { | 124 if (type == chrome::NOTIFICATION_EXTENSIONS_READY) { |
124 InitializeExtensionList(); | 125 InitializeExtensionLists(); |
125 return; | 126 return; |
126 } | 127 } |
127 | 128 |
128 if (!service_->is_ready()) | 129 if (!service_->is_ready()) |
129 return; | 130 return; |
130 | 131 |
131 const Extension* extension = NULL; | 132 const Extension* extension = NULL; |
132 if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED) { | 133 if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED) { |
133 extension = content::Details<extensions::UnloadedExtensionInfo>( | 134 extension = content::Details<extensions::UnloadedExtensionInfo>( |
134 details)->extension; | 135 details)->extension; |
135 } else { | 136 } else { |
136 extension = content::Details<const Extension>(details).ptr(); | 137 extension = content::Details<const Extension>(details).ptr(); |
137 } | 138 } |
138 if (type == chrome::NOTIFICATION_EXTENSION_LOADED) { | 139 if (type == chrome::NOTIFICATION_EXTENSION_LOADED) { |
139 // We don't want to add the same extension twice. It may have already been | 140 // We don't want to add the same extension twice. It may have already been |
140 // added by EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED below, if the user | 141 // added by EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED below, if the user |
141 // hides the browser action and then disables and enables the extension. | 142 // hides the browser action and then disables and enables the extension. |
142 for (size_t i = 0; i < toolitems_.size(); i++) { | 143 for (size_t i = 0; i < toolbar_items_.size(); i++) { |
143 if (toolitems_[i].get() == extension) | 144 if (toolbar_items_[i].get() == extension) |
144 return; // Already exists. | 145 return; // Already exists. |
145 } | 146 } |
146 if (service_->extension_prefs()->GetBrowserActionVisibility(extension)) | 147 if (service_->extension_prefs()->GetBrowserActionVisibility(extension)) |
147 AddExtension(extension); | 148 AddExtension(extension); |
148 } else if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED) { | 149 } else if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED) { |
149 RemoveExtension(extension); | 150 RemoveExtension(extension); |
150 } else if ( | 151 } else if ( |
151 type == | 152 type == |
152 chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED) { | 153 chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED) { |
153 if (service_->extension_prefs()->GetBrowserActionVisibility(extension)) | 154 if (service_->extension_prefs()->GetBrowserActionVisibility(extension)) |
154 AddExtension(extension); | 155 AddExtension(extension); |
155 else | 156 else |
156 RemoveExtension(extension); | 157 RemoveExtension(extension); |
157 } else { | 158 } else { |
158 NOTREACHED() << "Received unexpected notification"; | 159 NOTREACHED() << "Received unexpected notification"; |
159 } | 160 } |
160 } | 161 } |
161 | 162 |
162 void ExtensionToolbarModel::AddExtension(const Extension* extension) { | 163 void ExtensionToolbarModel::AddExtension(const Extension* extension) { |
163 // We only care about extensions with browser actions. | 164 // We only care about extensions with browser actions. |
164 if (!extension->browser_action()) | 165 if (!extension->browser_action()) |
165 return; | 166 return; |
166 | 167 |
167 if (extension->id() == last_extension_removed_ && | 168 if (extension->id() == last_extension_removed_ && |
168 last_extension_removed_index_ < toolitems_.size()) { | 169 last_extension_removed_index_ < toolbar_items_.size()) { |
169 toolitems_.insert(begin() + last_extension_removed_index_, | 170 toolbar_items_.insert(begin() + last_extension_removed_index_, |
170 make_scoped_refptr(extension)); | 171 make_scoped_refptr(extension)); |
171 FOR_EACH_OBSERVER(Observer, observers_, | 172 FOR_EACH_OBSERVER(Observer, observers_, |
172 BrowserActionAdded(extension, last_extension_removed_index_)); | 173 BrowserActionAdded(extension, last_extension_removed_index_)); |
173 } else { | 174 } else { |
174 toolitems_.push_back(make_scoped_refptr(extension)); | 175 toolbar_items_.push_back(make_scoped_refptr(extension)); |
175 FOR_EACH_OBSERVER(Observer, observers_, | 176 FOR_EACH_OBSERVER(Observer, observers_, |
176 BrowserActionAdded(extension, toolitems_.size() - 1)); | 177 BrowserActionAdded(extension, toolbar_items_.size() - 1)); |
177 } | 178 } |
178 | 179 |
179 last_extension_removed_ = ""; | 180 last_extension_removed_ = ""; |
180 last_extension_removed_index_ = -1; | 181 last_extension_removed_index_ = -1; |
181 | 182 |
182 UpdatePrefs(); | 183 UpdatePrefs(); |
183 } | 184 } |
184 | 185 |
185 void ExtensionToolbarModel::RemoveExtension(const Extension* extension) { | 186 void ExtensionToolbarModel::RemoveExtension(const Extension* extension) { |
186 ExtensionList::iterator pos = std::find(begin(), end(), extension); | 187 ExtensionList::iterator pos = std::find(begin(), end(), extension); |
187 if (pos == end()) { | 188 if (pos == end()) { |
188 return; | 189 return; |
189 } | 190 } |
190 | 191 |
191 last_extension_removed_ = extension->id(); | 192 last_extension_removed_ = extension->id(); |
192 last_extension_removed_index_ = pos - begin(); | 193 last_extension_removed_index_ = pos - begin(); |
193 | 194 |
194 toolitems_.erase(pos); | 195 toolbar_items_.erase(pos); |
195 FOR_EACH_OBSERVER(Observer, observers_, | 196 FOR_EACH_OBSERVER(Observer, observers_, |
196 BrowserActionRemoved(extension)); | 197 BrowserActionRemoved(extension)); |
197 | 198 |
198 UpdatePrefs(); | 199 UpdatePrefs(); |
199 } | 200 } |
200 | 201 |
201 // Combine the currently enabled extensions that have browser actions (which | 202 // Combine the currently enabled extensions that have browser actions (which |
202 // we get from the ExtensionService) with the ordering we get from the | 203 // we get from the ExtensionService) with the ordering we get from the |
203 // pref service. For robustness we use a somewhat inefficient process: | 204 // pref service. For robustness we use a somewhat inefficient process: |
204 // 1. Create a vector of extensions sorted by their pref values. This vector may | 205 // 1. Create a vector of extensions sorted by their pref values. This vector may |
205 // have holes. | 206 // have holes. |
206 // 2. Create a vector of extensions that did not have a pref value. | 207 // 2. Create a vector of extensions that did not have a pref value. |
207 // 3. Remove holes from the sorted vector and append the unsorted vector. | 208 // 3. Remove holes from the sorted vector and append the unsorted vector. |
208 void ExtensionToolbarModel::InitializeExtensionList() { | 209 void ExtensionToolbarModel::InitializeExtensionLists() { |
209 DCHECK(service_->is_ready()); | 210 DCHECK(service_->is_ready()); |
210 | 211 |
211 std::vector<std::string> pref_order = service_->extension_prefs()-> | 212 if (extensions::switch_utils::IsActionBoxEnabled()) |
212 GetToolbarOrder(); | 213 PopulateForActionBoxMode(); |
214 else | |
215 PopulateForNonActionBoxMode(); | |
216 | |
217 UpdatePrefs(); | |
218 | |
219 extensions_initialized_ = true; | |
220 FOR_EACH_OBSERVER(Observer, observers_, ModelLoaded()); | |
221 } | |
222 | |
223 void ExtensionToolbarModel::PopulateForActionBoxMode() { | |
224 const std::vector<std::string> bar_order = | |
Aaron Boodman
2012/07/02 22:41:34
Nit: toolbar_order?
yefimt
2012/07/11 22:34:34
Done.
| |
225 service_->extension_prefs()->GetToolbarOrder(); | |
226 const std::vector<std::string> action_box_order = | |
227 service_->extension_prefs()->GetActionBoxOrder(); | |
228 | |
229 // Items that have a pref for their position. | |
230 ExtensionList bar_sorted; | |
231 bar_sorted.resize(bar_order.size(), NULL); | |
232 ExtensionList action_box_sorted; | |
233 action_box_sorted.resize(action_box_order.size(), NULL); | |
234 | |
235 // The items that don't have a pref for their position. | |
236 ExtensionList bar_unsorted; | |
237 ExtensionList action_box_unsorted; | |
238 | |
239 // Create the lists. | |
240 for (ExtensionSet::const_iterator it = service_->extensions()->begin(); | |
241 it != service_->extensions()->end(); ++it) { | |
242 const Extension* extension = *it; | |
243 if (!extension->browser_action()) | |
244 continue; | |
245 | |
246 bool show_in_toolbar = | |
247 service_->extension_prefs()->GetBrowserActionVisibility(extension); | |
Aaron Boodman
2012/07/02 22:41:34
Do we need the pinned preference? Is it enough to
yefimt
2012/07/11 22:34:34
yes, I think pinned pref could be removed.
I've ch
| |
248 | |
249 if (show_in_toolbar) | |
250 AddToProperList(extension, bar_order, &bar_sorted, &bar_unsorted); | |
251 else | |
252 AddToProperList(extension, action_box_order, &action_box_sorted, | |
253 &action_box_unsorted); | |
254 } | |
255 | |
256 MergeLists(action_box_sorted, action_box_unsorted, &action_box_menu_items_); | |
257 MergeLists(bar_sorted, bar_unsorted, &toolbar_items_); | |
258 | |
259 // Inform observers. | |
260 for (size_t i = 0; i < toolbar_items_.size(); i++) { | |
261 FOR_EACH_OBSERVER(Observer, observers_, | |
262 BrowserActionAdded(action_box_menu_items_[i], i)); | |
263 FOR_EACH_OBSERVER(Observer, observers_, | |
264 BrowserActionAdded(toolbar_items_[i], i)); | |
265 } | |
266 } | |
267 | |
268 void ExtensionToolbarModel::AddToProperList(const Extension* extension, | |
269 const std::vector<std::string>& order, | |
270 ExtensionList* sorted, | |
271 ExtensionList* unsorted) { | |
272 std::vector<std::string>::const_iterator pos = | |
273 std::find(order.begin(), order.end(), extension->id()); | |
274 if (pos != order.end()) { | |
275 int index = std::distance(order.begin(), pos); | |
276 sorted->at(index) = extension; | |
Aaron Boodman
2012/07/02 22:41:34
Nit: clearer to just say sorted[index] = extension
yefimt
2012/07/11 22:34:34
sorted is a pointer so it would be (*sorted)[index
tfarina
2012/07/12 01:21:43
No, don't use std::vector<T>::at.
See Peter's rec
yefimt
2012/07/13 19:59:20
Done.
| |
277 } else { | |
278 unsorted->push_back(make_scoped_refptr(extension)); | |
279 } | |
280 } | |
281 | |
282 void ExtensionToolbarModel::MergeLists(const ExtensionList& sorted, | |
283 const ExtensionList& unsorted, | |
284 ExtensionList* result_list) { | |
285 result_list->reserve(sorted.size() + unsorted.size()); | |
286 for (ExtensionList::const_iterator iter = sorted.begin(); | |
287 iter != sorted.end(); | |
288 ++iter) { | |
289 if (*iter != NULL) | |
290 result_list->push_back(*iter); | |
291 } | |
292 result_list->insert(result_list->end(), unsorted.begin(), unsorted.end()); | |
293 } | |
294 | |
295 void ExtensionToolbarModel::PopulateForNonActionBoxMode() { | |
296 const std::vector<std::string> pref_order = | |
297 service_->extension_prefs()->GetToolbarOrder(); | |
213 // Items that have a pref for their position. | 298 // Items that have a pref for their position. |
214 ExtensionList sorted; | 299 ExtensionList sorted; |
215 sorted.resize(pref_order.size(), NULL); | 300 sorted.resize(pref_order.size(), NULL); |
216 // The items that don't have a pref for their position. | 301 // The items that don't have a pref for their position. |
217 ExtensionList unsorted; | 302 ExtensionList unsorted; |
218 | 303 |
219 // Create the lists. | 304 // Create the lists. |
220 for (ExtensionSet::const_iterator it = service_->extensions()->begin(); | 305 for (ExtensionSet::const_iterator it = service_->extensions()->begin(); |
221 it != service_->extensions()->end(); ++it) { | 306 it != service_->extensions()->end(); ++it) { |
222 const Extension* extension = *it; | 307 const Extension* extension = *it; |
223 if (!extension->browser_action()) | 308 if (!extension->browser_action()) |
224 continue; | 309 continue; |
225 if (!service_->extension_prefs()->GetBrowserActionVisibility(extension)) | 310 if (!service_->extension_prefs()->GetBrowserActionVisibility(extension)) |
226 continue; | 311 continue; |
227 | 312 |
228 std::vector<std::string>::iterator pos = | 313 AddToProperList(extension, pref_order, &sorted, &unsorted); |
229 std::find(pref_order.begin(), pref_order.end(), extension->id()); | |
230 if (pos != pref_order.end()) { | |
231 int index = std::distance(pref_order.begin(), pos); | |
232 sorted[index] = extension; | |
233 } else { | |
234 unsorted.push_back(make_scoped_refptr(extension)); | |
235 } | |
236 } | 314 } |
237 | 315 |
238 // Merge the lists. | 316 MergeLists(sorted, unsorted, &toolbar_items_); |
239 toolitems_.reserve(sorted.size() + unsorted.size()); | |
240 for (ExtensionList::iterator iter = sorted.begin(); | |
241 iter != sorted.end(); ++iter) { | |
242 if (*iter != NULL) | |
243 toolitems_.push_back(*iter); | |
244 } | |
245 toolitems_.insert(toolitems_.end(), unsorted.begin(), unsorted.end()); | |
246 | 317 |
247 // Inform observers. | 318 // Inform observers. |
248 for (size_t i = 0; i < toolitems_.size(); i++) { | 319 for (size_t i = 0; i < toolbar_items_.size(); i++) { |
249 FOR_EACH_OBSERVER(Observer, observers_, | 320 FOR_EACH_OBSERVER(Observer, observers_, |
250 BrowserActionAdded(toolitems_[i], i)); | 321 BrowserActionAdded(toolbar_items_[i], i)); |
251 } | 322 } |
252 | |
253 UpdatePrefs(); | |
254 | |
255 extensions_initialized_ = true; | |
256 FOR_EACH_OBSERVER(Observer, observers_, ModelLoaded()); | |
257 } | 323 } |
258 | 324 |
259 void ExtensionToolbarModel::UpdatePrefs() { | 325 void ExtensionToolbarModel::UpdatePrefs() { |
260 if (!service_->extension_prefs()) | 326 if (!service_->extension_prefs()) |
261 return; | 327 return; |
262 | 328 |
263 std::vector<std::string> ids; | 329 std::vector<std::string> ids; |
264 ids.reserve(toolitems_.size()); | 330 ids.reserve(toolbar_items_.size()); |
265 for (ExtensionList::iterator iter = begin(); iter != end(); ++iter) | 331 for (ExtensionList::iterator iter = begin(); iter != end(); ++iter) |
266 ids.push_back((*iter)->id()); | 332 ids.push_back((*iter)->id()); |
267 service_->extension_prefs()->SetToolbarOrder(ids); | 333 service_->extension_prefs()->SetToolbarOrder(ids); |
334 | |
335 ids.clear(); | |
336 ids.reserve(action_box_menu_items_.size()); | |
337 for (size_t i = 0; i < action_box_menu_items_.size(); ++i) | |
338 ids.push_back(action_box_menu_items_[i]->id()); | |
339 service_->extension_prefs()->SetActionBoxOrder(ids); | |
268 } | 340 } |
269 | 341 |
270 const Extension* ExtensionToolbarModel::GetExtensionByIndex(int index) const { | 342 const Extension* ExtensionToolbarModel::GetExtensionByIndex(int index) const { |
271 return toolitems_[index]; | 343 return toolbar_items_[index]; |
272 } | 344 } |
273 | 345 |
274 int ExtensionToolbarModel::IncognitoIndexToOriginal(int incognito_index) { | 346 int ExtensionToolbarModel::IncognitoIndexToOriginal(int incognito_index) { |
275 int original_index = 0, i = 0; | 347 int original_index = 0, i = 0; |
276 for (ExtensionList::iterator iter = begin(); iter != end(); | 348 for (ExtensionList::iterator iter = begin(); iter != end(); |
277 ++iter, ++original_index) { | 349 ++iter, ++original_index) { |
278 if (service_->IsIncognitoEnabled((*iter)->id())) { | 350 if (service_->IsIncognitoEnabled((*iter)->id())) { |
279 if (incognito_index == i) | 351 if (incognito_index == i) |
280 break; | 352 break; |
281 ++i; | 353 ++i; |
282 } | 354 } |
283 } | 355 } |
284 return original_index; | 356 return original_index; |
285 } | 357 } |
286 | 358 |
287 int ExtensionToolbarModel::OriginalIndexToIncognito(int original_index) { | 359 int ExtensionToolbarModel::OriginalIndexToIncognito(int original_index) { |
288 int incognito_index = 0, i = 0; | 360 int incognito_index = 0, i = 0; |
289 for (ExtensionList::iterator iter = begin(); iter != end(); | 361 for (ExtensionList::iterator iter = begin(); iter != end(); |
290 ++iter, ++i) { | 362 ++iter, ++i) { |
291 if (original_index == i) | 363 if (original_index == i) |
292 break; | 364 break; |
293 if (service_->IsIncognitoEnabled((*iter)->id())) | 365 if (service_->IsIncognitoEnabled((*iter)->id())) |
294 ++incognito_index; | 366 ++incognito_index; |
295 } | 367 } |
296 return incognito_index; | 368 return incognito_index; |
297 } | 369 } |
370 | |
371 const Extension* ExtensionToolbarModel::GetActionBoxExtensionByIndex( | |
372 int index) const { | |
373 return action_box_menu_items_[index]; | |
374 } | |
OLD | NEW |