blob: 405cae1491b4eb5af7da0466f0df16e1f4ec5e24 [file] [log] [blame]
[email protected]2e3b5202010-03-23 06:52:411// Copyright (c) 2010 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_MENU_MANAGER_H_
6#define CHROME_BROWSER_EXTENSIONS_EXTENSION_MENU_MANAGER_H_
7
8#include <map>
9#include <set>
10#include <string>
11#include <vector>
12
13#include "base/basictypes.h"
[email protected]f4f04592010-07-14 20:40:1314#include "base/scoped_ptr.h"
[email protected]2e3b5202010-03-23 06:52:4115#include "base/string16.h"
[email protected]b671760b2010-07-15 21:13:4716#include "chrome/browser/extensions/extension_icon_manager.h"
[email protected]9e9d7912010-07-18 21:05:2817#include "chrome/common/extensions/extension_extent.h"
[email protected]2e3b5202010-03-23 06:52:4118#include "chrome/common/notification_observer.h"
19#include "chrome/common/notification_registrar.h"
[email protected]2e3b5202010-03-23 06:52:4120
21struct ContextMenuParams;
22
[email protected]052c92702010-06-25 07:25:5223class Extension;
[email protected]2e3b5202010-03-23 06:52:4124class ExtensionMessageService;
25class Profile;
[email protected]b671760b2010-07-15 21:13:4726class SkBitmap;
[email protected]2e3b5202010-03-23 06:52:4127class TabContents;
28
29// Represents a menu item added by an extension.
30class ExtensionMenuItem {
31 public:
[email protected]63a414b52010-06-03 23:20:4932 // A list of ExtensionMenuItem's.
33 typedef std::vector<ExtensionMenuItem*> List;
[email protected]2e3b5202010-03-23 06:52:4134
[email protected]9e9d7912010-07-18 21:05:2835 // An Id is a pair of |extension id|, |int| where the |int| is unique per
36 // extension.
37 typedef std::pair<std::string, int> Id;
38
[email protected]a11fa342010-07-09 16:56:0039 // For context menus, these are the contexts where an item can appear.
[email protected]2e3b5202010-03-23 06:52:4140 enum Context {
41 ALL = 1,
42 PAGE = 2,
43 SELECTION = 4,
44 LINK = 8,
45 EDITABLE = 16,
46 IMAGE = 32,
47 VIDEO = 64,
48 AUDIO = 128,
49 };
50
51 // An item can be only one of these types.
52 enum Type {
53 NORMAL,
54 CHECKBOX,
55 RADIO,
56 SEPARATOR
57 };
58
[email protected]a11fa342010-07-09 16:56:0059 // A list of Contexts for an item.
[email protected]2e3b5202010-03-23 06:52:4160 class ContextList {
61 public:
62 ContextList() : value_(0) {}
63 explicit ContextList(Context context) : value_(context) {}
64 ContextList(const ContextList& other) : value_(other.value_) {}
65
66 void operator=(const ContextList& other) {
67 value_ = other.value_;
68 }
69
[email protected]66dbfb2c2010-05-12 20:20:1570 bool operator==(const ContextList& other) const {
71 return value_ == other.value_;
72 }
73
74 bool operator!=(const ContextList& other) const {
75 return !(*this == other);
76 }
77
[email protected]2e3b5202010-03-23 06:52:4178 bool Contains(Context context) const {
79 return (value_ & context) > 0;
80 }
81
82 void Add(Context context) {
83 value_ |= context;
84 }
85
86 private:
87 uint32 value_; // A bitmask of Context values.
88 };
89
[email protected]f4f04592010-07-14 20:40:1390 ExtensionMenuItem(const Id& id, std::string title, bool checked, Type type,
91 const ContextList& contexts);
[email protected]2e3b5202010-03-23 06:52:4192 virtual ~ExtensionMenuItem();
93
94 // Simple accessor methods.
[email protected]f4f04592010-07-14 20:40:1395 const std::string& extension_id() const { return id_.first; }
[email protected]2e3b5202010-03-23 06:52:4196 const std::string& title() const { return title_; }
[email protected]63a414b52010-06-03 23:20:4997 const List& children() { return children_; }
[email protected]f4f04592010-07-14 20:40:1398 const Id& id() const { return id_; }
99 Id* parent_id() const { return parent_id_.get(); }
[email protected]2e3b5202010-03-23 06:52:41100 int child_count() const { return children_.size(); }
101 ContextList contexts() const { return contexts_; }
[email protected]2e3b5202010-03-23 06:52:41102 Type type() const { return type_; }
103 bool checked() const { return checked_; }
[email protected]9e9d7912010-07-18 21:05:28104 const ExtensionExtent& document_url_patterns() const {
105 return document_url_patterns_;
106 }
107 const ExtensionExtent& target_url_patterns() const {
108 return target_url_patterns_;
109 }
[email protected]2e3b5202010-03-23 06:52:41110
[email protected]66dbfb2c2010-05-12 20:20:15111 // Simple mutator methods.
112 void set_title(std::string new_title) { title_ = new_title; }
113 void set_contexts(ContextList contexts) { contexts_ = contexts; }
[email protected]66dbfb2c2010-05-12 20:20:15114 void set_type(Type type) { type_ = type; }
[email protected]9e9d7912010-07-18 21:05:28115 void set_document_url_patterns(const ExtensionExtent& patterns) {
116 document_url_patterns_ = patterns;
117 }
118 void set_target_url_patterns(const ExtensionExtent& patterns) {
119 target_url_patterns_ = patterns;
120 }
[email protected]66dbfb2c2010-05-12 20:20:15121
[email protected]2e3b5202010-03-23 06:52:41122 // Returns the title with any instances of %s replaced by |selection|.
123 string16 TitleWithReplacement(const string16& selection) const;
124
[email protected]66dbfb2c2010-05-12 20:20:15125 // Set the checked state to |checked|. Returns true if successful.
126 bool SetChecked(bool checked);
127
[email protected]2e3b5202010-03-23 06:52:41128 protected:
129 friend class ExtensionMenuManager;
130
[email protected]2e3b5202010-03-23 06:52:41131 // Takes ownership of |item| and sets its parent_id_.
132 void AddChild(ExtensionMenuItem* item);
133
134 // Removes child menu item with the given id, returning true if the item was
135 // found and removed, or false otherwise.
[email protected]f4f04592010-07-14 20:40:13136 bool RemoveChild(const Id& child_id);
[email protected]2e3b5202010-03-23 06:52:41137
[email protected]66dbfb2c2010-05-12 20:20:15138 // Takes the child item from this parent. The item is returned and the caller
139 // then owns the pointer.
[email protected]f4f04592010-07-14 20:40:13140 ExtensionMenuItem* ReleaseChild(const Id& child_id, bool recursive);
[email protected]66dbfb2c2010-05-12 20:20:15141
142 // Recursively removes all descendant items (children, grandchildren, etc.),
143 // returning the ids of the removed items.
[email protected]f4f04592010-07-14 20:40:13144 std::set<Id> RemoveAllDescendants();
[email protected]66dbfb2c2010-05-12 20:20:15145
[email protected]2e3b5202010-03-23 06:52:41146 private:
[email protected]f4f04592010-07-14 20:40:13147 // The unique id for this item.
148 Id id_;
[email protected]2e3b5202010-03-23 06:52:41149
150 // What gets shown in the menu for this item.
151 std::string title_;
152
[email protected]2e3b5202010-03-23 06:52:41153 Type type_;
154
155 // This should only be true for items of type CHECKBOX or RADIO.
156 bool checked_;
157
158 // In what contexts should the item be shown?
159 ContextList contexts_;
160
[email protected]2e3b5202010-03-23 06:52:41161 // If this item is a child of another item, the unique id of its parent. If
[email protected]f4f04592010-07-14 20:40:13162 // this is a top-level item with no parent, this will be NULL.
163 scoped_ptr<Id> parent_id_;
[email protected]2e3b5202010-03-23 06:52:41164
[email protected]9e9d7912010-07-18 21:05:28165 // Patterns for restricting what documents this item will appear for. This
166 // applies to the frame where the click took place.
167 ExtensionExtent document_url_patterns_;
168
169 // Patterns for restricting where items appear based on the src/href
170 // attribute of IMAGE/AUDIO/VIDEO/LINK tags.
171 ExtensionExtent target_url_patterns_;
172
[email protected]2e3b5202010-03-23 06:52:41173 // Any children this item may have.
174 List children_;
175
176 DISALLOW_COPY_AND_ASSIGN(ExtensionMenuItem);
177};
178
179// This class keeps track of menu items added by extensions.
[email protected]b671760b2010-07-15 21:13:47180class ExtensionMenuManager : public NotificationObserver {
[email protected]2e3b5202010-03-23 06:52:41181 public:
[email protected]9e9d7912010-07-18 21:05:28182 // A bitmask of values from URLPattern::SchemeMasks indicating the schemes
183 // of pages where we'll show extension menu items.
184 static const int kAllowedSchemes;
185
[email protected]2e3b5202010-03-23 06:52:41186 ExtensionMenuManager();
187 virtual ~ExtensionMenuManager();
188
189 // Returns the ids of extensions which have menu items registered.
190 std::set<std::string> ExtensionIds();
191
192 // Returns a list of all the *top-level* menu items (added via AddContextItem)
193 // for the given extension id, *not* including child items (added via
194 // AddChildItem); although those can be reached via the top-level items'
[email protected]63a414b52010-06-03 23:20:49195 // children. A view can then decide how to display these, including whether to
196 // put them into a submenu if there are more than 1.
197 const ExtensionMenuItem::List* MenuItems(const std::string& extension_id);
[email protected]2e3b5202010-03-23 06:52:41198
[email protected]052c92702010-06-25 07:25:52199 // Adds a top-level menu item for an extension, requiring the |extension|
200 // pointer so it can load the icon for the extension. Takes ownership of
[email protected]f4f04592010-07-14 20:40:13201 // |item|. Returns a boolean indicating success or failure.
202 bool AddContextItem(Extension* extension, ExtensionMenuItem* item);
[email protected]2e3b5202010-03-23 06:52:41203
204 // Add an item as a child of another item which has been previously added, and
[email protected]f4f04592010-07-14 20:40:13205 // takes ownership of |item|. Returns a boolean indicating success or failure.
206 bool AddChildItem(const ExtensionMenuItem::Id& parent_id,
207 ExtensionMenuItem* child);
[email protected]2e3b5202010-03-23 06:52:41208
[email protected]66dbfb2c2010-05-12 20:20:15209 // Makes existing item with |child_id| a child of the item with |parent_id|.
210 // If the child item was already a child of another parent, this will remove
211 // it from that parent first. It is an error to try and move an item to be a
[email protected]f4f04592010-07-14 20:40:13212 // child of one of its own descendants. It is legal to pass NULL for
213 // |parent_id|, which means the item should be moved to the top-level.
214 bool ChangeParent(const ExtensionMenuItem::Id& child_id,
215 const ExtensionMenuItem::Id* parent_id);
[email protected]66dbfb2c2010-05-12 20:20:15216
[email protected]2e3b5202010-03-23 06:52:41217 // Removes a context menu item with the given id (whether it is a top-level
218 // item or a child of some other item), returning true if the item was found
219 // and removed or false otherwise.
[email protected]f4f04592010-07-14 20:40:13220 bool RemoveContextMenuItem(const ExtensionMenuItem::Id& id);
[email protected]2e3b5202010-03-23 06:52:41221
[email protected]66dbfb2c2010-05-12 20:20:15222 // Removes all items for the given extension id.
223 void RemoveAllContextItems(std::string extension_id);
224
[email protected]2e3b5202010-03-23 06:52:41225 // Returns the item with the given |id| or NULL.
[email protected]f4f04592010-07-14 20:40:13226 ExtensionMenuItem* GetItemById(const ExtensionMenuItem::Id& id) const;
[email protected]2e3b5202010-03-23 06:52:41227
228 // Called when a menu item is clicked on by the user.
229 void ExecuteCommand(Profile* profile, TabContents* tab_contents,
230 const ContextMenuParams& params,
[email protected]f4f04592010-07-14 20:40:13231 const ExtensionMenuItem::Id& menuItemId);
[email protected]2e3b5202010-03-23 06:52:41232
[email protected]052c92702010-06-25 07:25:52233 // This returns a bitmap of width/height kFavIconSize, loaded either from an
234 // entry specified in the extension's 'icon' section of the manifest, or a
235 // default extension icon.
236 const SkBitmap& GetIconForExtension(const std::string& extension_id);
237
[email protected]b671760b2010-07-15 21:13:47238 // Implements the NotificationObserver interface.
239 virtual void Observe(NotificationType type, const NotificationSource& source,
240 const NotificationDetails& details);
[email protected]052c92702010-06-25 07:25:52241
[email protected]9e9d7912010-07-18 21:05:28242 // Returns true if |url| has an allowed scheme for extension context menu
243 // items. This checks against kAllowedSchemes.
244 static bool HasAllowedScheme(const GURL& url);
245
[email protected]2e3b5202010-03-23 06:52:41246 private:
247 // This is a helper function which takes care of de-selecting any other radio
248 // items in the same group (i.e. that are adjacent in the list).
249 void RadioItemSelected(ExtensionMenuItem* item);
250
[email protected]66dbfb2c2010-05-12 20:20:15251 // Returns true if item is a descendant of an item with id |ancestor_id|.
[email protected]f4f04592010-07-14 20:40:13252 bool DescendantOf(ExtensionMenuItem* item,
253 const ExtensionMenuItem::Id& ancestor_id);
[email protected]66dbfb2c2010-05-12 20:20:15254
[email protected]2e3b5202010-03-23 06:52:41255 // We keep items organized by mapping an extension id to a list of items.
256 typedef std::map<std::string, ExtensionMenuItem::List> MenuItemMap;
257 MenuItemMap context_items_;
258
259 // This lets us make lookup by id fast. It maps id to ExtensionMenuItem* for
260 // all items the menu manager knows about, including all children of top-level
261 // items.
[email protected]f4f04592010-07-14 20:40:13262 std::map<ExtensionMenuItem::Id, ExtensionMenuItem*> items_by_id_;
[email protected]2e3b5202010-03-23 06:52:41263
264 NotificationRegistrar registrar_;
265
[email protected]b671760b2010-07-15 21:13:47266 ExtensionIconManager icon_manager_;
[email protected]052c92702010-06-25 07:25:52267
[email protected]2e3b5202010-03-23 06:52:41268 DISALLOW_COPY_AND_ASSIGN(ExtensionMenuManager);
269};
270
271#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_MENU_MANAGER_H_