OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/extension_context_menu_api.h" | 5 #include "chrome/browser/extensions/extension_context_menu_api.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/values.h" | 9 #include "base/values.h" |
10 #include "chrome/browser/extensions/extensions_service.h" | 10 #include "chrome/browser/extensions/extensions_service.h" |
11 #include "chrome/browser/profile.h" | 11 #include "chrome/browser/profile.h" |
12 #include "chrome/common/extensions/extension_error_utils.h" | 12 #include "chrome/common/extensions/extension_error_utils.h" |
13 | 13 |
14 const wchar_t kCheckedKey[] = L"checked"; | 14 const wchar_t kCheckedKey[] = L"checked"; |
15 const wchar_t kContextsKey[] = L"contexts"; | 15 const wchar_t kContextsKey[] = L"contexts"; |
| 16 const wchar_t kDocumentUrlPatternsKey[] = L"documentUrlPatterns"; |
16 const wchar_t kGeneratedIdKey[] = L"generatedId"; | 17 const wchar_t kGeneratedIdKey[] = L"generatedId"; |
17 const wchar_t kParentIdKey[] = L"parentId"; | 18 const wchar_t kParentIdKey[] = L"parentId"; |
| 19 const wchar_t kTargetUrlPatternsKey[] = L"targetUrlPatterns"; |
18 const wchar_t kTitleKey[] = L"title"; | 20 const wchar_t kTitleKey[] = L"title"; |
19 const wchar_t kTypeKey[] = L"type"; | 21 const wchar_t kTypeKey[] = L"type"; |
20 | 22 |
21 const char kCannotFindItemError[] = "Cannot find menu item with id *"; | 23 const char kCannotFindItemError[] = "Cannot find menu item with id *"; |
22 const char kCheckedError[] = | 24 const char kCheckedError[] = |
23 "Only items with type \"radio\" or \"checkbox\" can be checked"; | 25 "Only items with type \"radio\" or \"checkbox\" can be checked"; |
| 26 const char kInvalidURLPatternError[] = "Invalid url pattern '*'"; |
24 const char kInvalidValueError[] = "Invalid value for *"; | 27 const char kInvalidValueError[] = "Invalid value for *"; |
25 const char kInvalidTypeStringError[] = "Invalid type string '*'"; | 28 const char kInvalidTypeStringError[] = "Invalid type string '*'"; |
26 const char kParentsMustBeNormalError[] = | 29 const char kParentsMustBeNormalError[] = |
27 "Parent items must have type \"normal\""; | 30 "Parent items must have type \"normal\""; |
28 const char kTitleNeededError[] = | 31 const char kTitleNeededError[] = |
29 "All menu items except for separators must have a title"; | 32 "All menu items except for separators must have a title"; |
30 | 33 |
31 | 34 |
32 bool ExtensionContextMenuFunction::ParseContexts( | 35 bool ExtensionContextMenuFunction::ParseContexts( |
33 const DictionaryValue& properties, | 36 const DictionaryValue& properties, |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 if (!properties.GetBoolean(kCheckedKey, checked)) | 115 if (!properties.GetBoolean(kCheckedKey, checked)) |
113 return false; | 116 return false; |
114 if (checked && type != ExtensionMenuItem::CHECKBOX && | 117 if (checked && type != ExtensionMenuItem::CHECKBOX && |
115 type != ExtensionMenuItem::RADIO) { | 118 type != ExtensionMenuItem::RADIO) { |
116 error_ = kCheckedError; | 119 error_ = kCheckedError; |
117 return false; | 120 return false; |
118 } | 121 } |
119 return true; | 122 return true; |
120 } | 123 } |
121 | 124 |
| 125 bool ExtensionContextMenuFunction::ParseURLPatterns( |
| 126 const DictionaryValue& properties, |
| 127 const wchar_t* key, |
| 128 ExtensionExtent* result) { |
| 129 if (!properties.HasKey(key)) |
| 130 return true; |
| 131 ListValue* list = NULL; |
| 132 if (!properties.GetList(key, &list)) |
| 133 return false; |
| 134 for (ListValue::iterator i = list->begin(); i != list->end(); ++i) { |
| 135 std::string tmp; |
| 136 if (!(*i)->GetAsString(&tmp)) |
| 137 return false; |
| 138 |
| 139 URLPattern pattern(ExtensionMenuManager::kAllowedSchemes); |
| 140 if (!pattern.Parse(tmp)) { |
| 141 error_ = ExtensionErrorUtils::FormatErrorMessage(kInvalidURLPatternError, |
| 142 tmp); |
| 143 return false; |
| 144 } |
| 145 result->AddPattern(pattern); |
| 146 } |
| 147 return true; |
| 148 } |
| 149 |
| 150 bool ExtensionContextMenuFunction::SetURLPatterns( |
| 151 const DictionaryValue& properties, |
| 152 ExtensionMenuItem* item) { |
| 153 // Process the documentUrlPattern value. |
| 154 ExtensionExtent document_url_patterns; |
| 155 if (!ParseURLPatterns(properties, kDocumentUrlPatternsKey, |
| 156 &document_url_patterns)) |
| 157 return false; |
| 158 |
| 159 if (!document_url_patterns.is_empty()) { |
| 160 item->set_document_url_patterns(document_url_patterns); |
| 161 } |
| 162 |
| 163 // Process the targetUrlPattern value. |
| 164 ExtensionExtent target_url_patterns; |
| 165 if (!ParseURLPatterns(properties, kTargetUrlPatternsKey, |
| 166 &target_url_patterns)) |
| 167 return false; |
| 168 |
| 169 if (!target_url_patterns.is_empty()) { |
| 170 item->set_target_url_patterns(target_url_patterns); |
| 171 } |
| 172 |
| 173 return true; |
| 174 } |
| 175 |
| 176 |
122 bool ExtensionContextMenuFunction::GetParent( | 177 bool ExtensionContextMenuFunction::GetParent( |
123 const DictionaryValue& properties, | 178 const DictionaryValue& properties, |
124 const ExtensionMenuManager& manager, | 179 const ExtensionMenuManager& manager, |
125 ExtensionMenuItem** result) { | 180 ExtensionMenuItem** result) { |
126 if (!properties.HasKey(kParentIdKey)) | 181 if (!properties.HasKey(kParentIdKey)) |
127 return true; | 182 return true; |
128 ExtensionMenuItem::Id parent_id(extension_id(), 0); | 183 ExtensionMenuItem::Id parent_id(extension_id(), 0); |
129 if (properties.HasKey(kParentIdKey) && | 184 if (properties.HasKey(kParentIdKey) && |
130 !properties.GetInteger(kParentIdKey, &parent_id.second)) | 185 !properties.GetInteger(kParentIdKey, &parent_id.second)) |
131 return false; | 186 return false; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 return false; | 227 return false; |
173 } | 228 } |
174 | 229 |
175 bool checked; | 230 bool checked; |
176 if (!ParseChecked(type, *properties, false, &checked)) | 231 if (!ParseChecked(type, *properties, false, &checked)) |
177 return false; | 232 return false; |
178 | 233 |
179 scoped_ptr<ExtensionMenuItem> item( | 234 scoped_ptr<ExtensionMenuItem> item( |
180 new ExtensionMenuItem(id, title, checked, type, contexts)); | 235 new ExtensionMenuItem(id, title, checked, type, contexts)); |
181 | 236 |
| 237 if (!SetURLPatterns(*properties, item.get())) |
| 238 return false; |
| 239 |
182 bool success = true; | 240 bool success = true; |
183 if (properties->HasKey(kParentIdKey)) { | 241 if (properties->HasKey(kParentIdKey)) { |
184 ExtensionMenuItem::Id parent_id(extension_id(), 0); | 242 ExtensionMenuItem::Id parent_id(extension_id(), 0); |
185 EXTENSION_FUNCTION_VALIDATE(properties->GetInteger(kParentIdKey, | 243 EXTENSION_FUNCTION_VALIDATE(properties->GetInteger(kParentIdKey, |
186 &parent_id.second)); | 244 &parent_id.second)); |
187 ExtensionMenuItem* parent = menu_manager->GetItemById(parent_id); | 245 ExtensionMenuItem* parent = menu_manager->GetItemById(parent_id); |
188 if (!parent) { | 246 if (!parent) { |
189 error_ = ExtensionErrorUtils::FormatErrorMessage( | 247 error_ = ExtensionErrorUtils::FormatErrorMessage( |
190 kCannotFindItemError, IntToString(parent_id.second)); | 248 kCannotFindItemError, IntToString(parent_id.second)); |
191 return false; | 249 return false; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 profile()->GetExtensionsService()->menu_manager(); | 284 profile()->GetExtensionsService()->menu_manager(); |
227 | 285 |
228 // Type. | 286 // Type. |
229 ExtensionMenuItem::Type type; | 287 ExtensionMenuItem::Type type; |
230 if (!ParseType(*properties, item->type(), &type)) | 288 if (!ParseType(*properties, item->type(), &type)) |
231 return false; | 289 return false; |
232 if (type != item->type()) | 290 if (type != item->type()) |
233 item->set_type(type); | 291 item->set_type(type); |
234 | 292 |
235 // Title. | 293 // Title. |
236 std::string title; | 294 if (properties->HasKey(kTitleKey)) { |
237 if (properties->HasKey(kTitleKey) && | 295 std::string title; |
238 !properties->GetString(kTitleKey, &title)) | 296 EXTENSION_FUNCTION_VALIDATE(properties->GetString(kTitleKey, &title)); |
239 return false; | 297 if (title.empty() && type != ExtensionMenuItem::SEPARATOR) { |
240 if (title.empty() && type != ExtensionMenuItem::SEPARATOR) { | 298 error_ = kTitleNeededError; |
241 error_ = kTitleNeededError; | 299 return false; |
242 return false; | 300 } |
| 301 item->set_title(title); |
243 } | 302 } |
244 item->set_title(title); | |
245 | 303 |
246 // Checked state. | 304 // Checked state. |
247 bool checked; | 305 bool checked; |
248 if (!ParseChecked(item->type(), *properties, item->checked(), &checked)) | 306 if (!ParseChecked(item->type(), *properties, item->checked(), &checked)) |
249 return false; | 307 return false; |
250 if (checked != item->checked()) { | 308 if (checked != item->checked()) { |
251 if (!item->SetChecked(checked)) | 309 if (!item->SetChecked(checked)) |
252 return false; | 310 return false; |
253 } | 311 } |
254 | 312 |
255 // Contexts. | 313 // Contexts. |
256 ExtensionMenuItem::ContextList contexts(item->contexts()); | 314 ExtensionMenuItem::ContextList contexts(item->contexts()); |
257 if (!ParseContexts(*properties, kContextsKey, &contexts)) | 315 if (!ParseContexts(*properties, kContextsKey, &contexts)) |
258 return false; | 316 return false; |
259 if (contexts != item->contexts()) | 317 if (contexts != item->contexts()) |
260 item->set_contexts(contexts); | 318 item->set_contexts(contexts); |
261 | 319 |
262 // Parent id. | 320 // Parent id. |
263 ExtensionMenuItem* parent = NULL; | 321 ExtensionMenuItem* parent = NULL; |
264 if (!GetParent(*properties, *menu_manager, &parent)) | 322 if (!GetParent(*properties, *menu_manager, &parent)) |
265 return false; | 323 return false; |
266 if (parent && !menu_manager->ChangeParent(item->id(), &parent->id())) | 324 if (parent && !menu_manager->ChangeParent(item->id(), &parent->id())) |
267 return false; | 325 return false; |
268 | 326 |
| 327 if (!SetURLPatterns(*properties, item)) |
| 328 return false; |
| 329 |
269 return true; | 330 return true; |
270 } | 331 } |
271 | 332 |
272 bool RemoveContextMenuFunction::RunImpl() { | 333 bool RemoveContextMenuFunction::RunImpl() { |
273 ExtensionMenuItem::Id id(extension_id(), 0); | 334 ExtensionMenuItem::Id id(extension_id(), 0); |
274 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &id.second)); | 335 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &id.second)); |
275 ExtensionsService* service = profile()->GetExtensionsService(); | 336 ExtensionsService* service = profile()->GetExtensionsService(); |
276 ExtensionMenuManager* manager = service->menu_manager(); | 337 ExtensionMenuManager* manager = service->menu_manager(); |
277 | 338 |
278 ExtensionMenuItem* item = manager->GetItemById(id); | 339 ExtensionMenuItem* item = manager->GetItemById(id); |
279 // Ensure one extension can't remove another's menu items. | 340 // Ensure one extension can't remove another's menu items. |
280 if (!item || item->extension_id() != extension_id()) { | 341 if (!item || item->extension_id() != extension_id()) { |
281 error_ = ExtensionErrorUtils::FormatErrorMessage( | 342 error_ = ExtensionErrorUtils::FormatErrorMessage( |
282 kCannotFindItemError, IntToString(id.second)); | 343 kCannotFindItemError, IntToString(id.second)); |
283 return false; | 344 return false; |
284 } | 345 } |
285 | 346 |
286 return manager->RemoveContextMenuItem(id); | 347 return manager->RemoveContextMenuItem(id); |
287 } | 348 } |
288 | 349 |
289 bool RemoveAllContextMenusFunction::RunImpl() { | 350 bool RemoveAllContextMenusFunction::RunImpl() { |
290 ExtensionsService* service = profile()->GetExtensionsService(); | 351 ExtensionsService* service = profile()->GetExtensionsService(); |
291 ExtensionMenuManager* manager = service->menu_manager(); | 352 ExtensionMenuManager* manager = service->menu_manager(); |
292 manager->RemoveAllContextItems(extension_id()); | 353 manager->RemoveAllContextItems(extension_id()); |
293 return true; | 354 return true; |
294 } | 355 } |
OLD | NEW |