• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/blocked_content_container.h"
6 
7 #include "content/browser/tab_contents/tab_contents.h"
8 #include "ui/gfx/rect.h"
9 
10 // static
11 const size_t BlockedContentContainer::kImpossibleNumberOfPopups = 30;
12 
13 struct BlockedContentContainer::BlockedContent {
BlockedContentBlockedContentContainer::BlockedContent14   BlockedContent(TabContents* tab_contents,
15                  WindowOpenDisposition disposition,
16                  const gfx::Rect& bounds,
17                  bool user_gesture)
18       : tab_contents(tab_contents),
19         disposition(disposition),
20         bounds(bounds),
21         user_gesture(user_gesture) {
22   }
23 
24   TabContents* tab_contents;
25   WindowOpenDisposition disposition;
26   gfx::Rect bounds;
27   bool user_gesture;
28 };
29 
BlockedContentContainer(TabContents * owner)30 BlockedContentContainer::BlockedContentContainer(TabContents* owner)
31     : owner_(owner) {
32 }
33 
~BlockedContentContainer()34 BlockedContentContainer::~BlockedContentContainer() {}
35 
AddTabContents(TabContents * tab_contents,WindowOpenDisposition disposition,const gfx::Rect & bounds,bool user_gesture)36 void BlockedContentContainer::AddTabContents(TabContents* tab_contents,
37                                              WindowOpenDisposition disposition,
38                                              const gfx::Rect& bounds,
39                                              bool user_gesture) {
40   if (blocked_contents_.size() == (kImpossibleNumberOfPopups - 1)) {
41     delete tab_contents;
42     VLOG(1) << "Warning: Renderer is sending more popups to us than should be "
43                "possible. Renderer compromised?";
44     return;
45   }
46 
47   blocked_contents_.push_back(
48       BlockedContent(tab_contents, disposition, bounds, user_gesture));
49   tab_contents->set_delegate(this);
50   // Since the new tab_contents will not be showed, call WasHidden to change
51   // its status on both RenderViewHost and RenderView.
52   tab_contents->WasHidden();
53   if (blocked_contents_.size() == 1)
54     owner_->PopupNotificationVisibilityChanged(true);
55 }
56 
LaunchForContents(TabContents * tab_contents)57 void BlockedContentContainer::LaunchForContents(TabContents* tab_contents) {
58   // Open the popup.
59   for (BlockedContents::iterator i(blocked_contents_.begin());
60        i != blocked_contents_.end(); ++i) {
61     if (i->tab_contents == tab_contents) {
62       // To support the owner blocking the content again we copy and erase
63       // before attempting to add.
64       BlockedContent content(*i);
65       blocked_contents_.erase(i);
66       i = blocked_contents_.end();
67       tab_contents->set_delegate(NULL);
68       // We needn't call WasRestored to change its status because the
69       // TabContents::AddNewContents will do it.
70       owner_->AddOrBlockNewContents(tab_contents,
71                                     content.disposition,
72                                     content.bounds,
73                                     content.user_gesture);
74       break;
75     }
76   }
77 
78   if (blocked_contents_.empty())
79     Destroy();
80 }
81 
GetBlockedContentsCount() const82 size_t BlockedContentContainer::GetBlockedContentsCount() const {
83   return blocked_contents_.size();
84 }
85 
GetBlockedContents(std::vector<TabContents * > * blocked_contents) const86 void BlockedContentContainer::GetBlockedContents(
87     std::vector<TabContents*>* blocked_contents) const {
88   DCHECK(blocked_contents);
89   for (BlockedContents::const_iterator i(blocked_contents_.begin());
90        i != blocked_contents_.end(); ++i)
91     blocked_contents->push_back(i->tab_contents);
92 }
93 
Destroy()94 void BlockedContentContainer::Destroy() {
95   for (BlockedContents::iterator i(blocked_contents_.begin());
96        i != blocked_contents_.end(); ++i) {
97     TabContents* tab_contents = i->tab_contents;
98     tab_contents->set_delegate(NULL);
99     delete tab_contents;
100   }
101   blocked_contents_.clear();
102   owner_->WillCloseBlockedContentContainer(this);
103   delete this;
104 }
105 
106 // Overridden from TabContentsDelegate:
OpenURLFromTab(TabContents * source,const GURL & url,const GURL & referrer,WindowOpenDisposition disposition,PageTransition::Type transition)107 void BlockedContentContainer::OpenURLFromTab(TabContents* source,
108                                              const GURL& url,
109                                              const GURL& referrer,
110                                              WindowOpenDisposition disposition,
111                                              PageTransition::Type transition) {
112   owner_->OpenURL(url, referrer, disposition, transition);
113 }
114 
AddNewContents(TabContents * source,TabContents * new_contents,WindowOpenDisposition disposition,const gfx::Rect & initial_position,bool user_gesture)115 void BlockedContentContainer::AddNewContents(TabContents* source,
116                                              TabContents* new_contents,
117                                              WindowOpenDisposition disposition,
118                                              const gfx::Rect& initial_position,
119                                              bool user_gesture) {
120   owner_->AddOrBlockNewContents(
121       new_contents, disposition, initial_position, user_gesture);
122 }
123 
CloseContents(TabContents * source)124 void BlockedContentContainer::CloseContents(TabContents* source) {
125   for (BlockedContents::iterator i(blocked_contents_.begin());
126        i != blocked_contents_.end(); ++i) {
127     TabContents* tab_contents = i->tab_contents;
128     if (tab_contents == source) {
129       tab_contents->set_delegate(NULL);
130       blocked_contents_.erase(i);
131       delete tab_contents;
132       break;
133     }
134   }
135 }
136 
MoveContents(TabContents * source,const gfx::Rect & new_bounds)137 void BlockedContentContainer::MoveContents(TabContents* source,
138                                            const gfx::Rect& new_bounds) {
139   for (BlockedContents::iterator i(blocked_contents_.begin());
140        i != blocked_contents_.end(); ++i) {
141     if (i->tab_contents == source) {
142       i->bounds = new_bounds;
143       break;
144     }
145   }
146 }
147 
IsPopup(const TabContents * source) const148 bool BlockedContentContainer::IsPopup(const TabContents* source) const {
149   // Assume everything added is a popup. This may turn out to be wrong, but
150   // callers don't cache this information so it should be fine if the value ends
151   // up changing.
152   return true;
153 }
154 
GetConstrainingContents(TabContents * source)155 TabContents* BlockedContentContainer::GetConstrainingContents(
156     TabContents* source) {
157   return owner_;
158 }
159