| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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_popup_api.h" | 5 #include "chrome/browser/extensions/extension_popup_api.h" |
| 6 | 6 |
| 7 #include "base/json/json_writer.h" | 7 #include "base/json/json_writer.h" |
| 8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
| 9 #include "chrome/browser/extensions/extension_dom_ui.h" | 9 #include "chrome/browser/extensions/extension_dom_ui.h" |
| 10 #include "chrome/browser/extensions/extension_host.h" | 10 #include "chrome/browser/extensions/extension_host.h" |
| 11 #include "chrome/browser/extensions/extension_message_service.h" | 11 #include "chrome/browser/extensions/extension_message_service.h" |
| 12 #include "chrome/browser/browser.h" | 12 #include "chrome/browser/browser.h" |
| 13 #include "chrome/browser/browser_window.h" | 13 #include "chrome/browser/browser_window.h" |
| 14 #include "chrome/browser/profile.h" | 14 #include "chrome/browser/profile.h" |
| 15 #include "chrome/browser/renderer_host/render_view_host.h" |
| 16 #include "chrome/browser/renderer_host/render_view_host_delegate.h" |
| 17 #include "chrome/browser/renderer_host/render_widget_host_view.h" |
| 15 #include "chrome/browser/tab_contents/tab_contents.h" | 18 #include "chrome/browser/tab_contents/tab_contents.h" |
| 16 #include "chrome/common/extensions/extension.h" | 19 #include "chrome/common/extensions/extension.h" |
| 17 #include "chrome/common/notification_details.h" | 20 #include "chrome/common/notification_details.h" |
| 18 #include "chrome/common/notification_service.h" | 21 #include "chrome/common/notification_service.h" |
| 19 #include "chrome/common/notification_source.h" | 22 #include "chrome/common/notification_source.h" |
| 20 #include "chrome/common/notification_type.h" | 23 #include "chrome/common/notification_type.h" |
| 21 #include "chrome/common/url_constants.h" | 24 #include "chrome/common/url_constants.h" |
| 22 #include "gfx/point.h" | 25 #include "gfx/point.h" |
| 23 | 26 |
| 24 #if defined(TOOLKIT_VIEWS) | 27 #if defined(TOOLKIT_VIEWS) |
| 25 #include "chrome/browser/renderer_host/render_view_host.h" | |
| 26 #include "chrome/browser/renderer_host/render_view_host_delegate.h" | |
| 27 #include "chrome/browser/renderer_host/render_widget_host_view.h" | |
| 28 #include "chrome/browser/views/extensions/extension_popup.h" | 28 #include "chrome/browser/views/extensions/extension_popup.h" |
| 29 #include "views/view.h" | 29 #include "views/view.h" |
| 30 #include "views/focus/focus_manager.h" | 30 #include "views/focus/focus_manager.h" |
| 31 #endif // TOOLKIT_VIEWS | 31 #endif // TOOLKIT_VIEWS |
| 32 | 32 |
| 33 namespace extension_popup_module_events { | 33 namespace extension_popup_module_events { |
| 34 | 34 |
| 35 const char kOnPopupClosed[] = "experimental.popup.onClosed.%d"; | 35 const char kOnPopupClosed[] = "experimental.popup.onClosed.%d"; |
| 36 | 36 |
| 37 } // namespace extension_popup_module_events | 37 } // namespace extension_popup_module_events |
| 38 | 38 |
| 39 namespace { | 39 namespace { |
| 40 | 40 |
| 41 // Errors. | 41 // Errors. |
| 42 const char kBadAnchorArgument[] = "Invalid anchor argument."; | 42 const char kBadAnchorArgument[] = "Invalid anchor argument."; |
| 43 const char kInvalidURLError[] = "Invalid URL."; | 43 const char kInvalidURLError[] = "Invalid URL."; |
| 44 const char kNotAnExtension[] = "Not an extension view."; | 44 const char kNotAnExtension[] = "Not an extension view."; |
| 45 const char kPopupsDisallowed[] = |
| 46 "Popups are only supported from toolstrip or tab-contents views."; |
| 45 | 47 |
| 46 // Keys. | 48 // Keys. |
| 47 const wchar_t kUrlKey[] = L"url"; | 49 const wchar_t kUrlKey[] = L"url"; |
| 48 const wchar_t kWidthKey[] = L"width"; | 50 const wchar_t kWidthKey[] = L"width"; |
| 49 const wchar_t kHeightKey[] = L"height"; | 51 const wchar_t kHeightKey[] = L"height"; |
| 50 const wchar_t kTopKey[] = L"top"; | 52 const wchar_t kTopKey[] = L"top"; |
| 51 const wchar_t kLeftKey[] = L"left"; | 53 const wchar_t kLeftKey[] = L"left"; |
| 52 const wchar_t kGiveFocusKey[] = L"giveFocus"; | 54 const wchar_t kGiveFocusKey[] = L"giveFocus"; |
| 53 const wchar_t kDomAnchorKey[] = L"domAnchor"; | 55 const wchar_t kDomAnchorKey[] = L"domAnchor"; |
| 54 const wchar_t kBorderStyleKey[] = L"borderStyle"; | 56 const wchar_t kBorderStyleKey[] = L"borderStyle"; |
| 55 | 57 |
| 56 // chrome enumeration values | 58 // chrome enumeration values |
| 57 const char kRectangleChrome[] = "rectangle"; | 59 const char kRectangleChrome[] = "rectangle"; |
| 58 | 60 |
| 59 }; // namespace | 61 }; // namespace |
| 60 | 62 |
| 61 #if defined(TOOLKIT_VIEWS) | 63 #if defined(TOOLKIT_VIEWS) |
| 62 // ExtensionPopupHost objects implement the environment necessary to host | 64 // ExtensionPopupHost objects implement the environment necessary to host |
| 63 // an ExtensionPopup views for the popup api. Its main job is to handle | 65 // an ExtensionPopup views for the popup api. Its main job is to handle |
| 64 // its lifetime and to fire the popup-closed event when the popup is closed. | 66 // its lifetime and to fire the popup-closed event when the popup is closed. |
| 65 // Because the close-on-focus-lost behavior is different from page action | 67 // Because the close-on-focus-lost behavior is different from page action |
| 66 // and browser action, it also manages its own focus change listening. The | 68 // and browser action, it also manages its own focus change listening. The |
| 67 // difference in close-on-focus-lost is that in the page action and browser | 69 // difference in close-on-focus-lost is that in the page action and browser |
| 68 // action cases, the popup closes when the focus leaves the popup or any of its | 70 // action cases, the popup closes when the focus leaves the popup or any of its |
| 69 // children. In this case, the popup closes when the focus leaves the popups | 71 // children. In this case, the popup closes when the focus leaves the popups |
| 70 // containing view or any of *its* children. | 72 // containing view or any of *its* children. |
| 71 class ExtensionPopupHost : public ExtensionPopup::Observer, | 73 class ExtensionPopupHost : public ExtensionPopup::Observer, |
| 72 public views::WidgetFocusChangeListener, | 74 public views::WidgetFocusChangeListener, |
| 73 public base::RefCounted<ExtensionPopupHost> { | 75 public base::RefCounted<ExtensionPopupHost>, |
| 76 public NotificationObserver { |
| 74 public: | 77 public: |
| 75 explicit ExtensionPopupHost(ExtensionFunctionDispatcher* dispatcher) | 78 explicit ExtensionPopupHost(ExtensionFunctionDispatcher* dispatcher) |
| 76 : dispatcher_(dispatcher), popup_(NULL) { | 79 : dispatcher_(dispatcher), popup_(NULL) { |
| 77 AddRef(); // Balanced in DispatchPopupClosedEvent(). | 80 AddRef(); // Balanced in DispatchPopupClosedEvent(). |
| 78 views::FocusManager::GetWidgetFocusManager()->AddFocusChangeListener(this); | 81 views::FocusManager::GetWidgetFocusManager()->AddFocusChangeListener(this); |
| 79 } | 82 } |
| 80 | 83 |
| 81 ~ExtensionPopupHost() { | 84 ~ExtensionPopupHost() { |
| 82 views::FocusManager::GetWidgetFocusManager()-> | 85 views::FocusManager::GetWidgetFocusManager()-> |
| 83 RemoveFocusChangeListener(this); | 86 RemoveFocusChangeListener(this); |
| 84 } | 87 } |
| 85 | 88 |
| 86 void set_popup(ExtensionPopup* popup) { | 89 void set_popup(ExtensionPopup* popup) { |
| 87 popup_ = popup; | 90 popup_ = popup; |
| 91 |
| 92 // Now that a popup has been assigned, listen for subsequent popups being |
| 93 // created in the same extension - we want to disallow more than one |
| 94 // concurrently displayed popup windows. |
| 95 registrar_.Add( |
| 96 this, |
| 97 NotificationType::EXTENSION_HOST_CREATED, |
| 98 Source<ExtensionProcessManager>( |
| 99 dispatcher_->profile()->GetExtensionProcessManager())); |
| 88 } | 100 } |
| 89 | 101 |
| 90 // Overriden from ExtensionPopup::Observer | 102 // Overridden from ExtensionPopup::Observer |
| 91 virtual void ExtensionPopupClosed(ExtensionPopup* popup) { | 103 virtual void ExtensionPopupClosed(ExtensionPopup* popup) { |
| 92 // Unregister the automation resource routing registered upon host | 104 // Unregister the automation resource routing registered upon host |
| 93 // creation. | 105 // creation. |
| 94 AutomationResourceRoutingDelegate* router = | 106 AutomationResourceRoutingDelegate* router = |
| 95 GetRoutingFromDispatcher(dispatcher_); | 107 GetRoutingFromDispatcher(dispatcher_); |
| 96 if (router) | 108 if (router) |
| 97 router->UnregisterRenderViewHost(popup_->host()->render_view_host()); | 109 router->UnregisterRenderViewHost(popup_->host()->render_view_host()); |
| 98 | 110 |
| 99 // The OnPopupClosed event should be sent later to give the popup time to | 111 // The OnPopupClosed event should be sent later to give the popup time to |
| 100 // complete closing. | 112 // complete closing. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 112 router->RegisterRenderViewHost(host->render_view_host()); | 124 router->RegisterRenderViewHost(host->render_view_host()); |
| 113 } | 125 } |
| 114 | 126 |
| 115 virtual void DispatchPopupClosedEvent() { | 127 virtual void DispatchPopupClosedEvent() { |
| 116 PopupEventRouter::OnPopupClosed( | 128 PopupEventRouter::OnPopupClosed( |
| 117 dispatcher_->profile(), dispatcher_->render_view_host()->routing_id()); | 129 dispatcher_->profile(), dispatcher_->render_view_host()->routing_id()); |
| 118 dispatcher_ = NULL; | 130 dispatcher_ = NULL; |
| 119 Release(); // Balanced in ctor. | 131 Release(); // Balanced in ctor. |
| 120 } | 132 } |
| 121 | 133 |
| 122 // Overriden from views::WidgetFocusChangeListener | 134 // Overridden from views::WidgetFocusChangeListener |
| 123 virtual void NativeFocusWillChange(gfx::NativeView focused_before, | 135 virtual void NativeFocusWillChange(gfx::NativeView focused_before, |
| 124 gfx::NativeView focused_now) { | 136 gfx::NativeView focused_now) { |
| 125 // If no view is to be focused, then Chrome was deactivated, so hide the | 137 // If no view is to be focused, then Chrome was deactivated, so hide the |
| 126 // popup. | 138 // popup. |
| 127 if (focused_now) { | 139 if (focused_now) { |
| 128 gfx::NativeView host_view = | 140 gfx::NativeView host_view = |
| 129 dispatcher_->delegate()->GetNativeViewOfHost(); | 141 dispatcher_->delegate()->GetNativeViewOfHost(); |
| 130 | 142 |
| 131 // If the widget hosting the popup contains the newly focused view, then | 143 // If the widget hosting the popup contains the newly focused view, then |
| 132 // don't dismiss the pop-up. | 144 // don't dismiss the pop-up. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 149 render_host_view->ContainsNativeView(focused_now)) | 161 render_host_view->ContainsNativeView(focused_now)) |
| 150 return; | 162 return; |
| 151 } | 163 } |
| 152 | 164 |
| 153 // We are careful here to let the current event loop unwind before | 165 // We are careful here to let the current event loop unwind before |
| 154 // causing the popup to be closed. | 166 // causing the popup to be closed. |
| 155 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(popup_, | 167 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(popup_, |
| 156 &ExtensionPopup::Close)); | 168 &ExtensionPopup::Close)); |
| 157 } | 169 } |
| 158 | 170 |
| 171 // Overridden from NotificationObserver |
| 172 virtual void Observe(NotificationType type, |
| 173 const NotificationSource& source, |
| 174 const NotificationDetails& details) { |
| 175 DCHECK(NotificationType::EXTENSION_HOST_CREATED == type); |
| 176 if (NotificationType::EXTENSION_HOST_CREATED == type) { |
| 177 Details<ExtensionHost> details_host(details); |
| 178 // Disallow multiple pop-ups from the same extension, by closing |
| 179 // the presently opened popup during construction of any new popups. |
| 180 if (ViewType::EXTENSION_POPUP == details_host->GetRenderViewType() && |
| 181 popup_->host()->extension() == details_host->extension() && |
| 182 Details<ExtensionHost>(popup_->host()) != details) { |
| 183 popup_->Close(); |
| 184 } |
| 185 } |
| 186 } |
| 187 |
| 159 private: | 188 private: |
| 160 // Returns the AutomationResourceRoutingDelegate interface for |dispatcher|. | 189 // Returns the AutomationResourceRoutingDelegate interface for |dispatcher|. |
| 161 static AutomationResourceRoutingDelegate* | 190 static AutomationResourceRoutingDelegate* |
| 162 GetRoutingFromDispatcher(ExtensionFunctionDispatcher* dispatcher) { | 191 GetRoutingFromDispatcher(ExtensionFunctionDispatcher* dispatcher) { |
| 163 if (!dispatcher) | 192 if (!dispatcher) |
| 164 return NULL; | 193 return NULL; |
| 165 | 194 |
| 166 RenderViewHost* render_view_host = dispatcher->render_view_host(); | 195 RenderViewHost* render_view_host = dispatcher->render_view_host(); |
| 167 RenderViewHostDelegate* delegate = | 196 RenderViewHostDelegate* delegate = |
| 168 render_view_host ? render_view_host->delegate() : NULL; | 197 render_view_host ? render_view_host->delegate() : NULL; |
| 169 | 198 |
| 170 return delegate ? delegate->GetAutomationResourceRoutingDelegate() : NULL; | 199 return delegate ? delegate->GetAutomationResourceRoutingDelegate() : NULL; |
| 171 } | 200 } |
| 172 | 201 |
| 173 // A pointer to the dispatcher that handled the request that opened this | 202 // A pointer to the dispatcher that handled the request that opened this |
| 174 // popup view. | 203 // popup view. |
| 175 ExtensionFunctionDispatcher* dispatcher_; | 204 ExtensionFunctionDispatcher* dispatcher_; |
| 176 | 205 |
| 177 // A pointer to the popup. | 206 // A pointer to the popup. |
| 178 ExtensionPopup* popup_; | 207 ExtensionPopup* popup_; |
| 179 | 208 |
| 209 NotificationRegistrar registrar_; |
| 210 |
| 180 DISALLOW_COPY_AND_ASSIGN(ExtensionPopupHost); | 211 DISALLOW_COPY_AND_ASSIGN(ExtensionPopupHost); |
| 181 }; | 212 }; |
| 182 #endif // TOOLKIT_VIEWS | 213 #endif // TOOLKIT_VIEWS |
| 183 | 214 |
| 184 PopupShowFunction::PopupShowFunction() | 215 PopupShowFunction::PopupShowFunction() |
| 185 #if defined (TOOLKIT_VIEWS) | 216 #if defined (TOOLKIT_VIEWS) |
| 186 : popup_(NULL) | 217 : popup_(NULL) |
| 187 #endif | 218 #endif |
| 188 {} | 219 {} |
| 189 | 220 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 204 registrar_.Add(this, NotificationType::EXTENSION_HOST_DESTROYED, | 235 registrar_.Add(this, NotificationType::EXTENSION_HOST_DESTROYED, |
| 205 NotificationService::AllSources()); | 236 NotificationService::AllSources()); |
| 206 } | 237 } |
| 207 } | 238 } |
| 208 #else | 239 #else |
| 209 SendResponse(false); | 240 SendResponse(false); |
| 210 #endif | 241 #endif |
| 211 } | 242 } |
| 212 | 243 |
| 213 bool PopupShowFunction::RunImpl() { | 244 bool PopupShowFunction::RunImpl() { |
| 245 // Popups may only be displayed from TAB_CONTENTS and EXTENSION_TOOLSTRIP |
| 246 // views. |
| 247 ViewType::Type view_type = |
| 248 dispatcher()->render_view_host()->delegate()->GetRenderViewType(); |
| 249 if (ViewType::EXTENSION_TOOLSTRIP != view_type && |
| 250 ViewType::TAB_CONTENTS != view_type) { |
| 251 error_ = kPopupsDisallowed; |
| 252 return false; |
| 253 } |
| 254 |
| 214 EXTENSION_FUNCTION_VALIDATE(args_->IsType(Value::TYPE_LIST)); | 255 EXTENSION_FUNCTION_VALIDATE(args_->IsType(Value::TYPE_LIST)); |
| 215 const ListValue* args = args_as_list(); | 256 const ListValue* args = args_as_list(); |
| 216 | 257 |
| 217 std::string url_string; | 258 std::string url_string; |
| 218 EXTENSION_FUNCTION_VALIDATE(args->GetString(0, &url_string)); | 259 EXTENSION_FUNCTION_VALIDATE(args->GetString(0, &url_string)); |
| 219 | 260 |
| 220 DictionaryValue* show_details = NULL; | 261 DictionaryValue* show_details = NULL; |
| 221 EXTENSION_FUNCTION_VALIDATE(args->GetDictionary(1, &show_details)); | 262 EXTENSION_FUNCTION_VALIDATE(args->GetDictionary(1, &show_details)); |
| 222 | 263 |
| 223 DictionaryValue* dom_anchor = NULL; | 264 DictionaryValue* dom_anchor = NULL; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 | 306 |
| 266 // Disallow non-extension requests, or requests outside of the requesting | 307 // Disallow non-extension requests, or requests outside of the requesting |
| 267 // extension view's extension. | 308 // extension view's extension. |
| 268 const std::string& extension_id = url.host(); | 309 const std::string& extension_id = url.host(); |
| 269 if (extension_id != GetExtension()->id() || | 310 if (extension_id != GetExtension()->id() || |
| 270 !url.SchemeIs(chrome::kExtensionScheme)) { | 311 !url.SchemeIs(chrome::kExtensionScheme)) { |
| 271 error_ = kInvalidURLError; | 312 error_ = kInvalidURLError; |
| 272 return false; | 313 return false; |
| 273 } | 314 } |
| 274 | 315 |
| 275 #if defined(TOOLKIT_VIEWS) | |
| 276 gfx::Point origin(dom_left, dom_top); | 316 gfx::Point origin(dom_left, dom_top); |
| 277 if (!dispatcher()->render_view_host()->view()) { | 317 if (!dispatcher()->render_view_host()->view()) { |
| 278 error_ = kNotAnExtension; | 318 error_ = kNotAnExtension; |
| 279 return false; | 319 return false; |
| 280 } | 320 } |
| 281 | 321 |
| 282 gfx::Rect content_bounds = | 322 gfx::Rect content_bounds = |
| 283 dispatcher()->render_view_host()->view()->GetViewBounds(); | 323 dispatcher()->render_view_host()->view()->GetViewBounds(); |
| 284 origin.Offset(content_bounds.x(), content_bounds.y()); | 324 origin.Offset(content_bounds.x(), content_bounds.y()); |
| 285 gfx::Rect rect(origin.x(), origin.y(), dom_width, dom_height); | 325 gfx::Rect rect(origin.x(), origin.y(), dom_width, dom_height); |
| 286 | 326 |
| 287 // Pop-up from extension views (ExtensionShelf, etc.), and drop-down when | |
| 288 // in a TabContents view. | |
| 289 ViewType::Type view_type = | |
| 290 dispatcher()->render_view_host()->delegate()->GetRenderViewType(); | |
| 291 BubbleBorder::ArrowLocation arrow_location = | |
| 292 view_type == ViewType::TAB_CONTENTS ? | |
| 293 BubbleBorder::TOP_LEFT : BubbleBorder::BOTTOM_LEFT; | |
| 294 | |
| 295 // Get the correct native window to pass to ExtensionPopup. | 327 // Get the correct native window to pass to ExtensionPopup. |
| 296 // ExtensionFunctionDispatcher::Delegate may provide a custom implementation | 328 // ExtensionFunctionDispatcher::Delegate may provide a custom implementation |
| 297 // of this. | 329 // of this. |
| 298 gfx::NativeWindow window = | 330 gfx::NativeWindow window = |
| 299 dispatcher()->delegate()->GetCustomFrameNativeWindow(); | 331 dispatcher()->delegate()->GetCustomFrameNativeWindow(); |
| 300 if (!window) | 332 if (!window) |
| 301 window = GetCurrentBrowser()->window()->GetNativeHandle(); | 333 window = GetCurrentBrowser()->window()->GetNativeHandle(); |
| 302 | 334 |
| 335 #if defined(TOOLKIT_VIEWS) |
| 336 // Pop-up from extension views (ExtensionShelf, etc.), and drop-down when |
| 337 // in a TabContents view. |
| 338 BubbleBorder::ArrowLocation arrow_location = |
| 339 view_type == ViewType::TAB_CONTENTS ? |
| 340 BubbleBorder::TOP_LEFT : BubbleBorder::BOTTOM_LEFT; |
| 341 |
| 303 // ExtensionPopupHost manages it's own lifetime. | 342 // ExtensionPopupHost manages it's own lifetime. |
| 304 ExtensionPopupHost* popup_host = new ExtensionPopupHost(dispatcher()); | 343 ExtensionPopupHost* popup_host = new ExtensionPopupHost(dispatcher()); |
| 305 popup_ = ExtensionPopup::Show(url, | 344 popup_ = ExtensionPopup::Show(url, |
| 306 GetCurrentBrowser(), | 345 GetCurrentBrowser(), |
| 307 dispatcher()->profile(), | 346 dispatcher()->profile(), |
| 308 window, | 347 window, |
| 309 rect, | 348 rect, |
| 310 arrow_location, | 349 arrow_location, |
| 311 give_focus, | 350 give_focus, |
| 312 false, // inspect_with_devtools | 351 false, // inspect_with_devtools |
| 313 chrome, | 352 chrome, |
| 314 popup_host); // ExtensionPopup::Observer | 353 popup_host); // ExtensionPopup::Observer |
| 315 | 354 |
| 316 // popup_host will handle focus change listening and close the popup when | 355 // popup_host will handle focus change listening and close the popup when |
| 317 // focus leaves the containing views hierarchy. | 356 // focus leaves the containing views hierarchy. |
| 318 popup_->set_close_on_lost_focus(false); | 357 popup_->set_close_on_lost_focus(false); |
| 319 popup_host->set_popup(popup_); | 358 popup_host->set_popup(popup_); |
| 320 #endif // defined(TOOLKIT_VIEWS) | 359 #endif // defined(TOOLKIT_VIEWS) |
| 321 return true; | 360 return true; |
| 322 } | 361 } |
| 323 | 362 |
| 324 void PopupShowFunction::Observe(NotificationType type, | 363 void PopupShowFunction::Observe(NotificationType type, |
| 325 const NotificationSource& source, | 364 const NotificationSource& source, |
| 326 const NotificationDetails& details) { | 365 const NotificationDetails& details) { |
| 327 #if defined(TOOLKIT_VIEWS) | 366 #if defined(TOOLKIT_VIEWS) |
| 328 DCHECK(type == NotificationType::EXTENSION_POPUP_VIEW_READY || | 367 DCHECK(type == NotificationType::EXTENSION_POPUP_VIEW_READY || |
| 329 type == NotificationType::EXTENSION_HOST_DESTROYED); | 368 type == NotificationType::EXTENSION_HOST_DESTROYED); |
| 330 DCHECK(popup_ != NULL); | 369 DCHECK(popup_ != NULL); |
| 331 | 370 |
| 371 // Wait for notification that the popup view is ready (and onload has been |
| 372 // called), before completing the API call. |
| 332 if (popup_ && type == NotificationType::EXTENSION_POPUP_VIEW_READY && | 373 if (popup_ && type == NotificationType::EXTENSION_POPUP_VIEW_READY && |
| 333 Details<ExtensionHost>(popup_->host()) == details) { | 374 Details<ExtensionHost>(popup_->host()) == details) { |
| 334 SendResponse(true); | 375 SendResponse(true); |
| 335 Release(); // Balanced in Run(). | 376 Release(); // Balanced in Run(). |
| 336 } else if (popup_ && type == NotificationType::EXTENSION_HOST_DESTROYED && | 377 } else if (popup_ && type == NotificationType::EXTENSION_HOST_DESTROYED && |
| 337 Details<ExtensionHost>(popup_->host()) == details) { | 378 Details<ExtensionHost>(popup_->host()) == details) { |
| 338 // If the host was destroyed, then report failure, and release the remaining | 379 // If the host was destroyed, then report failure, and release the remaining |
| 339 // reference. | 380 // reference. |
| 340 SendResponse(false); | 381 SendResponse(false); |
| 341 Release(); // Balanced in Run(). | 382 Release(); // Balanced in Run(). |
| 342 } | 383 } |
| 343 #endif // defined(TOOLKIT_VIEWS) | 384 #endif // defined(TOOLKIT_VIEWS) |
| 344 } | 385 } |
| 345 | 386 |
| 346 // static | 387 // static |
| 347 void PopupEventRouter::OnPopupClosed(Profile* profile, | 388 void PopupEventRouter::OnPopupClosed(Profile* profile, |
| 348 int routing_id) { | 389 int routing_id) { |
| 349 std::string full_event_name = StringPrintf( | 390 std::string full_event_name = StringPrintf( |
| 350 extension_popup_module_events::kOnPopupClosed, | 391 extension_popup_module_events::kOnPopupClosed, |
| 351 routing_id); | 392 routing_id); |
| 352 | 393 |
| 353 profile->GetExtensionMessageService()->DispatchEventToRenderers( | 394 profile->GetExtensionMessageService()->DispatchEventToRenderers( |
| 354 full_event_name, | 395 full_event_name, |
| 355 base::JSONWriter::kEmptyArray, | 396 base::JSONWriter::kEmptyArray, |
| 356 profile->IsOffTheRecord(), | 397 profile->IsOffTheRecord(), |
| 357 GURL()); | 398 GURL()); |
| 358 } | 399 } |
| OLD | NEW |