// 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. // TODO(idanan): Rename class to BlockedContentContainer. #ifndef CHROME_BROWSER_BLOCKED_POPUP_CONTAINER_H_ #define CHROME_BROWSER_BLOCKED_POPUP_CONTAINER_H_ #include #include #include #include #include "app/gfx/native_widget_types.h" #include "base/gfx/rect.h" #include "base/string16.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 BlockedPopupContainer; class PrefService; class Profile; class TabContents; // Interface that the BlockedPopupContainer model/controller uses to // communicate with its platform specific view. class BlockedPopupContainerView { public: // Platform specific constructor used by BlockedPopupContainer to create a // view that is displayed to the user. static BlockedPopupContainerView* Create(BlockedPopupContainer* container); // Notification that the view should properly position itself in |view|. virtual void SetPosition() = 0; // Shows the blocked popup view / Animates the blocked popup view in. virtual void ShowView() = 0; // Sets the text in the blocked popup label. virtual void UpdateLabel() = 0; // Hides the blocked popup view / Animates the blocked popup view out. virtual void HideView() = 0; // Called by the BlockedPopupContainer that owns us. Destroys the view or // starts a delayed Task to destroy the View at some later time. virtual void Destroy() = 0; }; // 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. // // +- 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); static void RegisterUserPrefs(PrefService* prefs); // Returns the profile associated with the Browser this container exists in. Profile* profile() const { return profile_; } // Sets this BlockedPopupContainer's view. BlockedPopupContainer now owns // |view| and is responsible for calling Destroy() on it. void set_view(BlockedPopupContainerView* view) { view_ = view; } // 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; // Adds a blocked notice if one is not already there for the same host. void AddBlockedNotice(const GURL& url, const string16& reason); // Returns the hostname and reason for notice |index|. void GetHostAndReasonForNotice(size_t index, std::string* host, string16* reason) const; // Returns the number of blocked notices, popups don't count. size_t GetBlockedNoticeCount() const; // Returns true if host |index| is whitelisted. // NOTE: Does not sanity-check; do not pass an invalid index! 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. // NOTE: Does not sanity-check; do not pass an invalid index! void ToggleWhitelistingForHost(size_t index); // Deletes all popups and hides the interface parts. void CloseAll(); // Sets this object up to delete itself. void Destroy(); // Message called when a BlockedPopupContainer should move itself to the // bottom right corner of our parent view. void RepositionBlockedPopupContainer(); // Returns the TabContents for the blocked popup |index|. TabContents* GetTabContentsAt(size_t index) const; // Returns the names of hosts showing popups. std::vector GetHosts() const; // Returns the number of popup hosts. size_t GetPopupHostCount() const { return popup_hosts_.size(); } // Deletes all local state. void ClearData(); // 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) { } // 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; 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 BlockedPopups; // TabContents is the popup contents. string is opener hostname. typedef std::map UnblockedPopups; // string is hostname. bool is whitelisted status. typedef std::map PopupHosts; struct BlockedNotice { BlockedNotice(const GURL& url, const string16& reason) : url_(url), reason_(reason) {} GURL url_; string16 reason_; }; typedef std::vector BlockedNotices; // Hosts with notifications showing. typedef std::set NoticeHosts; // Creates a BlockedPopupContainer, anchoring the container to the lower // right corner using the given BlockedPopupContainerView. Use only for // testing. static BlockedPopupContainer* Create(TabContents* owner, Profile* profile, BlockedPopupContainerView* view); // Hides the UI portion of the container. void HideSelf(); // 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; friend class BlockedPopupContainerTest; friend class BlockedPopupContainerControllerTest; // string is hostname. typedef std::set Whitelist; // Creates a container for a certain TabContents: BlockedPopupContainer(TabContents* owner, Profile* profile); // Either hides the view if there are no popups, or updates the label if // there are. void UpdateView(); // 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. If the // profile is off the record, this will be NULL. 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_; // Notices for all blocked resources. BlockedNotices blocked_notices_; // Hosts which had notifications shown. NoticeHosts notice_hosts_; // Our platform specific view. BlockedPopupContainerView* view_; // The profile for the browser associated with the container. Profile* profile_; DISALLOW_IMPLICIT_CONSTRUCTORS(BlockedPopupContainer); }; #endif // CHROME_BROWSER_BLOCKED_POPUP_CONTAINER_H_