diff options
Diffstat (limited to 'chrome/browser/blocked_content_container.cc')
-rw-r--r-- | chrome/browser/blocked_content_container.cc | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/chrome/browser/blocked_content_container.cc b/chrome/browser/blocked_content_container.cc new file mode 100644 index 0000000..58897c4 --- /dev/null +++ b/chrome/browser/blocked_content_container.cc @@ -0,0 +1,149 @@ +// Copyright (c) 2010 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_content_container.h" + +#include "chrome/browser/tab_contents/tab_contents.h" +#include "gfx/rect.h" + +// static +const size_t BlockedContentContainer::kImpossibleNumberOfPopups = 30; + +struct BlockedContentContainer::BlockedContent { + BlockedContent(TabContents* tab_contents, + WindowOpenDisposition disposition, + const gfx::Rect& bounds, + bool user_gesture) + : tab_contents(tab_contents), + disposition(disposition), + bounds(bounds), + user_gesture(user_gesture) { + } + + TabContents* tab_contents; + WindowOpenDisposition disposition; + gfx::Rect bounds; + bool user_gesture; +}; + +BlockedContentContainer::BlockedContentContainer(TabContents* owner) + : owner_(owner) { +} + +void BlockedContentContainer::AddTabContents(TabContents* tab_contents, + WindowOpenDisposition disposition, + const gfx::Rect& bounds, + bool user_gesture) { + if (blocked_contents_.size() == (kImpossibleNumberOfPopups - 1)) { + delete tab_contents; + LOG(INFO) << "Warning: Renderer is sending more popups to us than should " + "be possible. Renderer compromised?"; + return; + } + + blocked_contents_.push_back( + BlockedContent(tab_contents, disposition, bounds, user_gesture)); + tab_contents->set_delegate(this); + if (blocked_contents_.size() == 1) + owner_->PopupNotificationVisibilityChanged(true); +} + +void BlockedContentContainer::LaunchForContents(TabContents* tab_contents) { + // Open the popup. + for (BlockedContents::iterator i(blocked_contents_.begin()); + i != blocked_contents_.end(); ++i) { + if (i->tab_contents == tab_contents) { + // To support the owner blocking the content again we copy and erase + // before attempting to add. + BlockedContent content(*i); + blocked_contents_.erase(i); + i = blocked_contents_.end(); + tab_contents->set_delegate(NULL); + owner_->AddNewContents(tab_contents, content.disposition, content.bounds, + content.user_gesture); + break; + } + } + + if (blocked_contents_.empty()) + Destroy(); +} + +size_t BlockedContentContainer::GetBlockedContentsCount() const { + return blocked_contents_.size(); +} + +void BlockedContentContainer::GetBlockedContents( + std::vector<TabContents*>* blocked_contents) const { + DCHECK(blocked_contents); + for (BlockedContents::const_iterator i(blocked_contents_.begin()); + i != blocked_contents_.end(); ++i) + blocked_contents->push_back(i->tab_contents); +} + +void BlockedContentContainer::Destroy() { + for (BlockedContents::iterator i(blocked_contents_.begin()); + i != blocked_contents_.end(); ++i) { + TabContents* tab_contents = i->tab_contents; + tab_contents->set_delegate(NULL); + delete tab_contents; + } + blocked_contents_.clear(); + owner_->WillCloseBlockedContentContainer(this); + delete this; +} + +// Overridden from TabContentsDelegate: +void BlockedContentContainer::OpenURLFromTab(TabContents* source, + const GURL& url, + const GURL& referrer, + WindowOpenDisposition disposition, + PageTransition::Type transition) { + owner_->OpenURL(url, referrer, disposition, transition); +} + +void BlockedContentContainer::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); +} + +void BlockedContentContainer::CloseContents(TabContents* source) { + for (BlockedContents::iterator i(blocked_contents_.begin()); + i != blocked_contents_.end(); ++i) { + TabContents* tab_contents = i->tab_contents; + if (tab_contents == source) { + tab_contents->set_delegate(NULL); + blocked_contents_.erase(i); + delete tab_contents; + break; + } + } +} + +void BlockedContentContainer::MoveContents(TabContents* source, + const gfx::Rect& new_bounds) { + for (BlockedContents::iterator i(blocked_contents_.begin()); + i != blocked_contents_.end(); ++i) { + if (i->tab_contents == source) { + i->bounds = new_bounds; + break; + } + } +} + +bool BlockedContentContainer::IsPopup(const TabContents* source) const { + // Assume everything added is a popup. This may turn out to be wrong, but + // callers don't cache this information so it should be fine if the value ends + // up changing. + return true; +} + +TabContents* BlockedContentContainer::GetConstrainingContents( + TabContents* source) { + return owner_; +} |