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 <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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |