Index: chrome/browser/extensions/script_badge_controller.cc |
diff --git a/chrome/browser/extensions/script_badge_controller.cc b/chrome/browser/extensions/script_badge_controller.cc |
index 843e7e6128294bed130c08453ff6410842f12c1e..03c25042927a9233bcf5bbb0b7b09cd854a59a58 100644 |
--- a/chrome/browser/extensions/script_badge_controller.cc |
+++ b/chrome/browser/extensions/script_badge_controller.cc |
@@ -4,6 +4,7 @@ |
#include "chrome/browser/extensions/script_badge_controller.h" |
+#include "base/compiler_specific.h" |
#include "chrome/browser/extensions/extension_service.h" |
#include "chrome/browser/extensions/extension_system.h" |
#include "chrome/browser/ui/tab_contents/tab_contents.h" |
@@ -19,9 +20,46 @@ |
#include "content/public/browser/web_contents.h" |
#include "ipc/ipc_message.h" |
#include "ipc/ipc_message_macros.h" |
+#include "ui/base/animation/animation_delegate.h" |
namespace extensions { |
+// Wraps an IconAnimation and implements its ui::AnimationDelegate to erase the |
+// animation from a map when the animation ends or is cancelled, causing itself |
+// and its owned IconAnimation to be deleted. |
+class ScriptBadgeController::IconAnimationWrapper |
+ : public ui::AnimationDelegate { |
+ public: |
+ IconAnimationWrapper(ScriptBadgeController* owner, const std::string& key) |
+ : owner_(owner), |
+ key_(key), |
+ ALLOW_THIS_IN_INITIALIZER_LIST(animation_(owner, this)) {} |
+ |
+ virtual ~IconAnimationWrapper() {} |
+ |
+ IconAnimation* animation() { |
+ return &animation_; |
+ } |
+ |
+ private: |
+ virtual void AnimationEnded(const ui::Animation* animation) OVERRIDE { |
+ Done(); |
+ } |
+ |
+ virtual void AnimationCanceled(const ui::Animation* animation) OVERRIDE { |
+ Done(); |
+ } |
+ |
+ void Done() { |
+ owner_->icon_animations_.erase(key_); |
+ // this will now have been deleted. |
+ } |
+ |
+ ScriptBadgeController* owner_; |
+ std::string key_; |
+ IconAnimation animation_; |
+}; |
+ |
ScriptBadgeController::ScriptBadgeController(TabContents* tab_contents) |
: content::WebContentsObserver(tab_contents->web_contents()), |
script_executor_(tab_contents->web_contents()), |
@@ -33,10 +71,19 @@ ScriptBadgeController::ScriptBadgeController(TabContents* tab_contents) |
ScriptBadgeController::~ScriptBadgeController() {} |
-std::vector<ExtensionAction*> ScriptBadgeController::GetCurrentActions() { |
+std::vector<ExtensionAction*> ScriptBadgeController::GetCurrentActions() const { |
return current_actions_; |
} |
+base::WeakPtr<LocationBarController::IconAnimation> |
+ ScriptBadgeController::GetIconAnimation( |
+ const ExtensionAction* action) const { |
+ IconAnimationMap::const_iterator it = |
+ icon_animations_.find(action->extension_id()); |
+ return (it != icon_animations_.end()) ? it->second->animation()->AsWeakPtr() |
+ : base::WeakPtr<IconAnimation>(); |
+} |
+ |
LocationBarController::Action ScriptBadgeController::OnClicked( |
const std::string& extension_id, int mouse_button) { |
ExtensionService* service = GetExtensionService(); |
@@ -167,10 +214,15 @@ bool ScriptBadgeController::InsertExtension(const std::string& extension_id) { |
return false; |
current_actions_.push_back(extension->script_badge()); |
+ |
+ IconAnimationWrapper* icon_animation = |
+ new IconAnimationWrapper(this, extension_id); |
+ icon_animations_[extension_id] = make_linked_ptr(icon_animation); |
+ icon_animation->animation()->Start(); |
+ |
return true; |
} |
- |
bool ScriptBadgeController::EraseExtension(const Extension* extension) { |
if (extensions_executing_scripts_.erase(extension->id()) == 0) |
return false; |
@@ -192,6 +244,9 @@ bool ScriptBadgeController::EraseExtension(const Extension* extension) { |
} |
CHECK_EQ(size_before, current_actions_.size() + 1); |
+ |
+ icon_animations_.erase(extension->id()); |
+ |
return true; |
} |