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_EXTENSION_CONTEXT_MENU_MODEL_H_ 6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_CONTEXT_MENU_MODEL_H_ 7 8 #include <memory> 9 #include <string> 10 11 #include "base/macros.h" 12 #include "base/optional.h" 13 #include "ui/base/models/simple_menu_model.h" 14 15 class Browser; 16 class GURL; 17 class Profile; 18 19 namespace content { 20 class WebContents; 21 } 22 23 namespace extensions { 24 class ContextMenuMatcher; 25 class Extension; 26 class ExtensionAction; 27 28 // The context menu model for extension icons. 29 class ExtensionContextMenuModel : public ui::SimpleMenuModel, 30 public ui::SimpleMenuModel::Delegate { 31 public: 32 enum MenuEntries { 33 HOME_PAGE = 0, 34 OPTIONS, 35 TOGGLE_VISIBILITY, 36 UNINSTALL, 37 MANAGE_EXTENSIONS, 38 INSPECT_POPUP, 39 PAGE_ACCESS_CANT_ACCESS, 40 PAGE_ACCESS_SUBMENU, 41 PAGE_ACCESS_RUN_ON_CLICK, 42 PAGE_ACCESS_RUN_ON_SITE, 43 PAGE_ACCESS_RUN_ON_ALL_SITES, 44 PAGE_ACCESS_LEARN_MORE, 45 // NOTE: If you update this, you probably need to update the 46 // ContextMenuAction enum below. 47 }; 48 49 // A separate enum to indicate the action taken on the menu. We have two 50 // enums (this and MenuEntries above) to avoid needing to have a single one 51 // with both action-specific values (like kNoAction) and menu-specific values 52 // (like PAGE_ACCESS_SUBMENU). 53 // These values are persisted to logs. Entries should not be renumbered and 54 // numeric values should never be reused. New values should be added before 55 // kMaxValue. 56 enum class ContextMenuAction { 57 kNoAction = 0, 58 kCustomCommand = 1, 59 kHomePage = 2, 60 kOptions = 3, 61 kToggleVisibility = 4, 62 kUninstall = 5, 63 kManageExtensions = 6, 64 kInspectPopup = 7, 65 kPageAccessRunOnClick = 8, 66 kPageAccessRunOnSite = 9, 67 kPageAccessRunOnAllSites = 10, 68 kPageAccessLearnMore = 11, 69 kMaxValue = kPageAccessLearnMore, 70 }; 71 72 // The current visibility of the extension; this affects the "pin" / "unpin" 73 // strings in the menu. 74 // TODO(devlin): Rename this "PinState" when we finish removing the old UI 75 // bits. 76 enum ButtonVisibility { 77 // The extension is pinned on the toolbar. 78 PINNED, 79 // The extension is temporarily visible on the toolbar, as for showing a 80 // popup. 81 TRANSITIVELY_VISIBLE, 82 // The extension is not pinned (and is shown in the extensions menu). 83 UNPINNED, 84 }; 85 86 // Delegate to handle showing an ExtensionAction popup. 87 class PopupDelegate { 88 public: 89 // Called when the user selects the menu item which requests that the 90 // popup be shown and inspected. 91 // The delegate should know which popup to display. 92 virtual void InspectPopup() = 0; 93 94 protected: ~PopupDelegate()95 virtual ~PopupDelegate() {} 96 }; 97 98 // Creates a menu model for the given extension. If 99 // prefs::kExtensionsUIDeveloperMode is enabled then a menu item 100 // will be shown for "Inspect Popup" which, when selected, will cause 101 // ShowPopupForDevToolsWindow() to be called on |delegate|. 102 ExtensionContextMenuModel(const Extension* extension, 103 Browser* browser, 104 ButtonVisibility visibility, 105 PopupDelegate* delegate, 106 bool can_show_icon_in_toolbar); 107 ~ExtensionContextMenuModel() override; 108 109 // SimpleMenuModel::Delegate: 110 bool IsCommandIdChecked(int command_id) const override; 111 bool IsCommandIdVisible(int command_id) const override; 112 bool IsCommandIdEnabled(int command_id) const override; 113 void ExecuteCommand(int command_id, int event_flags) override; 114 void OnMenuWillShow(ui::SimpleMenuModel* source) override; 115 void MenuClosed(ui::SimpleMenuModel* source) override; 116 page_access_submenu_for_testing()117 ui::SimpleMenuModel* page_access_submenu_for_testing() { 118 return page_access_submenu_.get(); 119 } 120 121 private: 122 void InitMenu(const Extension* extension, ButtonVisibility button_visibility); 123 124 void CreatePageAccessSubmenu(const Extension* extension); 125 126 MenuEntries GetCurrentPageAccess(const Extension* extension, 127 content::WebContents* web_contents) const; 128 129 // Returns true if the given page access command is enabled in the menu. 130 bool IsPageAccessCommandEnabled(const Extension& extension, 131 const GURL& url, 132 int command_id) const; 133 134 void HandlePageAccessCommand(int command_id, 135 const Extension* extension) const; 136 137 // Logs a user action when an option is selected in the page access section of 138 // the context menu. 139 void LogPageAccessAction(int command_id) const; 140 141 // Gets the extension we are displaying the menu for. Returns NULL if the 142 // extension has been uninstalled and no longer exists. 143 const Extension* GetExtension() const; 144 145 // Returns the active web contents. 146 content::WebContents* GetActiveWebContents() const; 147 148 // Appends the extension's context menu items. 149 void AppendExtensionItems(); 150 151 // A copy of the extension's id. 152 std::string extension_id_; 153 154 // Whether the menu is for a component extension. 155 bool is_component_; 156 157 // The extension action of the extension we are displaying the menu for (if 158 // it has one, otherwise NULL). 159 ExtensionAction* extension_action_; 160 161 Browser* const browser_; 162 163 Profile* profile_; 164 165 // The delegate which handles the 'inspect popup' menu command (or NULL). 166 PopupDelegate* delegate_; 167 168 // The visibility of the button at the time the menu opened. 169 ButtonVisibility button_visibility_; 170 171 const bool can_show_icon_in_toolbar_; 172 173 // Menu matcher for context menu items specified by the extension. 174 std::unique_ptr<ContextMenuMatcher> extension_items_; 175 176 std::unique_ptr<ui::SimpleMenuModel> page_access_submenu_; 177 178 // The action taken by the menu. Has a valid value when the menu is being 179 // shown. 180 base::Optional<ContextMenuAction> action_taken_; 181 182 DISALLOW_COPY_AND_ASSIGN(ExtensionContextMenuModel); 183 }; 184 185 } // namespace extensions 186 187 #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_CONTEXT_MENU_MODEL_H_ 188