| 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/common/extensions/extension_action.h" | 5 #include "chrome/common/extensions/extension_action.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 | 241 |
| 242 ExtensionAction::~ExtensionAction() { | 242 ExtensionAction::~ExtensionAction() { |
| 243 } | 243 } |
| 244 | 244 |
| 245 scoped_ptr<ExtensionAction> ExtensionAction::CopyForTest() const { | 245 scoped_ptr<ExtensionAction> ExtensionAction::CopyForTest() const { |
| 246 scoped_ptr<ExtensionAction> copy( | 246 scoped_ptr<ExtensionAction> copy( |
| 247 new ExtensionAction(extension_id_, action_type_)); | 247 new ExtensionAction(extension_id_, action_type_)); |
| 248 copy->popup_url_ = popup_url_; | 248 copy->popup_url_ = popup_url_; |
| 249 copy->title_ = title_; | 249 copy->title_ = title_; |
| 250 copy->icon_ = icon_; | 250 copy->icon_ = icon_; |
| 251 copy->icon_index_ = icon_index_; | |
| 252 copy->badge_text_ = badge_text_; | 251 copy->badge_text_ = badge_text_; |
| 253 copy->badge_background_color_ = badge_background_color_; | 252 copy->badge_background_color_ = badge_background_color_; |
| 254 copy->badge_text_color_ = badge_text_color_; | 253 copy->badge_text_color_ = badge_text_color_; |
| 255 copy->appearance_ = appearance_; | 254 copy->appearance_ = appearance_; |
| 256 copy->icon_animation_ = icon_animation_; | 255 copy->icon_animation_ = icon_animation_; |
| 257 copy->default_icon_path_ = default_icon_path_; | 256 copy->default_icon_path_ = default_icon_path_; |
| 258 copy->id_ = id_; | 257 copy->id_ = id_; |
| 259 copy->icon_paths_ = icon_paths_; | |
| 260 return copy.Pass(); | 258 return copy.Pass(); |
| 261 } | 259 } |
| 262 | 260 |
| 263 void ExtensionAction::SetPopupUrl(int tab_id, const GURL& url) { | 261 void ExtensionAction::SetPopupUrl(int tab_id, const GURL& url) { |
| 264 // We store |url| even if it is empty, rather than removing a URL from the | 262 // We store |url| even if it is empty, rather than removing a URL from the |
| 265 // map. If an extension has a default popup, and removes it for a tab via | 263 // map. If an extension has a default popup, and removes it for a tab via |
| 266 // the API, we must remember that there is no popup for that specific tab. | 264 // the API, we must remember that there is no popup for that specific tab. |
| 267 // If we removed the tab's URL, GetPopupURL would incorrectly return the | 265 // If we removed the tab's URL, GetPopupURL would incorrectly return the |
| 268 // default URL. | 266 // default URL. |
| 269 SetValue(&popup_url_, tab_id, url); | 267 SetValue(&popup_url_, tab_id, url); |
| 270 } | 268 } |
| 271 | 269 |
| 272 bool ExtensionAction::HasPopup(int tab_id) const { | 270 bool ExtensionAction::HasPopup(int tab_id) const { |
| 273 return !GetPopupUrl(tab_id).is_empty(); | 271 return !GetPopupUrl(tab_id).is_empty(); |
| 274 } | 272 } |
| 275 | 273 |
| 276 GURL ExtensionAction::GetPopupUrl(int tab_id) const { | 274 GURL ExtensionAction::GetPopupUrl(int tab_id) const { |
| 277 return GetValue(&popup_url_, tab_id); | 275 return GetValue(&popup_url_, tab_id); |
| 278 } | 276 } |
| 279 | 277 |
| 280 void ExtensionAction::CacheIcon(const std::string& path, | 278 void ExtensionAction::CacheIcon(const gfx::Image& icon) { |
| 281 const gfx::Image& icon) { | |
| 282 if (!icon.IsEmpty()) | 279 if (!icon.IsEmpty()) |
| 283 path_to_icon_cache_.insert(std::make_pair(path, *icon.ToImageSkia())); | 280 cached_icon_.reset(new gfx::ImageSkia(*icon.ToImageSkia())); |
| 284 } | 281 } |
| 285 | 282 |
| 286 void ExtensionAction::SetIcon(int tab_id, const gfx::Image& image) { | 283 void ExtensionAction::SetIcon(int tab_id, const gfx::Image& image) { |
| 287 SetValue(&icon_, tab_id, image.AsImageSkia()); | 284 SetValue(&icon_, tab_id, image.AsImageSkia()); |
| 288 } | 285 } |
| 289 | 286 |
| 290 gfx::Image ExtensionAction::GetIcon(int tab_id) const { | 287 gfx::Image ExtensionAction::GetIcon(int tab_id) const { |
| 291 // Check if a specific icon is set for this tab. | 288 // Check if a specific icon is set for this tab. |
| 292 gfx::ImageSkia icon = GetExplicitlySetIcon(tab_id); | 289 gfx::ImageSkia icon = GetExplicitlySetIcon(tab_id); |
| 293 if (icon.isNull()) { | 290 if (icon.isNull()) { |
| 294 // Need to find an icon from a path. | 291 if (cached_icon_.get()) { |
| 295 const std::string* path = NULL; | 292 icon = *cached_icon_; |
| 296 // Check if one of the elements of icon_path() was selected. | |
| 297 int icon_index = GetIconIndex(tab_id); | |
| 298 if (icon_index >= 0) { | |
| 299 path = &icon_paths()->at(icon_index); | |
| 300 } else { | |
| 301 // Otherwise, use the default icon. | |
| 302 path = &default_icon_path(); | |
| 303 } | |
| 304 | |
| 305 std::map<std::string, gfx::ImageSkia>::const_iterator cached_icon = | |
| 306 path_to_icon_cache_.find(*path); | |
| 307 if (cached_icon != path_to_icon_cache_.end()) { | |
| 308 icon = cached_icon->second; | |
| 309 } else { | 293 } else { |
| 310 icon = *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | 294 icon = *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
| 311 IDR_EXTENSIONS_FAVICON); | 295 IDR_EXTENSIONS_FAVICON); |
| 312 } | 296 } |
| 313 } | 297 } |
| 314 | 298 |
| 315 if (GetValue(&appearance_, tab_id) == WANTS_ATTENTION) | 299 if (GetValue(&appearance_, tab_id) == WANTS_ATTENTION) |
| 316 icon = gfx::ImageSkia(new GetAttentionImageSource(icon), icon.size()); | 300 icon = gfx::ImageSkia(new GetAttentionImageSource(icon), icon.size()); |
| 317 | 301 |
| 318 return gfx::Image(ApplyIconAnimation(tab_id, icon)); | 302 return gfx::Image(ApplyIconAnimation(tab_id, icon)); |
| 319 } | 303 } |
| 320 | 304 |
| 321 gfx::ImageSkia ExtensionAction::GetExplicitlySetIcon(int tab_id) const { | 305 gfx::ImageSkia ExtensionAction::GetExplicitlySetIcon(int tab_id) const { |
| 322 return GetValue(&icon_, tab_id); | 306 return GetValue(&icon_, tab_id); |
| 323 } | 307 } |
| 324 | 308 |
| 325 void ExtensionAction::SetIconIndex(int tab_id, int index) { | |
| 326 if (static_cast<size_t>(index) >= icon_paths_.size()) { | |
| 327 NOTREACHED(); | |
| 328 return; | |
| 329 } | |
| 330 SetValue(&icon_index_, tab_id, index); | |
| 331 } | |
| 332 | |
| 333 bool ExtensionAction::SetAppearance(int tab_id, Appearance new_appearance) { | 309 bool ExtensionAction::SetAppearance(int tab_id, Appearance new_appearance) { |
| 334 const Appearance old_appearance = GetValue(&appearance_, tab_id); | 310 const Appearance old_appearance = GetValue(&appearance_, tab_id); |
| 335 | 311 |
| 336 if (old_appearance == new_appearance) | 312 if (old_appearance == new_appearance) |
| 337 return false; | 313 return false; |
| 338 | 314 |
| 339 SetValue(&appearance_, tab_id, new_appearance); | 315 SetValue(&appearance_, tab_id, new_appearance); |
| 340 | 316 |
| 341 // When showing a badge for the first time on a web page, fade it | 317 // When showing a badge for the first time on a web page, fade it |
| 342 // in. Other transitions happen instantly. | 318 // in. Other transitions happen instantly. |
| 343 if (old_appearance == INVISIBLE && tab_id != kDefaultTabId) { | 319 if (old_appearance == INVISIBLE && tab_id != kDefaultTabId) { |
| 344 RunIconAnimation(tab_id); | 320 RunIconAnimation(tab_id); |
| 345 } | 321 } |
| 346 | 322 |
| 347 return true; | 323 return true; |
| 348 } | 324 } |
| 349 | 325 |
| 350 void ExtensionAction::ClearAllValuesForTab(int tab_id) { | 326 void ExtensionAction::ClearAllValuesForTab(int tab_id) { |
| 351 popup_url_.erase(tab_id); | 327 popup_url_.erase(tab_id); |
| 352 title_.erase(tab_id); | 328 title_.erase(tab_id); |
| 353 icon_.erase(tab_id); | 329 icon_.erase(tab_id); |
| 354 icon_index_.erase(tab_id); | |
| 355 badge_text_.erase(tab_id); | 330 badge_text_.erase(tab_id); |
| 356 badge_text_color_.erase(tab_id); | 331 badge_text_color_.erase(tab_id); |
| 357 badge_background_color_.erase(tab_id); | 332 badge_background_color_.erase(tab_id); |
| 358 appearance_.erase(tab_id); | 333 appearance_.erase(tab_id); |
| 359 icon_animation_.erase(tab_id); | 334 icon_animation_.erase(tab_id); |
| 360 } | 335 } |
| 361 | 336 |
| 362 void ExtensionAction::PaintBadge(gfx::Canvas* canvas, | 337 void ExtensionAction::PaintBadge(gfx::Canvas* canvas, |
| 363 const gfx::Rect& bounds, | 338 const gfx::Rect& bounds, |
| 364 int tab_id) { | 339 int tab_id) { |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 icon_animation->Start(); | 490 icon_animation->Start(); |
| 516 // After the icon is finished fading in (plus some padding to handle random | 491 // After the icon is finished fading in (plus some padding to handle random |
| 517 // timer delays), destroy it. We use a delayed task so that the Animation is | 492 // timer delays), destroy it. We use a delayed task so that the Animation is |
| 518 // deleted even if it hasn't finished by the time the MessageLoop is | 493 // deleted even if it hasn't finished by the time the MessageLoop is |
| 519 // destroyed. | 494 // destroyed. |
| 520 MessageLoop::current()->PostDelayedTask( | 495 MessageLoop::current()->PostDelayedTask( |
| 521 FROM_HERE, | 496 FROM_HERE, |
| 522 base::Bind(&DestroyIconAnimation, base::Passed(icon_animation.Pass())), | 497 base::Bind(&DestroyIconAnimation, base::Passed(icon_animation.Pass())), |
| 523 base::TimeDelta::FromMilliseconds(kIconFadeInDurationMs * 2)); | 498 base::TimeDelta::FromMilliseconds(kIconFadeInDurationMs * 2)); |
| 524 } | 499 } |
| OLD | NEW |