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

Side by Side Diff: chrome/browser/ui/views/extensions/extension_action_view_controller_views.cc

Issue 670463004: Make a platform-independent ToolbarActionViewController (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 months 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/ui/views/extensions/extension_action_view_controller.h" 5 #include "chrome/browser/ui/views/extensions/extension_action_view_controller_vi ews.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/strings/utf_string_conversions.h" 8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/extensions/api/commands/command_service.h" 9 #include "chrome/browser/extensions/api/commands/command_service.h"
10 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" 10 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
11 #include "chrome/browser/extensions/extension_action.h" 11 #include "chrome/browser/extensions/extension_action.h"
12 #include "chrome/browser/profiles/profile.h" 12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/sessions/session_tab_helper.h" 13 #include "chrome/browser/sessions/session_tab_helper.h"
14 #include "chrome/browser/ui/browser.h" 14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/extensions/accelerator_priority.h" 15 #include "chrome/browser/ui/extensions/accelerator_priority.h"
16 #include "chrome/browser/ui/views/toolbar/toolbar_action_view_delegate.h" 16 #include "chrome/browser/ui/views/toolbar/toolbar_action_view_delegate_views.h"
17 #include "chrome/browser/ui/views/toolbar/toolbar_view.h" 17 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
18 #include "chrome/common/extensions/api/extension_action/action_info.h" 18 #include "chrome/common/extensions/api/extension_action/action_info.h"
19 #include "content/public/browser/notification_details.h" 19 #include "content/public/browser/notification_details.h"
20 #include "content/public/browser/notification_source.h" 20 #include "content/public/browser/notification_source.h"
21 #include "extensions/browser/notification_types.h" 21 #include "extensions/browser/notification_types.h"
22 #include "extensions/common/extension.h" 22 #include "extensions/common/extension.h"
23 #include "extensions/common/manifest_constants.h" 23 #include "extensions/common/manifest_constants.h"
24 #include "ui/gfx/image/image_skia.h" 24 #include "ui/gfx/image/image_skia.h"
25 #include "ui/gfx/image/image_skia_operations.h" 25 #include "ui/gfx/image/image_skia_operations.h"
26 #include "ui/views/controls/menu/menu_controller.h" 26 #include "ui/views/controls/menu/menu_controller.h"
27 #include "ui/views/controls/menu/menu_runner.h" 27 #include "ui/views/controls/menu/menu_runner.h"
28 #include "ui/views/view.h" 28 #include "ui/views/view.h"
29 #include "ui/views/widget/widget.h" 29 #include "ui/views/widget/widget.h"
30 30
31 using extensions::ActionInfo; 31 using extensions::ActionInfo;
32 using extensions::CommandService; 32 using extensions::CommandService;
33 33
34 namespace { 34 namespace {
35 35
36 // The ExtensionActionViewController which is currently showing its context 36 // The ExtensionActionViewControllerViews which is currently showing its context
37 // menu, if any. 37 // menu, if any.
38 // Since only one context menu can be shown (even across browser windows), it's 38 // Since only one context menu can be shown (even across browser windows), it's
39 // safe to have this be a global singleton. 39 // safe to have this be a global singleton.
40 ExtensionActionViewController* context_menu_owner = NULL; 40 ExtensionActionViewControllerViews* context_menu_owner = NULL;
41 41
42 } // namespace 42 } // namespace
43 43
44 ExtensionActionViewController::ExtensionActionViewController( 44 ExtensionActionViewControllerViews::ExtensionActionViewControllerViews(
45 const extensions::Extension* extension, 45 const extensions::Extension* extension,
46 Browser* browser, 46 Browser* browser,
47 ExtensionAction* extension_action) 47 ExtensionAction* extension_action)
48 : extension_(extension), 48 : ExtensionActionViewController(extension, browser, extension_action),
49 browser_(browser),
50 extension_action_(extension_action),
51 delegate_(nullptr),
52 icon_factory_(browser->profile(), extension, extension_action, this),
53 icon_observer_(nullptr), 49 icon_observer_(nullptr),
54 popup_(nullptr), 50 popup_(nullptr),
55 weak_factory_(this) { 51 weak_factory_(this) {
56 DCHECK(extension_action);
57 DCHECK(extension_action->action_type() == ActionInfo::TYPE_PAGE ||
58 extension_action->action_type() == ActionInfo::TYPE_BROWSER);
59 DCHECK(extension);
60
61 content::NotificationSource notification_source = 52 content::NotificationSource notification_source =
62 content::Source<Profile>(browser->profile()->GetOriginalProfile()); 53 content::Source<Profile>(browser->profile()->GetOriginalProfile());
63 registrar_.Add(this, 54 registrar_.Add(this,
64 extensions::NOTIFICATION_EXTENSION_COMMAND_ADDED, 55 extensions::NOTIFICATION_EXTENSION_COMMAND_ADDED,
65 notification_source); 56 notification_source);
66 registrar_.Add(this, 57 registrar_.Add(this,
67 extensions::NOTIFICATION_EXTENSION_COMMAND_REMOVED, 58 extensions::NOTIFICATION_EXTENSION_COMMAND_REMOVED,
68 notification_source); 59 notification_source);
69 } 60 }
70 61
71 ExtensionActionViewController::~ExtensionActionViewController() { 62 ExtensionActionViewControllerViews::~ExtensionActionViewControllerViews() {
72 if (context_menu_owner == this) 63 if (context_menu_owner == this)
73 context_menu_owner = NULL; 64 context_menu_owner = NULL;
74 HidePopup(); 65 HidePopup();
75 UnregisterCommand(false); 66 UnregisterCommand(false);
76 } 67 }
77 68
78 const std::string& ExtensionActionViewController::GetId() const { 69 gfx::NativeView ExtensionActionViewControllerViews::GetPopupNativeView() {
79 return extension_->id();
80 }
81
82 void ExtensionActionViewController::SetDelegate(
83 ToolbarActionViewDelegate* delegate) {
84 delegate_ = delegate;
85 delegate_->GetAsView()->set_context_menu_controller(this);
86 }
87
88 gfx::Image ExtensionActionViewController::GetIcon(
89 content::WebContents* web_contents) {
90 return icon_factory_.GetIcon(SessionTabHelper::IdForTab(web_contents));
91 }
92
93 gfx::ImageSkia ExtensionActionViewController::GetIconWithBadge() {
94 content::WebContents* web_contents = delegate_->GetCurrentWebContents();
95 gfx::Size spacing(0, ToolbarView::kVertSpacing);
96 gfx::ImageSkia icon = *GetIcon(web_contents).ToImageSkia();
97 if (!IsEnabled(web_contents))
98 icon = gfx::ImageSkiaOperations::CreateTransparentImage(icon, .25);
99 return extension_action_->GetIconWithBadge(
100 icon, SessionTabHelper::IdForTab(web_contents), spacing);
101 }
102
103 base::string16 ExtensionActionViewController::GetAccessibleName(
104 content::WebContents* web_contents) const {
105 std::string title =
106 extension_action()->GetTitle(SessionTabHelper::IdForTab(web_contents));
107 return base::UTF8ToUTF16(title.empty() ? extension()->name() : title);
108 }
109
110 base::string16 ExtensionActionViewController::GetTooltip(
111 content::WebContents* web_contents) const {
112 return GetAccessibleName(web_contents);
113 }
114
115 bool ExtensionActionViewController::IsEnabled(
116 content::WebContents* web_contents) const {
117 return extension_action_->GetIsVisible(
118 SessionTabHelper::IdForTab(web_contents));
119 }
120
121 bool ExtensionActionViewController::HasPopup(
122 content::WebContents* web_contents) const {
123 int tab_id = SessionTabHelper::IdForTab(web_contents);
124 return (tab_id < 0) ? false : extension_action_->HasPopup(tab_id);
125 }
126
127 void ExtensionActionViewController::HidePopup() {
128 if (popup_)
129 CleanupPopup(true);
130 }
131
132 gfx::NativeView ExtensionActionViewController::GetPopupNativeView() {
133 return popup_ ? popup_->GetWidget()->GetNativeView() : nullptr; 70 return popup_ ? popup_->GetWidget()->GetNativeView() : nullptr;
134 } 71 }
135 72
136 bool ExtensionActionViewController::IsMenuRunning() const { 73 bool ExtensionActionViewControllerViews::IsMenuRunning() const {
137 return menu_runner_.get() != NULL; 74 return menu_runner_.get() != NULL;
138 } 75 }
139 76
140 bool ExtensionActionViewController::CanDrag() const { 77 void ExtensionActionViewControllerViews::RegisterCommand() {
141 return true;
142 }
143
144 bool ExtensionActionViewController::ExecuteAction(bool by_user) {
145 return ExecuteAction(ExtensionPopup::SHOW, by_user);
146 }
147
148 void ExtensionActionViewController::PaintExtra(
149 gfx::Canvas* canvas,
150 const gfx::Rect& bounds,
151 content::WebContents* web_contents) const {
152 int tab_id = SessionTabHelper::IdForTab(web_contents);
153 if (tab_id >= 0)
154 extension_action_->PaintBadge(canvas, bounds, tab_id);
155 }
156
157 void ExtensionActionViewController::RegisterCommand() {
158 // If we've already registered, do nothing. 78 // If we've already registered, do nothing.
159 if (action_keybinding_.get()) 79 if (action_keybinding_.get())
160 return; 80 return;
161 81
162 extensions::Command extension_command; 82 extensions::Command extension_command;
163 views::FocusManager* focus_manager = 83 views::FocusManager* focus_manager =
164 delegate_->GetFocusManagerForAccelerator(); 84 GetDelegateViews()->GetFocusManagerForAccelerator();
165 if (focus_manager && GetExtensionCommand(&extension_command)) { 85 if (focus_manager && GetExtensionCommand(&extension_command)) {
166 action_keybinding_.reset( 86 action_keybinding_.reset(
167 new ui::Accelerator(extension_command.accelerator())); 87 new ui::Accelerator(extension_command.accelerator()));
168 focus_manager->RegisterAccelerator( 88 focus_manager->RegisterAccelerator(
169 *action_keybinding_, 89 *action_keybinding_,
170 GetAcceleratorPriority(extension_command.accelerator(), extension_), 90 GetAcceleratorPriority(extension_command.accelerator(), extension()),
171 this); 91 this);
172 } 92 }
173 } 93 }
174 94
175 void ExtensionActionViewController::InspectPopup() { 95 bool ExtensionActionViewControllerViews::IsShowingPopup() const {
176 ExecuteAction(ExtensionPopup::SHOW_AND_INSPECT, true); 96 return popup_ != nullptr;
177 } 97 }
178 98
179 bool ExtensionActionViewController::ExecuteAction( 99 void ExtensionActionViewControllerViews::CloseActivePopup() {
180 ExtensionPopup::ShowAction show_action, bool grant_tab_permissions) { 100 GetDelegateViews()->HideActivePopup();
181 if (extensions::ExtensionActionAPI::Get(browser_->profile())->
182 ExecuteExtensionAction(extension_, browser_, grant_tab_permissions) ==
183 ExtensionAction::ACTION_SHOW_POPUP) {
184 GURL popup_url = extension_action_->GetPopupUrl(
185 SessionTabHelper::IdForTab(delegate_->GetCurrentWebContents()));
186 return static_cast<ExtensionActionViewController*>(
187 delegate_->GetPreferredPopupViewController())->ShowPopupWithUrl(
188 show_action, popup_url, grant_tab_permissions);
189 }
190 return false;
191 } 101 }
192 102
193 void ExtensionActionViewController::OnIconUpdated() { 103 void ExtensionActionViewControllerViews::ClosePopupImpl() {
194 delegate_->OnIconUpdated(); 104 // We should only be asked to close the popup if we're showing one.
195 if (icon_observer_) 105 DCHECK(popup_);
196 icon_observer_->OnIconUpdated(); 106 CleanupPopup(true);
197 } 107 }
198 108
199 bool ExtensionActionViewController::AcceleratorPressed( 109 bool ExtensionActionViewControllerViews::ShowPopupWithUrlImpl(
110 PopupShowAction show_action,
111 const GURL& popup_url,
112 bool grant_tab_permissions) {
113 views::BubbleBorder::Arrow arrow = base::i18n::IsRTL() ?
114 views::BubbleBorder::TOP_LEFT : views::BubbleBorder::TOP_RIGHT;
115
116 views::View* reference_view = GetDelegateViews()->GetReferenceViewForPopup();
117
118 ExtensionPopup::ShowAction popup_show_action =
119 show_action == SHOW_POPUP ? ExtensionPopup::SHOW :
120 ExtensionPopup::SHOW_AND_INSPECT;
121 popup_ = ExtensionPopup::ShowPopup(
122 popup_url, browser(), reference_view, arrow, popup_show_action);
123 popup_->GetWidget()->AddObserver(this);
124
125 GetDelegateViews()->OnPopupShown(grant_tab_permissions);
126
127 return true;
128 }
129
130 void ExtensionActionViewControllerViews::OnDelegateSet() {
131 GetDelegateViews()->GetAsView()->set_context_menu_controller(this);
132 }
133
134 void ExtensionActionViewControllerViews::Observe(
135 int type,
136 const content::NotificationSource& source,
137 const content::NotificationDetails& details) {
138 DCHECK(type == extensions::NOTIFICATION_EXTENSION_COMMAND_ADDED ||
139 type == extensions::NOTIFICATION_EXTENSION_COMMAND_REMOVED);
140 std::pair<const std::string, const std::string>* payload =
141 content::Details<std::pair<const std::string, const std::string> >(
142 details).ptr();
143 if (extension()->id() == payload->first &&
144 payload->second ==
145 extensions::manifest_values::kBrowserActionCommandEvent) {
146 if (type == extensions::NOTIFICATION_EXTENSION_COMMAND_ADDED)
147 RegisterCommand();
148 else
149 UnregisterCommand(true);
150 }
151 }
152
153 bool ExtensionActionViewControllerViews::AcceleratorPressed(
200 const ui::Accelerator& accelerator) { 154 const ui::Accelerator& accelerator) {
201 // We shouldn't be handling any accelerators if the view is hidden, unless 155 // We shouldn't be handling any accelerators if the view is hidden, unless
202 // this is a browser action. 156 // this is a browser action.
203 DCHECK(extension_action_->action_type() == ActionInfo::TYPE_BROWSER || 157 DCHECK(extension_action()->action_type() == ActionInfo::TYPE_BROWSER ||
204 delegate_->GetAsView()->visible()); 158 GetDelegateViews()->GetAsView()->visible());
205 159
206 // Normal priority shortcuts must be handled via standard browser commands to 160 // Normal priority shortcuts must be handled via standard browser commands to
207 // be processed at the proper time. 161 // be processed at the proper time.
208 if (GetAcceleratorPriority(accelerator, extension()) == 162 if (GetAcceleratorPriority(accelerator, extension()) ==
209 ui::AcceleratorManager::kNormalPriority) 163 ui::AcceleratorManager::kNormalPriority)
210 return false; 164 return false;
211 165
212 ExecuteAction(true); 166 ExecuteAction(true);
213 return true; 167 return true;
214 } 168 }
215 169
216 bool ExtensionActionViewController::CanHandleAccelerators() const { 170 bool ExtensionActionViewControllerViews::CanHandleAccelerators() const {
217 // Page actions can only handle accelerators when they are visible. 171 // Page actions can only handle accelerators when they are visible.
218 // Browser actions can handle accelerators even when not visible, since they 172 // Browser actions can handle accelerators even when not visible, since they
219 // might be hidden in an overflow menu. 173 // might be hidden in an overflow menu.
220 return extension_action_->action_type() == ActionInfo::TYPE_PAGE ? 174 return extension_action()->action_type() == ActionInfo::TYPE_PAGE ?
221 delegate_->GetAsView()->visible() : true; 175 GetDelegateViews()->GetAsView()->visible() : true;
222 } 176 }
223 177
224 void ExtensionActionViewController::OnWidgetDestroying(views::Widget* widget) { 178 void ExtensionActionViewControllerViews::OnWidgetDestroying(
179 views::Widget* widget) {
225 DCHECK(popup_); 180 DCHECK(popup_);
226 DCHECK_EQ(popup_->GetWidget(), widget); 181 DCHECK_EQ(popup_->GetWidget(), widget);
227 CleanupPopup(false); 182 CleanupPopup(false);
228 } 183 }
229 184
230 void ExtensionActionViewController::ShowContextMenuForView( 185 void ExtensionActionViewControllerViews::ShowContextMenuForView(
231 views::View* source, 186 views::View* source,
232 const gfx::Point& point, 187 const gfx::Point& point,
233 ui::MenuSourceType source_type) { 188 ui::MenuSourceType source_type) {
234 // If there's another active menu that won't be dismissed by opening this one, 189 // If there's another active menu that won't be dismissed by opening this one,
235 // then we can't show this one right away, since we can only show one nested 190 // then we can't show this one right away, since we can only show one nested
236 // menu at a time. 191 // menu at a time.
237 // If the other menu is an extension action's context menu, then we'll run 192 // If the other menu is an extension action's context menu, then we'll run
238 // this one after that one closes. If it's a different type of menu, then we 193 // this one after that one closes. If it's a different type of menu, then we
239 // close it and give up, for want of a better solution. (Luckily, this is 194 // close it and give up, for want of a better solution. (Luckily, this is
240 // rare). 195 // rare).
241 // TODO(devlin): Update this when views code no longer runs menus in a nested 196 // TODO(devlin): Update this when views code no longer runs menus in a nested
242 // loop. 197 // loop.
243 if (context_menu_owner) { 198 if (context_menu_owner) {
244 context_menu_owner->followup_context_menu_task_ = 199 context_menu_owner->followup_context_menu_task_ =
245 base::Bind(&ExtensionActionViewController::DoShowContextMenu, 200 base::Bind(&ExtensionActionViewControllerViews::DoShowContextMenu,
246 weak_factory_.GetWeakPtr(), 201 weak_factory_.GetWeakPtr(),
247 source_type); 202 source_type);
248 } 203 }
249 if (CloseActiveMenuIfNeeded()) 204 if (CloseActiveMenuIfNeeded())
250 return; 205 return;
251 206
252 // Otherwise, no other menu is showing, and we can proceed normally. 207 // Otherwise, no other menu is showing, and we can proceed normally.
253 DoShowContextMenu(source_type); 208 DoShowContextMenu(source_type);
254 } 209 }
255 210
256 void ExtensionActionViewController::Observe( 211 void ExtensionActionViewControllerViews::DoShowContextMenu(
257 int type,
258 const content::NotificationSource& source,
259 const content::NotificationDetails& details) {
260 DCHECK(type == extensions::NOTIFICATION_EXTENSION_COMMAND_ADDED ||
261 type == extensions::NOTIFICATION_EXTENSION_COMMAND_REMOVED);
262 std::pair<const std::string, const std::string>* payload =
263 content::Details<std::pair<const std::string, const std::string> >(
264 details).ptr();
265 if (extension_->id() == payload->first &&
266 payload->second ==
267 extensions::manifest_values::kBrowserActionCommandEvent) {
268 if (type == extensions::NOTIFICATION_EXTENSION_COMMAND_ADDED)
269 RegisterCommand();
270 else
271 UnregisterCommand(true);
272 }
273 }
274
275 void ExtensionActionViewController::DoShowContextMenu(
276 ui::MenuSourceType source_type) { 212 ui::MenuSourceType source_type) {
277 if (!extension_->ShowConfigureContextMenus()) 213 if (!extension()->ShowConfigureContextMenus())
278 return; 214 return;
279 215
280 DCHECK(!context_menu_owner); 216 DCHECK(!context_menu_owner);
281 context_menu_owner = this; 217 context_menu_owner = this;
282 218
283 // We shouldn't have both a popup and a context menu showing. 219 // We shouldn't have both a popup and a context menu showing.
284 delegate_->HideActivePopup(); 220 GetDelegateViews()->HideActivePopup();
285 221
286 // Reconstructs the menu every time because the menu's contents are dynamic. 222 // Reconstructs the menu every time because the menu's contents are dynamic.
287 scoped_refptr<ExtensionContextMenuModel> context_menu_model( 223 scoped_refptr<ExtensionContextMenuModel> context_menu_model(
288 new ExtensionContextMenuModel(extension_, browser_, this)); 224 new ExtensionContextMenuModel(extension(), browser(), this));
289 225
290 gfx::Point screen_loc; 226 gfx::Point screen_loc;
291 views::View::ConvertPointToScreen(delegate_->GetAsView(), &screen_loc); 227 views::View::ConvertPointToScreen(GetDelegateViews()->GetAsView(),
228 &screen_loc);
292 229
293 int run_types = views::MenuRunner::HAS_MNEMONICS | 230 int run_types = views::MenuRunner::HAS_MNEMONICS |
294 views::MenuRunner::CONTEXT_MENU; 231 views::MenuRunner::CONTEXT_MENU;
295 if (delegate_->IsShownInMenu()) 232 if (GetDelegateViews()->IsShownInMenu())
296 run_types |= views::MenuRunner::IS_NESTED; 233 run_types |= views::MenuRunner::IS_NESTED;
297 234
298 views::Widget* parent = delegate_->GetParentForContextMenu(); 235 views::Widget* parent = GetDelegateViews()->GetParentForContextMenu();
299 236
300 menu_runner_.reset( 237 menu_runner_.reset(
301 new views::MenuRunner(context_menu_model.get(), run_types)); 238 new views::MenuRunner(context_menu_model.get(), run_types));
302 239
303 if (menu_runner_->RunMenuAt( 240 if (menu_runner_->RunMenuAt(
304 parent, 241 parent,
305 delegate_->GetContextMenuButton(), 242 GetDelegateViews()->GetContextMenuButton(),
306 gfx::Rect(screen_loc, delegate_->GetAsView()->size()), 243 gfx::Rect(screen_loc, GetDelegateViews()->GetAsView()->size()),
307 views::MENU_ANCHOR_TOPLEFT, 244 views::MENU_ANCHOR_TOPLEFT,
308 source_type) == views::MenuRunner::MENU_DELETED) { 245 source_type) == views::MenuRunner::MENU_DELETED) {
309 return; 246 return;
310 } 247 }
311 248
312 context_menu_owner = NULL; 249 context_menu_owner = NULL;
313 menu_runner_.reset(); 250 menu_runner_.reset();
314 251
315 // If another extension action wants to show its context menu, allow it to. 252 // If another extension action wants to show its context menu, allow it to.
316 if (!followup_context_menu_task_.is_null()) { 253 if (!followup_context_menu_task_.is_null()) {
317 base::Closure task = followup_context_menu_task_; 254 base::Closure task = followup_context_menu_task_;
318 followup_context_menu_task_ = base::Closure(); 255 followup_context_menu_task_ = base::Closure();
319 task.Run(); 256 task.Run();
320 } 257 }
321 } 258 }
322 259
323 bool ExtensionActionViewController::ShowPopupWithUrl( 260 void ExtensionActionViewControllerViews::UnregisterCommand(
324 ExtensionPopup::ShowAction show_action, 261 bool only_if_removed) {
325 const GURL& popup_url,
326 bool grant_tab_permissions) {
327 // If we're already showing the popup for this browser action, just hide it
328 // and return.
329 bool already_showing = popup_ != NULL;
330
331 // Always hide the current popup, even if it's not the same.
332 // Only one popup should be visible at a time.
333 delegate_->HideActivePopup();
334
335 // Similarly, don't allow a context menu and a popup to be showing
336 // simultaneously.
337 CloseActiveMenuIfNeeded();
338
339 if (already_showing)
340 return false;
341
342 views::BubbleBorder::Arrow arrow = base::i18n::IsRTL() ?
343 views::BubbleBorder::TOP_LEFT : views::BubbleBorder::TOP_RIGHT;
344
345 views::View* reference_view = delegate_->GetReferenceViewForPopup();
346
347 popup_ = ExtensionPopup::ShowPopup(
348 popup_url, browser_, reference_view, arrow, show_action);
349 popup_->GetWidget()->AddObserver(this);
350
351 delegate_->OnPopupShown(grant_tab_permissions);
352
353 return true;
354 }
355
356 bool ExtensionActionViewController::GetExtensionCommand(
357 extensions::Command* command) {
358 DCHECK(command);
359 CommandService* command_service = CommandService::Get(browser_->profile());
360 if (extension_action_->action_type() == ActionInfo::TYPE_PAGE) {
361 return command_service->GetPageActionCommand(
362 extension_->id(), CommandService::ACTIVE_ONLY, command, NULL);
363 }
364 return command_service->GetBrowserActionCommand(
365 extension_->id(), CommandService::ACTIVE_ONLY, command, NULL);
366 }
367
368 void ExtensionActionViewController::UnregisterCommand(bool only_if_removed) {
369 views::FocusManager* focus_manager = 262 views::FocusManager* focus_manager =
370 delegate_->GetFocusManagerForAccelerator(); 263 GetDelegateViews()->GetFocusManagerForAccelerator();
371 if (!focus_manager || !action_keybinding_.get()) 264 if (!focus_manager || !action_keybinding_.get())
372 return; 265 return;
373 266
374 // If |only_if_removed| is true, it means that we only need to unregister 267 // If |only_if_removed| is true, it means that we only need to unregister
375 // ourselves as an accelerator if the command was removed. Otherwise, we need 268 // ourselves as an accelerator if the command was removed. Otherwise, we need
376 // to unregister ourselves no matter what (likely because we are shutting 269 // to unregister ourselves no matter what (likely because we are shutting
377 // down). 270 // down).
378 extensions::Command extension_command; 271 extensions::Command extension_command;
379 if (!only_if_removed || !GetExtensionCommand(&extension_command)) { 272 if (!only_if_removed || !GetExtensionCommand(&extension_command)) {
380 focus_manager->UnregisterAccelerator(*action_keybinding_, this); 273 focus_manager->UnregisterAccelerator(*action_keybinding_, this);
381 action_keybinding_.reset(); 274 action_keybinding_.reset();
382 } 275 }
383 } 276 }
384 277
385 bool ExtensionActionViewController::CloseActiveMenuIfNeeded() { 278 bool ExtensionActionViewControllerViews::CloseActiveMenuIfNeeded() {
386 // If this view is shown inside another menu, there's a possibility that there 279 // If this view is shown inside another menu, there's a possibility that there
387 // is another context menu showing that we have to close before we can 280 // is another context menu showing that we have to close before we can
388 // activate a different menu. 281 // activate a different menu.
389 if (delegate_->IsShownInMenu()) { 282 if (GetDelegateViews()->IsShownInMenu()) {
390 views::MenuController* menu_controller = 283 views::MenuController* menu_controller =
391 views::MenuController::GetActiveInstance(); 284 views::MenuController::GetActiveInstance();
392 // If this is shown inside a menu, then there should always be an active 285 // If this is shown inside a menu, then there should always be an active
393 // menu controller. 286 // menu controller.
394 DCHECK(menu_controller); 287 DCHECK(menu_controller);
395 if (menu_controller->in_nested_run()) { 288 if (menu_controller->in_nested_run()) {
396 // There is another menu showing. Close the outermost menu (since we are 289 // There is another menu showing. Close the outermost menu (since we are
397 // shown in the same menu, we don't want to close the whole thing). 290 // shown in the same menu, we don't want to close the whole thing).
398 menu_controller->Cancel(views::MenuController::EXIT_OUTERMOST); 291 menu_controller->Cancel(views::MenuController::EXIT_OUTERMOST);
399 return true; 292 return true;
400 } 293 }
401 } 294 }
402 295
403 return false; 296 return false;
404 } 297 }
405 298
406 void ExtensionActionViewController::CleanupPopup(bool close_widget) { 299 void ExtensionActionViewControllerViews::CleanupPopup(bool close_widget) {
407 DCHECK(popup_); 300 DCHECK(popup_);
408 delegate_->CleanupPopup(); 301 GetDelegateViews()->CleanupPopup();
409 popup_->GetWidget()->RemoveObserver(this); 302 popup_->GetWidget()->RemoveObserver(this);
410 if (close_widget) 303 if (close_widget)
411 popup_->GetWidget()->Close(); 304 popup_->GetWidget()->Close();
412 popup_ = NULL; 305 popup_ = NULL;
413 } 306 }
307
308 ToolbarActionViewDelegateViews*
309 ExtensionActionViewControllerViews::GetDelegateViews() const {
310 return static_cast<ToolbarActionViewDelegateViews*>(delegate());
311 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698