Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: chrome/browser/extensions/extension_popup_api.cc

Issue 385061: experimental.popup support for tab-content-viewed extensions (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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/gfx/point.h" 7 #include "base/gfx/point.h"
8 #include "base/json/json_writer.h" 8 #include "base/json/json_writer.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "chrome/common/extensions/extension.h" 10 #include "chrome/common/extensions/extension.h"
11 #include "chrome/common/notification_details.h" 11 #include "chrome/common/notification_details.h"
12 #include "chrome/common/notification_service.h" 12 #include "chrome/common/notification_service.h"
13 #include "chrome/common/notification_source.h" 13 #include "chrome/common/notification_source.h"
14 #include "chrome/common/notification_type.h" 14 #include "chrome/common/notification_type.h"
15 #include "chrome/browser/extensions/extension_dom_ui.h"
15 #include "chrome/browser/extensions/extension_host.h" 16 #include "chrome/browser/extensions/extension_host.h"
16 #include "chrome/browser/extensions/extension_message_service.h" 17 #include "chrome/browser/extensions/extension_message_service.h"
17 #include "chrome/browser/browser.h" 18 #include "chrome/browser/browser.h"
18 #include "chrome/browser/profile.h" 19 #include "chrome/browser/profile.h"
20 #include "chrome/browser/tab_contents/tab_contents.h"
19 #if defined(TOOLKIT_VIEWS) 21 #if defined(TOOLKIT_VIEWS)
20 #include "chrome/browser/views/extensions/extension_popup.h" 22 #include "chrome/browser/views/extensions/extension_popup.h"
21 #include "views/view.h" 23 #include "views/view.h"
22 #endif 24 #endif
23 25
24 namespace extension_popup_module_events { 26 namespace extension_popup_module_events {
25 27
26 const char kOnPopupClosed[] = "experimental.popup.onClosed.%d"; 28 const char kOnPopupClosed[] = "experimental.popup.onClosed.%d";
27 29
28 } // namespace extension_popup_module_events 30 } // namespace extension_popup_module_events
29 31
30 namespace { 32 namespace {
31 33
32 // Errors. 34 // Errors.
33 const char kBadAnchorArgument[] = "Invalid anchor argument."; 35 const char kBadAnchorArgument[] = "Invalid anchor argument.";
34 const char kInvalidURLError[] = "Invalid URL."; 36 const char kInvalidURLError[] = "Invalid URL.";
37 const char kNotAnExtension[] = "Not an extension view.";
35 38
36 // Keys. 39 // Keys.
37 const wchar_t kUrlKey[] = L"url"; 40 const wchar_t kUrlKey[] = L"url";
38 const wchar_t kWidthKey[] = L"width"; 41 const wchar_t kWidthKey[] = L"width";
39 const wchar_t kHeightKey[] = L"height"; 42 const wchar_t kHeightKey[] = L"height";
40 const wchar_t kTopKey[] = L"top"; 43 const wchar_t kTopKey[] = L"top";
41 const wchar_t kLeftKey[] = L"left"; 44 const wchar_t kLeftKey[] = L"left";
42 45
43 }; // namespace 46 }; // namespace
44 47
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 // Disallow non-extension requests, or requests outside of the requesting 107 // Disallow non-extension requests, or requests outside of the requesting
105 // extension view's extension. 108 // extension view's extension.
106 const std::string& extension_id = url.host(); 109 const std::string& extension_id = url.host();
107 if (extension_id != dispatcher()->GetExtension()->id() || 110 if (extension_id != dispatcher()->GetExtension()->id() ||
108 !url.SchemeIs("chrome-extension")) { 111 !url.SchemeIs("chrome-extension")) {
109 error_ = kInvalidURLError; 112 error_ = kInvalidURLError;
110 return false; 113 return false;
111 } 114 }
112 115
113 #if defined(TOOLKIT_VIEWS) 116 #if defined(TOOLKIT_VIEWS)
114 views::View* extension_view = dispatcher()->GetExtensionHost()->view();
115 gfx::Point origin(dom_left, dom_top); 117 gfx::Point origin(dom_left, dom_top);
116 views::View::ConvertPointToScreen(extension_view, &origin); 118 if (!ConvertHostPointToScreen(&origin)) {
119 error_ = kNotAnExtension;
120 return false;
121 }
117 gfx::Rect rect(origin.x(), origin.y(), dom_width, dom_height); 122 gfx::Rect rect(origin.x(), origin.y(), dom_width, dom_height);
118 123
124 // Pop-up from extension views (ExtensionShelf, etc.), and drop-down when
125 // in a TabContents view.
126 BubbleBorder::ArrowLocation arrow_location =
127 (NULL != dispatcher()->GetExtensionHost()) ? BubbleBorder::BOTTOM_LEFT :
128 BubbleBorder::TOP_LEFT;
119 popup_ = ExtensionPopup::Show(url, dispatcher()->GetBrowser(), rect, 129 popup_ = ExtensionPopup::Show(url, dispatcher()->GetBrowser(), rect,
120 BubbleBorder::BOTTOM_LEFT); 130 arrow_location);
121 131
122 dispatcher()->GetExtensionHost()->set_child_popup(popup_); 132 ExtensionPopupHost* popup_host = dispatcher()->GetPopupHost();
123 popup_->set_delegate(dispatcher()->GetExtensionHost()); 133 DCHECK(popup_host);
124 #endif 134
135 popup_host->set_child_popup(popup_);
136 popup_->set_delegate(popup_host);
137 #endif // defined(TOOLKIT_VIEWS)
138 return true;
139 }
140
141 bool PopupShowFunction::ConvertHostPointToScreen(gfx::Point* point) {
142 DCHECK(point);
143
144 // If the popup is being requested from an ExtensionHost, then compute
145 // the sreen coordinates based on the views::View object of the ExtensionHost.
146 if (dispatcher()->GetExtensionHost()) {
147 // A dispatcher cannot have both an ExtensionHost, and an ExtensionDOMUI.
148 DCHECK(!dispatcher()->GetExtensionDOMUI());
149
150 #if defined(TOOLKIT_VIEWS)
151 views::View* extension_view = dispatcher()->GetExtensionHost()->view();
152 if (!extension_view)
153 return false;
154
155 views::View::ConvertPointToScreen(extension_view, point);
156 #else
157 // TODO(port)
158 NOTIMPLEMENTED();
159 #endif // defined(TOOLKIT_VIEWS)
160 } else if (dispatcher()->GetExtensionDOMUI()) {
161 // Otherwise, the popup is being requested from a TabContents, so determine
162 // the screen-space position through the TabContentsView.
163 ExtensionDOMUI* dom_ui = dispatcher()->GetExtensionDOMUI();
164 TabContents* tab_contents = dom_ui->tab_contents();
165 if (!tab_contents)
166 return false;
167
168 gfx::Rect content_bounds;
169 tab_contents->GetContainerBounds(&content_bounds);
170 point->Offset(content_bounds.x(), content_bounds.y());
171 }
172
125 return true; 173 return true;
126 } 174 }
127 175
128 void PopupShowFunction::Observe(NotificationType type, 176 void PopupShowFunction::Observe(NotificationType type,
129 const NotificationSource& source, 177 const NotificationSource& source,
130 const NotificationDetails& details) { 178 const NotificationDetails& details) {
131 #if defined(TOOLKIT_VIEWS) 179 #if defined(TOOLKIT_VIEWS)
132 DCHECK(type == NotificationType::EXTENSION_POPUP_VIEW_READY || 180 DCHECK(type == NotificationType::EXTENSION_POPUP_VIEW_READY ||
133 type == NotificationType::EXTENSION_HOST_DESTROYED); 181 type == NotificationType::EXTENSION_HOST_DESTROYED);
134 DCHECK(popup_ != NULL); 182 DCHECK(popup_ != NULL);
135 183
136 if (popup_ && type == NotificationType::EXTENSION_POPUP_VIEW_READY && 184 if (popup_ && type == NotificationType::EXTENSION_POPUP_VIEW_READY &&
137 Details<ExtensionHost>(popup_->host()) == details) { 185 Details<ExtensionHost>(popup_->host()) == details) {
138 SendResponse(true); 186 SendResponse(true);
139 Release(); // Balanced in Run(). 187 Release(); // Balanced in Run().
140 } else if (popup_ && type == NotificationType::EXTENSION_HOST_DESTROYED && 188 } else if (popup_ && type == NotificationType::EXTENSION_HOST_DESTROYED &&
141 Details<ExtensionHost>(popup_->host()) == details) { 189 Details<ExtensionHost>(popup_->host()) == details) {
142 // If the host was destroyed, then report failure, and release the remaining 190 // If the host was destroyed, then report failure, and release the remaining
143 // reference. 191 // reference.
144 SendResponse(false); 192 SendResponse(false);
145 Release(); // Balanced in Run(). 193 Release(); // Balanced in Run().
146 } 194 }
147 #endif 195 #endif // defined(TOOLKIT_VIEWS)
148 } 196 }
149 197
150 // static 198 // static
151 void PopupEventRouter::OnPopupClosed(Profile* profile, 199 void PopupEventRouter::OnPopupClosed(Profile* profile,
152 int routing_id) { 200 int routing_id) {
153 std::string full_event_name = StringPrintf( 201 std::string full_event_name = StringPrintf(
154 extension_popup_module_events::kOnPopupClosed, 202 extension_popup_module_events::kOnPopupClosed,
155 routing_id); 203 routing_id);
156 204
157 profile->GetExtensionMessageService()->DispatchEventToRenderers( 205 profile->GetExtensionMessageService()->DispatchEventToRenderers(
158 full_event_name, 206 full_event_name,
159 base::JSONWriter::kEmptyArray); 207 base::JSONWriter::kEmptyArray);
160 } 208 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_popup_api.h ('k') | chrome/browser/extensions/extension_popup_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698