diff options
author | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-04 19:22:13 +0000 |
---|---|---|
committer | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-04 19:22:13 +0000 |
commit | 66ba493b842d92a7d9e515302d585d1c56848ee0 (patch) | |
tree | 59f303d8f54c0447268302fdabce7c873fe2c09b /chrome/browser/views | |
parent | 33b28a75192e79cff41ecbe82defd65ad5da9535 (diff) | |
download | chromium_src-66ba493b842d92a7d9e515302d585d1c56848ee0.zip chromium_src-66ba493b842d92a7d9e515302d585d1c56848ee0.tar.gz chromium_src-66ba493b842d92a7d9e515302d585d1c56848ee0.tar.bz2 |
Relanding 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.
This version has minor windows compile fixes that changed from under me.
Original Review URL: http://codereview.chromium.org/119006
TBR=beng
TEST=Popup notification still works.
Review URL: http://codereview.chromium.org/119107
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17647 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/views')
-rw-r--r-- | chrome/browser/views/blocked_popup_container.cc | 433 | ||||
-rw-r--r-- | chrome/browser/views/blocked_popup_container.h | 216 | ||||
-rw-r--r-- | chrome/browser/views/constrained_window_impl_interactive_uitest.cc | 30 |
3 files changed, 97 insertions, 582 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; -} diff --git a/chrome/browser/views/blocked_popup_container.h b/chrome/browser/views/blocked_popup_container.h index 291b0ee..74d3504 100644 --- a/chrome/browser/views/blocked_popup_container.h +++ b/chrome/browser/views/blocked_popup_container.h @@ -2,11 +2,6 @@ // source code is governed by a BSD-style license that can be found in the // LICENSE file. -// Defines the public interface for the blocked popup notifications. This -// interface should only be used by TabContents. Users and subclasses of -// TabContents should use the appropriate methods on TabContents to access -// information about blocked popups. - #ifndef CHROME_BROWSER_VIEWS_BLOCKED_POPUP_CONTAINER_H_ #define CHROME_BROWSER_VIEWS_BLOCKED_POPUP_CONTAINER_H_ @@ -15,17 +10,17 @@ #include <vector> #include "app/animation.h" +#include "base/gfx/native_widget_types.h" #include "base/gfx/rect.h" -#include "chrome/browser/tab_contents/constrained_window.h" +#include "chrome/browser/blocked_popup_container.h" #include "chrome/browser/tab_contents/tab_contents_delegate.h" -#include "chrome/common/notification_registrar.h" #include "views/controls/button/button.h" #include "views/controls/button/menu_button.h" #include "views/controls/menu/menu.h" #include "views/view.h" #include "views/widget/widget_win.h" -class BlockedPopupContainer; +class BlockedPopupContainerImpl; class PrefService; class Profile; class TabContents; @@ -41,7 +36,7 @@ class BlockedPopupContainerView : public views::View, public views::ButtonListener, public views::Menu::Delegate { public: - explicit BlockedPopupContainerView(BlockedPopupContainer* container); + explicit BlockedPopupContainerView(BlockedPopupContainerImpl* container); ~BlockedPopupContainerView(); // Sets the label on the menu button @@ -70,7 +65,7 @@ class BlockedPopupContainerView : public views::View, private: // Our owner and HWND parent. - BlockedPopupContainer* container_; + BlockedPopupContainerImpl* container_; // The button which brings up the popup menu. views::MenuButton* popup_count_label_; @@ -87,32 +82,14 @@ class BlockedPopupContainerView : public views::View, // Takes ownership of TabContents that are unrequested popup windows and // presents an interface to the user for launching them. (Or never showing them // again). -class BlockedPopupContainer : public Animation, - public ConstrainedWindow, - public NotificationObserver, - public TabContentsDelegate, - public views::WidgetWin { +// +// TODO(erg): When this class goes away, whatever is replaced shouldn't +// multiply inherit. +class BlockedPopupContainerImpl : public BlockedPopupContainer, + public Animation, + public views::WidgetWin { public: - virtual ~BlockedPopupContainer(); - - static void RegisterUserPrefs(PrefService* prefs); - - // Creates a BlockedPopupContainer, anchoring the container to the lower - // right corner. - static BlockedPopupContainer* Create( - TabContents* owner, Profile* profile, const gfx::Point& initial_anchor); - - // Adds a popup to this container. |bounds| are the window bounds requested by - // the popup window. - void AddTabContents(TabContents* tab_contents, - const gfx::Rect& bounds, - const std::string& host); - - // Shows the blocked popup at index |index|. - void LaunchPopupAtIndex(size_t index); - - // Returns the number of blocked popups - size_t GetBlockedPopupCount() const; + virtual ~BlockedPopupContainerImpl(); // Returns the URL and title for popup |index|, used to construct a string for // display. @@ -123,127 +100,25 @@ class BlockedPopupContainer : public Animation, // Returns the names of hosts showing popups. std::vector<std::wstring> GetHosts() const; - // Returns true if host |index| is whitelisted. Returns false if |index| is - // invalid. - bool IsHostWhitelisted(size_t index) const; - - // If host |index| is currently whitelisted, un-whitelists it. Otherwise, - // whitelists it and opens all blocked popups from it. - void ToggleWhitelistingForHost(size_t index); + virtual void Destroy(); - // Deletes all popups and hides the interface parts. - void CloseAll(); + virtual void RepositionBlockedPopupContainer(gfx::NativeView view); - // Called to force this container to never show itself again. - void set_dismissed() { has_been_dismissed_ = true; } - - // Overridden from ConstrainedWindow: + private: + friend class BlockedPopupContainer; - // Closes all of our blocked popups and then closes the BlockedPopupContainer. - virtual void CloseConstrainedWindow(); + // Creates a container for a certain TabContents. + BlockedPopupContainerImpl(TabContents* owner, PrefService* prefs); // Repositions our blocked popup notification so that the lower right corner // is at |anchor_point|. - virtual void RepositionConstrainedWindowTo(const gfx::Point& anchor_point); - - // A BlockedPopupContainer is part of the HWND heiarchy and therefore doesn't - // need to manually respond to hide and show events. - virtual void WasHidden() { } - virtual void DidBecomeSelected() { } - - // Debugging accessors only called from the unit tests. - virtual std::wstring GetWindowTitle() const { - return container_view_->label(); - } - virtual const gfx::Rect& GetCurrentBounds() const { return bounds_; } - - // Overridden from TabContentsDelegate: - - // Forwards OpenURLFromTab to our |owner_|. - virtual void OpenURLFromTab(TabContents* source, - const GURL& url, const GURL& referrer, - WindowOpenDisposition disposition, - PageTransition::Type transition); - - // Ignored; BlockedPopupContainer doesn't display a throbber. - virtual void NavigationStateChanged(const TabContents* source, - unsigned changed_flags) { } - - // Forwards AddNewContents to our |owner_|. - virtual void AddNewContents(TabContents* source, - TabContents* new_contents, - WindowOpenDisposition disposition, - const gfx::Rect& initial_position, - bool user_gesture); - - // Ignore activation requests from the TabContents we're blocking. - virtual void ActivateContents(TabContents* contents) { } - - // Ignored; BlockedPopupContainer doesn't display a throbber. - virtual void LoadingStateChanged(TabContents* source) { } - - // Removes |source| from our internal list of blocked popups. - virtual void CloseContents(TabContents* source); - - // Changes the opening rectangle associated with |source|. - virtual void MoveContents(TabContents* source, const gfx::Rect& new_bounds); - - // Always returns true. - virtual bool IsPopup(TabContents* source); - - // Returns our |owner_|. - virtual TabContents* GetConstrainingContents(TabContents* source); - - // Ignored; BlockedPopupContainer doesn't display a toolbar. - virtual void ToolbarSizeChanged(TabContents* source, bool is_animating) { } - - // Ignored; BlockedPopupContainer doesn't display a bookmarking star. - virtual void URLStarredChanged(TabContents* source, bool starred) { } - - // Ignored; BlockedPopupContainer doesn't display a URL bar. - virtual void UpdateTargetURL(TabContents* source, const GURL& url) { } - - // Creates an ExtensionFunctionDispatcher that has no browser - virtual ExtensionFunctionDispatcher* CreateExtensionFunctionDispatcher( - RenderViewHost* render_view_host, - const std::string& extension_id); - - private: - struct BlockedPopup { - BlockedPopup(TabContents* tab_contents, - const gfx::Rect& bounds, - const std::string& host) - : tab_contents(tab_contents), bounds(bounds), host(host) { - } - - TabContents* tab_contents; - gfx::Rect bounds; - std::string host; - }; - typedef std::vector<BlockedPopup> BlockedPopups; - - // TabContents is the popup contents. string is opener hostname. - typedef std::map<TabContents*, std::string> UnblockedPopups; - - // string is hostname. bool is whitelisted status. - typedef std::map<std::string, bool> PopupHosts; - - // string is hostname. - typedef std::set<std::string> Whitelist; - - // Creates a container for a certain TabContents. - BlockedPopupContainer(TabContents* owner, PrefService* prefs); + void RepositionWindowTo(const gfx::Point& anchor_point); // Overridden from Animation: - // Changes the visibility percentage of the BlockedPopupContainer. This is + // Changes the visibility percentage of the BlockedPopupContainerImpl. This is // called while animating in or out. virtual void AnimateToState(double state); - // Overridden from notificationObserver: - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - // Overridden from views::WidgetWin: // Alerts our |owner_| that we are closing ourselves. Cleans up any remaining @@ -257,59 +132,22 @@ class BlockedPopupContainer : public Animation, // browser window. void Init(const gfx::Point& initial_anchor); + // Shows the UI. + virtual void ShowSelf(); + // Hides the UI portion of the container. - void HideSelf(); + virtual void HideSelf(); + + virtual void UpdateLabel(); // Sets our position, based on our |anchor_point_| and on our // |visibility_percentage_|. This method is called whenever either of those // change. void SetPosition(); - // Deletes all local state. - void ClearData(); - - // Helper function to convert a host index (which the view uses) into an - // iterator into |popup_hosts_|. Returns popup_hosts_.end() if |index| is - // invalid. - PopupHosts::const_iterator ConvertHostIndexToIterator(size_t index) const; - - // Removes the popup at |i| from the blocked popup list. If this popup's host - // is not otherwised referenced on either popup list, removes the host from - // the host list. Updates the view's label to match the new state. - void EraseDataForPopupAndUpdateUI(BlockedPopups::iterator i); - - // Same as above, but works on the unblocked popup list, and returns the - // iterator that results from calling erase(). - UnblockedPopups::iterator EraseDataForPopupAndUpdateUI( - UnblockedPopups::iterator i); - - // The TabContents that owns and constrains this BlockedPopupContainer. - TabContents* owner_; - - // The PrefService we can query to find out what's on the whitelist. - PrefService* prefs_; - - // Registrar to handle notifications we care about. - NotificationRegistrar registrar_; - - // The whitelisted hosts, which we allow to open popups directly. - Whitelist whitelist_; - - // Information about all blocked popups. - BlockedPopups blocked_popups_; - - // Information about all unblocked popups. - UnblockedPopups unblocked_popups_; - - // Information about all popup hosts. - PopupHosts popup_hosts_; - // Our associated view object. BlockedPopupContainerView* container_view_; - // Once the container is hidden, this is set to prevent it from reappearing. - bool has_been_dismissed_; - // True while animating in; false while animating out. bool in_show_animation_; @@ -322,8 +160,6 @@ class BlockedPopupContainer : public Animation, // The bottom right corner of where we should appear in our parent window. gfx::Point anchor_point_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(BlockedPopupContainer); }; #endif diff --git a/chrome/browser/views/constrained_window_impl_interactive_uitest.cc b/chrome/browser/views/constrained_window_impl_interactive_uitest.cc index df8dd60..fcd7639 100644 --- a/chrome/browser/views/constrained_window_impl_interactive_uitest.cc +++ b/chrome/browser/views/constrained_window_impl_interactive_uitest.cc @@ -132,14 +132,6 @@ TEST_F(InteractiveConstrainedWindowTest, DontSpawnEndlessPopups) { scoped_refptr<TabProxy> popup_tab(popup_browser->GetTab(0)); ASSERT_TRUE(popup_tab.get()); - int constrained_window_count = 0; - ASSERT_TRUE(popup_tab->WaitForChildWindowCountToChange( - 0, &constrained_window_count, 10000)); - ASSERT_EQ(1, constrained_window_count); - scoped_refptr<ConstrainedWindowProxy> constrained_window( - popup_tab->GetConstrainedWindow(0)); - ASSERT_TRUE(constrained_window.get()); - // And now we spin, waiting to make sure that we don't spawn popup // windows endlessly. The current limit is 25, so allowing for possible race // conditions and one off errors, don't break out until we go over 30 popup @@ -151,9 +143,7 @@ TEST_F(InteractiveConstrainedWindowTest, DontSpawnEndlessPopups) { int times_slept = 0; bool continuing = true; while (continuing && popup_window_count < kMaxPopupWindows) { - std::wstring title; - ASSERT_TRUE(constrained_window->GetTitle(&title)); - ASSERT_TRUE(ParseCountOutOfTitle(title, &new_popup_window_count)); + ASSERT_TRUE(popup_tab->GetBlockedPopupCount(&new_popup_window_count)); if (new_popup_window_count == popup_window_count) { if (times_slept == 10) { continuing = false; @@ -180,8 +170,6 @@ TEST_F(InteractiveConstrainedWindowTest, WindowOpenWindowClosePopup) { ASSERT_TRUE(automation()->WaitForWindowCountToBecome(2, 5000)); - PlatformThread::Sleep(1000); - // Make sure we have a blocked popup notification scoped_refptr<BrowserProxy> popup_browser(automation()->GetBrowserWindow(1)); ASSERT_TRUE(popup_browser.get()); @@ -189,14 +177,7 @@ TEST_F(InteractiveConstrainedWindowTest, WindowOpenWindowClosePopup) { ASSERT_TRUE(popup_window.get()); scoped_refptr<TabProxy> popup_tab(popup_browser->GetTab(0)); ASSERT_TRUE(popup_tab.get()); - scoped_refptr<ConstrainedWindowProxy> popup_notification( - popup_tab->GetConstrainedWindow(0)); - ASSERT_TRUE(popup_notification.get()); - std::wstring title; - ASSERT_TRUE(popup_notification->GetTitle(&title)); - int count = 0; - ASSERT_TRUE(ParseCountOutOfTitle(title, &count)); - ASSERT_EQ(1, count); + ASSERT_TRUE(popup_tab->WaitForBlockedPopupCountToChangeTo(1, 1000)); // Ensure we didn't close the first popup window. ASSERT_FALSE(automation()->WaitForWindowCountToBecome(1, 3000)); @@ -214,13 +195,8 @@ TEST_F(InteractiveConstrainedWindowTest, BlockAlertFromBlockedPopup) { ASSERT_EQ(1, browser_window_count); // Ensure one blocked popup window: the popup didn't escape. - scoped_refptr<ConstrainedWindowProxy> popup_notification( - tab_->GetConstrainedWindow(0)); - ASSERT_TRUE(popup_notification.get()); - std::wstring title; - ASSERT_TRUE(popup_notification->GetTitle(&title)); int popup_count = 0; - ASSERT_TRUE(ParseCountOutOfTitle(title, &popup_count)); + ASSERT_TRUE(tab_->GetBlockedPopupCount(&popup_count)); ASSERT_EQ(1, popup_count); } |