| 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 |