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

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

Issue 459493002: Revert of Extend contextMenus API to support browser/page actions (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/extensions/context_menu_matcher.h" 5 #include "chrome/browser/extensions/context_menu_matcher.h"
6 6
7 #include "base/strings/utf_string_conversions.h" 7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/app/chrome_command_ids.h" 8 #include "chrome/app/chrome_command_ids.h"
9 #include "chrome/browser/extensions/extension_service.h" 9 #include "chrome/browser/extensions/extension_service.h"
10 #include "chrome/browser/extensions/extension_util.h" 10 #include "chrome/browser/extensions/extension_util.h"
11 #include "content/public/browser/browser_context.h" 11 #include "content/public/browser/browser_context.h"
12 #include "content/public/common/context_menu_params.h" 12 #include "content/public/common/context_menu_params.h"
13 #include "extensions/browser/extension_system.h" 13 #include "extensions/browser/extension_system.h"
14 #include "ui/gfx/favicon_size.h" 14 #include "ui/gfx/favicon_size.h"
15 #include "ui/gfx/image/image.h" 15 #include "ui/gfx/image/image.h"
16 16
17 #if defined(ENABLE_EXTENSIONS)
18 #include "chrome/common/extensions/api/context_menus.h"
19 #endif
20
21 namespace extensions { 17 namespace extensions {
22 18
23 namespace { 19 namespace {
24 20
25 #if defined(ENABLE_EXTENSIONS)
26 int action_menu_top_level_limit =
27 api::context_menus::ACTION_MENU_TOP_LEVEL_LIMIT;
28 #else
29 int action_menu_top_level_limit = 0;
30 #endif
31
32 // The range of command IDs reserved for extension's custom menus. 21 // The range of command IDs reserved for extension's custom menus.
33 // TODO(oshima): These values will be injected by embedders. 22 // TODO(oshima): These values will be injected by embedders.
34 int extensions_context_custom_first = IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST; 23 int extensions_context_custom_first = IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST;
35 int extensions_context_custom_last = IDC_EXTENSIONS_CONTEXT_CUSTOM_LAST; 24 int extensions_context_custom_last = IDC_EXTENSIONS_CONTEXT_CUSTOM_LAST;
36 25
37 } // namespace 26 } // namespace
38 27
39 // static 28 // static
40 const size_t ContextMenuMatcher::kMaxExtensionItemTitleLength = 75; 29 const size_t ContextMenuMatcher::kMaxExtensionItemTitleLength = 75;
41 30
(...skipping 15 matching lines...) Expand all
57 const base::Callback<bool(const MenuItem*)>& filter) 46 const base::Callback<bool(const MenuItem*)>& filter)
58 : browser_context_(browser_context), 47 : browser_context_(browser_context),
59 menu_model_(menu_model), 48 menu_model_(menu_model),
60 delegate_(delegate), 49 delegate_(delegate),
61 filter_(filter) { 50 filter_(filter) {
62 } 51 }
63 52
64 void ContextMenuMatcher::AppendExtensionItems( 53 void ContextMenuMatcher::AppendExtensionItems(
65 const MenuItem::ExtensionKey& extension_key, 54 const MenuItem::ExtensionKey& extension_key,
66 const base::string16& selection_text, 55 const base::string16& selection_text,
67 int* index, 56 int* index) {
68 bool is_action_menu) {
69 DCHECK_GE(*index, 0); 57 DCHECK_GE(*index, 0);
70 int max_index = 58 int max_index =
71 extensions_context_custom_last - extensions_context_custom_first; 59 extensions_context_custom_last - extensions_context_custom_first;
72 if (*index >= max_index) 60 if (*index >= max_index)
73 return; 61 return;
74 62
75 const Extension* extension = NULL; 63 const Extension* extension = NULL;
76 MenuItem::List items; 64 MenuItem::List items;
77 bool can_cross_incognito; 65 bool can_cross_incognito;
78 if (!GetRelevantExtensionTopLevelItems( 66 if (!GetRelevantExtensionTopLevelItems(
79 extension_key, &extension, &can_cross_incognito, items)) 67 extension_key, &extension, &can_cross_incognito, items))
80 return; 68 return;
81 69
82 if (items.empty()) 70 if (items.empty())
83 return; 71 return;
84 72
85 // If this is the first extension-provided menu item, and there are other 73 // If this is the first extension-provided menu item, and there are other
86 // items in the menu, and the last item is not a separator add a separator. 74 // items in the menu, and the last item is not a separator add a separator.
87 if (*index == 0 && menu_model_->GetItemCount()) 75 if (*index == 0 && menu_model_->GetItemCount())
88 menu_model_->AddSeparator(ui::NORMAL_SEPARATOR); 76 menu_model_->AddSeparator(ui::NORMAL_SEPARATOR);
89 77
90 // Extensions (other than platform apps) are only allowed one top-level slot 78 // Extensions (other than platform apps) are only allowed one top-level slot
91 // (and it can't be a radio or checkbox item because we are going to put the 79 // (and it can't be a radio or checkbox item because we are going to put the
92 // extension icon next to it), unless the context menu is an an action menu. 80 // extension icon next to it).
93 // Action menus do not include the extension action, and they only include 81 // If they have more than that, we automatically push them into a submenu.
94 // items from one extension, so they are not placed within a submenu. 82 if (extension->is_platform_app()) {
95 // Otherwise, we automatically push them into a submenu if there is more than 83 RecursivelyAppendExtensionItems(items, can_cross_incognito, selection_text,
96 // one top-level item. 84 menu_model_, index);
97 if (extension->is_platform_app() || is_action_menu) {
98 RecursivelyAppendExtensionItems(items,
99 can_cross_incognito,
100 selection_text,
101 menu_model_,
102 index,
103 is_action_menu);
104 } else { 85 } else {
105 int menu_id = ConvertToExtensionsCustomCommandId(*index); 86 int menu_id = ConvertToExtensionsCustomCommandId(*index);
106 (*index)++; 87 (*index)++;
107 base::string16 title; 88 base::string16 title;
108 MenuItem::List submenu_items; 89 MenuItem::List submenu_items;
109 90
110 if (items.size() > 1 || items[0]->type() != MenuItem::NORMAL) { 91 if (items.size() > 1 || items[0]->type() != MenuItem::NORMAL) {
111 title = base::UTF8ToUTF16(extension->name()); 92 title = base::UTF8ToUTF16(extension->name());
112 submenu_items = items; 93 submenu_items = items;
113 } else { 94 } else {
114 MenuItem* item = items[0]; 95 MenuItem* item = items[0];
115 extension_item_map_[menu_id] = item->id(); 96 extension_item_map_[menu_id] = item->id();
116 title = item->TitleWithReplacement(selection_text, 97 title = item->TitleWithReplacement(selection_text,
117 kMaxExtensionItemTitleLength); 98 kMaxExtensionItemTitleLength);
118 submenu_items = GetRelevantExtensionItems(item->children(), 99 submenu_items = GetRelevantExtensionItems(item->children(),
119 can_cross_incognito); 100 can_cross_incognito);
120 } 101 }
121 102
122 // Now add our item(s) to the menu_model_. 103 // Now add our item(s) to the menu_model_.
123 if (submenu_items.empty()) { 104 if (submenu_items.empty()) {
124 menu_model_->AddItem(menu_id, title); 105 menu_model_->AddItem(menu_id, title);
125 } else { 106 } else {
126 ui::SimpleMenuModel* submenu = new ui::SimpleMenuModel(delegate_); 107 ui::SimpleMenuModel* submenu = new ui::SimpleMenuModel(delegate_);
127 extension_menu_models_.push_back(submenu); 108 extension_menu_models_.push_back(submenu);
128 menu_model_->AddSubMenu(menu_id, title, submenu); 109 menu_model_->AddSubMenu(menu_id, title, submenu);
129 RecursivelyAppendExtensionItems(submenu_items, 110 RecursivelyAppendExtensionItems(submenu_items, can_cross_incognito,
130 can_cross_incognito, 111 selection_text, submenu, index);
131 selection_text,
132 submenu,
133 index,
134 false); // is_action_menu_top_level
135 } 112 }
136 if (!is_action_menu) 113 SetExtensionIcon(extension_key.extension_id);
137 SetExtensionIcon(extension_key.extension_id);
138 } 114 }
139 } 115 }
140 116
141 void ContextMenuMatcher::Clear() { 117 void ContextMenuMatcher::Clear() {
142 extension_item_map_.clear(); 118 extension_item_map_.clear();
143 extension_menu_models_.clear(); 119 extension_menu_models_.clear();
144 } 120 }
145 121
146 base::string16 ContextMenuMatcher::GetTopLevelContextMenuTitle( 122 base::string16 ContextMenuMatcher::GetTopLevelContextMenuTitle(
147 const MenuItem::ExtensionKey& extension_key, 123 const MenuItem::ExtensionKey& extension_key,
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 result.push_back(*i); 208 result.push_back(*i);
233 } 209 }
234 return result; 210 return result;
235 } 211 }
236 212
237 void ContextMenuMatcher::RecursivelyAppendExtensionItems( 213 void ContextMenuMatcher::RecursivelyAppendExtensionItems(
238 const MenuItem::List& items, 214 const MenuItem::List& items,
239 bool can_cross_incognito, 215 bool can_cross_incognito,
240 const base::string16& selection_text, 216 const base::string16& selection_text,
241 ui::SimpleMenuModel* menu_model, 217 ui::SimpleMenuModel* menu_model,
242 int* index, 218 int* index)
243 bool is_action_menu_top_level) { 219 {
244 MenuItem::Type last_type = MenuItem::NORMAL; 220 MenuItem::Type last_type = MenuItem::NORMAL;
245 int radio_group_id = 1; 221 int radio_group_id = 1;
246 int num_items = 0;
247 222
248 for (MenuItem::List::const_iterator i = items.begin(); 223 for (MenuItem::List::const_iterator i = items.begin();
249 i != items.end(); ++i) { 224 i != items.end(); ++i) {
250 MenuItem* item = *i; 225 MenuItem* item = *i;
251 226
252 // If last item was of type radio but the current one isn't, auto-insert 227 // If last item was of type radio but the current one isn't, auto-insert
253 // a separator. The converse case is handled below. 228 // a separator. The converse case is handled below.
254 if (last_type == MenuItem::RADIO && 229 if (last_type == MenuItem::RADIO &&
255 item->type() != MenuItem::RADIO) { 230 item->type() != MenuItem::RADIO) {
256 menu_model->AddSeparator(ui::NORMAL_SEPARATOR); 231 menu_model->AddSeparator(ui::NORMAL_SEPARATOR);
257 last_type = MenuItem::SEPARATOR; 232 last_type = MenuItem::SEPARATOR;
258 } 233 }
259 234
260 int menu_id = ConvertToExtensionsCustomCommandId(*index); 235 int menu_id = ConvertToExtensionsCustomCommandId(*index);
261 ++(*index); 236 (*index)++;
262 ++num_items; 237 if (menu_id >= extensions_context_custom_last)
263 // Action context menus have a limit for top level extension items to
264 // prevent control items from being pushed off the screen, since extension
265 // items will not be placed in a submenu.
266 if (menu_id >= extensions_context_custom_last ||
267 (is_action_menu_top_level && num_items >= action_menu_top_level_limit))
268 return; 238 return;
269
270 extension_item_map_[menu_id] = item->id(); 239 extension_item_map_[menu_id] = item->id();
271 base::string16 title = item->TitleWithReplacement(selection_text, 240 base::string16 title = item->TitleWithReplacement(selection_text,
272 kMaxExtensionItemTitleLength); 241 kMaxExtensionItemTitleLength);
273 if (item->type() == MenuItem::NORMAL) { 242 if (item->type() == MenuItem::NORMAL) {
274 MenuItem::List children = 243 MenuItem::List children =
275 GetRelevantExtensionItems(item->children(), can_cross_incognito); 244 GetRelevantExtensionItems(item->children(), can_cross_incognito);
276 if (children.empty()) { 245 if (children.empty()) {
277 menu_model->AddItem(menu_id, title); 246 menu_model->AddItem(menu_id, title);
278 } else { 247 } else {
279 ui::SimpleMenuModel* submenu = new ui::SimpleMenuModel(delegate_); 248 ui::SimpleMenuModel* submenu = new ui::SimpleMenuModel(delegate_);
280 extension_menu_models_.push_back(submenu); 249 extension_menu_models_.push_back(submenu);
281 menu_model->AddSubMenu(menu_id, title, submenu); 250 menu_model->AddSubMenu(menu_id, title, submenu);
282 RecursivelyAppendExtensionItems(children, 251 RecursivelyAppendExtensionItems(children, can_cross_incognito,
283 can_cross_incognito, 252 selection_text, submenu, index);
284 selection_text,
285 submenu,
286 index,
287 false); // is_action_menu_top_level
288 } 253 }
289 } else if (item->type() == MenuItem::CHECKBOX) { 254 } else if (item->type() == MenuItem::CHECKBOX) {
290 menu_model->AddCheckItem(menu_id, title); 255 menu_model->AddCheckItem(menu_id, title);
291 } else if (item->type() == MenuItem::RADIO) { 256 } else if (item->type() == MenuItem::RADIO) {
292 if (i != items.begin() && 257 if (i != items.begin() &&
293 last_type != MenuItem::RADIO) { 258 last_type != MenuItem::RADIO) {
294 radio_group_id++; 259 radio_group_id++;
295 260
296 // Auto-append a separator if needed. 261 // Auto-append a separator if needed.
297 menu_model->AddSeparator(ui::NORMAL_SEPARATOR); 262 menu_model->AddSeparator(ui::NORMAL_SEPARATOR);
(...skipping 26 matching lines...) Expand all
324 DCHECK_GE(index, 0); 289 DCHECK_GE(index, 0);
325 290
326 const SkBitmap& icon = menu_manager->GetIconForExtension(extension_id); 291 const SkBitmap& icon = menu_manager->GetIconForExtension(extension_id);
327 DCHECK(icon.width() == gfx::kFaviconSize); 292 DCHECK(icon.width() == gfx::kFaviconSize);
328 DCHECK(icon.height() == gfx::kFaviconSize); 293 DCHECK(icon.height() == gfx::kFaviconSize);
329 294
330 menu_model_->SetIcon(index, gfx::Image::CreateFrom1xBitmap(icon)); 295 menu_model_->SetIcon(index, gfx::Image::CreateFrom1xBitmap(icon));
331 } 296 }
332 297
333 } // namespace extensions 298 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/context_menu_matcher.h ('k') | chrome/browser/extensions/extension_context_menu_model.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698