summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views/blocked_popup_container.cc
diff options
context:
space:
mode:
authorerg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-03 16:44:57 +0000
committererg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-03 16:44:57 +0000
commit415ad48ad827f0a88645069f2bb731d497f5f23e (patch)
treea9efe67f99ae4625badca6c19848487e27bc5dad /chrome/browser/views/blocked_popup_container.cc
parentbd745438c31d1646cfb1e99a419e7b17dc2b90d2 (diff)
downloadchromium_src-415ad48ad827f0a88645069f2bb731d497f5f23e.zip
chromium_src-415ad48ad827f0a88645069f2bb731d497f5f23e.tar.gz
chromium_src-415ad48ad827f0a88645069f2bb731d497f5f23e.tar.bz2
This is the first of probably several patches trying to clean up the BlockedPopupContainer into something that can be cross-platform.
- BlokedPopupContainers are no longer ConstrainedWindows. - There is now a cross platform base class that contains most of the model/controller logic. The view now inherits from it. This is an improvement. Review URL: http://codereview.chromium.org/119006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17483 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/views/blocked_popup_container.cc')
-rw-r--r--chrome/browser/views/blocked_popup_container.cc433
1 files changed, 68 insertions, 365 deletions
diff --git a/chrome/browser/views/blocked_popup_container.cc b/chrome/browser/views/blocked_popup_container.cc
index fba9780..38fa3a5 100644
--- a/chrome/browser/views/blocked_popup_container.cc
+++ b/chrome/browser/views/blocked_popup_container.cc
@@ -11,6 +11,7 @@
#include "chrome/browser/views/blocked_popup_container.h"
#include <math.h>
+#include <windows.h>
#include "app/gfx/canvas.h"
#include "app/gfx/path.h"
@@ -21,19 +22,14 @@
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/notification_service.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/common/pref_service.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "views/background.h"
#include "views/controls/button/image_button.h"
-namespace {
-// A number larger than the internal popup count on the Renderer; meant for
-// preventing a compromised renderer from exhausting GDI memory by spawning
-// infinite windows.
-const int kImpossibleNumberOfPopups = 30;
+#include "views/controls/scrollbar/native_scroll_bar.h"
+namespace {
// The minimal border around the edge of the notification.
const int kSmallPadding = 2;
@@ -78,10 +74,10 @@ const SkScalar kRoundedCornerRad[8] = {
0
};
-}
+} // namespace
BlockedPopupContainerView::BlockedPopupContainerView(
- BlockedPopupContainer* container)
+ BlockedPopupContainerImpl* container)
: container_(container) {
ResourceBundle &resource_bundle = ResourceBundle::GetSharedInstance();
@@ -200,7 +196,8 @@ void BlockedPopupContainerView::ButtonPressed(views::Button* sender) {
if (!hosts.empty() && (popup_count > 0))
launch_menu_->AppendSeparator();
for (size_t i = 0; i < hosts.size(); ++i) {
- launch_menu_->AppendMenuItem(kImpossibleNumberOfPopups + i + 1,
+ launch_menu_->AppendMenuItem(
+ BlockedPopupContainer::kImpossibleNumberOfPopups + i + 1,
l10n_util::GetStringF(IDS_POPUP_HOST_FORMAT, hosts[i]),
views::Menu::NORMAL);
}
@@ -215,9 +212,9 @@ void BlockedPopupContainerView::ButtonPressed(views::Button* sender) {
}
bool BlockedPopupContainerView::IsItemChecked(int id) const {
- if (id > kImpossibleNumberOfPopups) {
+ if (id > BlockedPopupContainer::kImpossibleNumberOfPopups) {
return container_->IsHostWhitelisted(static_cast<size_t>(
- id - kImpossibleNumberOfPopups - 1));
+ id - BlockedPopupContainer::kImpossibleNumberOfPopups - 1));
}
return false;
@@ -226,114 +223,29 @@ bool BlockedPopupContainerView::IsItemChecked(int id) const {
void BlockedPopupContainerView::ExecuteCommand(int id) {
DCHECK_GT(id, 0);
size_t id_size_t = static_cast<size_t>(id);
- if (id_size_t > kImpossibleNumberOfPopups) {
+ if (id_size_t > BlockedPopupContainer::kImpossibleNumberOfPopups) {
// Decrement id since all index based commands have 1 added to them. (See
// ButtonPressed() for detail).
container_->ToggleWhitelistingForHost(
- id_size_t - kImpossibleNumberOfPopups - 1);
+ id_size_t - BlockedPopupContainer::kImpossibleNumberOfPopups - 1);
} else {
container_->LaunchPopupAtIndex(id_size_t - 1);
}
}
-BlockedPopupContainer::~BlockedPopupContainer() {
-}
-
-// static
-void BlockedPopupContainer::RegisterUserPrefs(PrefService* prefs) {
- prefs->RegisterListPref(prefs::kPopupWhitelistedHosts);
+BlockedPopupContainerImpl::~BlockedPopupContainerImpl() {
}
// static
BlockedPopupContainer* BlockedPopupContainer::Create(
TabContents* owner, Profile* profile, const gfx::Point& initial_anchor) {
- BlockedPopupContainer* container =
- new BlockedPopupContainer(owner, profile->GetPrefs());
+ BlockedPopupContainerImpl* container =
+ new BlockedPopupContainerImpl(owner, profile->GetPrefs());
container->Init(initial_anchor);
return container;
}
-void BlockedPopupContainer::AddTabContents(TabContents* tab_contents,
- const gfx::Rect& bounds,
- const std::string& host) {
- // Show whitelisted popups immediately.
- bool whitelisted = !!whitelist_.count(host);
- if (whitelisted)
- owner_->AddNewContents(tab_contents, NEW_POPUP, bounds, true, GURL());
-
- if (has_been_dismissed_) {
- // Don't want to show any other UI.
- if (!whitelisted)
- delete tab_contents; // Discard blocked popups entirely.
- return;
- }
-
- if (whitelisted) {
- // Listen for this popup's destruction, so if the user closes it manually,
- // we'll know to stop caring about it.
- registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED,
- Source<TabContents>(tab_contents));
-
- unblocked_popups_[tab_contents] = host;
- } else {
- if (blocked_popups_.size() >= kImpossibleNumberOfPopups) {
- delete tab_contents;
- LOG(INFO) << "Warning: Renderer is sending more popups to us than should "
- "be possible. Renderer compromised?";
- return;
- }
- blocked_popups_.push_back(BlockedPopup(tab_contents, bounds, host));
-
- tab_contents->set_delegate(this);
- }
-
- PopupHosts::const_iterator i(popup_hosts_.find(host));
- if (i == popup_hosts_.end())
- popup_hosts_[host] = whitelisted;
- else
- DCHECK_EQ(whitelisted, i->second);
-
- // Update UI.
- container_view_->UpdateLabel();
- SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
- if (!Animation::IsAnimating() && visibility_percentage_ < 1.0) {
- in_show_animation_ = true;
- Animation::SetDuration(kShowAnimationDurationMS);
- Animation::Start();
- }
- owner_->PopupNotificationVisibilityChanged(true);
-}
-
-void BlockedPopupContainer::LaunchPopupAtIndex(size_t index) {
- if (index >= blocked_popups_.size())
- return;
-
- // Open the popup.
- BlockedPopups::iterator i(blocked_popups_.begin() + index);
- TabContents* tab_contents = i->tab_contents;
- tab_contents->set_delegate(NULL);
- owner_->AddNewContents(tab_contents, NEW_POPUP, i->bounds, true, GURL());
-
- const std::string& host = i->host;
- if (!host.empty()) {
- // Listen for this popup's destruction, so if the user closes it manually,
- // we'll know to stop caring about it.
- registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED,
- Source<TabContents>(tab_contents));
-
- // Add the popup to the unblocked list. (Do this before the below call!)
- unblocked_popups_[tab_contents] = i->host;
- }
-
- // Remove the popup from the blocked list.
- EraseDataForPopupAndUpdateUI(i);
-}
-
-size_t BlockedPopupContainer::GetBlockedPopupCount() const {
- return blocked_popups_.size();
-}
-
-void BlockedPopupContainer::GetURLAndTitleForPopup(size_t index,
+void BlockedPopupContainerImpl::GetURLAndTitleForPopup(size_t index,
std::wstring* url,
std::wstring* title) const {
DCHECK(url);
@@ -344,7 +256,7 @@ void BlockedPopupContainer::GetURLAndTitleForPopup(size_t index,
*title = UTF16ToWideHack(tab_contents->GetTitle());
}
-std::vector<std::wstring> BlockedPopupContainer::GetHosts() const {
+std::vector<std::wstring> BlockedPopupContainerImpl::GetHosts() const {
std::vector<std::wstring> hosts;
for (PopupHosts::const_iterator i(popup_hosts_.begin());
i != popup_hosts_.end(); ++i)
@@ -352,187 +264,61 @@ std::vector<std::wstring> BlockedPopupContainer::GetHosts() const {
return hosts;
}
-bool BlockedPopupContainer::IsHostWhitelisted(size_t index) const {
- PopupHosts::const_iterator i(ConvertHostIndexToIterator(index));
- return (i == popup_hosts_.end()) ? false : i->second;
-}
-
-void BlockedPopupContainer::ToggleWhitelistingForHost(size_t index) {
- PopupHosts::const_iterator i(ConvertHostIndexToIterator(index));
- const std::string& host = i->first;
- bool should_whitelist = !i->second;
- popup_hosts_[host] = should_whitelist;
-
- ListValue* whitelist_pref =
- prefs_->GetMutableList(prefs::kPopupWhitelistedHosts);
- if (should_whitelist) {
- whitelist_.insert(host);
- whitelist_pref->Append(new StringValue(host));
-
- // Open the popups in order.
- for (size_t j = 0; j < blocked_popups_.size(); ) {
- if (blocked_popups_[j].host == host)
- LaunchPopupAtIndex(j); // This shifts the rest of the entries down.
- else
- ++j;
- }
- } else {
- // Remove from whitelist.
- whitelist_.erase(host);
- whitelist_pref->Remove(StringValue(host));
-
- for (UnblockedPopups::iterator i(unblocked_popups_.begin());
- i != unblocked_popups_.end(); ) {
- TabContents* tab_contents = i->first;
- TabContentsDelegate* delegate = tab_contents->delegate();
- if ((i->second == host) && delegate->IsPopup(tab_contents)) {
- // Convert the popup back into a blocked popup.
- delegate->DetachContents(tab_contents);
- tab_contents->set_delegate(this);
-
- // Add the popup to the blocked list. (Do this before the below call!)
- gfx::Rect bounds;
- tab_contents->GetContainerBounds(&bounds);
- blocked_popups_.push_back(BlockedPopup(tab_contents, bounds, host));
-
- // Remove the popup from the unblocked list.
- i = EraseDataForPopupAndUpdateUI(i);
- } else {
- ++i;
- }
- }
- }
-}
-
-void BlockedPopupContainer::CloseAll() {
- ClearData();
- HideSelf();
-}
-
// Overridden from ConstrainedWindow:
-void BlockedPopupContainer::CloseConstrainedWindow() {
+void BlockedPopupContainerImpl::Destroy() {
ClearData();
-
- // Broadcast to all observers of NOTIFY_CWINDOW_CLOSED.
- // One example of such an observer is AutomationCWindowTracker in the
- // automation component.
- NotificationService::current()->Notify(NotificationType::CWINDOW_CLOSED,
- Source<ConstrainedWindow>(this),
- NotificationService::NoDetails());
-
Close();
}
-void BlockedPopupContainer::RepositionConstrainedWindowTo(
- const gfx::Point& anchor_point) {
- anchor_point_ = anchor_point;
- SetPosition();
-}
+void BlockedPopupContainerImpl::RepositionBlockedPopupContainer(
+ gfx::NativeView view) {
+ if (::IsWindow(view)) {
+ CRect client_rect;
+ ::GetClientRect(view, &client_rect);
-// Overridden from TabContentsDelegate:
-void BlockedPopupContainer::OpenURLFromTab(TabContents* source,
- const GURL& url,
- const GURL& referrer,
- WindowOpenDisposition disposition,
- PageTransition::Type transition) {
- owner_->OpenURL(url, referrer, disposition, transition);
-}
+ // TODO(erg): There's no way to detect whether scroll bars are
+ // visible, so for beta, we're just going to assume that the
+ // vertical scroll bar is visible, and not care about covering up
+ // the horizontal scroll bar. Fixing this is half of
+ // http://b/1118139.
+ gfx::Point anchor_position(
+ client_rect.Width() -
+ views::NativeScrollBar::GetVerticalScrollBarWidth(),
+ client_rect.Height());
-void BlockedPopupContainer::AddNewContents(TabContents* source,
- TabContents* new_contents,
- WindowOpenDisposition disposition,
- const gfx::Rect& initial_position,
- bool user_gesture) {
- owner_->AddNewContents(new_contents, disposition, initial_position,
- user_gesture, GURL());
-}
-
-void BlockedPopupContainer::CloseContents(TabContents* source) {
- for (BlockedPopups::iterator it = blocked_popups_.begin();
- it != blocked_popups_.end(); ++it) {
- TabContents* tab_contents = it->tab_contents;
- if (tab_contents == source) {
- tab_contents->set_delegate(NULL);
- EraseDataForPopupAndUpdateUI(it);
- delete tab_contents;
- break;
- }
- }
-}
-
-void BlockedPopupContainer::MoveContents(TabContents* source,
- const gfx::Rect& new_bounds) {
- for (BlockedPopups::iterator it = blocked_popups_.begin();
- it != blocked_popups_.end(); ++it) {
- if (it->tab_contents == source) {
- it->bounds = new_bounds;
- break;
- }
+ RepositionWindowTo(anchor_position);
}
}
-bool BlockedPopupContainer::IsPopup(TabContents* source) {
- return true;
-}
-
-TabContents* BlockedPopupContainer::GetConstrainingContents(
- TabContents* source) {
- return owner_;
-}
-
-ExtensionFunctionDispatcher* BlockedPopupContainer::
- CreateExtensionFunctionDispatcher(RenderViewHost* render_view_host,
- const std::string& extension_id) {
- return new ExtensionFunctionDispatcher(render_view_host, NULL, extension_id);
-}
-
// private:
-BlockedPopupContainer::BlockedPopupContainer(TabContents* owner,
- PrefService* prefs)
- : Animation(kFramerate, NULL),
- owner_(owner),
- prefs_(prefs),
+BlockedPopupContainerImpl::BlockedPopupContainerImpl(TabContents* owner,
+ PrefService* prefs)
+ : BlockedPopupContainer(owner, prefs),
+ Animation(kFramerate, NULL),
container_view_(NULL),
- has_been_dismissed_(false),
in_show_animation_(false),
visibility_percentage_(0) {
- // Copy whitelist pref into local member that's easier to use.
- const ListValue* whitelist_pref =
- prefs_->GetList(prefs::kPopupWhitelistedHosts);
- // Careful: The returned value could be NULL if the pref has never been set.
- if (whitelist_pref != NULL) {
- for (ListValue::const_iterator i(whitelist_pref->begin());
- i != whitelist_pref->end(); ++i) {
- std::string host;
- (*i)->GetAsString(&host);
- whitelist_.insert(host);
- }
- }
}
-void BlockedPopupContainer::AnimateToState(double state) {
- visibility_percentage_ = in_show_animation_ ? state : (1 - state);
+void BlockedPopupContainerImpl::RepositionWindowTo(
+ const gfx::Point& anchor_point) {
+ anchor_point_ = anchor_point;
SetPosition();
}
-void BlockedPopupContainer::Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- DCHECK(type == NotificationType::TAB_CONTENTS_DESTROYED);
- TabContents* tab_contents = Source<TabContents>(source).ptr();
- UnblockedPopups::iterator i(unblocked_popups_.find(tab_contents));
- DCHECK(i != unblocked_popups_.end());
- EraseDataForPopupAndUpdateUI(i);
+void BlockedPopupContainerImpl::AnimateToState(double state) {
+ visibility_percentage_ = in_show_animation_ ? state : (1 - state);
+ SetPosition();
}
-void BlockedPopupContainer::OnFinalMessage(HWND window) {
- owner_->WillClose(this);
+void BlockedPopupContainerImpl::OnFinalMessage(HWND window) {
+ GetConstrainingContents(NULL)->WillCloseBlockedPopupContainer(this);
ClearData();
WidgetWin::OnFinalMessage(window);
}
-void BlockedPopupContainer::OnSize(UINT param, const CSize& size) {
+void BlockedPopupContainerImpl::OnSize(UINT param, const CSize& size) {
// Set the window region so we have rounded corners on the top.
SkRect rect;
rect.set(0, 0, SkIntToScalar(size.cx), SkIntToScalar(size.cy));
@@ -543,24 +329,41 @@ void BlockedPopupContainer::OnSize(UINT param, const CSize& size) {
ChangeSize(param, size);
}
-void BlockedPopupContainer::Init(const gfx::Point& initial_anchor) {
+void BlockedPopupContainerImpl::Init(const gfx::Point& initial_anchor) {
container_view_ = new BlockedPopupContainerView(this);
container_view_->SetVisible(true);
set_window_style(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
- WidgetWin::Init(owner_->GetNativeView(), gfx::Rect(), false);
+ WidgetWin::Init(GetConstrainingContents(NULL)->GetNativeView(), gfx::Rect(),
+ false);
SetContentsView(container_view_);
- RepositionConstrainedWindowTo(initial_anchor);
+ RepositionWindowTo(initial_anchor);
}
-void BlockedPopupContainer::HideSelf() {
+void BlockedPopupContainerImpl::ShowSelf() {
+ SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
+ if (!Animation::IsAnimating() && visibility_percentage_ < 1.0) {
+ in_show_animation_ = true;
+ Animation::SetDuration(kShowAnimationDurationMS);
+ Animation::Start();
+ }
+}
+
+void BlockedPopupContainerImpl::HideSelf() {
in_show_animation_ = false;
Animation::SetDuration(kHideAnimationDurationMS);
Animation::Start();
- owner_->PopupNotificationVisibilityChanged(false);
+ BlockedPopupContainer::HideSelf();
+}
+
+void BlockedPopupContainerImpl::UpdateLabel() {
+ if (blocked_popups_.empty() && unblocked_popups_.empty())
+ HideSelf();
+ else
+ container_view_->UpdateLabel();
}
-void BlockedPopupContainer::SetPosition() {
+void BlockedPopupContainerImpl::SetPosition() {
gfx::Size size = container_view_->GetPreferredSize();
int base_x = anchor_point_.x() - size.width();
int base_y = anchor_point_.y() - size.height();
@@ -590,103 +393,3 @@ void BlockedPopupContainer::SetPosition() {
SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW);
}
}
-
-void BlockedPopupContainer::ClearData() {
- for (BlockedPopups::iterator i(blocked_popups_.begin());
- i != blocked_popups_.end(); ++i) {
- TabContents* tab_contents = i->tab_contents;
- tab_contents->set_delegate(NULL);
- delete tab_contents;
- }
- blocked_popups_.clear();
-
- registrar_.RemoveAll();
- unblocked_popups_.clear();
-
- popup_hosts_.clear();
-}
-
-BlockedPopupContainer::PopupHosts::const_iterator
- BlockedPopupContainer::ConvertHostIndexToIterator(size_t index) const {
- if (index >= popup_hosts_.size())
- return popup_hosts_.end();
- // If only there was a std::map::const_iterator::operator +=() ...
- PopupHosts::const_iterator i(popup_hosts_.begin());
- for (size_t j = 0; j < index; ++j)
- ++i;
- return i;
-}
-
-void BlockedPopupContainer::EraseDataForPopupAndUpdateUI(
- BlockedPopups::iterator i) {
- // Erase the host if this is the last popup for that host.
- const std::string& host = i->host;
- if (!host.empty()) {
- bool should_erase_host = true;
- for (BlockedPopups::const_iterator j(blocked_popups_.begin());
- j != blocked_popups_.end(); ++j) {
- if ((j != i) && (j->host == host)) {
- should_erase_host = false;
- break;
- }
- }
- if (should_erase_host) {
- for (UnblockedPopups::const_iterator j(unblocked_popups_.begin());
- j != unblocked_popups_.end(); ++j) {
- if (j->second == host) {
- should_erase_host = false;
- break;
- }
- }
- if (should_erase_host)
- popup_hosts_.erase(host);
- }
- }
-
- // Erase the popup and update the UI.
- blocked_popups_.erase(i);
- if (blocked_popups_.empty() && unblocked_popups_.empty())
- HideSelf();
- else
- container_view_->UpdateLabel();
-}
-
-BlockedPopupContainer::UnblockedPopups::iterator
- BlockedPopupContainer::EraseDataForPopupAndUpdateUI(
- UnblockedPopups::iterator i) {
- // Stop listening for this popup's destruction.
- registrar_.Remove(this, NotificationType::TAB_CONTENTS_DESTROYED,
- Source<TabContents>(i->first));
-
- // Erase the host if this is the last popup for that host.
- const std::string& host = i->second;
- if (!host.empty()) {
- bool should_erase_host = true;
- for (UnblockedPopups::const_iterator j(unblocked_popups_.begin());
- j != unblocked_popups_.end(); ++j) {
- if ((j != i) && (j->second == host)) {
- should_erase_host = false;
- break;
- }
- }
- if (should_erase_host) {
- for (BlockedPopups::const_iterator j(blocked_popups_.begin());
- j != blocked_popups_.end(); ++j) {
- if (j->host == host) {
- should_erase_host = false;
- break;
- }
- }
- if (should_erase_host)
- popup_hosts_.erase(host);
- }
- }
-
- // Erase the popup and update the UI.
- UnblockedPopups::iterator next_popup = unblocked_popups_.erase(i);
- if (blocked_popups_.empty() && unblocked_popups_.empty())
- HideSelf();
- else
- container_view_->UpdateLabel();
- return next_popup;
-}