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

Side by Side Diff: chrome/browser/ui/views/location_bar/page_action_image_view.cc

Issue 431173002: Create ExtensionActionView class (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 4 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/location_bar/page_action_image_view.h" 5 #include "chrome/browser/ui/views/location_bar/page_action_image_view.h"
6 6
7 #include "base/strings/utf_string_conversions.h" 7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/extensions/api/commands/command_service.h"
9 #include "chrome/browser/extensions/extension_action.h" 8 #include "chrome/browser/extensions/extension_action.h"
10 #include "chrome/browser/extensions/extension_action_icon_factory.h"
11 #include "chrome/browser/extensions/extension_action_manager.h"
12 #include "chrome/browser/extensions/extension_context_menu_model.h"
13 #include "chrome/browser/extensions/extension_tab_util.h"
14 #include "chrome/browser/extensions/location_bar_controller.h"
15 #include "chrome/browser/extensions/tab_helper.h"
16 #include "chrome/browser/platform_util.h" 9 #include "chrome/browser/platform_util.h"
17 #include "chrome/browser/profiles/profile.h" 10 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/sessions/session_id.h" 11 #include "chrome/browser/ui/browser.h"
19 #include "chrome/browser/ui/browser_list.h"
20 #include "chrome/browser/ui/extensions/accelerator_priority.h"
21 #include "chrome/browser/ui/views/frame/browser_view.h"
22 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" 12 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
23 #include "chrome/browser/ui/webui/extensions/extension_info_ui.h"
24 #include "extensions/browser/extension_registry.h" 13 #include "extensions/browser/extension_registry.h"
25 #include "extensions/common/extension.h"
26 #include "ui/accessibility/ax_view_state.h" 14 #include "ui/accessibility/ax_view_state.h"
27 #include "ui/events/event.h" 15 #include "ui/events/event.h"
28 #include "ui/gfx/canvas.h" 16 #include "ui/gfx/canvas.h"
29 #include "ui/gfx/image/image.h" 17 #include "ui/gfx/image/image.h"
30 #include "ui/views/controls/menu/menu_runner.h"
31
32 using content::WebContents;
33 using extensions::LocationBarController;
34 using extensions::Extension;
35 18
36 PageActionImageView::PageActionImageView(LocationBarView* owner, 19 PageActionImageView::PageActionImageView(LocationBarView* owner,
37 ExtensionAction* page_action, 20 ExtensionAction* page_action,
38 Browser* browser) 21 Browser* browser)
39 : owner_(owner), 22 : extension_action_view_(new ExtensionActionView(
40 page_action_(page_action), 23 extensions::ExtensionRegistry::Get(browser->profile())->
41 browser_(browser), 24 enabled_extensions().GetByID(page_action->extension_id()),
42 current_tab_id_(-1), 25 browser,
43 preview_enabled_(false), 26 page_action,
44 popup_(NULL) { 27 this)),
45 const Extension* extension = extensions::ExtensionRegistry::Get( 28 owner_(owner),
46 owner_->profile())->enabled_extensions().GetByID( 29 preview_enabled_(false) {
47 page_action->extension_id());
48 DCHECK(extension);
49
50 icon_factory_.reset(
51 new ExtensionActionIconFactory(
52 owner_->profile(), extension, page_action, this));
53
54 SetAccessibilityFocusable(true); 30 SetAccessibilityFocusable(true);
55 set_context_menu_controller(this); 31 extension_action_view_->RegisterCommand();
sky 2014/08/05 22:29:47 At the time this is invoked does GetFocusManagerFo
Devlin 2014/08/05 23:51:10 This shouldn't be any different than the existing
sky 2014/08/06 00:28:25 No need to delay if everything is good. How about
Devlin 2014/08/06 16:19:02 Done, via DCHECK(GetFocusManagerForAccelerator()).
56 32 set_context_menu_controller(extension_action_view_.get());
57 extensions::CommandService* command_service =
58 extensions::CommandService::Get(browser_->profile());
59 extensions::Command page_action_command;
60 if (command_service->GetPageActionCommand(
61 extension->id(),
62 extensions::CommandService::ACTIVE_ONLY,
63 &page_action_command,
64 NULL)) {
65 page_action_keybinding_.reset(
66 new ui::Accelerator(page_action_command.accelerator()));
67 owner_->GetFocusManager()->RegisterAccelerator(
68 *page_action_keybinding_.get(),
69 GetAcceleratorPriority(page_action_command.accelerator(), extension),
70 this);
71 }
72 } 33 }
73 34
74 PageActionImageView::~PageActionImageView() { 35 PageActionImageView::~PageActionImageView() {
75 if (owner_->GetFocusManager()) {
76 if (page_action_keybinding_.get()) {
77 owner_->GetFocusManager()->UnregisterAccelerator(
78 *page_action_keybinding_.get(), this);
79 }
80 }
81
82 if (popup_)
83 popup_->GetWidget()->RemoveObserver(this);
84 HidePopup();
85 }
86
87 void PageActionImageView::ExecuteAction(
88 ExtensionPopup::ShowAction show_action) {
89 WebContents* web_contents = owner_->GetWebContents();
90 if (!web_contents)
91 return;
92
93 extensions::TabHelper* extensions_tab_helper =
94 extensions::TabHelper::FromWebContents(web_contents);
95 LocationBarController* controller =
96 extensions_tab_helper->location_bar_controller();
97
98 switch (controller->OnClicked(page_action_)) {
99 case LocationBarController::ACTION_NONE:
100 break;
101
102 case LocationBarController::ACTION_SHOW_POPUP:
103 ShowPopupWithURL(page_action_->GetPopupUrl(current_tab_id_), show_action);
104 break;
105
106 case LocationBarController::ACTION_SHOW_CONTEXT_MENU:
107 // We are never passing OnClicked a right-click button, so assume that
108 // we're never going to be asked to show a context menu.
109 // TODO(kalman): if this changes, update this class to pass the real
110 // mouse button through to the LocationBarController.
111 NOTREACHED();
112 break;
113 }
114 } 36 }
115 37
116 void PageActionImageView::GetAccessibleState(ui::AXViewState* state) { 38 void PageActionImageView::GetAccessibleState(ui::AXViewState* state) {
117 state->role = ui::AX_ROLE_BUTTON; 39 state->role = ui::AX_ROLE_BUTTON;
118 state->name = base::UTF8ToUTF16(tooltip_); 40 state->name = base::UTF8ToUTF16(tooltip_);
119 } 41 }
120 42
121 bool PageActionImageView::OnMousePressed(const ui::MouseEvent& event) { 43 bool PageActionImageView::OnMousePressed(const ui::MouseEvent& event) {
122 // We want to show the bubble on mouse release; that is the standard behavior 44 // We want to show the bubble on mouse release; that is the standard behavior
123 // for buttons. (Also, triggering on mouse press causes bugs like 45 // for buttons. (Also, triggering on mouse press causes bugs like
124 // http://crbug.com/33155.) 46 // http://crbug.com/33155.)
125 return true; 47 return true;
126 } 48 }
127 49
128 void PageActionImageView::OnMouseReleased(const ui::MouseEvent& event) { 50 void PageActionImageView::OnMouseReleased(const ui::MouseEvent& event) {
129 if (!HitTestPoint(event.location())) 51 if (!HitTestPoint(event.location()))
130 return; 52 return;
131 53
132 if (event.IsRightMouseButton()) { 54 if (event.IsRightMouseButton()) {
133 // Don't show a menu here, its handled in View::ProcessMouseReleased. We 55 // Don't show a menu here, its handled in View::ProcessMouseReleased. We
134 // show the context menu by way of being the ContextMenuController. 56 // show the context menu by way of being the ContextMenuController.
135 return; 57 return;
136 } 58 }
137 59
138 ExecuteAction(ExtensionPopup::SHOW); 60 extension_action_view_->ExecuteActionByUser();
139 } 61 }
140 62
141 bool PageActionImageView::OnKeyPressed(const ui::KeyEvent& event) { 63 bool PageActionImageView::OnKeyPressed(const ui::KeyEvent& event) {
142 if (event.key_code() == ui::VKEY_SPACE || 64 if (event.key_code() == ui::VKEY_SPACE ||
143 event.key_code() == ui::VKEY_RETURN) { 65 event.key_code() == ui::VKEY_RETURN) {
144 ExecuteAction(ExtensionPopup::SHOW); 66 extension_action_view_->ExecuteActionByUser();
145 return true; 67 return true;
146 } 68 }
147 return false; 69 return false;
148 } 70 }
149 71
150 void PageActionImageView::ShowContextMenuForView(
151 View* source,
152 const gfx::Point& point,
153 ui::MenuSourceType source_type) {
154 const Extension* extension = extensions::ExtensionRegistry::Get(
155 owner_->profile())->enabled_extensions().GetByID(
156 page_action()->extension_id());
157 if (!extension->ShowConfigureContextMenus())
158 return;
159
160 scoped_refptr<ExtensionContextMenuModel> context_menu_model(
161 new ExtensionContextMenuModel(extension, browser_, this));
162 menu_runner_.reset(new views::MenuRunner(
163 context_menu_model.get(),
164 views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU));
165 gfx::Point screen_loc;
166 views::View::ConvertPointToScreen(this, &screen_loc);
167 if (menu_runner_->RunMenuAt(GetWidget(),
168 NULL,
169 gfx::Rect(screen_loc, size()),
170 views::MENU_ANCHOR_TOPLEFT,
171 source_type) == views::MenuRunner::MENU_DELETED) {
172 return;
173 }
174 }
175
176 bool PageActionImageView::AcceleratorPressed( 72 bool PageActionImageView::AcceleratorPressed(
177 const ui::Accelerator& accelerator) { 73 const ui::Accelerator& accelerator) {
178 DCHECK(visible()); // Should not have happened due to CanHandleAccelerator. 74 DCHECK(visible()); // Should not have happened due to CanHandleAccelerator.
179 75 return extension_action_view_->AcceleratorPressed(accelerator);
180 const std::string extension_id = page_action()->extension_id();
181 const ui::AcceleratorManager::HandlerPriority priority =
182 GetAcceleratorPriorityById(accelerator, extension_id, owner_->profile());
183 // Normal priority shortcuts must be handled via standard browser commands
184 // to be processed at the proper time.
185 if (priority == ui::AcceleratorManager::kHighPriority)
186 ExecuteAction(ExtensionPopup::SHOW);
187 return priority == ui::AcceleratorManager::kHighPriority;
188 } 76 }
189 77
190 bool PageActionImageView::CanHandleAccelerators() const { 78 bool PageActionImageView::CanHandleAccelerators() const {
191 // While visible, we don't handle accelerators and while so we also don't 79 // While visible, we don't handle accelerators and while so we also don't
192 // count as a priority accelerator handler. 80 // count as a priority accelerator handler.
193 return visible(); 81 return visible();
194 } 82 }
195 83
196 void PageActionImageView::UpdateVisibility(WebContents* contents, 84 void PageActionImageView::UpdateVisibility(content::WebContents* contents) {
197 const GURL& url) { 85 int tab_id = extension_action_view_->GetCurrentTabId();
198 // Save this off so we can pass it back to the extension when the action gets
199 // executed. See PageActionImageView::OnMousePressed.
200 current_tab_id_ =
201 contents ? extensions::ExtensionTabUtil::GetTabId(contents) : -1;
202 current_url_ = url;
203 86
204 if (!contents || 87 if (!contents ||
205 (!preview_enabled_ && !page_action_->GetIsVisible(current_tab_id_))) { 88 tab_id == -1 ||
89 (!preview_enabled_ && !extension_action()->GetIsVisible(tab_id))) {
206 SetVisible(false); 90 SetVisible(false);
207 return; 91 return;
208 } 92 }
209 93
210 // Set the tooltip. 94 // Set the tooltip.
211 tooltip_ = page_action_->GetTitle(current_tab_id_); 95 tooltip_ = extension_action()->GetTitle(tab_id);
212 SetTooltipText(base::UTF8ToUTF16(tooltip_)); 96 SetTooltipText(base::UTF8ToUTF16(tooltip_));
213 97
214 // Set the image. 98 // Set the image.
215 gfx::Image icon = icon_factory_->GetIcon(current_tab_id_); 99 gfx::Image icon = extension_action_view_->GetIcon(tab_id);
216 if (!icon.IsEmpty()) 100 if (!icon.IsEmpty())
217 SetImage(*icon.ToImageSkia()); 101 SetImage(*icon.ToImageSkia());
218 102
219 SetVisible(true); 103 SetVisible(true);
220 } 104 }
221 105
222 void PageActionImageView::InspectPopup() { 106 void PageActionImageView::PaintChildren(gfx::Canvas* canvas,
223 ExecuteAction(ExtensionPopup::SHOW_AND_INSPECT); 107 const views::CullSet& cull_set) {
224 } 108 View::PaintChildren(canvas, cull_set);
225 109 int tab_id = extension_action_view_->GetCurrentTabId();
226 void PageActionImageView::OnWidgetDestroying(views::Widget* widget) { 110 if (tab_id >= 0) {
227 DCHECK_EQ(popup_->GetWidget(), widget); 111 extension_action_view_->extension_action()->PaintBadge(
228 popup_->GetWidget()->RemoveObserver(this); 112 canvas, GetLocalBounds(), tab_id);
229 popup_ = NULL; 113 }
230 } 114 }
231 115
232 void PageActionImageView::OnIconUpdated() { 116 void PageActionImageView::OnIconUpdated() {
233 WebContents* web_contents = owner_->GetWebContents(); 117 UpdateVisibility(GetCurrentWebContents());
234 if (web_contents)
235 UpdateVisibility(web_contents, current_url_);
236 } 118 }
237 119
238 void PageActionImageView::PaintChildren(gfx::Canvas* canvas, 120 views::View* PageActionImageView::GetAsView() {
239 const views::CullSet& cull_set) { 121 return this;
240 View::PaintChildren(canvas, cull_set);
241 if (current_tab_id_ >= 0)
242 page_action_->PaintBadge(canvas, GetLocalBounds(), current_tab_id_);
243 } 122 }
244 123
245 void PageActionImageView::ShowPopupWithURL( 124 bool PageActionImageView::IsNestedView() {
246 const GURL& popup_url, 125 return false;
247 ExtensionPopup::ShowAction show_action) {
248 bool popup_showing = popup_ != NULL;
249
250 // Always hide the current popup. Only one popup at a time.
251 HidePopup();
252
253 // If we were already showing, then treat this click as a dismiss.
254 if (popup_showing)
255 return;
256
257 views::BubbleBorder::Arrow arrow = base::i18n::IsRTL() ?
258 views::BubbleBorder::TOP_LEFT : views::BubbleBorder::TOP_RIGHT;
259
260 popup_ = ExtensionPopup::ShowPopup(popup_url, browser_, this, arrow,
261 show_action);
262 popup_->GetWidget()->AddObserver(this);
263 } 126 }
264 127
265 void PageActionImageView::HidePopup() { 128 views::FocusManager* PageActionImageView::GetFocusManagerForAccelerator() {
266 if (popup_) 129 return owner_->GetFocusManager();
267 popup_->GetWidget()->Close();
268 } 130 }
131
132 views::Widget* PageActionImageView::GetParentForContextMenu() {
133 return GetWidget();
134 }
135
136 views::View* PageActionImageView::GetReferenceViewForPopup() {
137 return this;
138 }
139
140 content::WebContents* PageActionImageView::GetCurrentWebContents() {
141 return owner_->GetWebContents();
142 }
143
144 void PageActionImageView::HideActivePopup() {
145 // The only popup that will be active is this popup.
146 extension_action_view_->HidePopup();
147 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698