OLD | NEW |
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" | |
10 #include "chrome/browser/extensions/extension_util.h" | 9 #include "chrome/browser/extensions/extension_util.h" |
| 10 #include "chrome/common/extensions/api/context_menus.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_registry.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 int GetActionMenuTopLevelLimit() { | |
26 #if defined(ENABLE_EXTENSIONS) | |
27 return api::context_menus::ACTION_MENU_TOP_LEVEL_LIMIT; | |
28 #else | |
29 return 0; | |
30 #endif | |
31 } | |
32 | |
33 // The range of command IDs reserved for extension's custom menus. | 21 // The range of command IDs reserved for extension's custom menus. |
34 // TODO(oshima): These values will be injected by embedders. | 22 // TODO(oshima): These values will be injected by embedders. |
35 int extensions_context_custom_first = IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST; | 23 int extensions_context_custom_first = IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST; |
36 int extensions_context_custom_last = IDC_EXTENSIONS_CONTEXT_CUSTOM_LAST; | 24 int extensions_context_custom_last = IDC_EXTENSIONS_CONTEXT_CUSTOM_LAST; |
37 | 25 |
38 } // namespace | 26 } // namespace |
39 | 27 |
40 // static | 28 // static |
41 const size_t ContextMenuMatcher::kMaxExtensionItemTitleLength = 75; | 29 const size_t ContextMenuMatcher::kMaxExtensionItemTitleLength = 75; |
42 | 30 |
(...skipping 27 matching lines...) Expand all Loading... |
70 DCHECK_GE(*index, 0); | 58 DCHECK_GE(*index, 0); |
71 int max_index = | 59 int max_index = |
72 extensions_context_custom_last - extensions_context_custom_first; | 60 extensions_context_custom_last - extensions_context_custom_first; |
73 if (*index >= max_index) | 61 if (*index >= max_index) |
74 return; | 62 return; |
75 | 63 |
76 const Extension* extension = NULL; | 64 const Extension* extension = NULL; |
77 MenuItem::List items; | 65 MenuItem::List items; |
78 bool can_cross_incognito; | 66 bool can_cross_incognito; |
79 if (!GetRelevantExtensionTopLevelItems( | 67 if (!GetRelevantExtensionTopLevelItems( |
80 extension_key, &extension, &can_cross_incognito, items)) | 68 extension_key, &extension, &can_cross_incognito, &items)) |
81 return; | 69 return; |
82 | 70 |
83 if (items.empty()) | 71 if (items.empty()) |
84 return; | 72 return; |
85 | 73 |
86 // If this is the first extension-provided menu item, and there are other | 74 // If this is the first extension-provided menu item, and there are other |
87 // items in the menu, and the last item is not a separator add a separator. | 75 // items in the menu, and the last item is not a separator add a separator. |
88 if (*index == 0 && menu_model_->GetItemCount()) | 76 if (*index == 0 && menu_model_->GetItemCount()) |
89 menu_model_->AddSeparator(ui::NORMAL_SEPARATOR); | 77 menu_model_->AddSeparator(ui::NORMAL_SEPARATOR); |
90 | 78 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 extension_menu_models_.clear(); | 132 extension_menu_models_.clear(); |
145 } | 133 } |
146 | 134 |
147 base::string16 ContextMenuMatcher::GetTopLevelContextMenuTitle( | 135 base::string16 ContextMenuMatcher::GetTopLevelContextMenuTitle( |
148 const MenuItem::ExtensionKey& extension_key, | 136 const MenuItem::ExtensionKey& extension_key, |
149 const base::string16& selection_text) { | 137 const base::string16& selection_text) { |
150 const Extension* extension = NULL; | 138 const Extension* extension = NULL; |
151 MenuItem::List items; | 139 MenuItem::List items; |
152 bool can_cross_incognito; | 140 bool can_cross_incognito; |
153 GetRelevantExtensionTopLevelItems( | 141 GetRelevantExtensionTopLevelItems( |
154 extension_key, &extension, &can_cross_incognito, items); | 142 extension_key, &extension, &can_cross_incognito, &items); |
155 | 143 |
156 base::string16 title; | 144 base::string16 title; |
157 | 145 |
158 if (items.empty() || | 146 if (items.empty() || |
159 items.size() > 1 || | 147 items.size() > 1 || |
160 items[0]->type() != MenuItem::NORMAL) { | 148 items[0]->type() != MenuItem::NORMAL) { |
161 title = base::UTF8ToUTF16(extension->name()); | 149 title = base::UTF8ToUTF16(extension->name()); |
162 } else { | 150 } else { |
163 MenuItem* item = items[0]; | 151 MenuItem* item = items[0]; |
164 title = item->TitleWithReplacement( | 152 title = item->TitleWithReplacement( |
(...skipping 24 matching lines...) Expand all Loading... |
189 return; | 177 return; |
190 | 178 |
191 MenuManager* manager = MenuManager::Get(browser_context_); | 179 MenuManager* manager = MenuManager::Get(browser_context_); |
192 manager->ExecuteCommand(browser_context_, web_contents, params, item->id()); | 180 manager->ExecuteCommand(browser_context_, web_contents, params, item->id()); |
193 } | 181 } |
194 | 182 |
195 bool ContextMenuMatcher::GetRelevantExtensionTopLevelItems( | 183 bool ContextMenuMatcher::GetRelevantExtensionTopLevelItems( |
196 const MenuItem::ExtensionKey& extension_key, | 184 const MenuItem::ExtensionKey& extension_key, |
197 const Extension** extension, | 185 const Extension** extension, |
198 bool* can_cross_incognito, | 186 bool* can_cross_incognito, |
199 MenuItem::List& items) { | 187 MenuItem::List* items) { |
200 ExtensionService* service = | 188 *extension = ExtensionRegistry::Get( |
201 extensions::ExtensionSystem::Get(browser_context_)->extension_service(); | 189 browser_context_)->enabled_extensions().GetByID( |
202 *extension = service->GetExtensionById(extension_key.extension_id, false); | 190 extension_key.extension_id); |
203 | |
204 if (!*extension) | 191 if (!*extension) |
205 return false; | 192 return false; |
206 | 193 |
207 // Find matching items. | 194 // Find matching items. |
208 MenuManager* manager = MenuManager::Get(browser_context_); | 195 MenuManager* manager = MenuManager::Get(browser_context_); |
209 const MenuItem::List* all_items = manager->MenuItems(extension_key); | 196 const MenuItem::List* all_items = manager->MenuItems(extension_key); |
210 if (!all_items || all_items->empty()) | 197 if (!all_items || all_items->empty()) |
211 return false; | 198 return false; |
212 | 199 |
213 *can_cross_incognito = util::CanCrossIncognito(*extension, browser_context_); | 200 *can_cross_incognito = util::CanCrossIncognito(*extension, browser_context_); |
214 items = GetRelevantExtensionItems(*all_items, | 201 *items = GetRelevantExtensionItems(*all_items, *can_cross_incognito); |
215 *can_cross_incognito); | |
216 | 202 |
217 return true; | 203 return true; |
218 } | 204 } |
219 | 205 |
220 MenuItem::List ContextMenuMatcher::GetRelevantExtensionItems( | 206 MenuItem::List ContextMenuMatcher::GetRelevantExtensionItems( |
221 const MenuItem::List& items, | 207 const MenuItem::List& items, |
222 bool can_cross_incognito) { | 208 bool can_cross_incognito) { |
223 MenuItem::List result; | 209 MenuItem::List result; |
224 for (MenuItem::List::const_iterator i = items.begin(); | 210 for (MenuItem::List::const_iterator i = items.begin(); |
225 i != items.end(); ++i) { | 211 i != items.end(); ++i) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 menu_model->AddSeparator(ui::NORMAL_SEPARATOR); | 243 menu_model->AddSeparator(ui::NORMAL_SEPARATOR); |
258 last_type = MenuItem::SEPARATOR; | 244 last_type = MenuItem::SEPARATOR; |
259 } | 245 } |
260 | 246 |
261 int menu_id = ConvertToExtensionsCustomCommandId(*index); | 247 int menu_id = ConvertToExtensionsCustomCommandId(*index); |
262 ++(*index); | 248 ++(*index); |
263 ++num_items; | 249 ++num_items; |
264 // Action context menus have a limit for top level extension items to | 250 // Action context menus have a limit for top level extension items to |
265 // prevent control items from being pushed off the screen, since extension | 251 // prevent control items from being pushed off the screen, since extension |
266 // items will not be placed in a submenu. | 252 // items will not be placed in a submenu. |
| 253 const int top_level_limit = api::context_menus::ACTION_MENU_TOP_LEVEL_LIMIT; |
267 if (menu_id >= extensions_context_custom_last || | 254 if (menu_id >= extensions_context_custom_last || |
268 (is_action_menu_top_level && num_items >= GetActionMenuTopLevelLimit())) | 255 (is_action_menu_top_level && num_items >= top_level_limit)) |
269 return; | 256 return; |
270 | 257 |
271 extension_item_map_[menu_id] = item->id(); | 258 extension_item_map_[menu_id] = item->id(); |
272 base::string16 title = item->TitleWithReplacement(selection_text, | 259 base::string16 title = item->TitleWithReplacement(selection_text, |
273 kMaxExtensionItemTitleLength); | 260 kMaxExtensionItemTitleLength); |
274 if (item->type() == MenuItem::NORMAL) { | 261 if (item->type() == MenuItem::NORMAL) { |
275 MenuItem::List children = | 262 MenuItem::List children = |
276 GetRelevantExtensionItems(item->children(), can_cross_incognito); | 263 GetRelevantExtensionItems(item->children(), can_cross_incognito); |
277 if (children.empty()) { | 264 if (children.empty()) { |
278 menu_model->AddItem(menu_id, title); | 265 menu_model->AddItem(menu_id, title); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 DCHECK_GE(index, 0); | 312 DCHECK_GE(index, 0); |
326 | 313 |
327 const SkBitmap& icon = menu_manager->GetIconForExtension(extension_id); | 314 const SkBitmap& icon = menu_manager->GetIconForExtension(extension_id); |
328 DCHECK(icon.width() == gfx::kFaviconSize); | 315 DCHECK(icon.width() == gfx::kFaviconSize); |
329 DCHECK(icon.height() == gfx::kFaviconSize); | 316 DCHECK(icon.height() == gfx::kFaviconSize); |
330 | 317 |
331 menu_model_->SetIcon(index, gfx::Image::CreateFrom1xBitmap(icon)); | 318 menu_model_->SetIcon(index, gfx::Image::CreateFrom1xBitmap(icon)); |
332 } | 319 } |
333 | 320 |
334 } // namespace extensions | 321 } // namespace extensions |
OLD | NEW |