Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/api/context_menu/context_menu_api.h" | 5 #include "chrome/browser/extensions/api/context_menu/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 "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
| 11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 12 #include "chrome/browser/extensions/extension_service.h" | 12 #include "chrome/browser/extensions/extension_service.h" |
| 13 #include "chrome/browser/extensions/menu_manager.h" | |
| 13 #include "chrome/browser/profiles/profile.h" | 14 #include "chrome/browser/profiles/profile.h" |
| 15 #include "chrome/common/extensions/api/context_menus.h" | |
| 14 #include "chrome/common/extensions/extension_error_utils.h" | 16 #include "chrome/common/extensions/extension_error_utils.h" |
| 17 #include "chrome/common/extensions/url_pattern_set.h" | |
| 15 | 18 |
| 16 namespace { | 19 namespace { |
| 17 | 20 |
| 18 const char kCheckedKey[] = "checked"; | 21 const char kCheckedKey[] = "checked"; |
| 19 const char kContextsKey[] = "contexts"; | 22 const char kContextsKey[] = "contexts"; |
| 20 const char kDocumentUrlPatternsKey[] = "documentUrlPatterns"; | 23 const char kDocumentUrlPatternsKey[] = "documentUrlPatterns"; |
| 21 const char kEnabledKey[] = "enabled"; | 24 const char kEnabledKey[] = "enabled"; |
| 22 const char kGeneratedIdKey[] = "generatedId"; | 25 const char kGeneratedIdKey[] = "generatedId"; |
| 23 const char kIdKey[] = "id"; | 26 const char kIdKey[] = "id"; |
| 24 const char kOnclickKey[] = "onclick"; | 27 const char kOnclickKey[] = "onclick"; |
| 25 const char kParentIdKey[] = "parentId"; | 28 const char kParentIdKey[] = "parentId"; |
| 26 const char kTargetUrlPatternsKey[] = "targetUrlPatterns"; | 29 const char kTargetUrlPatternsKey[] = "targetUrlPatterns"; |
| 27 const char kTitleKey[] = "title"; | 30 const char kTitleKey[] = "title"; |
| 28 const char kTypeKey[] = "type"; | 31 const char kTypeKey[] = "type"; |
|
not at google - send to devlin
2012/07/26 04:16:20
see how many of these constants you can delete.
chebert
2012/07/27 01:28:24
Done.
| |
| 29 | 32 |
| 30 const char kCannotFindItemError[] = "Cannot find menu item with id *"; | 33 const char kCannotFindItemError[] = "Cannot find menu item with id *"; |
| 31 const char kOnclickDisallowedError[] = "Extensions using event pages cannot " | 34 const char kOnclickDisallowedError[] = "Extensions using event pages cannot " |
| 32 "pass an onclick parameter to chrome.contextMenus.create. Instead, use " | 35 "pass an onclick parameter to chrome.contextMenus.create. Instead, use " |
| 33 "the chrome.contextMenus.onClicked event."; | 36 "the chrome.contextMenus.onClicked event."; |
| 34 const char kCheckedError[] = | 37 const char kCheckedError[] = |
| 35 "Only items with type \"radio\" or \"checkbox\" can be checked"; | 38 "Only items with type \"radio\" or \"checkbox\" can be checked"; |
| 36 const char kDuplicateIDError[] = | 39 const char kDuplicateIDError[] = |
| 37 "Cannot create item with duplicate id *"; | 40 "Cannot create item with duplicate id *"; |
| 38 const char kIdRequiredError[] = "Extensions using event pages must pass an " | 41 const char kIdRequiredError[] = "Extensions using event pages must pass an " |
| 39 "id parameter to chrome.contextMenus.create"; | 42 "id parameter to chrome.contextMenus.create"; |
| 40 const char kInvalidValueError[] = "Invalid value for *"; | 43 const char kInvalidValueError[] = "Invalid value for *"; |
| 41 const char kInvalidTypeStringError[] = "Invalid type string '*'"; | 44 const char kInvalidTypeStringError[] = "Invalid type string '*'"; |
| 42 const char kParentsMustBeNormalError[] = | 45 const char kParentsMustBeNormalError[] = |
| 43 "Parent items must have type \"normal\""; | 46 "Parent items must have type \"normal\""; |
| 44 const char kTitleNeededError[] = | 47 const char kTitleNeededError[] = |
| 45 "All menu items except for separators must have a title"; | 48 "All menu items except for separators must have a title"; |
| 46 | 49 |
| 47 std::string GetIDString(const extensions::MenuItem::Id& id) { | 50 std::string GetIDString(const extensions::MenuItem::Id& id) { |
| 48 if (id.uid == 0) | 51 if (id.uid == 0) |
| 49 return id.string_uid; | 52 return id.string_uid; |
| 50 else | 53 else |
| 51 return base::IntToString(id.uid); | 54 return base::IntToString(id.uid); |
| 52 } | 55 } |
| 53 | 56 |
| 54 } // namespace | 57 } // namespace |
| 55 | 58 |
| 59 namespace Create = extensions::api::context_menus::Create; | |
| 60 namespace Remove = extensions::api::context_menus::Remove; | |
| 61 namespace Update = extensions::api::context_menus::Update; | |
|
not at google - send to devlin
2012/07/26 04:16:20
move these inside the extensions namespace, then y
chebert
2012/07/27 01:28:24
Done.
| |
| 62 | |
| 56 namespace extensions { | 63 namespace extensions { |
| 57 | 64 |
| 58 bool ExtensionContextMenuFunction::ParseContexts( | 65 bool CreateContextMenuFunction::RunImpl() { |
| 59 const DictionaryValue& properties, | 66 MenuItem::Id id(profile()->IsOffTheRecord(), extension_id()); |
| 60 const char* key, | 67 scoped_ptr<Create::Params> params(Create::Params::Create(*args_)); |
| 61 MenuItem::ContextList* result) { | 68 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 62 ListValue* list = NULL; | |
| 63 if (!properties.GetList(key, &list)) { | |
| 64 return true; | |
| 65 } | |
| 66 MenuItem::ContextList tmp_result; | |
| 67 | 69 |
| 68 std::string value; | 70 if (params->create_properties.id.get()) { |
| 69 for (size_t i = 0; i < list->GetSize(); i++) { | 71 id.string_uid = *params->create_properties.id; |
| 70 if (!list->GetString(i, &value)) | |
| 71 return false; | |
| 72 | |
| 73 if (value == "all") { | |
| 74 tmp_result.Add(MenuItem::ALL); | |
| 75 } else if (value == "page") { | |
| 76 tmp_result.Add(MenuItem::PAGE); | |
| 77 } else if (value == "selection") { | |
| 78 tmp_result.Add(MenuItem::SELECTION); | |
| 79 } else if (value == "link") { | |
| 80 tmp_result.Add(MenuItem::LINK); | |
| 81 } else if (value == "editable") { | |
| 82 tmp_result.Add(MenuItem::EDITABLE); | |
| 83 } else if (value == "image") { | |
| 84 tmp_result.Add(MenuItem::IMAGE); | |
| 85 } else if (value == "video") { | |
| 86 tmp_result.Add(MenuItem::VIDEO); | |
| 87 } else if (value == "audio") { | |
| 88 tmp_result.Add(MenuItem::AUDIO); | |
| 89 } else if (value == "frame") { | |
| 90 tmp_result.Add(MenuItem::FRAME); | |
| 91 } else { | |
| 92 error_ = ExtensionErrorUtils::FormatErrorMessage(kInvalidValueError, key); | |
| 93 return false; | |
| 94 } | |
| 95 } | |
| 96 *result = tmp_result; | |
| 97 return true; | |
| 98 } | |
| 99 | |
| 100 bool ExtensionContextMenuFunction::ParseType( | |
| 101 const DictionaryValue& properties, | |
| 102 const MenuItem::Type& default_value, | |
| 103 MenuItem::Type* result) { | |
| 104 DCHECK(result); | |
| 105 if (!properties.HasKey(kTypeKey)) { | |
| 106 *result = default_value; | |
| 107 return true; | |
| 108 } | |
| 109 | |
| 110 std::string type_string; | |
| 111 if (!properties.GetString(kTypeKey, &type_string)) | |
| 112 return false; | |
| 113 | |
| 114 if (type_string == "normal") { | |
| 115 *result = MenuItem::NORMAL; | |
| 116 } else if (type_string == "checkbox") { | |
| 117 *result = MenuItem::CHECKBOX; | |
| 118 } else if (type_string == "radio") { | |
| 119 *result = MenuItem::RADIO; | |
| 120 } else if (type_string == "separator") { | |
| 121 *result = MenuItem::SEPARATOR; | |
| 122 } else { | |
| 123 error_ = ExtensionErrorUtils::FormatErrorMessage(kInvalidTypeStringError, | |
| 124 type_string); | |
| 125 return false; | |
| 126 } | |
| 127 return true; | |
| 128 } | |
| 129 | |
| 130 bool ExtensionContextMenuFunction::ParseChecked( | |
| 131 MenuItem::Type type, | |
| 132 const DictionaryValue& properties, | |
| 133 bool default_value, | |
| 134 bool* checked) { | |
| 135 if (!properties.HasKey(kCheckedKey)) { | |
| 136 *checked = default_value; | |
| 137 return true; | |
| 138 } | |
| 139 if (!properties.GetBoolean(kCheckedKey, checked)) | |
| 140 return false; | |
| 141 if (checked && type != MenuItem::CHECKBOX && type != MenuItem::RADIO) { | |
| 142 error_ = kCheckedError; | |
| 143 return false; | |
| 144 } | |
| 145 return true; | |
| 146 } | |
| 147 | |
| 148 bool ExtensionContextMenuFunction::ParseID(const Value* value, | |
| 149 MenuItem::Id* result) { | |
| 150 return (value->GetAsInteger(&result->uid) || | |
| 151 value->GetAsString(&result->string_uid)); | |
| 152 } | |
| 153 | |
| 154 bool ExtensionContextMenuFunction::GetParent(const DictionaryValue& properties, | |
| 155 const MenuManager& manager, | |
| 156 MenuItem** result) { | |
| 157 if (!properties.HasKey(kParentIdKey)) | |
| 158 return true; | |
| 159 MenuItem::Id parent_id(profile()->IsOffTheRecord(), extension_id()); | |
| 160 Value* parent_id_value = NULL; | |
| 161 if (properties.Get(kParentIdKey, &parent_id_value) && | |
| 162 !ParseID(parent_id_value, &parent_id)) | |
| 163 return false; | |
| 164 | |
| 165 MenuItem* parent = manager.GetItemById(parent_id); | |
| 166 if (!parent) { | |
| 167 error_ = ExtensionErrorUtils::FormatErrorMessage( | |
| 168 kCannotFindItemError, GetIDString(parent_id)); | |
| 169 return false; | |
| 170 } | |
| 171 if (parent->type() != MenuItem::NORMAL) { | |
| 172 error_ = kParentsMustBeNormalError; | |
| 173 return false; | |
| 174 } | |
| 175 *result = parent; | |
| 176 return true; | |
| 177 } | |
| 178 | |
| 179 bool CreateContextMenuFunction::RunImpl() { | |
| 180 DictionaryValue* properties; | |
| 181 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &properties)); | |
| 182 EXTENSION_FUNCTION_VALIDATE(properties != NULL); | |
| 183 | |
| 184 MenuItem::Id id(profile()->IsOffTheRecord(), extension_id()); | |
| 185 if (properties->HasKey(kIdKey)) { | |
| 186 EXTENSION_FUNCTION_VALIDATE(properties->GetString(kIdKey, | |
| 187 &id.string_uid)); | |
| 188 } else { | 72 } else { |
| 189 if (GetExtension()->has_lazy_background_page()) { | 73 if (GetExtension()->has_lazy_background_page()) { |
| 190 error_ = kIdRequiredError; | 74 error_ = kIdRequiredError; |
| 191 return false; | 75 return false; |
| 192 } | 76 } |
| 77 | |
| 78 DictionaryValue* properties; | |
| 79 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &properties)); | |
| 80 EXTENSION_FUNCTION_VALIDATE(properties != NULL); | |
|
not at google - send to devlin
2012/07/26 04:16:20
this will never be NULL because properties wasn't
chebert
2012/07/27 01:28:24
This gets generated in the custom_bindings which a
not at google - send to devlin
2012/07/30 15:36:53
Yeah that's what I meant, but I thought of somethi
| |
| 193 EXTENSION_FUNCTION_VALIDATE(properties->GetInteger(kGeneratedIdKey, | 81 EXTENSION_FUNCTION_VALIDATE(properties->GetInteger(kGeneratedIdKey, |
| 194 &id.uid)); | 82 &id.uid)); |
| 195 } | 83 } |
| 196 | 84 |
| 197 std::string title; | 85 std::string title; |
| 198 if (properties->HasKey(kTitleKey) && | 86 if (params->create_properties.title.get()) |
| 199 !properties->GetString(kTitleKey, &title)) | 87 title = *params->create_properties.title; |
| 200 return false; | |
| 201 | 88 |
| 202 MenuManager* menu_manager = profile()->GetExtensionService()->menu_manager(); | 89 MenuManager* menu_manager = profile()->GetExtensionService()->menu_manager(); |
| 203 | 90 |
| 204 if (menu_manager->GetItemById(id)) { | 91 if (menu_manager->GetItemById(id)) { |
| 205 error_ = ExtensionErrorUtils::FormatErrorMessage(kDuplicateIDError, | 92 error_ = ExtensionErrorUtils::FormatErrorMessage(kDuplicateIDError, |
| 206 GetIDString(id)); | 93 GetIDString(id)); |
| 207 return false; | 94 return false; |
| 208 } | 95 } |
| 209 | 96 |
| 210 if (GetExtension()->has_lazy_background_page() && | 97 if (GetExtension()->has_lazy_background_page() && |
| 211 properties->HasKey(kOnclickKey)) { | 98 params->create_properties.onclick.get()) { |
| 212 error_ = kOnclickDisallowedError; | 99 error_ = kOnclickDisallowedError; |
| 213 return false; | 100 return false; |
| 214 } | 101 } |
| 215 | 102 |
| 216 MenuItem::ContextList contexts(MenuItem::PAGE); | 103 MenuItem::ContextList contexts(MenuItem::PAGE); |
| 217 if (!ParseContexts(*properties, kContextsKey, &contexts)) | 104 if (params->create_properties.contexts.get()) { |
| 218 return false; | 105 for (size_t i = 0; i < params->create_properties.contexts->size(); ++i) { |
| 106 Create::Params::CreateProperties::ContextsElement context = | |
| 107 params->create_properties.contexts->at(i); | |
|
not at google - send to devlin
2012/07/26 04:16:20
switch plz.
chebert
2012/07/27 01:28:24
Done.
| |
| 108 if (context == Create::Params::CreateProperties::CONTEXTS_ELEMENT_ALL) { | |
| 109 contexts.Add(MenuItem::ALL); | |
| 110 } else if (context == | |
| 111 Create::Params::CreateProperties::CONTEXTS_ELEMENT_PAGE) { | |
| 112 contexts.Add(MenuItem::PAGE); | |
| 113 } else if (context == | |
| 114 Create::Params::CreateProperties::CONTEXTS_ELEMENT_SELECTION) { | |
| 115 contexts.Add(MenuItem::SELECTION); | |
| 116 } else if (context == | |
| 117 Create::Params::CreateProperties::CONTEXTS_ELEMENT_LINK) { | |
| 118 contexts.Add(MenuItem::LINK); | |
| 119 } else if (context == | |
| 120 Create::Params::CreateProperties::CONTEXTS_ELEMENT_EDITABLE) { | |
| 121 contexts.Add(MenuItem::EDITABLE); | |
| 122 } else if (context == | |
| 123 Create::Params::CreateProperties::CONTEXTS_ELEMENT_IMAGE) { | |
| 124 contexts.Add(MenuItem::IMAGE); | |
| 125 } else if (context == | |
| 126 Create::Params::CreateProperties::CONTEXTS_ELEMENT_VIDEO) { | |
| 127 contexts.Add(MenuItem::VIDEO); | |
| 128 } else if (context == | |
| 129 Create::Params::CreateProperties::CONTEXTS_ELEMENT_AUDIO) { | |
| 130 contexts.Add(MenuItem::AUDIO); | |
| 131 } else if (context == | |
| 132 Create::Params::CreateProperties::CONTEXTS_ELEMENT_FRAME) { | |
| 133 contexts.Add(MenuItem::FRAME); | |
| 134 } else { | |
| 135 return false; | |
| 136 } | |
| 137 } | |
| 138 } | |
| 219 | 139 |
| 220 MenuItem::Type type; | 140 MenuItem::Type type; |
| 221 if (!ParseType(*properties, MenuItem::NORMAL, &type)) | 141 if (params->create_properties.type == |
| 222 return false; | 142 Create::Params::CreateProperties::TYPE_NONE || |
| 143 params->create_properties.type == | |
| 144 Create::Params::CreateProperties::TYPE_NORMAL) { | |
| 145 type = MenuItem::NORMAL; | |
| 146 } else if (params->create_properties.type == | |
| 147 Create::Params::CreateProperties::TYPE_CHECKBOX) { | |
| 148 type = MenuItem::CHECKBOX; | |
| 149 } else if (params->create_properties.type == | |
| 150 Create::Params::CreateProperties::TYPE_RADIO) { | |
| 151 type = MenuItem::RADIO; | |
| 152 } else if (params->create_properties.type == | |
| 153 Create::Params::CreateProperties::TYPE_SEPARATOR) { | |
| 154 type = MenuItem::SEPARATOR; | |
| 155 } | |
|
not at google - send to devlin
2012/07/26 04:16:20
switch here too
chebert
2012/07/27 01:28:24
Done.
| |
| 223 | 156 |
| 224 if (title.empty() && type != MenuItem::SEPARATOR) { | 157 if (title.empty() && type != MenuItem::SEPARATOR) { |
| 225 error_ = kTitleNeededError; | 158 error_ = kTitleNeededError; |
| 226 return false; | 159 return false; |
| 227 } | 160 } |
| 228 | 161 |
| 229 bool checked; | 162 bool checked = false; |
| 230 if (!ParseChecked(type, *properties, false, &checked)) | 163 if (params->create_properties.checked.get()) |
| 231 return false; | 164 checked = *params->create_properties.checked; |
| 232 | 165 |
| 233 bool enabled = true; | 166 bool enabled = true; |
| 234 if (properties->HasKey(kEnabledKey)) | 167 if (params->create_properties.enabled.get()) |
| 235 EXTENSION_FUNCTION_VALIDATE(properties->GetBoolean(kEnabledKey, &enabled)); | 168 enabled = *params->create_properties.enabled; |
| 236 | 169 |
| 237 scoped_ptr<MenuItem> item( | 170 scoped_ptr<MenuItem> item( |
| 238 new MenuItem(id, title, checked, enabled, type, contexts)); | 171 new MenuItem(id, title, checked, enabled, type, contexts)); |
| 239 | 172 |
| 173 scoped_ptr<ListValue> document_url_patterns; | |
|
not at google - send to devlin
2012/07/26 04:16:20
This is just converting back to the typeless data
chebert
2012/07/27 01:28:24
Done.
| |
| 174 scoped_ptr<ListValue> target_url_patterns; | |
| 175 if (params->create_properties.document_url_patterns.get()) { | |
| 176 document_url_patterns.reset(new ListValue()); | |
| 177 for (size_t i = 0; | |
| 178 i < params->create_properties.document_url_patterns->size(); | |
| 179 ++i) { | |
| 180 document_url_patterns->Append(Value::CreateStringValue( | |
| 181 params->create_properties.document_url_patterns->at(i))); | |
| 182 } | |
| 183 } | |
| 184 if (params->create_properties.target_url_patterns.get()) { | |
| 185 target_url_patterns.reset(new ListValue()); | |
| 186 for (size_t i = 0; | |
| 187 i < params->create_properties.target_url_patterns->size(); | |
| 188 ++i) { | |
| 189 document_url_patterns->Append(Value::CreateStringValue( | |
| 190 params->create_properties.target_url_patterns->at(i))); | |
| 191 } | |
| 192 } | |
| 240 if (!item->PopulateURLPatterns( | 193 if (!item->PopulateURLPatterns( |
| 241 *properties, kDocumentUrlPatternsKey, kTargetUrlPatternsKey, &error_)) | 194 document_url_patterns.get(), target_url_patterns.get(), &error_)) { |
| 242 return false; | 195 return false; |
| 196 } | |
| 243 | 197 |
| 244 bool success = true; | 198 bool success = true; |
| 245 if (properties->HasKey(kParentIdKey)) { | 199 if (params->create_properties.parent_id_type != |
|
not at google - send to devlin
2012/07/26 04:16:20
can this be switched over too?
This looks very bo
chebert
2012/07/27 01:28:24
Switchy...
On 2012/07/26 04:16:20, kalman wrote:
| |
| 246 MenuItem* parent = NULL; | 200 Create::Params::CreateProperties::PARENT_ID_NONE) { |
| 247 if (!GetParent(*properties, *menu_manager, &parent)) | 201 MenuItem::Id parent_id(profile()->IsOffTheRecord(), extension_id()); |
| 202 if (params->create_properties.parent_id_type == | |
| 203 Create::Params::CreateProperties::PARENT_ID_INTEGER) { | |
| 204 parent_id.uid = *params->create_properties.parent_id_integer; | |
| 205 } else if (params->create_properties.parent_id_type == | |
| 206 Create::Params::CreateProperties::PARENT_ID_STRING) { | |
| 207 parent_id.string_uid = *params->create_properties.parent_id_string; | |
| 208 } | |
| 209 MenuItem* parent = menu_manager->GetItemById(parent_id); | |
| 210 if (!parent) { | |
| 211 error_ = ExtensionErrorUtils::FormatErrorMessage( | |
| 212 kCannotFindItemError, GetIDString(parent_id)); | |
| 248 return false; | 213 return false; |
| 214 } | |
| 215 if (parent->type() != MenuItem::NORMAL) { | |
| 216 error_ = kParentsMustBeNormalError; | |
| 217 return false; | |
| 218 } | |
| 219 | |
| 249 success = menu_manager->AddChildItem(parent->id(), item.release()); | 220 success = menu_manager->AddChildItem(parent->id(), item.release()); |
| 250 } else { | 221 } else { |
| 251 success = menu_manager->AddContextItem(GetExtension(), item.release()); | 222 success = menu_manager->AddContextItem(GetExtension(), item.release()); |
| 252 } | 223 } |
| 253 | 224 |
| 254 if (!success) | 225 if (!success) |
| 255 return false; | 226 return false; |
| 256 | 227 |
| 257 menu_manager->WriteToStorage(GetExtension()); | 228 menu_manager->WriteToStorage(GetExtension()); |
| 258 return true; | 229 return true; |
| 259 } | 230 } |
| 260 | 231 |
| 261 bool UpdateContextMenuFunction::RunImpl() { | 232 bool UpdateContextMenuFunction::RunImpl() { |
| 262 bool radioItemUpdated = false; | 233 bool radioItemUpdated = false; |
| 263 MenuItem::Id item_id(profile()->IsOffTheRecord(), extension_id()); | 234 MenuItem::Id item_id(profile()->IsOffTheRecord(), extension_id()); |
| 264 Value* id_value = NULL; | 235 scoped_ptr<Update::Params> params(Update::Params::Create(*args_)); |
| 265 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &id_value)); | 236 |
| 266 EXTENSION_FUNCTION_VALIDATE(ParseID(id_value, &item_id)); | 237 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 238 if (params->id_type == Update::Params::ID_STRING) | |
| 239 item_id.string_uid = *params->id_string; | |
| 240 else if (params->id_type == Update::Params::ID_INTEGER) | |
| 241 item_id.uid = *params->id_integer; | |
|
not at google - send to devlin
2012/07/26 04:16:20
switch
chebert
2012/07/27 01:28:24
Done.
| |
| 267 | 242 |
| 268 ExtensionService* service = profile()->GetExtensionService(); | 243 ExtensionService* service = profile()->GetExtensionService(); |
| 269 MenuManager* manager = service->menu_manager(); | 244 MenuManager* manager = service->menu_manager(); |
| 270 MenuItem* item = manager->GetItemById(item_id); | 245 MenuItem* item = manager->GetItemById(item_id); |
| 271 if (!item || item->extension_id() != extension_id()) { | 246 if (!item || item->extension_id() != extension_id()) { |
| 272 error_ = ExtensionErrorUtils::FormatErrorMessage( | 247 error_ = ExtensionErrorUtils::FormatErrorMessage( |
| 273 kCannotFindItemError, GetIDString(item_id)); | 248 kCannotFindItemError, GetIDString(item_id)); |
| 274 return false; | 249 return false; |
| 275 } | 250 } |
| 276 | 251 |
| 277 DictionaryValue* properties = NULL; | |
| 278 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &properties)); | |
| 279 EXTENSION_FUNCTION_VALIDATE(properties != NULL); | |
| 280 | |
| 281 // Type. | 252 // Type. |
| 282 MenuItem::Type type; | 253 if (params->update_properties.type != |
| 283 if (!ParseType(*properties, item->type(), &type)) | 254 Update::Params::UpdateProperties::TYPE_NONE) { |
|
not at google - send to devlin
2012/07/26 04:16:20
switch
chebert
2012/07/27 01:28:24
Done.
| |
| 284 return false; | 255 MenuItem::Type type; |
| 285 if (type != item->type()) { | 256 if (params->update_properties.type == |
| 286 if (type == MenuItem::RADIO || item->type() == MenuItem::RADIO) { | 257 Update::Params::UpdateProperties::TYPE_NORMAL) { |
| 287 radioItemUpdated = true; | 258 type = MenuItem::NORMAL; |
| 259 } else if (params->update_properties.type == | |
| 260 Update::Params::UpdateProperties::TYPE_CHECKBOX) { | |
| 261 type = MenuItem::CHECKBOX; | |
| 262 } else if (params->update_properties.type == | |
| 263 Update::Params::UpdateProperties::TYPE_RADIO) { | |
| 264 type = MenuItem::RADIO; | |
| 265 } else if (params->update_properties.type == | |
| 266 Update::Params::UpdateProperties::TYPE_SEPARATOR) { | |
| 267 type = MenuItem::SEPARATOR; | |
| 288 } | 268 } |
| 289 item->set_type(type); | 269 if (type != item->type()) { |
| 270 if (type == MenuItem::RADIO || item->type() == MenuItem::RADIO) { | |
| 271 radioItemUpdated = true; | |
| 272 } | |
| 273 item->set_type(type); | |
| 274 } | |
| 290 } | 275 } |
| 291 | 276 |
| 292 // Title. | 277 // Title. |
| 293 if (properties->HasKey(kTitleKey)) { | 278 if (params->update_properties.title.get()) { |
| 294 std::string title; | 279 std::string title(*params->update_properties.title); |
| 295 EXTENSION_FUNCTION_VALIDATE(properties->GetString(kTitleKey, &title)); | 280 if (title.empty() && item->type() != MenuItem::SEPARATOR) { |
| 296 if (title.empty() && type != MenuItem::SEPARATOR) { | |
| 297 error_ = kTitleNeededError; | 281 error_ = kTitleNeededError; |
| 298 return false; | 282 return false; |
| 299 } | 283 } |
| 300 item->set_title(title); | 284 item->set_title(title); |
| 301 } | 285 } |
| 302 | 286 |
| 303 // Checked state. | 287 // Checked state. |
| 304 bool checked; | 288 if (params->update_properties.checked.get()) { |
| 305 if (!ParseChecked(item->type(), *properties, item->checked(), &checked)) | 289 bool checked; |
| 306 return false; | 290 checked = *params->update_properties.checked; |
|
not at google - send to devlin
2012/07/26 04:16:20
combine with line above?
chebert
2012/07/27 01:28:24
Done.
| |
| 307 if (checked != item->checked()) { | 291 if (checked && item->type() != MenuItem::CHECKBOX && |
| 308 if (!item->SetChecked(checked)) | 292 item->type() != MenuItem::RADIO) { |
| 293 error_ = kCheckedError; | |
| 309 return false; | 294 return false; |
| 310 radioItemUpdated = true; | 295 } |
| 296 if (checked != item->checked()) { | |
| 297 if (!item->SetChecked(checked)) { | |
| 298 error_ = kCheckedError; | |
| 299 return false; | |
| 300 } | |
| 301 radioItemUpdated = true; | |
| 302 } | |
| 311 } | 303 } |
| 312 | 304 |
| 313 // Enabled. | 305 // Enabled. |
| 314 bool enabled; | 306 if (params->update_properties.enabled.get()) |
| 315 if (properties->HasKey(kEnabledKey)) { | 307 item->set_enabled(*params->update_properties.enabled); |
| 316 EXTENSION_FUNCTION_VALIDATE(properties->GetBoolean(kEnabledKey, &enabled)); | |
| 317 item->set_enabled(enabled); | |
| 318 } | |
| 319 | 308 |
| 320 // Contexts. | 309 // Contexts. |
| 321 MenuItem::ContextList contexts(item->contexts()); | 310 MenuItem::ContextList contexts; |
| 322 if (!ParseContexts(*properties, kContextsKey, &contexts)) | 311 if (params->update_properties.contexts.get()) { |
| 323 return false; | 312 for (size_t i = 0; i < params->update_properties.contexts->size(); ++i) { |
| 324 if (contexts != item->contexts()) | 313 Update::Params::UpdateProperties::ContextsElement context = |
|
not at google - send to devlin
2012/07/26 04:16:20
switch.
Didn't we talk about pulling the enum int
chebert
2012/07/27 01:28:24
I want to do that, but I looked into that, and I t
| |
| 325 item->set_contexts(contexts); | 314 params->update_properties.contexts->at(i); |
| 315 if (context == Update::Params::UpdateProperties::CONTEXTS_ELEMENT_ALL) { | |
| 316 contexts.Add(MenuItem::ALL); | |
| 317 } else if (context == | |
| 318 Update::Params::UpdateProperties::CONTEXTS_ELEMENT_PAGE) { | |
| 319 contexts.Add(MenuItem::PAGE); | |
| 320 } else if (context == | |
| 321 Update::Params::UpdateProperties::CONTEXTS_ELEMENT_SELECTION) { | |
| 322 contexts.Add(MenuItem::SELECTION); | |
| 323 } else if (context == | |
| 324 Update::Params::UpdateProperties::CONTEXTS_ELEMENT_LINK) { | |
| 325 contexts.Add(MenuItem::LINK); | |
| 326 } else if (context == | |
| 327 Update::Params::UpdateProperties::CONTEXTS_ELEMENT_EDITABLE) { | |
| 328 contexts.Add(MenuItem::EDITABLE); | |
| 329 } else if (context == | |
| 330 Update::Params::UpdateProperties::CONTEXTS_ELEMENT_IMAGE) { | |
| 331 contexts.Add(MenuItem::IMAGE); | |
| 332 } else if (context == | |
| 333 Update::Params::UpdateProperties::CONTEXTS_ELEMENT_VIDEO) { | |
| 334 contexts.Add(MenuItem::VIDEO); | |
| 335 } else if (context == | |
| 336 Update::Params::UpdateProperties::CONTEXTS_ELEMENT_AUDIO) { | |
| 337 contexts.Add(MenuItem::AUDIO); | |
| 338 } else if (context == | |
| 339 Update::Params::UpdateProperties::CONTEXTS_ELEMENT_FRAME) { | |
| 340 contexts.Add(MenuItem::FRAME); | |
| 341 } | |
| 342 } | |
| 343 if (contexts != item->contexts()) | |
| 344 item->set_contexts(contexts); | |
| 345 } | |
| 326 | 346 |
| 327 // Parent id. | 347 // Parent id. |
| 328 MenuItem* parent = NULL; | 348 MenuItem* parent = NULL; |
| 329 if (!GetParent(*properties, *manager, &parent)) | 349 if (params->update_properties.parent_id_type != |
|
not at google - send to devlin
2012/07/26 04:16:20
switch or something
chebert
2012/07/27 01:28:24
Done.
| |
| 350 Update::Params::UpdateProperties::PARENT_ID_NONE) { | |
| 351 MenuItem::Id parent_id(profile()->IsOffTheRecord(), extension_id()); | |
| 352 if (params->update_properties.parent_id_type == | |
| 353 Update::Params::UpdateProperties::PARENT_ID_STRING) { | |
| 354 parent_id.string_uid = *params->update_properties.parent_id_string; | |
| 355 } else if (params->update_properties.parent_id_type == | |
| 356 Update::Params::UpdateProperties::PARENT_ID_INTEGER) { | |
| 357 parent_id.uid = *params->update_properties.parent_id_integer; | |
| 358 } | |
| 359 parent = manager->GetItemById(parent_id); | |
| 360 if (!parent) { | |
| 361 error_ = ExtensionErrorUtils::FormatErrorMessage( | |
| 362 kCannotFindItemError, GetIDString(parent_id)); | |
| 363 return false; | |
| 364 } | |
| 365 if (parent->type() != MenuItem::NORMAL) { | |
| 366 error_ = kParentsMustBeNormalError; | |
| 367 return false; | |
| 368 } | |
| 369 if (parent && !manager->ChangeParent(item->id(), &parent->id())) | |
| 370 return false; | |
| 371 } | |
| 372 | |
| 373 // URL Patterns. | |
| 374 scoped_ptr<ListValue> document_url_patterns; | |
| 375 scoped_ptr<ListValue> target_url_patterns; | |
| 376 if (params->update_properties.document_url_patterns.get()) { | |
|
not at google - send to devlin
2012/07/26 04:16:20
same deal with passing through the vectors
chebert
2012/07/27 01:28:24
Done.
| |
| 377 document_url_patterns.reset(new ListValue()); | |
| 378 for (size_t i = 0; | |
| 379 i < params->update_properties.document_url_patterns->size(); | |
| 380 ++i) { | |
| 381 document_url_patterns->Append(Value::CreateStringValue( | |
| 382 params->update_properties.document_url_patterns->at(i))); | |
| 383 } | |
| 384 } | |
| 385 if (params->update_properties.target_url_patterns.get()) { | |
| 386 target_url_patterns.reset(new ListValue()); | |
| 387 for (size_t i = 0; | |
| 388 i < params->update_properties.target_url_patterns->size(); | |
| 389 ++i) { | |
| 390 document_url_patterns->Append(Value::CreateStringValue( | |
| 391 params->update_properties.target_url_patterns->at(i))); | |
| 392 } | |
| 393 } | |
| 394 if (!item->PopulateURLPatterns( | |
| 395 document_url_patterns.get(), target_url_patterns.get(), &error_)) { | |
| 330 return false; | 396 return false; |
| 331 if (parent && !manager->ChangeParent(item->id(), &parent->id())) | 397 } |
| 332 return false; | |
| 333 | |
| 334 if (!item->PopulateURLPatterns( | |
| 335 *properties, kDocumentUrlPatternsKey, kTargetUrlPatternsKey, &error_)) | |
| 336 return false; | |
| 337 | 398 |
| 338 // There is no need to call ItemUpdated if ChangeParent is called because | 399 // There is no need to call ItemUpdated if ChangeParent is called because |
| 339 // all sanitation is taken care of in ChangeParent. | 400 // all sanitation is taken care of in ChangeParent. |
| 340 if (!parent && radioItemUpdated && !manager->ItemUpdated(item->id())) | 401 if (!parent && radioItemUpdated && !manager->ItemUpdated(item->id())) |
| 341 return false; | 402 return false; |
| 342 | 403 |
| 343 manager->WriteToStorage(GetExtension()); | 404 manager->WriteToStorage(GetExtension()); |
| 344 return true; | 405 return true; |
| 345 } | 406 } |
| 346 | 407 |
| 347 bool RemoveContextMenuFunction::RunImpl() { | 408 bool RemoveContextMenuFunction::RunImpl() { |
| 348 MenuItem::Id id(profile()->IsOffTheRecord(), extension_id()); | 409 MenuItem::Id id(profile()->IsOffTheRecord(), extension_id()); |
| 349 Value* id_value = NULL; | 410 |
| 350 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &id_value)); | 411 scoped_ptr<Remove::Params> params(Remove::Params::Create(*args_)); |
| 351 EXTENSION_FUNCTION_VALIDATE(ParseID(id_value, &id)); | 412 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 413 | |
| 414 if (params->menu_item_id_type == Remove::Params::MENU_ITEM_ID_STRING) | |
| 415 id.string_uid = *params->menu_item_id_string; | |
| 416 else if (params->menu_item_id_type == Remove::Params::MENU_ITEM_ID_INTEGER) | |
|
not at google - send to devlin
2012/07/26 04:16:20
switch
chebert
2012/07/27 01:28:24
Done.
| |
| 417 id.uid = *params->menu_item_id_integer; | |
| 418 | |
| 352 ExtensionService* service = profile()->GetExtensionService(); | 419 ExtensionService* service = profile()->GetExtensionService(); |
| 353 MenuManager* manager = service->menu_manager(); | 420 MenuManager* manager = service->menu_manager(); |
| 354 | 421 |
| 355 MenuItem* item = manager->GetItemById(id); | 422 MenuItem* item = manager->GetItemById(id); |
| 356 // Ensure one extension can't remove another's menu items. | 423 // Ensure one extension can't remove another's menu items. |
| 357 if (!item || item->extension_id() != extension_id()) { | 424 if (!item || item->extension_id() != extension_id()) { |
| 358 error_ = ExtensionErrorUtils::FormatErrorMessage( | 425 error_ = ExtensionErrorUtils::FormatErrorMessage( |
| 359 kCannotFindItemError, GetIDString(id)); | 426 kCannotFindItemError, GetIDString(id)); |
| 360 return false; | 427 return false; |
| 361 } | 428 } |
| 362 | 429 |
| 363 if (!manager->RemoveContextMenuItem(id)) | 430 if (!manager->RemoveContextMenuItem(id)) |
| 364 return false; | 431 return false; |
| 365 manager->WriteToStorage(GetExtension()); | 432 manager->WriteToStorage(GetExtension()); |
| 366 return true; | 433 return true; |
| 367 } | 434 } |
| 368 | 435 |
| 369 bool RemoveAllContextMenusFunction::RunImpl() { | 436 bool RemoveAllContextMenusFunction::RunImpl() { |
| 370 ExtensionService* service = profile()->GetExtensionService(); | 437 ExtensionService* service = profile()->GetExtensionService(); |
| 371 MenuManager* manager = service->menu_manager(); | 438 MenuManager* manager = service->menu_manager(); |
| 372 manager->RemoveAllContextItems(GetExtension()->id()); | 439 manager->RemoveAllContextItems(GetExtension()->id()); |
| 373 manager->WriteToStorage(GetExtension()); | 440 manager->WriteToStorage(GetExtension()); |
| 374 return true; | 441 return true; |
| 375 } | 442 } |
| 376 | 443 |
| 377 } // namespace extensions | 444 } // namespace extensions |
| OLD | NEW |