| 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 |