[Extensions API] Remove inline enums
[chromium-blink-merge.git] / chrome / browser / extensions / api / context_menus / context_menus_api_helpers.h
blob9b7ce87d0080c0b671e3f23e863ce2c696906772
1 // Copyright 2014 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.
5 // Definition of helper functions for the ContextMenus API.
7 #ifndef CHROME_BROWSER_EXTENSIONS_API_CONTEXT_MENUS_CONTEXT_MENUS_API_HELPERS_H_
8 #define CHROME_BROWSER_EXTENSIONS_API_CONTEXT_MENUS_CONTEXT_MENUS_API_HELPERS_H_
10 #include "chrome/browser/extensions/menu_manager.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/common/extensions/api/context_menus.h"
13 #include "extensions/common/error_utils.h"
14 #include "extensions/common/manifest_handlers/background_info.h"
16 namespace extensions {
17 namespace context_menus_api_helpers {
19 namespace {
21 template <typename PropertyWithEnumT>
22 scoped_ptr<extensions::MenuItem::Id> GetParentId(
23 const PropertyWithEnumT& property,
24 bool is_off_the_record,
25 const MenuItem::ExtensionKey& key) {
26 if (!property.parent_id)
27 return scoped_ptr<extensions::MenuItem::Id>();
29 scoped_ptr<extensions::MenuItem::Id> parent_id(
30 new extensions::MenuItem::Id(is_off_the_record, key));
31 if (property.parent_id->as_integer)
32 parent_id->uid = *property.parent_id->as_integer;
33 else if (property.parent_id->as_string)
34 parent_id->string_uid = *property.parent_id->as_string;
35 else
36 NOTREACHED();
37 return parent_id.Pass();
40 } // namespace
42 extern const char kActionNotAllowedError[];
43 extern const char kCannotFindItemError[];
44 extern const char kCheckedError[];
45 extern const char kDuplicateIDError[];
46 extern const char kGeneratedIdKey[];
47 extern const char kLauncherNotAllowedError[];
48 extern const char kOnclickDisallowedError[];
49 extern const char kParentsMustBeNormalError[];
50 extern const char kTitleNeededError[];
52 std::string GetIDString(const MenuItem::Id& id);
54 MenuItem* GetParent(MenuItem::Id parent_id,
55 const MenuManager* menu_manager,
56 std::string* error);
58 MenuItem::ContextList GetContexts(const std::vector<
59 extensions::api::context_menus::ContextType>& in_contexts);
61 MenuItem::Type GetType(extensions::api::context_menus::ItemType type,
62 MenuItem::Type default_type);
64 // Creates and adds a menu item from |create_properties|.
65 template<typename PropertyWithEnumT>
66 bool CreateMenuItem(const PropertyWithEnumT& create_properties,
67 Profile* profile,
68 const Extension* extension,
69 const MenuItem::Id& item_id,
70 std::string* error) {
71 bool is_webview = item_id.extension_key.webview_instance_id != 0;
72 MenuManager* menu_manager = MenuManager::Get(profile);
74 if (menu_manager->GetItemById(item_id)) {
75 *error = ErrorUtils::FormatErrorMessage(kDuplicateIDError,
76 GetIDString(item_id));
77 return false;
80 if (!is_webview && BackgroundInfo::HasLazyBackgroundPage(extension) &&
81 create_properties.onclick.get()) {
82 *error = kOnclickDisallowedError;
83 return false;
86 // Contexts.
87 MenuItem::ContextList contexts;
88 if (create_properties.contexts.get())
89 contexts = GetContexts(*create_properties.contexts);
90 else
91 contexts.Add(MenuItem::PAGE);
93 if (contexts.Contains(MenuItem::LAUNCHER)) {
94 // Launcher item is not allowed for <webview>.
95 if (!extension->is_platform_app() || is_webview) {
96 *error = kLauncherNotAllowedError;
97 return false;
101 if (contexts.Contains(MenuItem::BROWSER_ACTION) ||
102 contexts.Contains(MenuItem::PAGE_ACTION)) {
103 // Action items are not allowed for <webview>.
104 if (!extension->is_extension() || is_webview) {
105 *error = kActionNotAllowedError;
106 return false;
110 // Title.
111 std::string title;
112 if (create_properties.title.get())
113 title = *create_properties.title;
115 MenuItem::Type type = GetType(create_properties.type, MenuItem::NORMAL);
116 if (title.empty() && type != MenuItem::SEPARATOR) {
117 *error = kTitleNeededError;
118 return false;
121 // Checked state.
122 bool checked = false;
123 if (create_properties.checked.get())
124 checked = *create_properties.checked;
126 // Enabled.
127 bool enabled = true;
128 if (create_properties.enabled.get())
129 enabled = *create_properties.enabled;
131 scoped_ptr<MenuItem> item(
132 new MenuItem(item_id, title, checked, enabled, type, contexts));
134 // URL Patterns.
135 if (!item->PopulateURLPatterns(
136 create_properties.document_url_patterns.get(),
137 create_properties.target_url_patterns.get(),
138 error)) {
139 return false;
142 // Parent id.
143 bool success = true;
144 scoped_ptr<MenuItem::Id> parent_id(GetParentId(
145 create_properties, profile->IsOffTheRecord(), item_id.extension_key));
146 if (parent_id.get()) {
147 MenuItem* parent = GetParent(*parent_id, menu_manager, error);
148 if (!parent)
149 return false;
150 success = menu_manager->AddChildItem(parent->id(), item.release());
151 } else {
152 success = menu_manager->AddContextItem(extension, item.release());
155 if (!success)
156 return false;
158 menu_manager->WriteToStorage(extension, item_id.extension_key);
159 return true;
162 // Updates a menu item from |update_properties|.
163 template<typename PropertyWithEnumT>
164 bool UpdateMenuItem(const PropertyWithEnumT& update_properties,
165 Profile* profile,
166 const Extension* extension,
167 const MenuItem::Id& item_id,
168 std::string* error) {
169 bool radio_item_updated = false;
170 bool is_webview = item_id.extension_key.webview_instance_id != 0;
171 MenuManager* menu_manager = MenuManager::Get(profile);
173 MenuItem* item = menu_manager->GetItemById(item_id);
174 if (!item || item->extension_id() != extension->id()){
175 *error = ErrorUtils::FormatErrorMessage(
176 kCannotFindItemError, GetIDString(item_id));
177 return false;
180 // Type.
181 MenuItem::Type type = GetType(update_properties.type, item->type());
183 if (type != item->type()) {
184 if (type == MenuItem::RADIO || item->type() == MenuItem::RADIO)
185 radio_item_updated = true;
186 item->set_type(type);
189 // Title.
190 if (update_properties.title.get()) {
191 std::string title(*update_properties.title);
192 if (title.empty() && item->type() != MenuItem::SEPARATOR) {
193 *error = kTitleNeededError;
194 return false;
196 item->set_title(title);
199 // Checked state.
200 if (update_properties.checked.get()) {
201 bool checked = *update_properties.checked;
202 if (checked &&
203 item->type() != MenuItem::CHECKBOX &&
204 item->type() != MenuItem::RADIO) {
205 *error = kCheckedError;
206 return false;
208 if (checked != item->checked()) {
209 if (!item->SetChecked(checked)) {
210 *error = kCheckedError;
211 return false;
213 radio_item_updated = true;
217 // Enabled.
218 if (update_properties.enabled.get())
219 item->set_enabled(*update_properties.enabled);
221 // Contexts.
222 MenuItem::ContextList contexts;
223 if (update_properties.contexts.get()) {
224 contexts = GetContexts(*update_properties.contexts);
226 if (contexts.Contains(MenuItem::LAUNCHER)) {
227 // Launcher item is not allowed for <webview>.
228 if (!extension->is_platform_app() || is_webview) {
229 *error = kLauncherNotAllowedError;
230 return false;
234 if (contexts != item->contexts())
235 item->set_contexts(contexts);
238 // Parent id.
239 MenuItem* parent = NULL;
240 scoped_ptr<MenuItem::Id> parent_id(GetParentId(
241 update_properties, profile->IsOffTheRecord(), item_id.extension_key));
242 if (parent_id.get()) {
243 MenuItem* parent = GetParent(*parent_id, menu_manager, error);
244 if (!parent || !menu_manager->ChangeParent(item->id(), &parent->id()))
245 return false;
248 // URL Patterns.
249 if (!item->PopulateURLPatterns(
250 update_properties.document_url_patterns.get(),
251 update_properties.target_url_patterns.get(), error)) {
252 return false;
255 // There is no need to call ItemUpdated if ChangeParent is called because
256 // all sanitation is taken care of in ChangeParent.
257 if (!parent && radio_item_updated && !menu_manager->ItemUpdated(item->id()))
258 return false;
260 menu_manager->WriteToStorage(extension, item_id.extension_key);
261 return true;
264 } // namespace context_menus_api_helpers
265 } // namespace extensions
267 #endif // CHROME_BROWSER_EXTENSIONS_API_CONTEXT_MENUS_CONTEXT_MENUS_API_HELPERS_H_