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

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

Issue 476873002: Make hiding an extension action cause it to go to the overflow menu (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 6 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
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 <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/message_loop/message_loop.h"
10 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
11 #include "base/metrics/histogram_base.h" 12 #include "base/metrics/histogram_base.h"
12 #include "base/prefs/pref_service.h" 13 #include "base/prefs/pref_service.h"
13 #include "chrome/browser/chrome_notification_types.h" 14 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" 15 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
15 #include "chrome/browser/extensions/extension_action_manager.h" 16 #include "chrome/browser/extensions/extension_action_manager.h"
16 #include "chrome/browser/extensions/extension_tab_util.h" 17 #include "chrome/browser/extensions/extension_tab_util.h"
17 #include "chrome/browser/extensions/extension_toolbar_model_factory.h" 18 #include "chrome/browser/extensions/extension_toolbar_model_factory.h"
18 #include "chrome/browser/extensions/extension_util.h" 19 #include "chrome/browser/extensions/extension_util.h"
19 #include "chrome/browser/extensions/tab_helper.h" 20 #include "chrome/browser/extensions/tab_helper.h"
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 if (!inserted) { 111 if (!inserted) {
111 DCHECK_EQ(index, static_cast<int>(toolbar_items_.size())); 112 DCHECK_EQ(index, static_cast<int>(toolbar_items_.size()));
112 index = toolbar_items_.size(); 113 index = toolbar_items_.size();
113 114
114 toolbar_items_.push_back(make_scoped_refptr(extension)); 115 toolbar_items_.push_back(make_scoped_refptr(extension));
115 last_known_positions_.push_back(extension->id()); 116 last_known_positions_.push_back(extension->id());
116 } 117 }
117 118
118 FOR_EACH_OBSERVER( 119 FOR_EACH_OBSERVER(
119 Observer, observers_, ToolbarExtensionMoved(extension, index)); 120 Observer, observers_, ToolbarExtensionMoved(extension, index));
120 121 MaybeUpdateVisibilityPref(extension, index);
121 UpdatePrefs(); 122 UpdatePrefs();
122 } 123 }
123 124
124 ExtensionAction::ShowAction ExtensionToolbarModel::ExecuteBrowserAction( 125 ExtensionAction::ShowAction ExtensionToolbarModel::ExecuteBrowserAction(
125 const Extension* extension, 126 const Extension* extension,
126 Browser* browser, 127 Browser* browser,
127 GURL* popup_url_out, 128 GURL* popup_url_out,
128 bool should_grant) { 129 bool should_grant) {
129 content::WebContents* web_contents = NULL; 130 content::WebContents* web_contents = NULL;
130 int tab_id = 0; 131 int tab_id = 0;
(...skipping 20 matching lines...) Expand all
151 } 152 }
152 153
153 ExtensionActionAPI::BrowserActionExecuted( 154 ExtensionActionAPI::BrowserActionExecuted(
154 browser->profile(), *browser_action, web_contents); 155 browser->profile(), *browser_action, web_contents);
155 return ExtensionAction::ACTION_NONE; 156 return ExtensionAction::ACTION_NONE;
156 } 157 }
157 158
158 void ExtensionToolbarModel::SetVisibleIconCount(int count) { 159 void ExtensionToolbarModel::SetVisibleIconCount(int count) {
159 visible_icon_count_ = 160 visible_icon_count_ =
160 count == static_cast<int>(toolbar_items_.size()) ? -1 : count; 161 count == static_cast<int>(toolbar_items_.size()) ? -1 : count;
162
161 // Only set the prefs if we're not in highlight mode. Highlight mode is 163 // Only set the prefs if we're not in highlight mode. Highlight mode is
162 // designed to be a transitory state, and should not persist across browser 164 // designed to be a transitory state, and should not persist across browser
163 // restarts (though it may be re-entered). 165 // restarts (though it may be re-entered).
164 if (!is_highlighting_) 166 if (!is_highlighting_) {
167 // Additionally, if we are using the new toolbar, any icons which are in the
168 // overflow menu are considered "hidden". But it so happens that the times
169 // we are likely to call SetVisibleIconCount() are also those when we are
170 // in flux. So wait for things to cool down before setting the prefs.
171 base::MessageLoop::current()->PostTask(
172 FROM_HERE,
173 base::Bind(&ExtensionToolbarModel::MaybeUpdateVisibilityPrefs,
174 weak_ptr_factory_.GetWeakPtr()));
165 prefs_->SetInteger(pref_names::kToolbarSize, visible_icon_count_); 175 prefs_->SetInteger(pref_names::kToolbarSize, visible_icon_count_);
176 }
166 } 177 }
167 178
168 void ExtensionToolbarModel::OnExtensionActionUpdated( 179 void ExtensionToolbarModel::OnExtensionActionUpdated(
169 ExtensionAction* extension_action, 180 ExtensionAction* extension_action,
170 content::WebContents* web_contents, 181 content::WebContents* web_contents,
171 content::BrowserContext* browser_context) { 182 content::BrowserContext* browser_context) {
172 const Extension* extension = 183 const Extension* extension =
173 ExtensionRegistry::Get(profile_)->enabled_extensions().GetByID( 184 ExtensionRegistry::Get(profile_)->enabled_extensions().GetByID(
174 extension_action->extension_id()); 185 extension_action->extension_id());
175 // Notify observers if the extension exists and is in the model. 186 // Notify observers if the extension exists and is in the model.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 if (pos != last_known_positions_.end()) { 226 if (pos != last_known_positions_.end()) {
216 last_known_positions_.erase(pos); 227 last_known_positions_.erase(pos);
217 UpdatePrefs(); 228 UpdatePrefs();
218 } 229 }
219 } 230 }
220 231
221 void ExtensionToolbarModel::Observe( 232 void ExtensionToolbarModel::Observe(
222 int type, 233 int type,
223 const content::NotificationSource& source, 234 const content::NotificationSource& source,
224 const content::NotificationDetails& details) { 235 const content::NotificationDetails& details) {
225 DCHECK_EQ( 236 DCHECK_EQ(NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED, type);
226 extensions::NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED,
227 type);
228 const Extension* extension = 237 const Extension* extension =
229 ExtensionRegistry::Get(profile_)->GetExtensionById( 238 ExtensionRegistry::Get(profile_)->GetExtensionById(
230 *content::Details<const std::string>(details).ptr(), 239 *content::Details<const std::string>(details).ptr(),
231 ExtensionRegistry::EVERYTHING); 240 ExtensionRegistry::EVERYTHING);
232 if (ExtensionActionAPI::GetBrowserActionVisibility(extension_prefs_, 241
233 extension->id())) 242 bool visible = ExtensionActionAPI::GetBrowserActionVisibility(
234 AddExtension(extension); 243 extension_prefs_, extension->id());
235 else 244 // Hiding works differently with the new and old toolbars.
236 RemoveExtension(extension); 245 if (include_all_extensions_) {
246 int new_size = 0;
247 int new_index = 0;
248 if (visible) {
249 // If this action used to be hidden, we can't possible be showing all.
250 DCHECK_NE(-1, visible_icon_count_);
251 // Grow the bar by one and move the extension to the end of the visibles.
252 new_size = visible_icon_count_ + 1;
253 new_index = new_size - 1;
254 } else {
255 // If we're hiding one, we must be showing at least one.
256 DCHECK_NE(visible_icon_count_, 0);
257 // Shrink the bar by one and move the extension to the beginning of the
258 // overflow menu.
259 new_size = visible_icon_count_ == -1 ?
260 toolbar_items_.size() - 1 : visible_icon_count_ - 1;
261 new_index = new_size;
262 }
263 SetVisibleIconCount(new_size);
264 MoveExtensionIcon(extension, new_index);
265 FOR_EACH_OBSERVER(Observer, observers_, ToolbarVisibleCountChanged());
266 } else { // Don't include all extensions.
267 if (visible)
268 AddExtension(extension);
269 else
270 RemoveExtension(extension);
271 }
237 } 272 }
238 273
239 void ExtensionToolbarModel::OnReady() { 274 void ExtensionToolbarModel::OnReady() {
240 ExtensionRegistry* registry = ExtensionRegistry::Get(profile_); 275 ExtensionRegistry* registry = ExtensionRegistry::Get(profile_);
241 InitializeExtensionList(registry->enabled_extensions()); 276 InitializeExtensionList(registry->enabled_extensions());
242 // Wait until the extension system is ready before observing any further 277 // Wait until the extension system is ready before observing any further
243 // changes so that the toolbar buttons can be shown in their stable ordering 278 // changes so that the toolbar buttons can be shown in their stable ordering
244 // taken from prefs. 279 // taken from prefs.
245 extension_registry_observer_.Add(registry); 280 extension_registry_observer_.Add(registry);
246 extension_action_observer_.Add(ExtensionActionAPI::Get(profile_)); 281 extension_action_observer_.Add(ExtensionActionAPI::Get(profile_));
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 toolbar_items_.push_back(make_scoped_refptr(extension)); 346 toolbar_items_.push_back(make_scoped_refptr(extension));
312 } 347 }
313 } else { 348 } else {
314 // This is a never before seen extension, that was added to the end. Make 349 // This is a never before seen extension, that was added to the end. Make
315 // sure to reflect that. (|new_index| was set above.) 350 // sure to reflect that. (|new_index| was set above.)
316 toolbar_items_.push_back(make_scoped_refptr(extension)); 351 toolbar_items_.push_back(make_scoped_refptr(extension));
317 last_known_positions_.push_back(extension->id()); 352 last_known_positions_.push_back(extension->id());
318 UpdatePrefs(); 353 UpdatePrefs();
319 } 354 }
320 355
356 MaybeUpdateVisibilityPref(extension, new_index);
357
321 // If we're currently highlighting, then even though we add a browser action 358 // If we're currently highlighting, then even though we add a browser action
322 // to the full list (|toolbar_items_|, there won't be another *visible* 359 // to the full list (|toolbar_items_|, there won't be another *visible*
323 // browser action, which was what the observers care about. 360 // browser action, which was what the observers care about.
324 if (!is_highlighting_) { 361 if (!is_highlighting_) {
325 FOR_EACH_OBSERVER( 362 FOR_EACH_OBSERVER(
326 Observer, observers_, ToolbarExtensionAdded(extension, new_index)); 363 Observer, observers_, ToolbarExtensionAdded(extension, new_index));
327 } 364 }
328 } 365 }
329 366
330 void ExtensionToolbarModel::RemoveExtension(const Extension* extension) { 367 void ExtensionToolbarModel::RemoveExtension(const Extension* extension) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 // 1. Create a vector of extensions sorted by their pref values. This vector may 399 // 1. Create a vector of extensions sorted by their pref values. This vector may
363 // have holes. 400 // have holes.
364 // 2. Create a vector of extensions that did not have a pref value. 401 // 2. Create a vector of extensions that did not have a pref value.
365 // 3. Remove holes from the sorted vector and append the unsorted vector. 402 // 3. Remove holes from the sorted vector and append the unsorted vector.
366 void ExtensionToolbarModel::InitializeExtensionList( 403 void ExtensionToolbarModel::InitializeExtensionList(
367 const ExtensionSet& extensions) { 404 const ExtensionSet& extensions) {
368 last_known_positions_ = extension_prefs_->GetToolbarOrder(); 405 last_known_positions_ = extension_prefs_->GetToolbarOrder();
369 Populate(last_known_positions_, extensions); 406 Populate(last_known_positions_, extensions);
370 407
371 extensions_initialized_ = true; 408 extensions_initialized_ = true;
409 MaybeUpdateVisibilityPrefs();
372 FOR_EACH_OBSERVER(Observer, observers_, ToolbarVisibleCountChanged()); 410 FOR_EACH_OBSERVER(Observer, observers_, ToolbarVisibleCountChanged());
373 } 411 }
374 412
375 void ExtensionToolbarModel::Populate(const ExtensionIdList& positions, 413 void ExtensionToolbarModel::Populate(const ExtensionIdList& positions,
376 const ExtensionSet& extensions) { 414 const ExtensionSet& extensions) {
377 // Items that have explicit positions. 415 // Items that have explicit positions.
378 ExtensionList sorted; 416 ExtensionList sorted;
379 sorted.resize(positions.size(), NULL); 417 sorted.resize(positions.size(), NULL);
380 // The items that don't have explicit positions. 418 // The items that don't have explicit positions.
381 ExtensionList unsorted; 419 ExtensionList unsorted;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 void ExtensionToolbarModel::UpdatePrefs() { 500 void ExtensionToolbarModel::UpdatePrefs() {
463 if (!extension_prefs_) 501 if (!extension_prefs_)
464 return; 502 return;
465 503
466 // Don't observe change caused by self. 504 // Don't observe change caused by self.
467 pref_change_registrar_.Remove(pref_names::kToolbar); 505 pref_change_registrar_.Remove(pref_names::kToolbar);
468 extension_prefs_->SetToolbarOrder(last_known_positions_); 506 extension_prefs_->SetToolbarOrder(last_known_positions_);
469 pref_change_registrar_.Add(pref_names::kToolbar, pref_change_callback_); 507 pref_change_registrar_.Add(pref_names::kToolbar, pref_change_callback_);
470 } 508 }
471 509
510 void ExtensionToolbarModel::MaybeUpdateVisibilityPref(
511 const Extension* extension, int index) {
512 // We only update the visibility pref for hidden/not hidden based on the
513 // overflow menu with the new toolbar design.
514 if (include_all_extensions_) {
515 bool visible = index < visible_icon_count_ || visible_icon_count_ == -1;
516 if (visible != ExtensionActionAPI::GetBrowserActionVisibility(
517 extension_prefs_, extension->id())) {
518 // Don't observe changes caused by ourselves.
519 bool was_registered = false;
520 if (registrar_.IsRegistered(
521 this,
522 NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED,
523 content::Source<ExtensionPrefs>(extension_prefs_))) {
524 was_registered = true;
525 registrar_.Remove(
526 this,
527 NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED,
528 content::Source<ExtensionPrefs>(extension_prefs_));
529 }
530 ExtensionActionAPI::SetBrowserActionVisibility(
531 extension_prefs_, extension->id(), visible);
532 if (was_registered) {
533 registrar_.Add(this,
534 NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED,
535 content::Source<ExtensionPrefs>(extension_prefs_));
536 }
537 }
538 }
539 }
540
541 void ExtensionToolbarModel::MaybeUpdateVisibilityPrefs() {
542 for (size_t i = 0u; i < toolbar_items_.size(); ++i)
543 MaybeUpdateVisibilityPref(toolbar_items_[i], i);
544 }
545
472 int ExtensionToolbarModel::IncognitoIndexToOriginal(int incognito_index) { 546 int ExtensionToolbarModel::IncognitoIndexToOriginal(int incognito_index) {
473 int original_index = 0, i = 0; 547 int original_index = 0, i = 0;
474 for (ExtensionList::iterator iter = toolbar_items_.begin(); 548 for (ExtensionList::iterator iter = toolbar_items_.begin();
475 iter != toolbar_items_.end(); 549 iter != toolbar_items_.end();
476 ++iter, ++original_index) { 550 ++iter, ++original_index) {
477 if (util::IsIncognitoEnabled((*iter)->id(), profile_)) { 551 if (util::IsIncognitoEnabled((*iter)->id(), profile_)) {
478 if (incognito_index == i) 552 if (incognito_index == i)
479 break; 553 break;
480 ++i; 554 ++i;
481 } 555 }
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 is_highlighting_ = false; 686 is_highlighting_ = false;
613 if (old_visible_icon_count_ != visible_icon_count_) { 687 if (old_visible_icon_count_ != visible_icon_count_) {
614 SetVisibleIconCount(old_visible_icon_count_); 688 SetVisibleIconCount(old_visible_icon_count_);
615 FOR_EACH_OBSERVER(Observer, observers_, ToolbarVisibleCountChanged()); 689 FOR_EACH_OBSERVER(Observer, observers_, ToolbarVisibleCountChanged());
616 } 690 }
617 FOR_EACH_OBSERVER(Observer, observers_, ToolbarHighlightModeChanged(false)); 691 FOR_EACH_OBSERVER(Observer, observers_, ToolbarHighlightModeChanged(false));
618 } 692 }
619 } 693 }
620 694
621 } // namespace extensions 695 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_toolbar_model.h ('k') | chrome/browser/extensions/extension_toolbar_model_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698