1 // Copyright (c) 2012 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/ui/blocked_content/blocked_content_container.h" 6 7 #include "base/logging.h" 8 #include "chrome/browser/favicon/favicon_tab_helper.h" 9 #include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h" 10 #include "content/public/browser/web_contents.h" 11 #include "ui/gfx/rect.h" 12 13 using content::OpenURLParams; 14 using content::WebContents; 15 16 // static 17 const size_t BlockedContentContainer::kImpossibleNumberOfPopups = 30; 18 19 struct BlockedContentContainer::BlockedContent { 20 BlockedContent(WebContents* web_contents, 21 WindowOpenDisposition disposition, 22 const gfx::Rect& bounds, 23 bool user_gesture) 24 : web_contents(web_contents), 25 disposition(disposition), 26 bounds(bounds), 27 user_gesture(user_gesture) { 28 } 29 30 WebContents* web_contents; 31 WindowOpenDisposition disposition; 32 gfx::Rect bounds; 33 bool user_gesture; 34 }; 35 36 BlockedContentContainer::BlockedContentContainer(content::WebContents* owner) 37 : owner_(owner) { 38 } 39 40 BlockedContentContainer::~BlockedContentContainer() { 41 Clear(); 42 } 43 44 void BlockedContentContainer::AddWebContents(content::WebContents* web_contents, 45 WindowOpenDisposition disposition, 46 const gfx::Rect& bounds, 47 bool user_gesture) { 48 if (blocked_contents_.size() == (kImpossibleNumberOfPopups - 1)) { 49 delete web_contents; 50 VLOG(1) << "Warning: Renderer is sending more popups to us than should be " 51 "possible. Renderer compromised?"; 52 return; 53 } 54 55 blocked_contents_.push_back( 56 BlockedContent(web_contents, disposition, bounds, user_gesture)); 57 web_contents->SetDelegate(this); 58 59 BlockedContentTabHelper::CreateForWebContents(web_contents); 60 // Various UI parts assume the ability to retrieve favicons from blocked 61 // content. 62 FaviconTabHelper::CreateForWebContents(web_contents); 63 BlockedContentTabHelper::FromWebContents(web_contents)->set_delegate(this); 64 65 // Since the new web_contents will not be shown, call WasHidden to change 66 // its status on both RenderViewHost and RenderView. 67 web_contents->WasHidden(); 68 } 69 70 void BlockedContentContainer::LaunchForContents( 71 content::WebContents* web_contents) { 72 // Open the popup. 73 for (BlockedContents::iterator i = blocked_contents_.begin(); 74 i != blocked_contents_.end(); ++i) { 75 if (i->web_contents == web_contents) { 76 // To support the owner blocking the content again we copy and erase 77 // before attempting to add. 78 BlockedContent content(*i); 79 blocked_contents_.erase(i); 80 i = blocked_contents_.end(); 81 web_contents->SetDelegate(NULL); 82 BlockedContentTabHelper::FromWebContents(web_contents)-> 83 set_delegate(NULL); 84 // We needn't call WasShown to change its status because the 85 // WebContents::AddNewContents will do it. 86 WebContentsDelegate* delegate = owner_->GetDelegate(); 87 if (delegate) { 88 delegate->AddNewContents(owner_, 89 web_contents, 90 content.disposition, 91 content.bounds, 92 content.user_gesture, 93 NULL); 94 } 95 break; 96 } 97 } 98 } 99 100 size_t BlockedContentContainer::GetBlockedContentsCount() const { 101 return blocked_contents_.size(); 102 } 103 104 void BlockedContentContainer::GetBlockedContents( 105 std::vector<WebContents*>* blocked_contents) const { 106 DCHECK(blocked_contents); 107 for (BlockedContents::const_iterator i = blocked_contents_.begin(); 108 i != blocked_contents_.end(); ++i) 109 blocked_contents->push_back(i->web_contents); 110 } 111 112 void BlockedContentContainer::Clear() { 113 for (BlockedContents::iterator i = blocked_contents_.begin(); 114 i != blocked_contents_.end(); ++i) { 115 WebContents* web_contents = i->web_contents; 116 web_contents->SetDelegate(NULL); 117 BlockedContentTabHelper::FromWebContents(web_contents)->set_delegate(NULL); 118 delete web_contents; 119 } 120 blocked_contents_.clear(); 121 } 122 123 // Overridden from content::WebContentsDelegate: 124 125 WebContents* BlockedContentContainer::OpenURLFromTab( 126 WebContents* source, 127 const OpenURLParams& params) { 128 return owner_->OpenURL(params); 129 } 130 131 void BlockedContentContainer::AddNewContents(WebContents* source, 132 WebContents* new_contents, 133 WindowOpenDisposition disposition, 134 const gfx::Rect& initial_position, 135 bool user_gesture, 136 bool* was_blocked) { 137 WebContentsDelegate* delegate = owner_->GetDelegate(); 138 if (delegate) { 139 delegate->AddNewContents(owner_, new_contents, disposition, 140 initial_position, user_gesture, was_blocked); 141 } 142 } 143 144 void BlockedContentContainer::CloseContents(WebContents* source) { 145 for (BlockedContents::iterator i = blocked_contents_.begin(); 146 i != blocked_contents_.end(); ++i) { 147 WebContents* web_contents = i->web_contents; 148 if (web_contents == source) { 149 web_contents->SetDelegate(NULL); 150 BlockedContentTabHelper::FromWebContents(web_contents)-> 151 set_delegate(NULL); 152 blocked_contents_.erase(i); 153 delete web_contents; 154 break; 155 } 156 } 157 } 158 159 void BlockedContentContainer::MoveContents(WebContents* source, 160 const gfx::Rect& new_bounds) { 161 for (BlockedContents::iterator i = blocked_contents_.begin(); 162 i != blocked_contents_.end(); ++i) { 163 if (i->web_contents == source) { 164 i->bounds = new_bounds; 165 break; 166 } 167 } 168 } 169 170 bool BlockedContentContainer::IsPopupOrPanel(const WebContents* source) const { 171 // Assume everything added is a popup. This may turn out to be wrong, but 172 // callers don't cache this information so it should be fine if the value ends 173 // up changing. 174 return true; 175 } 176 177 bool BlockedContentContainer::ShouldSuppressDialogs() { 178 // Suppress JavaScript dialogs when inside a constrained popup window (because 179 // that activates them and breaks them out of the constrained window jail). 180 return true; 181 } 182 183 content::WebContents* BlockedContentContainer::GetConstrainingWebContents( 184 content::WebContents* source) { 185 return owner_; 186 } 187