| Index: chrome/browser/extensions/extension_action.h
|
| diff --git a/chrome/browser/extensions/extension_action.h b/chrome/browser/extensions/extension_action.h
|
| index 18684039a00b6d8508714d3a15ba934a5c815e28..95fae5a69a44a6e2522738617be5d29367c42a7c 100644
|
| --- a/chrome/browser/extensions/extension_action.h
|
| +++ b/chrome/browser/extensions/extension_action.h
|
| @@ -220,15 +220,22 @@ class ExtensionAction {
|
| // care of any appropriate transition animations. Returns true if
|
| // the appearance has changed.
|
| bool SetAppearance(int tab_id, Appearance value);
|
| + // The declarative appearance overrides a default appearance but is overrided
|
| + // by an appearance set directly on the tab.
|
| + void SetDeclarativeAppearance(int tab_id, Appearance value);
|
| + void ClearDeclarativeAppearance(int tab_id);
|
| +
|
| // Get the badge visibility for a tab, or the default badge visibility
|
| // if none was set.
|
| bool GetIsVisible(int tab_id) const {
|
| - return GetValue(&appearance_, tab_id) != INVISIBLE;
|
| + return GetDeclarativeValue(&appearance_, &declarative_appearance_, tab_id)
|
| + != INVISIBLE;
|
| }
|
|
|
| // True if the tab's action wants the user's attention.
|
| bool WantsAttention(int tab_id) const {
|
| - return GetValue(&appearance_, tab_id) == WANTS_ATTENTION;
|
| + return GetDeclarativeValue(&appearance_, &declarative_appearance_, tab_id)
|
| + == WANTS_ATTENTION;
|
| }
|
|
|
| // Remove all tab-specific state.
|
| @@ -283,6 +290,30 @@ class ExtensionAction {
|
| }
|
| }
|
|
|
| + // Returns the first of map[tab_id], declarative_map[tab_id],
|
| + // map[kDefaultTabId], or ValueTraits<T>::CreateEmpty() that's defined. Don't
|
| + // return this result to an extension's background page because the
|
| + // declarative state can leak information about hosts the extension doesn't
|
| + // have permission to access.
|
| + template<class T>
|
| + T GetDeclarativeValue(const std::map<int, T>* map,
|
| + const std::map<int, T>* declarative_map,
|
| + int tab_id) const {
|
| + typename std::map<int, T>::const_iterator iter = map->find(tab_id);
|
| + if (iter != map->end())
|
| + return iter->second;
|
| +
|
| + iter = declarative_map->find(tab_id);
|
| + if (iter != declarative_map->end())
|
| + return iter->second;
|
| +
|
| + iter = map->find(kDefaultTabId);
|
| + if (iter != map->end())
|
| + return iter->second;
|
| +
|
| + return ValueTraits<T>::CreateEmpty();
|
| + }
|
| +
|
| // The id for the extension this action belongs to (as defined in the
|
| // extension manifest).
|
| const std::string extension_id_;
|
| @@ -298,6 +329,13 @@ class ExtensionAction {
|
| std::map<int, SkColor> badge_background_color_;
|
| std::map<int, SkColor> badge_text_color_;
|
| std::map<int, Appearance> appearance_;
|
| + // Declarative state exists for two reasons: First, we need to hide it from
|
| + // the extension's background/event page to avoid leaking data from hosts the
|
| + // extension doesn't have permission to access. Second, the action's state
|
| + // gets both reset and given its declarative values in response to a
|
| + // WebContentsObserver::DidNavigateMainFrame event, and there's no way to set
|
| + // those up to be called in the right order.
|
| + std::map<int, Appearance> declarative_appearance_;
|
|
|
| // IconAnimations are destroyed by a delayed task on the UI message loop so
|
| // that even if the Extension and ExtensionAction are destroyed on a non-UI
|
|
|