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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/extensions/api/context_menus/context_menus_api.h" 6 7 #include <string> 8 9 #include "base/strings/string_util.h" 10 #include "base/values.h" 11 #include "chrome/browser/extensions/api/context_menus/context_menus_api_helpers.h" 12 #include "chrome/browser/extensions/menu_manager.h" 13 #include "chrome/browser/profiles/profile.h" 14 #include "chrome/common/extensions/api/context_menus.h" 15 #include "extensions/common/error_utils.h" 16 #include "extensions/common/manifest_handlers/background_info.h" 17 #include "extensions/common/url_pattern_set.h" 18 19 using extensions::ErrorUtils; 20 namespace helpers = extensions::context_menus_api_helpers; 21 22 namespace { 23 24 const char kIdRequiredError[] = "Extensions using event pages must pass an " 25 "id parameter to chrome.contextMenus.create"; 26 27 } // namespace 28 29 namespace extensions { 30 31 namespace Create = api::context_menus::Create; 32 namespace Remove = api::context_menus::Remove; 33 namespace Update = api::context_menus::Update; 34 35 bool ContextMenusCreateFunction::RunSync() { 36 MenuItem::Id id(GetProfile()->IsOffTheRecord(), 37 MenuItem::ExtensionKey(extension_id())); 38 scoped_ptr<Create::Params> params(Create::Params::Create(*args_)); 39 EXTENSION_FUNCTION_VALIDATE(params.get()); 40 41 if (params->create_properties.id.get()) { 42 id.string_uid = *params->create_properties.id; 43 } else { 44 if (BackgroundInfo::HasLazyBackgroundPage(extension())) { 45 error_ = kIdRequiredError; 46 return false; 47 } 48 49 // The Generated Id is added by context_menus_custom_bindings.js. 50 base::DictionaryValue* properties = NULL; 51 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &properties)); 52 EXTENSION_FUNCTION_VALIDATE( 53 properties->GetInteger(helpers::kGeneratedIdKey, &id.uid)); 54 } 55 56 return helpers::CreateMenuItem( 57 params->create_properties, GetProfile(), extension(), id, &error_); 58 } 59 60 bool ContextMenusUpdateFunction::RunSync() { 61 MenuItem::Id item_id(GetProfile()->IsOffTheRecord(), 62 MenuItem::ExtensionKey(extension_id())); 63 scoped_ptr<Update::Params> params(Update::Params::Create(*args_)); 64 65 EXTENSION_FUNCTION_VALIDATE(params.get()); 66 if (params->id.as_string) 67 item_id.string_uid = *params->id.as_string; 68 else if (params->id.as_integer) 69 item_id.uid = *params->id.as_integer; 70 else 71 NOTREACHED(); 72 73 return helpers::UpdateMenuItem( 74 params->update_properties, GetProfile(), extension(), item_id, &error_); 75 } 76 77 bool ContextMenusRemoveFunction::RunSync() { 78 scoped_ptr<Remove::Params> params(Remove::Params::Create(*args_)); 79 EXTENSION_FUNCTION_VALIDATE(params.get()); 80 81 MenuManager* manager = MenuManager::Get(GetProfile()); 82 83 MenuItem::Id id(GetProfile()->IsOffTheRecord(), 84 MenuItem::ExtensionKey(extension_id())); 85 if (params->menu_item_id.as_string) 86 id.string_uid = *params->menu_item_id.as_string; 87 else if (params->menu_item_id.as_integer) 88 id.uid = *params->menu_item_id.as_integer; 89 else 90 NOTREACHED(); 91 92 MenuItem* item = manager->GetItemById(id); 93 // Ensure one extension can't remove another's menu items. 94 if (!item || item->extension_id() != extension_id()) { 95 error_ = ErrorUtils::FormatErrorMessage( 96 helpers::kCannotFindItemError, helpers::GetIDString(id)); 97 return false; 98 } 99 100 if (!manager->RemoveContextMenuItem(id)) 101 return false; 102 manager->WriteToStorage(extension(), id.extension_key); 103 return true; 104 } 105 106 bool ContextMenusRemoveAllFunction::RunSync() { 107 MenuManager* manager = MenuManager::Get(GetProfile()); 108 manager->RemoveAllContextItems(MenuItem::ExtensionKey(extension()->id())); 109 manager->WriteToStorage(extension(), 110 MenuItem::ExtensionKey(extension()->id())); 111 return true; 112 } 113 114 } // namespace extensions 115