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

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

Issue 675023002: Make extensions that desire to act pop out if in overflow (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Peter's Created 6 years, 1 month 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/message_loop/message_loop.h"
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 toolbar_items_.push_back(extension); 114 toolbar_items_.push_back(extension);
115 last_known_positions_.push_back(id); 115 last_known_positions_.push_back(id);
116 } 116 }
117 117
118 FOR_EACH_OBSERVER( 118 FOR_EACH_OBSERVER(
119 Observer, observers_, ToolbarExtensionMoved(extension.get(), index)); 119 Observer, observers_, ToolbarExtensionMoved(extension.get(), index));
120 MaybeUpdateVisibilityPref(extension.get(), index); 120 MaybeUpdateVisibilityPref(extension.get(), index);
121 UpdatePrefs(); 121 UpdatePrefs();
122 } 122 }
123 123
124 void ExtensionToolbarModel::SetVisibleIconCount(int count) { 124 void ExtensionToolbarModel::SetVisibleIconCount(size_t count) {
125 visible_icon_count_ = 125 visible_icon_count_ = (count == toolbar_items_.size()) ? -1 : count;
126 count == static_cast<int>(toolbar_items_.size()) ? -1 : count;
127 126
128 // Only set the prefs if we're not in highlight mode and the profile is not 127 // Only set the prefs if we're not in highlight mode and the profile is not
129 // incognito. Highlight mode is designed to be a transitory state, and should 128 // incognito. Highlight mode is designed to be a transitory state, and should
130 // not persist across browser restarts (though it may be re-entered), and we 129 // not persist across browser restarts (though it may be re-entered), and we
131 // don't store anything in incognito. 130 // don't store anything in incognito.
132 if (!is_highlighting_ && !profile_->IsOffTheRecord()) { 131 if (!is_highlighting_ && !profile_->IsOffTheRecord()) {
133 // Additionally, if we are using the new toolbar, any icons which are in the 132 // Additionally, if we are using the new toolbar, any icons which are in the
134 // overflow menu are considered "hidden". But it so happens that the times 133 // overflow menu are considered "hidden". But it so happens that the times
135 // we are likely to call SetVisibleIconCount() are also those when we are 134 // we are likely to call SetVisibleIconCount() are also those when we are
136 // in flux. So wait for things to cool down before setting the prefs. 135 // in flux. So wait for things to cool down before setting the prefs.
137 base::MessageLoop::current()->PostTask( 136 base::MessageLoop::current()->PostTask(
138 FROM_HERE, 137 FROM_HERE,
139 base::Bind(&ExtensionToolbarModel::MaybeUpdateVisibilityPrefs, 138 base::Bind(&ExtensionToolbarModel::MaybeUpdateVisibilityPrefs,
140 weak_ptr_factory_.GetWeakPtr())); 139 weak_ptr_factory_.GetWeakPtr()));
141 prefs_->SetInteger(pref_names::kToolbarSize, visible_icon_count_); 140 prefs_->SetInteger(pref_names::kToolbarSize, visible_icon_count_);
142 } 141 }
143 142
144 FOR_EACH_OBSERVER(Observer, observers_, ToolbarVisibleCountChanged()); 143 FOR_EACH_OBSERVER(Observer, observers_, ToolbarVisibleCountChanged());
145 } 144 }
146 145
147 void ExtensionToolbarModel::OnExtensionActionUpdated( 146 void ExtensionToolbarModel::OnExtensionActionUpdated(
148 ExtensionAction* extension_action, 147 ExtensionAction* extension_action,
149 content::WebContents* web_contents, 148 content::WebContents* web_contents,
150 content::BrowserContext* browser_context) { 149 content::BrowserContext* browser_context) {
151 const Extension* extension = 150 const Extension* extension =
152 ExtensionRegistry::Get(profile_)->enabled_extensions().GetByID( 151 ExtensionRegistry::Get(profile_)->enabled_extensions().GetByID(
153 extension_action->extension_id()); 152 extension_action->extension_id());
154 // Notify observers if the extension exists and is in the model. 153 // Notify observers if the extension exists and is in the model.
155 if (extension && 154 ExtensionList::const_iterator iter =
156 std::find(toolbar_items_.begin(), 155 std::find(toolbar_items_.begin(), toolbar_items_.end(), extension);
157 toolbar_items_.end(), 156 if (iter != toolbar_items_.end()) {
158 extension) != toolbar_items_.end()) { 157 FOR_EACH_OBSERVER(
159 FOR_EACH_OBSERVER(Observer, observers_, ToolbarExtensionUpdated(extension)); 158 Observer, observers_, ToolbarExtensionUpdated(extension));
159 // If the action was in the overflow menu, we have to alert observers that
160 // the toolbar needs to be reordered (to show the action).
161 if (static_cast<size_t>(iter - toolbar_items_.begin()) >=
162 visible_icon_count()) {
163 FOR_EACH_OBSERVER(
164 Observer, observers_, OnToolbarReorderNecessary(web_contents));
165 }
160 } 166 }
161 } 167 }
162 168
163 void ExtensionToolbarModel::OnExtensionLoaded( 169 void ExtensionToolbarModel::OnExtensionLoaded(
164 content::BrowserContext* browser_context, 170 content::BrowserContext* browser_context,
165 const Extension* extension) { 171 const Extension* extension) {
166 // We don't want to add the same extension twice. It may have already been 172 // We don't want to add the same extension twice. It may have already been
167 // added by EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED below, if the user 173 // added by EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED below, if the user
168 // hides the browser action and then disables and enables the extension. 174 // hides the browser action and then disables and enables the extension.
169 for (size_t i = 0; i < toolbar_items_.size(); i++) { 175 for (size_t i = 0; i < toolbar_items_.size(); i++) {
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 489
484 void ExtensionToolbarModel::IncognitoPopulate() { 490 void ExtensionToolbarModel::IncognitoPopulate() {
485 DCHECK(profile_->IsOffTheRecord()); 491 DCHECK(profile_->IsOffTheRecord());
486 // Clear the current items, if any. 492 // Clear the current items, if any.
487 ClearItems(); 493 ClearItems();
488 494
489 const ExtensionToolbarModel* original_model = 495 const ExtensionToolbarModel* original_model =
490 ExtensionToolbarModel::Get(profile_->GetOriginalProfile()); 496 ExtensionToolbarModel::Get(profile_->GetOriginalProfile());
491 497
492 // Find the absolute value of the original model's count. 498 // Find the absolute value of the original model's count.
493 int original_visible = original_model->GetVisibleIconCount(); 499 int original_visible = original_model->visible_icon_count();
494 if (original_visible == -1)
495 original_visible = original_model->toolbar_items_.size();
496 500
497 // In incognito mode, we show only those extensions that are 501 // In incognito mode, we show only those extensions that are
498 // incognito-enabled. Further, any actions that were overflowed in regular 502 // incognito-enabled. Further, any actions that were overflowed in regular
499 // mode are still overflowed. Order is the same as in regular mode. 503 // mode are still overflowed. Order is the same as in regular mode.
500 visible_icon_count_ = 0; 504 visible_icon_count_ = 0;
501 for (ExtensionList::const_iterator iter = 505 for (ExtensionList::const_iterator iter =
502 original_model->toolbar_items_.begin(); 506 original_model->toolbar_items_.begin();
503 iter != original_model->toolbar_items_.end(); ++iter) { 507 iter != original_model->toolbar_items_.end(); ++iter) {
504 if (ShouldAddExtension(iter->get())) { 508 if (ShouldAddExtension(iter->get())) {
505 toolbar_items_.push_back(*iter); 509 toolbar_items_.push_back(*iter);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 if (last_known_positions_.size() > pref_position_size) { 586 if (last_known_positions_.size() > pref_position_size) {
583 // Need to update pref because we have extra icons. But can't call 587 // Need to update pref because we have extra icons. But can't call
584 // UpdatePrefs() directly within observation closure. 588 // UpdatePrefs() directly within observation closure.
585 base::MessageLoop::current()->PostTask( 589 base::MessageLoop::current()->PostTask(
586 FROM_HERE, 590 FROM_HERE,
587 base::Bind(&ExtensionToolbarModel::UpdatePrefs, 591 base::Bind(&ExtensionToolbarModel::UpdatePrefs,
588 weak_ptr_factory_.GetWeakPtr())); 592 weak_ptr_factory_.GetWeakPtr()));
589 } 593 }
590 } 594 }
591 595
596 size_t ExtensionToolbarModel::GetVisibleIconCountForTab(
597 content::WebContents* web_contents) const {
598 if (all_icons_visible())
599 return visible_icon_count(); // Already displaying all actions.
600
601 ExtensionActionAPI* extension_action_api = ExtensionActionAPI::Get(profile_);
602 size_t total_icons = visible_icon_count_;
603 for (size_t i = total_icons; i < toolbar_items_.size(); ++i) {
604 if (extension_action_api->ExtensionWantsToRun(toolbar_items_[i].get(),
605 web_contents))
606 ++total_icons;
607 }
608 return total_icons;
609 }
610
611 ExtensionList ExtensionToolbarModel::GetItemOrderForTab(
612 content::WebContents* web_contents) const {
613 // If we're highlighting, the items are always the same.
614 if (is_highlighting_)
615 return highlighted_items_;
616
617 // Start by initializing the array to be the same as toolbar items (this isn't
618 // any more expensive than initializing it to be of the same size with all
619 // nulls, and saves us time at the end).
620 ExtensionList result = toolbar_items_;
621 if (toolbar_items_.empty())
622 return result;
623
624 ExtensionList overflowed_actions_wanting_to_run;
625 ExtensionActionAPI* extension_action_api = ExtensionActionAPI::Get(profile_);
626 size_t boundary = visible_icon_count();
627 // Rotate any actions that want to run to the boundary between visible and
628 // overflowed actions.
629 for (size_t i = boundary; i < result.size(); ++i) {
630 if (extension_action_api->ExtensionWantsToRun(result[i].get(),
631 web_contents)) {
632 std::rotate(result.rbegin() + (result.size() - i - 1),
633 result.rbegin() + (result.size() - i),
634 result.rbegin() + (result.size() - boundary));
Peter Kasting 2014/10/31 19:01:08 Why use rbegin() + result.size() - x in all these?
Devlin 2014/10/31 20:49:29 Excellent question. For some reason, I thought a r
635 ++boundary;
636 }
637 }
638 return result;
639 }
640
592 bool ExtensionToolbarModel::ShowExtensionActionPopup( 641 bool ExtensionToolbarModel::ShowExtensionActionPopup(
593 const Extension* extension, 642 const Extension* extension,
594 Browser* browser, 643 Browser* browser,
595 bool grant_active_tab) { 644 bool grant_active_tab) {
596 ObserverListBase<Observer>::Iterator it(observers_); 645 ObserverListBase<Observer>::Iterator it(observers_);
597 Observer* obs = NULL; 646 Observer* obs = NULL;
598 // Look for the Observer associated with the browser. 647 // Look for the Observer associated with the browser.
599 // This would be cleaner if we had an abstract class for the Toolbar UI 648 // This would be cleaner if we had an abstract class for the Toolbar UI
600 // (like we do for LocationBar), but sadly, we don't. 649 // (like we do for LocationBar), but sadly, we don't.
601 while ((obs = it.GetNext()) != NULL) { 650 while ((obs = it.GetNext()) != NULL) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 if (is_highlighting_) { 721 if (is_highlighting_) {
673 highlighted_items_.clear(); 722 highlighted_items_.clear();
674 is_highlighting_ = false; 723 is_highlighting_ = false;
675 if (old_visible_icon_count_ != visible_icon_count_) 724 if (old_visible_icon_count_ != visible_icon_count_)
676 SetVisibleIconCount(old_visible_icon_count_); 725 SetVisibleIconCount(old_visible_icon_count_);
677 FOR_EACH_OBSERVER(Observer, observers_, ToolbarHighlightModeChanged(false)); 726 FOR_EACH_OBSERVER(Observer, observers_, ToolbarHighlightModeChanged(false));
678 } 727 }
679 } 728 }
680 729
681 } // namespace extensions 730 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698