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 |