| OLD | NEW |
| 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. Use of this | 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. Use of this |
| 2 // source code is governed by a BSD-style license that can be found in the | 2 // source code is governed by a BSD-style license that can be found in the |
| 3 // LICENSE file. | 3 // LICENSE file. |
| 4 | 4 |
| 5 // Implementation of BlockedPopupContainer and its corresponding View | 5 // Implementation of BlockedPopupContainer and its corresponding View |
| 6 // class. The BlockedPopupContainer is the sort of Model class which owns the | 6 // class. The BlockedPopupContainer is the sort of Model class which owns the |
| 7 // blocked popups' TabContents (but like most Chromium interface code, it there | 7 // blocked popups' TabContents (but like most Chromium interface code, it there |
| 8 // isn't a strict Model/View separation), and BlockedPopupContainerView | 8 // isn't a strict Model/View separation), and BlockedPopupContainerView |
| 9 // presents the user interface controls, creates and manages the popup menu. | 9 // presents the user interface controls, creates and manages the popup menu. |
| 10 | 10 |
| 11 #include "chrome/browser/views/blocked_popup_container.h" | 11 #include "chrome/browser/views/blocked_popup_container.h" |
| 12 | 12 |
| 13 #include <math.h> | 13 #include <math.h> |
| 14 | 14 |
| 15 #include "app/gfx/chrome_canvas.h" | 15 #include "app/gfx/chrome_canvas.h" |
| 16 #include "app/gfx/path.h" | 16 #include "app/gfx/path.h" |
| 17 #include "app/l10n_util.h" | 17 #include "app/l10n_util.h" |
| 18 #include "app/resource_bundle.h" | 18 #include "app/resource_bundle.h" |
| 19 #include "base/string_util.h" | 19 #include "base/string_util.h" |
| 20 #include "chrome/browser/extensions/extension_function_dispatcher.h" | 20 #include "chrome/browser/extensions/extension_function_dispatcher.h" |
| 21 #include "chrome/browser/profile.h" | 21 #include "chrome/browser/profile.h" |
| 22 #include "chrome/browser/tab_contents/tab_contents.h" | 22 #include "chrome/browser/tab_contents/tab_contents.h" |
| 23 #include "chrome/common/notification_service.h" | 23 #include "chrome/common/notification_service.h" |
| 24 #include "chrome/common/pref_names.h" |
| 25 #include "chrome/common/pref_service.h" |
| 24 #include "grit/generated_resources.h" | 26 #include "grit/generated_resources.h" |
| 25 #include "grit/theme_resources.h" | 27 #include "grit/theme_resources.h" |
| 26 #include "views/background.h" | 28 #include "views/background.h" |
| 27 #include "views/controls/button/image_button.h" | 29 #include "views/controls/button/image_button.h" |
| 28 | 30 |
| 29 namespace { | 31 namespace { |
| 30 // A number larger than the internal popup count on the Renderer; meant for | 32 // A number larger than the internal popup count on the Renderer; meant for |
| 31 // preventing a compromised renderer from exhausting GDI memory by spawning | 33 // preventing a compromised renderer from exhausting GDI memory by spawning |
| 32 // infinite windows. | 34 // infinite windows. |
| 33 const int kImpossibleNumberOfPopups = 30; | 35 const int kImpossibleNumberOfPopups = 30; |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 bool BlockedPopupContainerView::IsItemChecked(int id) const { | 216 bool BlockedPopupContainerView::IsItemChecked(int id) const { |
| 215 if (id > kImpossibleNumberOfPopups) { | 217 if (id > kImpossibleNumberOfPopups) { |
| 216 return container_->IsHostWhitelisted(static_cast<size_t>( | 218 return container_->IsHostWhitelisted(static_cast<size_t>( |
| 217 id - kImpossibleNumberOfPopups - 1)); | 219 id - kImpossibleNumberOfPopups - 1)); |
| 218 } | 220 } |
| 219 | 221 |
| 220 return false; | 222 return false; |
| 221 } | 223 } |
| 222 | 224 |
| 223 void BlockedPopupContainerView::ExecuteCommand(int id) { | 225 void BlockedPopupContainerView::ExecuteCommand(int id) { |
| 224 DCHECK(id > 0); | 226 DCHECK_GT(id, 0); |
| 225 size_t id_size_t = static_cast<size_t>(id); | 227 size_t id_size_t = static_cast<size_t>(id); |
| 226 if (id_size_t > kImpossibleNumberOfPopups) { | 228 if (id_size_t > kImpossibleNumberOfPopups) { |
| 227 // Decrement id since all index based commands have 1 added to them. (See | 229 // Decrement id since all index based commands have 1 added to them. (See |
| 228 // ButtonPressed() for detail). | 230 // ButtonPressed() for detail). |
| 229 container_->ToggleWhitelistingForHost( | 231 container_->ToggleWhitelistingForHost( |
| 230 id_size_t - kImpossibleNumberOfPopups - 1); | 232 id_size_t - kImpossibleNumberOfPopups - 1); |
| 231 } else { | 233 } else { |
| 232 container_->LaunchPopupAtIndex(id_size_t - 1); | 234 container_->LaunchPopupAtIndex(id_size_t - 1); |
| 233 } | 235 } |
| 234 } | 236 } |
| 235 | 237 |
| 236 // static | 238 // static |
| 239 void BlockedPopupContainer::RegisterUserPrefs(PrefService* prefs) { |
| 240 prefs->RegisterListPref(prefs::kPopupWhitelistedHosts); |
| 241 } |
| 242 |
| 243 // static |
| 237 BlockedPopupContainer* BlockedPopupContainer::Create( | 244 BlockedPopupContainer* BlockedPopupContainer::Create( |
| 238 TabContents* owner, Profile* profile, const gfx::Point& initial_anchor) { | 245 TabContents* owner, Profile* profile, const gfx::Point& initial_anchor) { |
| 239 BlockedPopupContainer* container = new BlockedPopupContainer(owner, profile); | 246 BlockedPopupContainer* container = |
| 247 new BlockedPopupContainer(owner, profile->GetPrefs()); |
| 240 container->Init(initial_anchor); | 248 container->Init(initial_anchor); |
| 241 return container; | 249 return container; |
| 242 } | 250 } |
| 243 | 251 |
| 244 BlockedPopupContainer::~BlockedPopupContainer() { | 252 BlockedPopupContainer::~BlockedPopupContainer() { |
| 245 } | 253 } |
| 246 | 254 |
| 247 BlockedPopupContainer::BlockedPopupContainer(TabContents* owner, | 255 BlockedPopupContainer::BlockedPopupContainer(TabContents* owner, |
| 248 Profile* profile) | 256 PrefService* prefs) |
| 249 : Animation(kFramerate, NULL), | 257 : Animation(kFramerate, NULL), |
| 250 owner_(owner), | 258 owner_(owner), |
| 259 prefs_(prefs), |
| 251 container_view_(NULL), | 260 container_view_(NULL), |
| 252 has_been_dismissed_(false), | 261 has_been_dismissed_(false), |
| 253 in_show_animation_(false), | 262 in_show_animation_(false), |
| 254 visibility_percentage_(0) { | 263 visibility_percentage_(0) { |
| 264 // Copy whitelist pref into local member that's easier to use. |
| 265 const ListValue* whitelist_pref = |
| 266 prefs_->GetList(prefs::kPopupWhitelistedHosts); |
| 267 // Careful: The returned value could be NULL if the pref has never been set. |
| 268 if (whitelist_pref != NULL) { |
| 269 for (ListValue::const_iterator i(whitelist_pref->begin()); |
| 270 i != whitelist_pref->end(); ++i) { |
| 271 std::string host; |
| 272 (*i)->GetAsString(&host); |
| 273 whitelist_.insert(host); |
| 274 } |
| 275 } |
| 255 } | 276 } |
| 256 | 277 |
| 257 void BlockedPopupContainer::AddTabContents(TabContents* tab_contents, | 278 void BlockedPopupContainer::AddTabContents(TabContents* tab_contents, |
| 258 const gfx::Rect& bounds, | 279 const gfx::Rect& bounds, |
| 259 const std::string& host) { | 280 const std::string& host) { |
| 260 bool whitelisted = false; // TODO: Check if host is on whitelist. | |
| 261 | |
| 262 // Show whitelisted popups immediately. | 281 // Show whitelisted popups immediately. |
| 282 bool whitelisted = !!whitelist_.count(host); |
| 263 if (whitelisted) | 283 if (whitelisted) |
| 264 owner_->AddNewContents(tab_contents, NEW_POPUP, bounds, true, GURL()); | 284 owner_->AddNewContents(tab_contents, NEW_POPUP, bounds, true, GURL()); |
| 265 | 285 |
| 266 if (has_been_dismissed_) { | 286 if (has_been_dismissed_) { |
| 267 // Don't want to show any other UI. | 287 // Don't want to show any other UI. |
| 268 if (!whitelisted) | 288 if (!whitelisted) |
| 269 delete tab_contents; // Discard blocked popups entirely. | 289 delete tab_contents; // Discard blocked popups entirely. |
| 270 return; | 290 return; |
| 271 } | 291 } |
| 272 | 292 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 286 } | 306 } |
| 287 blocked_popups_.push_back(BlockedPopup(tab_contents, bounds, host)); | 307 blocked_popups_.push_back(BlockedPopup(tab_contents, bounds, host)); |
| 288 | 308 |
| 289 tab_contents->set_delegate(this); | 309 tab_contents->set_delegate(this); |
| 290 } | 310 } |
| 291 | 311 |
| 292 PopupHosts::const_iterator i(popup_hosts_.find(host)); | 312 PopupHosts::const_iterator i(popup_hosts_.find(host)); |
| 293 if (i == popup_hosts_.end()) | 313 if (i == popup_hosts_.end()) |
| 294 popup_hosts_[host] = whitelisted; | 314 popup_hosts_[host] = whitelisted; |
| 295 else | 315 else |
| 296 DCHECK(!i->second); // This host was already reported as whitelisted! | 316 DCHECK_EQ(whitelisted, i->second); |
| 297 | 317 |
| 298 // Update UI. | 318 // Update UI. |
| 299 container_view_->UpdateLabel(); | 319 container_view_->UpdateLabel(); |
| 300 SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); | 320 SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); |
| 301 if (!Animation::IsAnimating() && visibility_percentage_ < 1.0) { | 321 if (!Animation::IsAnimating() && visibility_percentage_ < 1.0) { |
| 302 in_show_animation_ = true; | 322 in_show_animation_ = true; |
| 303 Animation::SetDuration(kShowAnimationDurationMS); | 323 Animation::SetDuration(kShowAnimationDurationMS); |
| 304 Animation::Start(); | 324 Animation::Start(); |
| 305 } | 325 } |
| 306 owner_->PopupNotificationVisibilityChanged(true); | 326 owner_->PopupNotificationVisibilityChanged(true); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 bool BlockedPopupContainer::IsHostWhitelisted(size_t index) const { | 377 bool BlockedPopupContainer::IsHostWhitelisted(size_t index) const { |
| 358 PopupHosts::const_iterator i(ConvertHostIndexToIterator(index)); | 378 PopupHosts::const_iterator i(ConvertHostIndexToIterator(index)); |
| 359 return (i == popup_hosts_.end()) ? false : i->second; | 379 return (i == popup_hosts_.end()) ? false : i->second; |
| 360 } | 380 } |
| 361 | 381 |
| 362 void BlockedPopupContainer::ToggleWhitelistingForHost(size_t index) { | 382 void BlockedPopupContainer::ToggleWhitelistingForHost(size_t index) { |
| 363 PopupHosts::const_iterator i(ConvertHostIndexToIterator(index)); | 383 PopupHosts::const_iterator i(ConvertHostIndexToIterator(index)); |
| 364 const std::string& host = i->first; | 384 const std::string& host = i->first; |
| 365 bool should_whitelist = !i->second; | 385 bool should_whitelist = !i->second; |
| 366 popup_hosts_[host] = should_whitelist; | 386 popup_hosts_[host] = should_whitelist; |
| 367 // TODO: Update whitelist pref. | |
| 368 | 387 |
| 388 ListValue* whitelist_pref = |
| 389 prefs_->GetMutableList(prefs::kPopupWhitelistedHosts); |
| 369 if (should_whitelist) { | 390 if (should_whitelist) { |
| 391 whitelist_.insert(host); |
| 392 whitelist_pref->Append(new StringValue(host)); |
| 393 |
| 370 // Open the popups in order. | 394 // Open the popups in order. |
| 371 for (size_t j = 0; j < blocked_popups_.size(); ) { | 395 for (size_t j = 0; j < blocked_popups_.size(); ) { |
| 372 if (blocked_popups_[j].host == host) | 396 if (blocked_popups_[j].host == host) |
| 373 LaunchPopupAtIndex(j); // This shifts the rest of the entries down. | 397 LaunchPopupAtIndex(j); // This shifts the rest of the entries down. |
| 374 else | 398 else |
| 375 ++j; | 399 ++j; |
| 376 } | 400 } |
| 377 } else { | 401 } else { |
| 402 // Remove from whitelist. |
| 403 whitelist_.erase(host); |
| 404 StringValue host_value(host); |
| 405 whitelist_pref->Remove(&host_value); |
| 406 |
| 378 for (UnblockedPopups::iterator i(unblocked_popups_.begin()); | 407 for (UnblockedPopups::iterator i(unblocked_popups_.begin()); |
| 379 i != unblocked_popups_.end(); ) { | 408 i != unblocked_popups_.end(); ) { |
| 380 TabContents* tab_contents = i->first; | 409 TabContents* tab_contents = i->first; |
| 381 TabContentsDelegate* delegate = tab_contents->delegate(); | 410 TabContentsDelegate* delegate = tab_contents->delegate(); |
| 382 if ((i->second == host) && delegate->IsPopup(tab_contents)) { | 411 if ((i->second == host) && delegate->IsPopup(tab_contents)) { |
| 383 // Convert the popup back into a blocked popup. | 412 // Convert the popup back into a blocked popup. |
| 384 delegate->DetachContents(tab_contents); | 413 delegate->DetachContents(tab_contents); |
| 385 tab_contents->set_delegate(this); | 414 tab_contents->set_delegate(this); |
| 386 | 415 |
| 387 // Add the popup to the blocked list. (Do this before the below call!) | 416 // Add the popup to the blocked list. (Do this before the below call!) |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 } | 673 } |
| 645 | 674 |
| 646 // Erase the popup and update the UI. | 675 // Erase the popup and update the UI. |
| 647 UnblockedPopups::iterator next_popup = unblocked_popups_.erase(i); | 676 UnblockedPopups::iterator next_popup = unblocked_popups_.erase(i); |
| 648 if (blocked_popups_.empty() && unblocked_popups_.empty()) | 677 if (blocked_popups_.empty() && unblocked_popups_.empty()) |
| 649 HideSelf(); | 678 HideSelf(); |
| 650 else | 679 else |
| 651 container_view_->UpdateLabel(); | 680 container_view_->UpdateLabel(); |
| 652 return next_popup; | 681 return next_popup; |
| 653 } | 682 } |
| OLD | NEW |