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 3// found in the LICENSE file. 4 5#ifndef CHROME_BROWSER_EXTENSIONS_CONTEXT_MENU_MATCHER_H_ 6#define CHROME_BROWSER_EXTENSIONS_CONTEXT_MENU_MATCHER_H_ 7 8#include <map> 9 10#include "base/callback.h" 11#include "base/memory/scoped_ptr.h" 12#include "base/memory/scoped_vector.h" 13#include "chrome/browser/extensions/menu_manager.h" 14#include "ui/base/models/simple_menu_model.h" 15 16class ExtensionContextMenuBrowserTest; 17 18namespace content { 19class BrowserContext; 20} 21 22namespace extensions { 23 24// This class contains code that is shared between the various places where 25// context menu items added by the extension or app should be shown. 26class ContextMenuMatcher { 27 public: 28 static const size_t kMaxExtensionItemTitleLength; 29 30 // Convert a command ID so that it fits within the range for 31 // extension context menu. 32 static int ConvertToExtensionsCustomCommandId(int id); 33 34 // Returns true if the given id is one generated for extension context menu. 35 static bool IsExtensionsCustomCommandId(int id); 36 37 // The |filter| will be called on possibly matching menu items, and its 38 // result is used to determine which items to actually append to the menu. 39 ContextMenuMatcher(content::BrowserContext* context, 40 ui::SimpleMenuModel::Delegate* delegate, 41 ui::SimpleMenuModel* menu_model, 42 const base::Callback<bool(const MenuItem*)>& filter); 43 44 // This is a helper function to append items for one particular extension. 45 // The |index| parameter is used for assigning id's, and is incremented for 46 // each item actually added. |is_action_menu| is used for browser and page 47 // action context menus, in which menu items are not placed in submenus 48 // and the extension's icon is not shown. 49 void AppendExtensionItems(const MenuItem::ExtensionKey& extension_key, 50 const base::string16& selection_text, 51 int* index, 52 bool is_action_menu); 53 54 void Clear(); 55 56 // This function returns the top level context menu title of an extension 57 // based on a printable selection text. 58 base::string16 GetTopLevelContextMenuTitle( 59 const MenuItem::ExtensionKey& extension_key, 60 const base::string16& selection_text); 61 62 bool IsCommandIdChecked(int command_id) const; 63 bool IsCommandIdEnabled(int command_id) const; 64 void ExecuteCommand(int command_id, 65 content::WebContents* web_contents, 66 const content::ContextMenuParams& params); 67 68 private: 69 friend class ::ExtensionContextMenuBrowserTest; 70 71 bool GetRelevantExtensionTopLevelItems( 72 const MenuItem::ExtensionKey& extension_key, 73 const Extension** extension, 74 bool* can_cross_incognito, 75 MenuItem::List* items); 76 77 MenuItem::List GetRelevantExtensionItems( 78 const MenuItem::List& items, 79 bool can_cross_incognito); 80 81 // Used for recursively adding submenus of extension items. 82 void RecursivelyAppendExtensionItems(const MenuItem::List& items, 83 bool can_cross_incognito, 84 const base::string16& selection_text, 85 ui::SimpleMenuModel* menu_model, 86 int* index, 87 bool is_action_menu_top_level); 88 89 // Attempts to get an MenuItem given the id of a context menu item. 90 extensions::MenuItem* GetExtensionMenuItem(int id) const; 91 92 // This will set the icon on the most recently-added item in the menu_model_. 93 void SetExtensionIcon(const std::string& extension_id); 94 95 content::BrowserContext* browser_context_; 96 ui::SimpleMenuModel* menu_model_; 97 ui::SimpleMenuModel::Delegate* delegate_; 98 99 base::Callback<bool(const MenuItem*)> filter_; 100 101 // Maps the id from a context menu item to the MenuItem's internal id. 102 std::map<int, extensions::MenuItem::Id> extension_item_map_; 103 104 // Keep track of and clean up menu models for submenus. 105 ScopedVector<ui::SimpleMenuModel> extension_menu_models_; 106 107 DISALLOW_COPY_AND_ASSIGN(ContextMenuMatcher); 108}; 109 110} // namespace extensions 111 112#endif // CHROME_BROWSER_EXTENSIONS_CONTEXT_MENU_MATCHER_H_ 113