summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorerg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-03 16:56:38 +0000
committererg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-03 16:56:38 +0000
commit0c9ee9904acbfe0766f488edb207ff232635efd3 (patch)
tree5118e9af778ed35f8a68490171a75676ce202c4d /chrome
parentbbf87943104ec3343bd93152500fdb0bf81ee563 (diff)
downloadchromium_src-0c9ee9904acbfe0766f488edb207ff232635efd3.zip
chromium_src-0c9ee9904acbfe0766f488edb207ff232635efd3.tar.gz
chromium_src-0c9ee9904acbfe0766f488edb207ff232635efd3.tar.bz2
Revert "This is the first of probably several patches trying to clean up the BlockedPopupContainer
into something that can be cross-platform." This reverts commit 0247f4d628f8f56c0a42ab44efd1d29058167a11 (r17483). Review URL: http://codereview.chromium.org/118166 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17485 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/automation/automation_provider.cc21
-rw-r--r--chrome/browser/automation/automation_provider.h3
-rw-r--r--chrome/browser/blocked_popup_container.cc337
-rw-r--r--chrome/browser/blocked_popup_container.h258
-rw-r--r--chrome/browser/browser.vcproj8
-rw-r--r--chrome/browser/tab_contents/tab_contents.cc40
-rw-r--r--chrome/browser/tab_contents/tab_contents.h12
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_win.cc2
-rw-r--r--chrome/browser/views/blocked_popup_container.cc433
-rw-r--r--chrome/browser/views/blocked_popup_container.h216
-rw-r--r--chrome/browser/views/constrained_window_impl_interactive_uitest.cc30
-rw-r--r--chrome/chrome.gyp2
-rw-r--r--chrome/test/automation/automation_messages_internal.h7
-rw-r--r--chrome/test/automation/automation_proxy_uitest.cc41
-rw-r--r--chrome/test/automation/tab_proxy.cc27
-rw-r--r--chrome/test/automation/tab_proxy.h7
-rw-r--r--chrome/test/data/constrained_files/constrained_window_onload_moveto.html17
17 files changed, 671 insertions, 790 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index fac1b83..c2e0877 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -21,7 +21,6 @@
#include "chrome/browser/automation/url_request_failed_dns_job.h"
#include "chrome/browser/automation/url_request_mock_http_job.h"
#include "chrome/browser/automation/url_request_slow_download_job.h"
-#include "chrome/browser/blocked_popup_container.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/dom_operation_notification_details.h"
#include "chrome/browser/download/download_manager.h"
@@ -1083,7 +1082,6 @@ void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(AutomationMsg_WindowTitle, GetWindowTitle)
IPC_MESSAGE_HANDLER(AutomationMsg_SetEnableExtensionAutomation,
SetEnableExtensionAutomation)
- IPC_MESSAGE_HANDLER(AutomationMsg_BlockedPopupCount, GetBlockedPopupCount)
IPC_END_MESSAGE_MAP()
}
@@ -2988,22 +2986,3 @@ void AutomationProvider::GetWindowTitle(int handle, string16* text) {
gfx::NativeWindow window = window_tracker_->GetResource(handle);
text->assign(platform_util::GetWindowTitle(window));
}
-
-void AutomationProvider::GetBlockedPopupCount(int handle, int* count) {
- *count = -1; // -1 is the error code
- if (tab_tracker_->ContainsHandle(handle)) {
- NavigationController* nav_controller = tab_tracker_->GetResource(handle);
- TabContents* tab_contents = nav_controller->tab_contents();
- if (tab_contents) {
- BlockedPopupContainer* container =
- tab_contents->blocked_popup_container();
- if (container) {
- *count = static_cast<int>(container->GetBlockedPopupCount());
- } else {
- // If we don't have a container, we don't have any blocked popups to
- // contain!
- *count = 0;
- }
- }
- }
-}
diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h
index 3c49ddb..1506868 100644
--- a/chrome/browser/automation/automation_provider.h
+++ b/chrome/browser/automation/automation_provider.h
@@ -451,9 +451,6 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>,
void GetWindowTitle(int handle, string16* text);
- // Returns the number of blocked popups in the tab |handle|.
- void GetBlockedPopupCount(int handle, int* count);
-
// Convert a tab handle into a TabContents. If |tab| is non-NULL a pointer
// to the tab is also returned. Returns NULL in case of failure or if the tab
// is not of the TabContents type.
diff --git a/chrome/browser/blocked_popup_container.cc b/chrome/browser/blocked_popup_container.cc
deleted file mode 100644
index ad9c7c6..0000000
--- a/chrome/browser/blocked_popup_container.cc
+++ /dev/null
@@ -1,337 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
-// source code is governed by a BSD-style license that can be found in the
-// LICENSE file.
-
-#include "chrome/browser/blocked_popup_container.h"
-
-#include "chrome/browser/extensions/extension_function_dispatcher.h"
-#include "chrome/browser/profile.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/common/pref_service.h"
-#include "chrome/common/notification_service.h"
-
-// static
-void BlockedPopupContainer::RegisterUserPrefs(PrefService* prefs) {
- prefs->RegisterListPref(prefs::kPopupWhitelistedHosts);
-}
-
-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.
- UpdateLabel();
- ShowSelf();
- 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();
-}
-
-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);
- StringValue host_as_string(host);
- whitelist_pref->Remove(host_as_string);
-
- 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.
- UnblockedPopups::iterator to_erase = i;
- ++i;
- EraseDataForPopupAndUpdateUI(to_erase);
- } else {
- ++i;
- }
- }
- }
-}
-
-void BlockedPopupContainer::CloseAll() {
- ClearData();
- HideSelf();
-}
-
-// 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);
-}
-
-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;
- }
- }
-}
-
-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);
-}
-
-void BlockedPopupContainer::HideSelf() {
- owner_->PopupNotificationVisibilityChanged(false);
-}
-
-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);
- UpdateLabel();
-}
-
-void 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.
- unblocked_popups_.erase(i);
- UpdateLabel();
-}
-
-
-// private:
-
-BlockedPopupContainer::BlockedPopupContainer(TabContents* owner,
- PrefService* prefs)
- : owner_(owner),
- prefs_(prefs),
- has_been_dismissed_(false) {
- // 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::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);
-}
diff --git a/chrome/browser/blocked_popup_container.h b/chrome/browser/blocked_popup_container.h
deleted file mode 100644
index f9b5d14..0000000
--- a/chrome/browser/blocked_popup_container.h
+++ /dev/null
@@ -1,258 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
-// 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_BLOCKED_POPUP_CONTAINER_H_
-#define CHROME_BROWSER_BLOCKED_POPUP_CONTAINER_H_
-
-#include <map>
-#include <set>
-
-#include "base/gfx/native_widget_types.h"
-#include "base/gfx/rect.h"
-#include "chrome/browser/tab_contents/constrained_window.h"
-#include "chrome/browser/tab_contents/tab_contents_delegate.h"
-#include "chrome/common/notification_registrar.h"
-
-class BlockedPopupContainerImpl;
-class PrefService;
-class Profile;
-class TabContents;
-
-// Takes ownership of TabContents that are unrequested popup windows and
-// presents an interface to the user for launching them. (Or never showing them
-// again). This class contains all the cross-platform bits that can be used in
-// all ports.
-//
-// Currently, BlockedPopupContainer only exists as a cross platform model
-// extracted from browser/views/blocked_popup_container.cc. This is what it
-// used to look like before:
-//
-// +- BlockedPopupContainer -------------------------------+
-// | <views::WidgetWin> |
-// | All model logic. |
-// | All views code. |
-// +-------------------------------------------------------+
-//
-// As of now, it looks like this:
-//
-// +- BlockedPopupContainer -------------------------------+
-// | All model logic |
-// +-------------------------------------------------------+
-// ^
-// |
-// +- BlockedPopupContainerImpl ---------------------------+
-// | views::WidgetWin |
-// | All views code. |
-// | |
-// +-------------------------------------------------------+
-//
-// TODO(erg): While it is not in this state yet, I want it to look like this:
-//
-// +- BlockedPopupContainer ---+ +- BlockedPopupContainerView -----+
-// | All model logic | +--->| Abstract cross platform |
-// | | | | interface |
-// | | | | |
-// | Owns a platform view_ +----+ | |
-// +---------------------------+ +---------------------------------+
-// ^
-// |
-// +-------------------------------+-----------+
-// | |
-// +- BPCViewGtk -----------+ +- BPCViewWin ----------------------+
-// | Gtk UI | | Views UI |
-// | | | |
-// +------------------------+ +-----------------------------------+
-//
-// Getting here will take multiple patches.
-class BlockedPopupContainer : public TabContentsDelegate,
- public NotificationObserver {
- public:
- // Creates a BlockedPopupContainer, anchoring the container to the lower
- // right corner.
- static BlockedPopupContainer* Create(
- TabContents* owner, Profile* profile, const gfx::Point& initial_anchor);
-
- static void RegisterUserPrefs(PrefService* prefs);
-
- // 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;
-
- // 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);
-
- // Deletes all popups and hides the interface parts.
- void CloseAll();
-
- // Sets this object up to delete itself.
- virtual void Destroy() = 0;
-
- // Message called when a BlockedPopupContainer should move itself to the
- // bottom right corner of |view|.
- virtual void RepositionBlockedPopupContainer(gfx::NativeView view) = 0;
-
- // Called to force this container to never show itself again.
- void set_dismissed() { has_been_dismissed_ = true; }
-
- // 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);
-
- // 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.
- static const size_t kImpossibleNumberOfPopups = 30;
-
- protected:
- 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;
-
- // Shows the UI.
- virtual void ShowSelf() = 0;
-
- // Hides the UI portion of the container.
- virtual void HideSelf();
-
- // Updates the text on the label on the notification.
- virtual void UpdateLabel() = 0;
-
- // Deletes all local state.
- virtual 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.
- void EraseDataForPopupAndUpdateUI(UnblockedPopups::iterator i);
-
- private:
- friend class BlockedPopupContainerImpl;
-
- // string is hostname.
- typedef std::set<std::string> Whitelist;
-
- // Creates a container for a certain TabContents:
- BlockedPopupContainer(TabContents* owner, PrefService* prefs);
-
- // Overridden from notificationObserver:
- virtual void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details);
-
- // 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_;
-
- // Once the container is hidden, this is set to prevent it from reappearing.
- bool has_been_dismissed_;
-
- // 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_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(BlockedPopupContainer);
-};
-
-#endif // CHROME_BROWSER_BLOCKED_POPUP_CONTAINER_H_
diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj
index bf7d2df..d11b0dc 100644
--- a/chrome/browser/browser.vcproj
+++ b/chrome/browser/browser.vcproj
@@ -2669,14 +2669,6 @@
</File>
</Filter>
<File
- RelativePath=".\blocked_popup_container.cc"
- >
- </File>
- <File
- RelativePath=".\blocked_popup_container.h"
- >
- </File>
- <File
RelativePath=".\browser_trial.cc"
>
</File>
diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc
index 509b38f..db05c00 100644
--- a/chrome/browser/tab_contents/tab_contents.cc
+++ b/chrome/browser/tab_contents/tab_contents.cc
@@ -11,7 +11,6 @@
#include "base/string16.h"
#include "base/time.h"
#include "chrome/browser/autofill_manager.h"
-#include "chrome/browser/blocked_popup_container.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/cert_store.h"
@@ -58,6 +57,7 @@
#if defined(OS_WIN)
// TODO(port): some of these headers should be ported.
#include "chrome/browser/modal_html_dialog_delegate.h"
+#include "chrome/browser/views/blocked_popup_container.h"
#include "views/controls/scrollbar/native_scroll_bar.h"
#endif
@@ -315,9 +315,6 @@ TabContents::~TabContents() {
window->CloseConstrainedWindow();
}
- if (blocked_popups_)
- blocked_popups_->Destroy();
-
// Notify any observer that have a reference on this tab contents.
NotificationService::current()->Notify(
NotificationType::TAB_CONTENTS_DESTROYED,
@@ -827,10 +824,12 @@ void TabContents::AddNewContents(TabContents* new_contents,
#endif
}
+#if defined(OS_WIN)
void TabContents::CloseAllSuppressedPopups() {
if (blocked_popups_)
blocked_popups_->CloseAll();
}
+#endif
void TabContents::PopupNotificationVisibilityChanged(bool visible) {
render_view_host()->PopupNotificationVisibilityChanged(visible);
@@ -1007,12 +1006,18 @@ void TabContents::WillClose(ConstrainedWindow* window) {
find(child_windows_.begin(), child_windows_.end(), window);
if (it != child_windows_.end())
child_windows_.erase(it);
-}
-void TabContents::WillCloseBlockedPopupContainer(
- BlockedPopupContainer* container) {
- DCHECK(blocked_popups_ == container);
- blocked_popups_ = NULL;
+#if defined(OS_WIN)
+ if (window == blocked_popups_)
+ blocked_popups_ = NULL;
+
+ if (::IsWindow(GetNativeView())) {
+ CRect client_rect;
+ GetClientRect(GetNativeView(), &client_rect);
+ RepositionSupressedPopupsToFit(
+ gfx::Size(client_rect.Width(), client_rect.Height()));
+ }
+#endif
}
void TabContents::DidMoveOrResize(ConstrainedWindow* window) {
@@ -1176,6 +1181,7 @@ void TabContents::CreateBlockedPopupContainerIfNecessary() {
client_rect.Height());
blocked_popups_ = BlockedPopupContainer::Create(this, profile(),
anchor_position);
+ child_windows_.push_back(blocked_popups_);
}
void TabContents::AddPopup(TabContents* new_contents,
@@ -1184,18 +1190,28 @@ void TabContents::AddPopup(TabContents* new_contents,
CreateBlockedPopupContainerIfNecessary();
blocked_popups_->AddTabContents(new_contents, initial_pos, host);
}
-#endif
// TODO(brettw) This should be on the TabContentsView.
-void TabContents::RepositionSupressedPopupsToFit() {
+void TabContents::RepositionSupressedPopupsToFit(const gfx::Size& new_size) {
+ // 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(
+ new_size.width() -
+ views::NativeScrollBar::GetVerticalScrollBarWidth(),
+ new_size.height());
+
if (blocked_popups_)
- blocked_popups_->RepositionBlockedPopupContainer(GetNativeView());
+ blocked_popups_->RepositionConstrainedWindowTo(anchor_position);
}
bool TabContents::ShowingBlockedPopupNotification() const {
return blocked_popups_ != NULL &&
blocked_popups_->GetBlockedPopupCount() != 0;
}
+#endif // defined(OS_WIN)
namespace {
bool TransitionIsReload(PageTransition::Type transition) {
diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h
index c766f56..c43a919 100644
--- a/chrome/browser/tab_contents/tab_contents.h
+++ b/chrome/browser/tab_contents/tab_contents.h
@@ -432,9 +432,6 @@ class TabContents : public PageNavigator,
// Called when a ConstrainedWindow we own is about to be closed.
void WillClose(ConstrainedWindow* window);
- // Called when a BlockedPopupContainer we own is about to be closed.
- void WillCloseBlockedPopupContainer(BlockedPopupContainer* container);
-
// Called when a ConstrainedWindow we own is moved or resized.
void DidMoveOrResize(ConstrainedWindow* window);
@@ -577,10 +574,6 @@ class TabContents : public PageNavigator,
render_view_host()->WindowMoveOrResizeStarted();
}
- BlockedPopupContainer* blocked_popup_container() const {
- return blocked_popups_;
- }
-
private:
friend class NavigationController;
// Used to access the child_windows_ (ConstrainedWindowList) for testing
@@ -641,7 +634,7 @@ class TabContents : public PageNavigator,
// Called by a derived class when the TabContents is resized, causing
// suppressed constrained web popups to be repositioned to the new bounds
// if necessary.
- void RepositionSupressedPopupsToFit();
+ void RepositionSupressedPopupsToFit(const gfx::Size& new_size);
// Whether we have a notification AND the notification owns popups windows.
// (We keep the notification object around even when it's not shown since it
@@ -1006,7 +999,8 @@ class TabContents : public PageNavigator,
bool shelf_visible_;
// ConstrainedWindow with additional methods for managing blocked
- // popups.
+ // popups. This pointer also goes in |child_windows_| for ownership,
+ // repositioning, etc.
BlockedPopupContainer* blocked_popups_;
// Delegates for InfoBars associated with this TabContents.
diff --git a/chrome/browser/tab_contents/tab_contents_view_win.cc b/chrome/browser/tab_contents/tab_contents_view_win.cc
index 6b673e8..fac170d 100644
--- a/chrome/browser/tab_contents/tab_contents_view_win.cc
+++ b/chrome/browser/tab_contents/tab_contents_view_win.cc
@@ -570,7 +570,7 @@ void TabContentsViewWin::WasSized(const gfx::Size& size) {
tab_contents()->render_widget_host_view()->SetSize(size);
// TODO(brettw) this function can probably be moved to this class.
- tab_contents()->RepositionSupressedPopupsToFit();
+ tab_contents()->RepositionSupressedPopupsToFit(size);
}
bool TabContentsViewWin::ScrollZoom(int scroll_type) {
diff --git a/chrome/browser/views/blocked_popup_container.cc b/chrome/browser/views/blocked_popup_container.cc
index 38fa3a5..fba9780 100644
--- a/chrome/browser/views/blocked_popup_container.cc
+++ b/chrome/browser/views/blocked_popup_container.cc
@@ -11,7 +11,6 @@
#include "chrome/browser/views/blocked_popup_container.h"
#include <math.h>
-#include <windows.h>
#include "app/gfx/canvas.h"
#include "app/gfx/path.h"
@@ -22,14 +21,19 @@
#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"
-#include "views/controls/scrollbar/native_scroll_bar.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;
+
// The minimal border around the edge of the notification.
const int kSmallPadding = 2;
@@ -74,10 +78,10 @@ const SkScalar kRoundedCornerRad[8] = {
0
};
-} // namespace
+}
BlockedPopupContainerView::BlockedPopupContainerView(
- BlockedPopupContainerImpl* container)
+ BlockedPopupContainer* container)
: container_(container) {
ResourceBundle &resource_bundle = ResourceBundle::GetSharedInstance();
@@ -196,8 +200,7 @@ 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(
- BlockedPopupContainer::kImpossibleNumberOfPopups + i + 1,
+ launch_menu_->AppendMenuItem(kImpossibleNumberOfPopups + i + 1,
l10n_util::GetStringF(IDS_POPUP_HOST_FORMAT, hosts[i]),
views::Menu::NORMAL);
}
@@ -212,9 +215,9 @@ void BlockedPopupContainerView::ButtonPressed(views::Button* sender) {
}
bool BlockedPopupContainerView::IsItemChecked(int id) const {
- if (id > BlockedPopupContainer::kImpossibleNumberOfPopups) {
+ if (id > kImpossibleNumberOfPopups) {
return container_->IsHostWhitelisted(static_cast<size_t>(
- id - BlockedPopupContainer::kImpossibleNumberOfPopups - 1));
+ id - kImpossibleNumberOfPopups - 1));
}
return false;
@@ -223,29 +226,114 @@ 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 > BlockedPopupContainer::kImpossibleNumberOfPopups) {
+ if (id_size_t > kImpossibleNumberOfPopups) {
// Decrement id since all index based commands have 1 added to them. (See
// ButtonPressed() for detail).
container_->ToggleWhitelistingForHost(
- id_size_t - BlockedPopupContainer::kImpossibleNumberOfPopups - 1);
+ id_size_t - kImpossibleNumberOfPopups - 1);
} else {
container_->LaunchPopupAtIndex(id_size_t - 1);
}
}
-BlockedPopupContainerImpl::~BlockedPopupContainerImpl() {
+BlockedPopupContainer::~BlockedPopupContainer() {
+}
+
+// static
+void BlockedPopupContainer::RegisterUserPrefs(PrefService* prefs) {
+ prefs->RegisterListPref(prefs::kPopupWhitelistedHosts);
}
// static
BlockedPopupContainer* BlockedPopupContainer::Create(
TabContents* owner, Profile* profile, const gfx::Point& initial_anchor) {
- BlockedPopupContainerImpl* container =
- new BlockedPopupContainerImpl(owner, profile->GetPrefs());
+ BlockedPopupContainer* container =
+ new BlockedPopupContainer(owner, profile->GetPrefs());
container->Init(initial_anchor);
return container;
}
-void BlockedPopupContainerImpl::GetURLAndTitleForPopup(size_t index,
+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,
std::wstring* url,
std::wstring* title) const {
DCHECK(url);
@@ -256,7 +344,7 @@ void BlockedPopupContainerImpl::GetURLAndTitleForPopup(size_t index,
*title = UTF16ToWideHack(tab_contents->GetTitle());
}
-std::vector<std::wstring> BlockedPopupContainerImpl::GetHosts() const {
+std::vector<std::wstring> BlockedPopupContainer::GetHosts() const {
std::vector<std::wstring> hosts;
for (PopupHosts::const_iterator i(popup_hosts_.begin());
i != popup_hosts_.end(); ++i)
@@ -264,61 +352,187 @@ std::vector<std::wstring> BlockedPopupContainerImpl::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 BlockedPopupContainerImpl::Destroy() {
+void BlockedPopupContainer::CloseConstrainedWindow() {
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 BlockedPopupContainerImpl::RepositionBlockedPopupContainer(
- gfx::NativeView view) {
- if (::IsWindow(view)) {
- CRect client_rect;
- ::GetClientRect(view, &client_rect);
+void BlockedPopupContainer::RepositionConstrainedWindowTo(
+ const gfx::Point& anchor_point) {
+ anchor_point_ = anchor_point;
+ SetPosition();
+}
- // 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());
+// 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);
+}
- RepositionWindowTo(anchor_position);
+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;
+ }
}
}
+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:
-BlockedPopupContainerImpl::BlockedPopupContainerImpl(TabContents* owner,
- PrefService* prefs)
- : BlockedPopupContainer(owner, prefs),
- Animation(kFramerate, NULL),
+BlockedPopupContainer::BlockedPopupContainer(TabContents* owner,
+ PrefService* prefs)
+ : Animation(kFramerate, NULL),
+ owner_(owner),
+ prefs_(prefs),
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 BlockedPopupContainerImpl::RepositionWindowTo(
- const gfx::Point& anchor_point) {
- anchor_point_ = anchor_point;
+void BlockedPopupContainer::AnimateToState(double state) {
+ visibility_percentage_ = in_show_animation_ ? state : (1 - state);
SetPosition();
}
-void BlockedPopupContainerImpl::AnimateToState(double state) {
- visibility_percentage_ = in_show_animation_ ? state : (1 - state);
- 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::OnFinalMessage(HWND window) {
- GetConstrainingContents(NULL)->WillCloseBlockedPopupContainer(this);
+void BlockedPopupContainer::OnFinalMessage(HWND window) {
+ owner_->WillClose(this);
ClearData();
WidgetWin::OnFinalMessage(window);
}
-void BlockedPopupContainerImpl::OnSize(UINT param, const CSize& size) {
+void BlockedPopupContainer::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));
@@ -329,41 +543,24 @@ void BlockedPopupContainerImpl::OnSize(UINT param, const CSize& size) {
ChangeSize(param, size);
}
-void BlockedPopupContainerImpl::Init(const gfx::Point& initial_anchor) {
+void BlockedPopupContainer::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(GetConstrainingContents(NULL)->GetNativeView(), gfx::Rect(),
- false);
+ WidgetWin::Init(owner_->GetNativeView(), gfx::Rect(), false);
SetContentsView(container_view_);
- RepositionWindowTo(initial_anchor);
+ RepositionConstrainedWindowTo(initial_anchor);
}
-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() {
+void BlockedPopupContainer::HideSelf() {
in_show_animation_ = false;
Animation::SetDuration(kHideAnimationDurationMS);
Animation::Start();
- BlockedPopupContainer::HideSelf();
-}
-
-void BlockedPopupContainerImpl::UpdateLabel() {
- if (blocked_popups_.empty() && unblocked_popups_.empty())
- HideSelf();
- else
- container_view_->UpdateLabel();
+ owner_->PopupNotificationVisibilityChanged(false);
}
-void BlockedPopupContainerImpl::SetPosition() {
+void BlockedPopupContainer::SetPosition() {
gfx::Size size = container_view_->GetPreferredSize();
int base_x = anchor_point_.x() - size.width();
int base_y = anchor_point_.y() - size.height();
@@ -393,3 +590,103 @@ void BlockedPopupContainerImpl::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 74d3504..291b0ee 100644
--- a/chrome/browser/views/blocked_popup_container.h
+++ b/chrome/browser/views/blocked_popup_container.h
@@ -2,6 +2,11 @@
// 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_
@@ -10,17 +15,17 @@
#include <vector>
#include "app/animation.h"
-#include "base/gfx/native_widget_types.h"
#include "base/gfx/rect.h"
-#include "chrome/browser/blocked_popup_container.h"
+#include "chrome/browser/tab_contents/constrained_window.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 BlockedPopupContainerImpl;
+class BlockedPopupContainer;
class PrefService;
class Profile;
class TabContents;
@@ -36,7 +41,7 @@ class BlockedPopupContainerView : public views::View,
public views::ButtonListener,
public views::Menu::Delegate {
public:
- explicit BlockedPopupContainerView(BlockedPopupContainerImpl* container);
+ explicit BlockedPopupContainerView(BlockedPopupContainer* container);
~BlockedPopupContainerView();
// Sets the label on the menu button
@@ -65,7 +70,7 @@ class BlockedPopupContainerView : public views::View,
private:
// Our owner and HWND parent.
- BlockedPopupContainerImpl* container_;
+ BlockedPopupContainer* container_;
// The button which brings up the popup menu.
views::MenuButton* popup_count_label_;
@@ -82,14 +87,32 @@ 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).
-//
-// TODO(erg): When this class goes away, whatever is replaced shouldn't
-// multiply inherit.
-class BlockedPopupContainerImpl : public BlockedPopupContainer,
- public Animation,
- public views::WidgetWin {
+class BlockedPopupContainer : public Animation,
+ public ConstrainedWindow,
+ public NotificationObserver,
+ public TabContentsDelegate,
+ public views::WidgetWin {
public:
- virtual ~BlockedPopupContainerImpl();
+ 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;
// Returns the URL and title for popup |index|, used to construct a string for
// display.
@@ -100,25 +123,127 @@ class BlockedPopupContainerImpl : public BlockedPopupContainer,
// Returns the names of hosts showing popups.
std::vector<std::wstring> GetHosts() const;
- virtual void Destroy();
+ // Returns true if host |index| is whitelisted. Returns false if |index| is
+ // invalid.
+ bool IsHostWhitelisted(size_t index) const;
- virtual void RepositionBlockedPopupContainer(gfx::NativeView view);
+ // If host |index| is currently whitelisted, un-whitelists it. Otherwise,
+ // whitelists it and opens all blocked popups from it.
+ void ToggleWhitelistingForHost(size_t index);
- private:
- friend class BlockedPopupContainer;
+ // Deletes all popups and hides the interface parts.
+ void CloseAll();
- // Creates a container for a certain TabContents.
- BlockedPopupContainerImpl(TabContents* owner, PrefService* prefs);
+ // Called to force this container to never show itself again.
+ void set_dismissed() { has_been_dismissed_ = true; }
+
+ // Overridden from ConstrainedWindow:
+
+ // Closes all of our blocked popups and then closes the BlockedPopupContainer.
+ virtual void CloseConstrainedWindow();
// Repositions our blocked popup notification so that the lower right corner
// is at |anchor_point|.
- void RepositionWindowTo(const gfx::Point& 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);
// Overridden from Animation:
- // Changes the visibility percentage of the BlockedPopupContainerImpl. This is
+ // Changes the visibility percentage of the BlockedPopupContainer. 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
@@ -132,22 +257,59 @@ class BlockedPopupContainerImpl : public BlockedPopupContainer,
// browser window.
void Init(const gfx::Point& initial_anchor);
- // Shows the UI.
- virtual void ShowSelf();
-
// Hides the UI portion of the container.
- virtual void HideSelf();
-
- virtual void UpdateLabel();
+ void HideSelf();
// 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_;
@@ -160,6 +322,8 @@ class BlockedPopupContainerImpl : public BlockedPopupContainer,
// 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 fcd7639..df8dd60 100644
--- a/chrome/browser/views/constrained_window_impl_interactive_uitest.cc
+++ b/chrome/browser/views/constrained_window_impl_interactive_uitest.cc
@@ -132,6 +132,14 @@ 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
@@ -143,7 +151,9 @@ TEST_F(InteractiveConstrainedWindowTest, DontSpawnEndlessPopups) {
int times_slept = 0;
bool continuing = true;
while (continuing && popup_window_count < kMaxPopupWindows) {
- ASSERT_TRUE(popup_tab->GetBlockedPopupCount(&new_popup_window_count));
+ std::wstring title;
+ ASSERT_TRUE(constrained_window->GetTitle(&title));
+ ASSERT_TRUE(ParseCountOutOfTitle(title, &new_popup_window_count));
if (new_popup_window_count == popup_window_count) {
if (times_slept == 10) {
continuing = false;
@@ -170,6 +180,8 @@ 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());
@@ -177,7 +189,14 @@ TEST_F(InteractiveConstrainedWindowTest, WindowOpenWindowClosePopup) {
ASSERT_TRUE(popup_window.get());
scoped_refptr<TabProxy> popup_tab(popup_browser->GetTab(0));
ASSERT_TRUE(popup_tab.get());
- ASSERT_TRUE(popup_tab->WaitForBlockedPopupCountToChangeTo(1, 1000));
+ 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);
// Ensure we didn't close the first popup window.
ASSERT_FALSE(automation()->WaitForWindowCountToBecome(1, 3000));
@@ -195,8 +214,13 @@ 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(tab_->GetBlockedPopupCount(&popup_count));
+ ASSERT_TRUE(ParseCountOutOfTitle(title, &popup_count));
ASSERT_EQ(1, popup_count);
}
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 10c2656..2d00a51 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -588,8 +588,6 @@
'browser/back_forward_menu_model.h',
'browser/back_forward_menu_model_views.cc',
'browser/back_forward_menu_model_views.h',
- 'browser/blocked_popup_container.cc',
- 'browser/blocked_popup_container.h',
'browser/bookmarks/bookmark_codec.cc',
'browser/bookmarks/bookmark_codec.h',
'browser/bookmarks/bookmark_context_menu_gtk.cc',
diff --git a/chrome/test/automation/automation_messages_internal.h b/chrome/test/automation/automation_messages_internal.h
index 7e6d9e7..3922869 100644
--- a/chrome/test/automation/automation_messages_internal.h
+++ b/chrome/test/automation/automation_messages_internal.h
@@ -927,11 +927,4 @@ IPC_BEGIN_MESSAGES(Automation)
IPC_SYNC_MESSAGE_ROUTED1_0(AutomationMsg_SetProxyConfig,
std::string /* proxy_config_json_string */)
- // This message requests the number of blocked popups in a certain tab with
- // the given handle. The return value is the number of blocked popups, or -1
- // if this request failed.
- IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_BlockedPopupCount,
- int /* tab_handle */,
- int /* blocked_popup_count */)
-
IPC_END_MESSAGES(Automation)
diff --git a/chrome/test/automation/automation_proxy_uitest.cc b/chrome/test/automation/automation_proxy_uitest.cc
index bb838dd..cefef1fd 100644
--- a/chrome/test/automation/automation_proxy_uitest.cc
+++ b/chrome/test/automation/automation_proxy_uitest.cc
@@ -621,9 +621,48 @@ TEST_F(AutomationProxyTest, ConstrainedWindowTest) {
ASSERT_TRUE(tab->NavigateToURL(net::FilePathToFileURL(filename)));
- ASSERT_TRUE(tab->WaitForBlockedPopupCountToChangeTo(2, 5000));
+ int count;
+ ASSERT_TRUE(tab->WaitForChildWindowCountToChange(0, &count, 5000));
+
+ ASSERT_EQ(1, count);
+
+ scoped_refptr<ConstrainedWindowProxy> cwindow = tab->GetConstrainedWindow(0);
+ ASSERT_TRUE(cwindow.get());
+
+ std::wstring title;
+ ASSERT_TRUE(cwindow->GetTitle(&title));
+ std::wstring window_title = L"Pop-ups Blocked: 2";
+ ASSERT_STREQ(window_title.c_str(), title.c_str());
}
+TEST_F(AutomationProxyTest, CantEscapeByOnloadMoveto) {
+ scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
+ ASSERT_TRUE(window.get());
+
+ scoped_refptr<TabProxy> tab(window->GetTab(0));
+ ASSERT_TRUE(tab.get());
+
+ FilePath filename(test_data_directory_);
+ filename = filename.AppendASCII("constrained_files");
+ filename = filename.AppendASCII("constrained_window_onload_moveto.html");
+
+ ASSERT_TRUE(tab->NavigateToURL(net::FilePathToFileURL(filename)));
+
+ int count;
+ ASSERT_TRUE(tab->WaitForChildWindowCountToChange(0, &count, 5000));
+
+ ASSERT_EQ(1, count);
+
+ scoped_refptr<ConstrainedWindowProxy> cwindow = tab->GetConstrainedWindow(0);
+ ASSERT_TRUE(cwindow.get());
+
+ gfx::Rect rect;
+ bool is_timeout = false;
+ ASSERT_TRUE(cwindow->GetBoundsWithTimeout(&rect, 1000, &is_timeout));
+ ASSERT_FALSE(is_timeout);
+ ASSERT_NE(20, rect.x());
+ ASSERT_NE(20, rect.y());
+}
#endif // defined(OS_WIN)
// TODO(port): Remove HWND if possible
diff --git a/chrome/test/automation/tab_proxy.cc b/chrome/test/automation/tab_proxy.cc
index 55d0dc4..207efac 100644
--- a/chrome/test/automation/tab_proxy.cc
+++ b/chrome/test/automation/tab_proxy.cc
@@ -377,33 +377,6 @@ bool TabProxy::WaitForChildWindowCountToChange(int count, int* new_count,
return false;
}
-bool TabProxy::GetBlockedPopupCount(int* count) const {
- if (!is_valid())
- return false;
-
- if (!count) {
- NOTREACHED();
- return false;
- }
-
- return sender_->Send(new AutomationMsg_BlockedPopupCount(
- 0, handle_, count));
-}
-
-bool TabProxy::WaitForBlockedPopupCountToChangeTo(int target_count,
- int wait_timeout) {
- int intervals = std::min(wait_timeout/automation::kSleepTime, 1);
- for (int i = 0; i < intervals; ++i) {
- PlatformThread::Sleep(automation::kSleepTime);
- int new_count = -1;
- bool succeeded = GetBlockedPopupCount(&new_count);
- if (!succeeded) return false;
- if (target_count == new_count) return true;
- }
- // Constrained Window count did not change, return false.
- return false;
-}
-
bool TabProxy::GetCookies(const GURL& url, std::string* cookies) {
if (!is_valid())
return false;
diff --git a/chrome/test/automation/tab_proxy.h b/chrome/test/automation/tab_proxy.h
index ae513e0..02bf99e 100644
--- a/chrome/test/automation/tab_proxy.h
+++ b/chrome/test/automation/tab_proxy.h
@@ -207,13 +207,6 @@ class TabProxy : public AutomationResourceProxy {
bool WaitForChildWindowCountToChange(int count, int* new_count,
int wait_timeout);
- // Gets the number of popups blocked from this tab.
- bool GetBlockedPopupCount(int* count) const;
-
- // Blocks the thread until the number of blocked popup is equal to
- // |target_count|.
- bool WaitForBlockedPopupCountToChangeTo(int target_count, int wait_timeout);
-
bool GetDownloadDirectory(std::wstring* download_directory);
// Shows an interstitial page. Blocks until the interstitial page
diff --git a/chrome/test/data/constrained_files/constrained_window_onload_moveto.html b/chrome/test/data/constrained_files/constrained_window_onload_moveto.html
new file mode 100644
index 0000000..9da3aa6
--- /dev/null
+++ b/chrome/test/data/constrained_files/constrained_window_onload_moveto.html
@@ -0,0 +1,17 @@
+<HTML>
+ <HEAD>
+ <TITLE>
+ Parent Window
+ </TITLE>
+<SCRIPT TYPE="text/javascript" LANGUAGE="JavaScript">
+<!-- Begin
+function enter(url, x, y) {
+ window.open(url,'','height=320,width=300,left='+x+',top='+y);
+}
+// End -->
+</SCRIPT>
+
+ <BODY
+ onload="enter('target_onload_moveto.html', 100, 100);">
+ </BODY>
+ </HTML>