| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/extension_view_host.h" | 5 #include "chrome/browser/extensions/extension_view_host.h" |
| 6 | 6 |
| 7 #include "base/strings/string_piece.h" | 7 #include "base/strings/string_piece.h" |
| 8 #include "chrome/browser/chrome_notification_types.h" |
| 9 #include "chrome/browser/extensions/extension_service.h" |
| 10 #include "chrome/browser/extensions/extension_system.h" |
| 8 #include "chrome/browser/extensions/window_controller.h" | 11 #include "chrome/browser/extensions/window_controller.h" |
| 12 #include "chrome/browser/platform_util.h" |
| 9 #include "chrome/browser/ui/browser.h" | 13 #include "chrome/browser/ui/browser.h" |
| 10 #include "chrome/common/extensions/extension_messages.h" | 14 #include "chrome/common/extensions/extension_messages.h" |
| 15 #include "components/web_modal/web_contents_modal_dialog_manager.h" |
| 16 #include "content/public/browser/notification_source.h" |
| 11 #include "content/public/browser/render_view_host.h" | 17 #include "content/public/browser/render_view_host.h" |
| 18 #include "content/public/browser/web_contents.h" |
| 19 #include "content/public/browser/web_contents_view.h" |
| 12 #include "grit/browser_resources.h" | 20 #include "grit/browser_resources.h" |
| 13 #include "ui/base/resource/resource_bundle.h" | 21 #include "ui/base/resource/resource_bundle.h" |
| 14 #include "ui/events/keycodes/keyboard_codes.h" | 22 #include "ui/events/keycodes/keyboard_codes.h" |
| 15 | 23 |
| 16 using content::NativeWebKeyboardEvent; | 24 using content::NativeWebKeyboardEvent; |
| 17 using content::OpenURLParams; | 25 using content::OpenURLParams; |
| 18 using content::RenderViewHost; | 26 using content::RenderViewHost; |
| 19 using content::WebContents; | 27 using content::WebContents; |
| 20 using content::WebContentsObserver; | 28 using content::WebContentsObserver; |
| 29 using web_modal::WebContentsModalDialogManager; |
| 21 | 30 |
| 22 namespace extensions { | 31 namespace extensions { |
| 23 | 32 |
| 24 // Notifies an ExtensionViewHost when a WebContents is destroyed. | 33 // Notifies an ExtensionViewHost when a WebContents is destroyed. |
| 25 class ExtensionViewHost::AssociatedWebContentsObserver | 34 class ExtensionViewHost::AssociatedWebContentsObserver |
| 26 : public WebContentsObserver { | 35 : public WebContentsObserver { |
| 27 public: | 36 public: |
| 28 AssociatedWebContentsObserver(ExtensionViewHost* host, | 37 AssociatedWebContentsObserver(ExtensionViewHost* host, |
| 29 WebContents* web_contents) | 38 WebContents* web_contents) |
| 30 : WebContentsObserver(web_contents), host_(host) {} | 39 : WebContentsObserver(web_contents), host_(host) {} |
| (...skipping 17 matching lines...) Expand all Loading... |
| 48 const GURL& url, | 57 const GURL& url, |
| 49 ViewType host_type) | 58 ViewType host_type) |
| 50 : ExtensionHost(extension, site_instance, url, host_type), | 59 : ExtensionHost(extension, site_instance, url, host_type), |
| 51 associated_web_contents_(NULL) { | 60 associated_web_contents_(NULL) { |
| 52 // Not used for panels, see PanelHost. | 61 // Not used for panels, see PanelHost. |
| 53 DCHECK(host_type == VIEW_TYPE_EXTENSION_DIALOG || | 62 DCHECK(host_type == VIEW_TYPE_EXTENSION_DIALOG || |
| 54 host_type == VIEW_TYPE_EXTENSION_INFOBAR || | 63 host_type == VIEW_TYPE_EXTENSION_INFOBAR || |
| 55 host_type == VIEW_TYPE_EXTENSION_POPUP); | 64 host_type == VIEW_TYPE_EXTENSION_POPUP); |
| 56 } | 65 } |
| 57 | 66 |
| 58 ExtensionViewHost::~ExtensionViewHost() {} | 67 ExtensionViewHost::~ExtensionViewHost() { |
| 68 // The hosting WebContents will be deleted in the base class, so unregister |
| 69 // this object before it deletes the attached WebContentsModalDialogManager. |
| 70 WebContentsModalDialogManager* manager = |
| 71 WebContentsModalDialogManager::FromWebContents(host_contents()); |
| 72 if (manager) |
| 73 manager->SetDelegate(NULL); |
| 74 } |
| 59 | 75 |
| 60 void ExtensionViewHost::CreateView(Browser* browser) { | 76 void ExtensionViewHost::CreateView(Browser* browser) { |
| 61 #if defined(TOOLKIT_VIEWS) | 77 #if defined(TOOLKIT_VIEWS) |
| 62 view_.reset(new ExtensionViewViews(this, browser)); | 78 view_.reset(new ExtensionViewViews(this, browser)); |
| 63 // We own |view_|, so don't auto delete when it's removed from the view | 79 // We own |view_|, so don't auto delete when it's removed from the view |
| 64 // hierarchy. | 80 // hierarchy. |
| 65 view_->set_owned_by_client(); | 81 view_->set_owned_by_client(); |
| 66 #elif defined(OS_MACOSX) | 82 #elif defined(OS_MACOSX) |
| 67 view_.reset(new ExtensionViewMac(this, browser)); | 83 view_.reset(new ExtensionViewMac(this, browser)); |
| 68 view_->Init(); | 84 view_->Init(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 79 associated_web_contents_ = web_contents; | 95 associated_web_contents_ = web_contents; |
| 80 if (associated_web_contents_) { | 96 if (associated_web_contents_) { |
| 81 // Observe the new WebContents for deletion. | 97 // Observe the new WebContents for deletion. |
| 82 associated_web_contents_observer_.reset( | 98 associated_web_contents_observer_.reset( |
| 83 new AssociatedWebContentsObserver(this, associated_web_contents_)); | 99 new AssociatedWebContentsObserver(this, associated_web_contents_)); |
| 84 } else { | 100 } else { |
| 85 associated_web_contents_observer_.reset(); | 101 associated_web_contents_observer_.reset(); |
| 86 } | 102 } |
| 87 } | 103 } |
| 88 | 104 |
| 89 // ExtensionHost overrides: | |
| 90 | |
| 91 void ExtensionViewHost::UnhandledKeyboardEvent( | 105 void ExtensionViewHost::UnhandledKeyboardEvent( |
| 92 WebContents* source, | 106 WebContents* source, |
| 93 const content::NativeWebKeyboardEvent& event) { | 107 const content::NativeWebKeyboardEvent& event) { |
| 94 Browser* browser = view_->browser(); | 108 Browser* browser = view_->browser(); |
| 95 if (browser) { | 109 if (browser) { |
| 96 // Handle lower priority browser shortcuts such as Ctrl-f. | 110 // Handle lower priority browser shortcuts such as Ctrl-f. |
| 97 return browser->HandleKeyboardEvent(source, event); | 111 return browser->HandleKeyboardEvent(source, event); |
| 98 } else { | 112 } else { |
| 99 #if defined(TOOLKIT_VIEWS) | 113 #if defined(TOOLKIT_VIEWS) |
| 100 // In case there's no Browser (e.g. for dialogs), pass it to | 114 // In case there's no Browser (e.g. for dialogs), pass it to |
| 101 // ExtensionViewViews to handle accelerators. The view's FocusManager does | 115 // ExtensionViewViews to handle accelerators. The view's FocusManager does |
| 102 // not know anything about Browser accelerators, but might know others such | 116 // not know anything about Browser accelerators, but might know others such |
| 103 // as Ash's. | 117 // as Ash's. |
| 104 view_->HandleKeyboardEvent(event); | 118 view_->HandleKeyboardEvent(event); |
| 105 #endif | 119 #endif |
| 106 } | 120 } |
| 107 } | 121 } |
| 108 | 122 |
| 123 // ExtensionHost overrides: |
| 124 |
| 109 void ExtensionViewHost::OnDidStopLoading() { | 125 void ExtensionViewHost::OnDidStopLoading() { |
| 110 DCHECK(did_stop_loading()); | 126 DCHECK(did_stop_loading()); |
| 111 #if defined(TOOLKIT_VIEWS) || defined(OS_MACOSX) | 127 #if defined(TOOLKIT_VIEWS) || defined(OS_MACOSX) |
| 112 view_->DidStopLoading(); | 128 view_->DidStopLoading(); |
| 113 #endif | 129 #endif |
| 114 } | 130 } |
| 115 | 131 |
| 116 void ExtensionViewHost::OnDocumentAvailable() { | 132 void ExtensionViewHost::OnDocumentAvailable() { |
| 117 if (extension_host_type() == VIEW_TYPE_EXTENSION_INFOBAR) { | 133 if (extension_host_type() == VIEW_TYPE_EXTENSION_INFOBAR) { |
| 118 // No style sheet for other types, at the moment. | 134 // No style sheet for other types, at the moment. |
| 119 InsertInfobarCSS(); | 135 InsertInfobarCSS(); |
| 120 } | 136 } |
| 121 } | 137 } |
| 122 | 138 |
| 139 void ExtensionViewHost::LoadInitialURL() { |
| 140 if (!ExtensionSystem::GetForBrowserContext(browser_context())-> |
| 141 extension_service()->IsBackgroundPageReady(extension())) { |
| 142 // Make sure the background page loads before any others. |
| 143 registrar()->Add(this, |
| 144 chrome::NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY, |
| 145 content::Source<Extension>(extension())); |
| 146 return; |
| 147 } |
| 148 |
| 149 // Popups may spawn modal dialogs, which need positioning information. |
| 150 if (extension_host_type() == VIEW_TYPE_EXTENSION_POPUP) { |
| 151 WebContentsModalDialogManager::CreateForWebContents(host_contents()); |
| 152 WebContentsModalDialogManager::FromWebContents( |
| 153 host_contents())->SetDelegate(this); |
| 154 } |
| 155 |
| 156 ExtensionHost::LoadInitialURL(); |
| 157 } |
| 158 |
| 123 bool ExtensionViewHost::IsBackgroundPage() const { | 159 bool ExtensionViewHost::IsBackgroundPage() const { |
| 124 DCHECK(view_); | 160 DCHECK(view_); |
| 125 return false; | 161 return false; |
| 126 } | 162 } |
| 127 | 163 |
| 128 WebContents* ExtensionViewHost::OpenURLFromTab( | 164 WebContents* ExtensionViewHost::OpenURLFromTab( |
| 129 WebContents* source, | 165 WebContents* source, |
| 130 const OpenURLParams& params) { | 166 const OpenURLParams& params) { |
| 131 // Whitelist the dispositions we will allow to be opened. | 167 // Whitelist the dispositions we will allow to be opened. |
| 132 switch (params.disposition) { | 168 switch (params.disposition) { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 | 231 |
| 196 // If the host is bound to a window, then extract its id. Extensions hosted | 232 // If the host is bound to a window, then extract its id. Extensions hosted |
| 197 // in ExternalTabContainer objects may not have an associated window. | 233 // in ExternalTabContainer objects may not have an associated window. |
| 198 WindowController* window = GetExtensionWindowController(); | 234 WindowController* window = GetExtensionWindowController(); |
| 199 if (window) { | 235 if (window) { |
| 200 render_view_host->Send(new ExtensionMsg_UpdateBrowserWindowId( | 236 render_view_host->Send(new ExtensionMsg_UpdateBrowserWindowId( |
| 201 render_view_host->GetRoutingID(), window->GetWindowId())); | 237 render_view_host->GetRoutingID(), window->GetWindowId())); |
| 202 } | 238 } |
| 203 } | 239 } |
| 204 | 240 |
| 205 #if !defined(OS_ANDROID) | 241 web_modal::WebContentsModalDialogHost* |
| 242 ExtensionViewHost::GetWebContentsModalDialogHost() { |
| 243 return this; |
| 244 } |
| 245 |
| 246 bool ExtensionViewHost::IsWebContentsVisible(WebContents* web_contents) { |
| 247 return platform_util::IsVisible(web_contents->GetView()->GetNativeView()); |
| 248 } |
| 249 |
| 206 gfx::NativeView ExtensionViewHost::GetHostView() const { | 250 gfx::NativeView ExtensionViewHost::GetHostView() const { |
| 207 return view_->native_view(); | 251 return view_->native_view(); |
| 208 } | 252 } |
| 209 #endif // !defined(OS_ANDROID) | 253 |
| 254 gfx::Point ExtensionViewHost::GetDialogPosition(const gfx::Size& size) { |
| 255 if (!GetVisibleWebContents()) |
| 256 return gfx::Point(); |
| 257 gfx::Rect bounds = GetVisibleWebContents()->GetView()->GetViewBounds(); |
| 258 return gfx::Point( |
| 259 std::max(0, (bounds.width() - size.width()) / 2), |
| 260 std::max(0, (bounds.height() - size.height()) / 2)); |
| 261 } |
| 262 |
| 263 gfx::Size ExtensionViewHost::GetMaximumDialogSize() { |
| 264 if (!GetVisibleWebContents()) |
| 265 return gfx::Size(); |
| 266 return GetVisibleWebContents()->GetView()->GetViewBounds().size(); |
| 267 } |
| 268 |
| 269 void ExtensionViewHost::AddObserver( |
| 270 web_modal::ModalDialogHostObserver* observer) { |
| 271 } |
| 272 |
| 273 void ExtensionViewHost::RemoveObserver( |
| 274 web_modal::ModalDialogHostObserver* observer) { |
| 275 } |
| 210 | 276 |
| 211 WindowController* ExtensionViewHost::GetExtensionWindowController() const { | 277 WindowController* ExtensionViewHost::GetExtensionWindowController() const { |
| 212 return view_->browser() ? view_->browser()->extension_window_controller() | 278 return view_->browser() ? view_->browser()->extension_window_controller() |
| 213 : NULL; | 279 : NULL; |
| 214 } | 280 } |
| 215 | 281 |
| 216 WebContents* ExtensionViewHost::GetAssociatedWebContents() const { | 282 WebContents* ExtensionViewHost::GetAssociatedWebContents() const { |
| 217 return associated_web_contents_; | 283 return associated_web_contents_; |
| 218 } | 284 } |
| 219 | 285 |
| 220 WebContents* ExtensionViewHost::GetVisibleWebContents() const { | 286 WebContents* ExtensionViewHost::GetVisibleWebContents() const { |
| 221 if (associated_web_contents_) | 287 if (associated_web_contents_) |
| 222 return associated_web_contents_; | 288 return associated_web_contents_; |
| 223 if (extension_host_type() == VIEW_TYPE_EXTENSION_POPUP) | 289 if (extension_host_type() == VIEW_TYPE_EXTENSION_POPUP) |
| 224 return host_contents(); | 290 return host_contents(); |
| 225 return NULL; | 291 return NULL; |
| 226 } | 292 } |
| 227 | 293 |
| 294 void ExtensionViewHost::Observe(int type, |
| 295 const content::NotificationSource& source, |
| 296 const content::NotificationDetails& details) { |
| 297 if (type == chrome::NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY) { |
| 298 DCHECK(ExtensionSystem::GetForBrowserContext(browser_context())-> |
| 299 extension_service()->IsBackgroundPageReady(extension())); |
| 300 LoadInitialURL(); |
| 301 return; |
| 302 } |
| 303 ExtensionHost::Observe(type, source, details); |
| 304 } |
| 305 |
| 228 void ExtensionViewHost::InsertInfobarCSS() { | 306 void ExtensionViewHost::InsertInfobarCSS() { |
| 229 static const base::StringPiece css( | 307 static const base::StringPiece css( |
| 230 ResourceBundle::GetSharedInstance().GetRawDataResource( | 308 ResourceBundle::GetSharedInstance().GetRawDataResource( |
| 231 IDR_EXTENSIONS_INFOBAR_CSS)); | 309 IDR_EXTENSIONS_INFOBAR_CSS)); |
| 232 | 310 |
| 233 render_view_host()->InsertCSS(string16(), css.as_string()); | 311 render_view_host()->InsertCSS(string16(), css.as_string()); |
| 234 } | 312 } |
| 235 | 313 |
| 236 } // namespace extensions | 314 } // namespace extensions |
| OLD | NEW |