blob: 4b38ef1baaa883912b9d5e806e08386ec84118ba [file] [log] [blame]
[email protected]e0a760e2012-04-17 04:49:331// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]7e9f4a82010-03-22 22:36:202// 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
dchengc963c7142016-04-08 03:55:228#include <memory>
[email protected]f681c782010-11-19 11:19:399#include <string>
10
Keishi Hattori0e45c022021-11-27 09:25:5211#include "base/memory/raw_ptr.h"
Anton Bikineev46bbb972021-05-15 17:53:5312#include "third_party/abseil-cpp/absl/types/optional.h"
[email protected]44cbd9e2011-01-14 15:49:4013#include "ui/base/models/simple_menu_model.h"
[email protected]7e9f4a82010-03-22 22:36:2014
15class Browser;
[email protected]7e9f4a82010-03-22 22:36:2016class Profile;
17
[email protected]e1670582014-08-15 23:05:4118namespace content {
19class WebContents;
20}
21
[email protected]1c321ee2012-05-21 03:02:3422namespace extensions {
[email protected]69e1c12d2014-08-13 08:25:3423class ContextMenuMatcher;
Devlin Cronin720a0fb2020-07-22 01:31:3824class Extension;
25class ExtensionAction;
[email protected]1c321ee2012-05-21 03:02:3426
[email protected]ddaaaa12013-01-29 22:52:5227// The context menu model for extension icons.
rdevlin.cronin2b74ad82015-09-17 22:15:5428class ExtensionContextMenuModel : public ui::SimpleMenuModel,
29 public ui::SimpleMenuModel::Delegate {
[email protected]7e9f4a82010-03-22 22:36:2030 public:
[email protected]65187152012-06-02 13:14:1431 enum MenuEntries {
Devlin Cronin94aa4fb2018-09-21 05:24:0032 HOME_PAGE = 0,
33 OPTIONS,
[email protected]b87c48d2014-08-21 20:44:0434 TOGGLE_VISIBILITY,
[email protected]65187152012-06-02 13:14:1435 UNINSTALL,
Devlin Cronin94aa4fb2018-09-21 05:24:0036 MANAGE_EXTENSIONS,
[email protected]e1670582014-08-15 23:05:4137 INSPECT_POPUP,
Devlin Croninc40a10c12018-11-30 22:10:3738 PAGE_ACCESS_CANT_ACCESS,
rdevlin.croninb2e7ac02015-10-29 17:05:5639 PAGE_ACCESS_SUBMENU,
40 PAGE_ACCESS_RUN_ON_CLICK,
41 PAGE_ACCESS_RUN_ON_SITE,
42 PAGE_ACCESS_RUN_ON_ALL_SITES,
Devlin Cronin35a3d942018-09-17 22:36:3743 PAGE_ACCESS_LEARN_MORE,
Karan Bhatia6b9706d2018-09-25 00:46:2444 // NOTE: If you update this, you probably need to update the
45 // ContextMenuAction enum below.
46 };
47
48 // A separate enum to indicate the action taken on the menu. We have two
49 // enums (this and MenuEntries above) to avoid needing to have a single one
50 // with both action-specific values (like kNoAction) and menu-specific values
51 // (like PAGE_ACCESS_SUBMENU).
52 // These values are persisted to logs. Entries should not be renumbered and
53 // numeric values should never be reused. New values should be added before
54 // kMaxValue.
55 enum class ContextMenuAction {
56 kNoAction = 0,
57 kCustomCommand = 1,
58 kHomePage = 2,
59 kOptions = 3,
60 kToggleVisibility = 4,
61 kUninstall = 5,
62 kManageExtensions = 6,
63 kInspectPopup = 7,
64 kPageAccessRunOnClick = 8,
65 kPageAccessRunOnSite = 9,
66 kPageAccessRunOnAllSites = 10,
67 kPageAccessLearnMore = 11,
68 kMaxValue = kPageAccessLearnMore,
[email protected]65187152012-06-02 13:14:1469 };
70
Emilia Paz498abfc2022-01-20 17:51:4271 // Location where the context menu is open from.
72 enum class ContextMenuSource { kToolbarAction = 0, kMenuItem = 1 };
73
Devlin Croninbff8e3172020-09-01 11:02:1174 // The current visibility of the extension; this affects the "pin" / "unpin"
rdevlin.cronin6540a512015-04-30 20:58:3175 // strings in the menu.
Devlin Croninbff8e3172020-09-01 11:02:1176 // TODO(devlin): Rename this "PinState" when we finish removing the old UI
77 // bits.
rdevlin.cronin6540a512015-04-30 20:58:3178 enum ButtonVisibility {
Devlin Croninbff8e3172020-09-01 11:02:1179 // The extension is pinned on the toolbar.
80 PINNED,
81 // The extension is temporarily visible on the toolbar, as for showing a
82 // popup.
rdevlin.cronin6540a512015-04-30 20:58:3183 TRANSITIVELY_VISIBLE,
Devlin Croninbff8e3172020-09-01 11:02:1184 // The extension is not pinned (and is shown in the extensions menu).
85 UNPINNED,
rdevlin.cronin6540a512015-04-30 20:58:3186 };
87
[email protected]c82526da2012-06-20 00:29:0788 // Delegate to handle showing an ExtensionAction popup.
89 class PopupDelegate {
90 public:
91 // Called when the user selects the menu item which requests that the
92 // popup be shown and inspected.
[email protected]fbabd742014-07-31 03:23:2393 // The delegate should know which popup to display.
94 virtual void InspectPopup() = 0;
[email protected]c82526da2012-06-20 00:29:0795
96 protected:
97 virtual ~PopupDelegate() {}
98 };
99
[email protected]ddaaaa12013-01-29 22:52:52100 // Creates a menu model for the given extension. If
[email protected]c82526da2012-06-20 00:29:07101 // prefs::kExtensionsUIDeveloperMode is enabled then a menu item
102 // will be shown for "Inspect Popup" which, when selected, will cause
103 // ShowPopupForDevToolsWindow() to be called on |delegate|.
rdevlin.cronin2b74ad82015-09-17 22:15:54104 ExtensionContextMenuModel(const Extension* extension,
[email protected]c82526da2012-06-20 00:29:07105 Browser* browser,
rdevlin.cronin6540a512015-04-30 20:58:31106 ButtonVisibility visibility,
Eric Willigersdf4c3002019-06-14 21:02:07107 PopupDelegate* delegate,
Emilia Paz498abfc2022-01-20 17:51:42108 bool can_show_icon_in_toolbar,
109 ContextMenuSource source);
Peter Boström6316db82021-09-24 16:15:11110
111 ExtensionContextMenuModel(const ExtensionContextMenuModel&) = delete;
112 ExtensionContextMenuModel& operator=(const ExtensionContextMenuModel&) =
113 delete;
114
rdevlin.cronin2b74ad82015-09-17 22:15:54115 ~ExtensionContextMenuModel() override;
[email protected]c82526da2012-06-20 00:29:07116
rdevlin.cronina0ea3c22015-09-25 19:33:09117 // SimpleMenuModel::Delegate:
dchengae36a4a2014-10-21 12:36:36118 bool IsCommandIdChecked(int command_id) const override;
catmullingsff2cdbc2017-08-22 22:07:02119 bool IsCommandIdVisible(int command_id) const override;
dchengae36a4a2014-10-21 12:36:36120 bool IsCommandIdEnabled(int command_id) const override;
dchengae36a4a2014-10-21 12:36:36121 void ExecuteCommand(int command_id, int event_flags) override;
Karan Bhatia6b9706d2018-09-25 00:46:24122 void OnMenuWillShow(ui::SimpleMenuModel* source) override;
123 void MenuClosed(ui::SimpleMenuModel* source) override;
[email protected]7e9f4a82010-03-22 22:36:20124
rdevlin.croninb2e7ac02015-10-29 17:05:56125 ui::SimpleMenuModel* page_access_submenu_for_testing() {
126 return page_access_submenu_.get();
127 }
128
[email protected]7e9f4a82010-03-22 22:36:20129 private:
rdevlin.cronin2b74ad82015-09-17 22:15:54130 void InitMenu(const Extension* extension, ButtonVisibility button_visibility);
[email protected]7e9f4a82010-03-22 22:36:20131
rdevlin.croninb2e7ac02015-10-29 17:05:56132 void CreatePageAccessSubmenu(const Extension* extension);
133
Devlin Croninc02de652018-12-08 02:51:03134 // Returns true if the given page access command is enabled in the menu.
135 bool IsPageAccessCommandEnabled(const Extension& extension,
Devlin Croninc02de652018-12-08 02:51:03136 int command_id) const;
137
rdevlin.croninb2e7ac02015-10-29 17:05:56138 void HandlePageAccessCommand(int command_id,
139 const Extension* extension) const;
140
Tim Judkinsc394b4b92020-07-17 19:50:48141 // Logs a user action when an option is selected in the page access section of
142 // the context menu.
143 void LogPageAccessAction(int command_id) const;
144
[email protected]9e685e52010-10-22 19:45:30145 // Gets the extension we are displaying the menu for. Returns NULL if the
146 // extension has been uninstalled and no longer exists.
rdevlin.cronin2b74ad82015-09-17 22:15:54147 const Extension* GetExtension() const;
[email protected]9e685e52010-10-22 19:45:30148
[email protected]e1670582014-08-15 23:05:41149 // Returns the active web contents.
150 content::WebContents* GetActiveWebContents() const;
151
[email protected]69e1c12d2014-08-13 08:25:34152 // Appends the extension's context menu items.
153 void AppendExtensionItems();
154
[email protected]9e685e52010-10-22 19:45:30155 // A copy of the extension's id.
156 std::string extension_id_;
[email protected]7e9f4a82010-03-22 22:36:20157
rdevlin.cronin0515a3b2015-05-14 20:50:52158 // Whether the menu is for a component extension.
159 bool is_component_;
160
[email protected]ddaaaa12013-01-29 22:52:52161 // The extension action of the extension we are displaying the menu for (if
162 // it has one, otherwise NULL).
Keishi Hattori0e45c022021-11-27 09:25:52163 raw_ptr<ExtensionAction> extension_action_;
[email protected]7e9f4a82010-03-22 22:36:20164
Keishi Hattori0e45c022021-11-27 09:25:52165 const raw_ptr<Browser> browser_;
[email protected]7e9f4a82010-03-22 22:36:20166
Keishi Hattori0e45c022021-11-27 09:25:52167 raw_ptr<Profile> profile_;
[email protected]7e9f4a82010-03-22 22:36:20168
[email protected]c82526da2012-06-20 00:29:07169 // The delegate which handles the 'inspect popup' menu command (or NULL).
Keishi Hattori0e45c022021-11-27 09:25:52170 raw_ptr<PopupDelegate> delegate_;
[email protected]c82526da2012-06-20 00:29:07171
rdevlin.cronin9a906512015-10-12 19:53:08172 // The visibility of the button at the time the menu opened.
173 ButtonVisibility button_visibility_;
174
Eric Willigersdf4c3002019-06-14 21:02:07175 const bool can_show_icon_in_toolbar_;
176
[email protected]69e1c12d2014-08-13 08:25:34177 // Menu matcher for context menu items specified by the extension.
dchengc963c7142016-04-08 03:55:22178 std::unique_ptr<ContextMenuMatcher> extension_items_;
[email protected]69e1c12d2014-08-13 08:25:34179
dchengc963c7142016-04-08 03:55:22180 std::unique_ptr<ui::SimpleMenuModel> page_access_submenu_;
rdevlin.croninb2e7ac02015-10-29 17:05:56181
Karan Bhatia6b9706d2018-09-25 00:46:24182 // The action taken by the menu. Has a valid value when the menu is being
183 // shown.
Anton Bikineev46bbb972021-05-15 17:53:53184 absl::optional<ContextMenuAction> action_taken_;
Emilia Paz498abfc2022-01-20 17:51:42185
186 ContextMenuSource source_;
[email protected]7e9f4a82010-03-22 22:36:20187};
188
rdevlin.cronin2b74ad82015-09-17 22:15:54189} // namespace extensions
190
[email protected]7e9f4a82010-03-22 22:36:20191#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_CONTEXT_MENU_MODEL_H_