diff options
11 files changed, 364 insertions, 144 deletions
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi index 0ec191b..78d14ff 100644 --- a/chrome/chrome_renderer.gypi +++ b/chrome/chrome_renderer.gypi @@ -1,4 +1,4 @@ -# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -72,6 +72,10 @@ 'renderer/extensions/chrome_v8_extension_handler.h', 'renderer/extensions/chrome_webstore_bindings.cc', 'renderer/extensions/chrome_webstore_bindings.h', + 'renderer/extensions/contextMenus_custom_bindings.cc', + 'renderer/extensions/contextMenus_custom_bindings.h', + 'renderer/extensions/custom_bindings_util.cc', + 'renderer/extensions/custom_bindings_util.h', 'renderer/extensions/event_bindings.cc', 'renderer/extensions/event_bindings.h', 'renderer/extensions/extension_dispatcher.cc', @@ -106,6 +110,7 @@ 'renderer/resources/extensions/greasemonkey_api.js', 'renderer/resources/extensions/json_schema.js', 'renderer/resources/extensions/miscellaneous_bindings.js', + 'renderer/resources/extensions/contextMenus_custom_bindings.js', 'renderer/resources/extensions/schema_generated_bindings.js', 'renderer/about_handler.cc', 'renderer/about_handler.h', diff --git a/chrome/renderer/extensions/contextMenus_custom_bindings.cc b/chrome/renderer/extensions/contextMenus_custom_bindings.cc new file mode 100644 index 0000000..a1b5049 --- /dev/null +++ b/chrome/renderer/extensions/contextMenus_custom_bindings.cc @@ -0,0 +1,38 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/renderer/extensions/contextMenus_custom_bindings.h" + +#include "grit/renderer_resources.h" +#include "v8/include/v8.h" + +namespace extensions { + +ContextMenusCustomBindings::ContextMenusCustomBindings( + int dependency_count, + const char** dependencies) + : ChromeV8Extension( + "extensions/contextMenus_custom_bindings.js", + IDR_CONTEXTMENUS_CUSTOM_BINDINGS_JS, + dependency_count, + dependencies, + NULL) {} + +static v8::Handle<v8::Value> GetNextContextMenuId(const v8::Arguments& args) { + // Note: this works because contextMenus.create() only works in the + // extension process. If that API is opened up to content scripts, this + // will need to change. See crbug.com/77023 + static int next_context_menu_id = 1; + return v8::Integer::New(next_context_menu_id++); +} + +v8::Handle<v8::FunctionTemplate> ContextMenusCustomBindings::GetNativeFunction( + v8::Handle<v8::String> name) { + if (name->Equals(v8::String::New("GetNextContextMenuId"))) + return v8::FunctionTemplate::New(GetNextContextMenuId); + + return ChromeV8Extension::GetNativeFunction(name); +} + +} // extensions diff --git a/chrome/renderer/extensions/contextMenus_custom_bindings.h b/chrome/renderer/extensions/contextMenus_custom_bindings.h new file mode 100644 index 0000000..8acd2bd --- /dev/null +++ b/chrome/renderer/extensions/contextMenus_custom_bindings.h @@ -0,0 +1,24 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_RENDERER_EXTENSIONS_CONTEXTMENUS_CUSTOM_BINDINGS_H_ +#define CHROME_RENDERER_EXTENSIONS_CONTEXTMENUS_CUSTOM_BINDINGS_H_ +#pragma once + +#include "chrome/renderer/extensions/chrome_v8_extension.h" + +namespace extensions { + +// Implements custom bindings for the contextMenus API. +class ContextMenusCustomBindings : public ChromeV8Extension { + public: + ContextMenusCustomBindings(int dependency_count, const char** dependencies); + + virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( + v8::Handle<v8::String> name) OVERRIDE; +}; + +} // extensions + +#endif // CHROME_RENDERER_EXTENSIONS_CONTEXTMENUS_CUSTOM_BINDINGS_H_ diff --git a/chrome/renderer/extensions/custom_bindings_util.cc b/chrome/renderer/extensions/custom_bindings_util.cc new file mode 100644 index 0000000..c17740f --- /dev/null +++ b/chrome/renderer/extensions/custom_bindings_util.cc @@ -0,0 +1,70 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/renderer/extensions/custom_bindings_util.h" + +#include <map> + +#include "base/string_util.h" +#include "chrome/common/extensions/extension.h" +#include "chrome/renderer/extensions/chrome_v8_extension.h" +#include "chrome/renderer/extensions/contextMenus_custom_bindings.h" +#include "base/logging.h" +#include "grit/renderer_resources.h" +#include "v8/include/v8.h" + +namespace extensions { + +namespace custom_bindings_util { + +std::vector<v8::Extension*> GetAll() { + static const char* kDependencies[] = { + "extensions/schema_generated_bindings.js", + }; + static const size_t kDependencyCount = arraysize(kDependencies); + + std::vector<v8::Extension*> result; + + result.push_back( + new ContextMenusCustomBindings(kDependencyCount, kDependencies)); + + return result; +} + +// Extracts the name of an API from the name of the V8 extension which contains +// custom bindings for it (see kCustomBindingNames). +std::string GetAPIName(const std::string& v8_extension_name) { + // Extract the name of the API from the v8 extension name. + // This is "${api_name}" in "extensions/${api_name}_custom_bindings.js". + std::string prefix = "extensions/"; + const bool kCaseSensitive = true; + if (!StartsWithASCII(v8_extension_name, prefix, kCaseSensitive)) + return ""; + + std::string suffix = "_custom_bindings.js"; + if (!EndsWith(v8_extension_name, suffix, kCaseSensitive)) + return ""; + + return v8_extension_name.substr( + prefix.size(), + v8_extension_name.size() - prefix.size() - suffix.size()); +} + +bool AllowAPIInjection(const std::string& api_name, + const Extension& extension) { + CHECK(api_name != ""); + + // As in ExtensionAPI::GetSchemasForExtension, we need to allow any bindings + // for an API that the extension *might* have permission to use. + if (!extension.required_permission_set()->HasAnyAccessToAPI(api_name) && + !extension.optional_permission_set()->HasAnyAccessToAPI(api_name)) { + return false; + } + + return true; +} + +} // namespace custom_bindings_util + +} // namespace extensions diff --git a/chrome/renderer/extensions/custom_bindings_util.h b/chrome/renderer/extensions/custom_bindings_util.h new file mode 100644 index 0000000..9832386 --- /dev/null +++ b/chrome/renderer/extensions/custom_bindings_util.h @@ -0,0 +1,44 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_RENDERER_EXTENSIONS_CUSTOM_BINDINGS_UTIL_H_ +#define CHROME_RENDERER_EXTENSIONS_CUSTOM_BINDINGS_UTIL_H_ +#pragma once + +#include <string> +#include <vector> + +#include "chrome/renderer/extensions/chrome_v8_extension.h" + +class Extension; + +namespace v8 { +class Extension; +} + +namespace extensions { + +// Utilities for managing the set of V8 extensions for extension API custom +// bindings. +namespace custom_bindings_util { + +// Creates V8 extensions for all custom bindings. +std::vector<v8::Extension*> GetAll(); + +// Extracts the name of an API from the name of the V8 extension which contains +// custom bindings for it. +// Returns an empty string if the extension is not for a custom binding. +std::string GetAPIName(const std::string& v8_extension_name); + +// Returns whether the custom binding for an API should be allowed to run for +// |extension|. This is based on whether the extension has any permission +// (required or optional) for that API. +bool AllowAPIInjection(const std::string& api_name, + const Extension& extension); + +} // namespace custom_bindings_util + +} // namespace extensions + +#endif // CHROME_RENDERER_EXTENSIONS_CUSTOM_BINDINGS_UTIL_H_ diff --git a/chrome/renderer/extensions/extension_dispatcher.cc b/chrome/renderer/extensions/extension_dispatcher.cc index 13a0655..b1663cd 100644 --- a/chrome/renderer/extensions/extension_dispatcher.cc +++ b/chrome/renderer/extensions/extension_dispatcher.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -16,6 +16,7 @@ #include "chrome/renderer/extensions/chrome_v8_context.h" #include "chrome/renderer/extensions/chrome_v8_extension.h" #include "chrome/renderer/extensions/chrome_webstore_bindings.h" +#include "chrome/renderer/extensions/custom_bindings_util.h" #include "chrome/renderer/extensions/event_bindings.h" #include "chrome/renderer/extensions/extension_groups.h" #include "chrome/renderer/extensions/file_browser_private_bindings.h" @@ -39,8 +40,8 @@ static const int64 kInitialExtensionIdleHandlerDelayMs = 5*1000; static const int64 kMaxExtensionIdleHandlerDelayMs = 5*60*1000; } -using extensions::MiscellaneousBindings; -using extensions::SchemaGeneratedBindings; +using namespace extensions; + using WebKit::WebDataSource; using WebKit::WebDocument; using WebKit::WebFrame; @@ -115,6 +116,12 @@ void ExtensionDispatcher::WebKitInitialized() { RegisterExtension(new ChromeV8Extension( "extensions/apitest.js", IDR_EXTENSION_APITEST_JS, NULL), true); + std::vector<v8::Extension*> custom_bindings = custom_bindings_util::GetAll(); + for (std::vector<v8::Extension*>::iterator it = custom_bindings.begin(); + it != custom_bindings.end(); ++it) { + RegisterExtension(*it, true); + } + // Initialize host permissions for any extensions that were activated before // WebKit was initialized. for (std::set<std::string>::iterator iter = active_extension_ids_.begin(); @@ -286,6 +293,21 @@ bool ExtensionDispatcher::AllowScriptExtension( extensions_.ExtensionBindingsAllowed(ExtensionURLInfo( frame->document().securityOrigin(), UserScriptSlave::GetDataSourceURLForFrame(frame)))) { + // If the extension is a custom API binding, only allow if the extension + // has permission to use the API. + std::string custom_binding_api_name = + custom_bindings_util::GetAPIName(v8_extension_name); + if (!custom_binding_api_name.empty()) { + const Extension* extension = + extensions_.GetByID(GetExtensionID(frame, world_id)); + // TODO(kalman): there appears to be a race condition, particularly hit + // on windows tests, causing this check to fail. It should be a check. + if (!extension) + return true; + return custom_bindings_util::AllowAPIInjection( + custom_binding_api_name, *extension); + } + return true; } @@ -294,19 +316,8 @@ bool ExtensionDispatcher::AllowScriptExtension( void ExtensionDispatcher::DidCreateScriptContext( WebFrame* frame, v8::Handle<v8::Context> v8_context, int world_id) { - std::string extension_id; - if (!test_extension_id_.empty()) { - extension_id = test_extension_id_; - } else if (world_id != 0) { - extension_id = user_script_slave_->GetExtensionIdForIsolatedWorld(world_id); - } else { - GURL frame_url = UserScriptSlave::GetDataSourceURLForFrame(frame); - extension_id = extensions_.GetExtensionOrAppIDByURL( - ExtensionURLInfo(frame->document().securityOrigin(), frame_url)); - } - ChromeV8Context* context = - new ChromeV8Context(v8_context, frame, extension_id); + new ChromeV8Context(v8_context, frame, GetExtensionID(frame, world_id)); v8_context_set_.Add(context); context->DispatchOnLoadEvent( @@ -316,6 +327,20 @@ void ExtensionDispatcher::DidCreateScriptContext( VLOG(1) << "Num tracked contexts: " << v8_context_set_.size(); } +std::string ExtensionDispatcher::GetExtensionID(WebFrame* frame, int world_id) { + if (!test_extension_id_.empty()) { + return test_extension_id_; + } else if (world_id != 0) { + // Isolated worlds (content script). + return user_script_slave_->GetExtensionIdForIsolatedWorld(world_id); + } else { + // Extension pages (chrome-extension:// URLs). + GURL frame_url = UserScriptSlave::GetDataSourceURLForFrame(frame); + return extensions_.GetExtensionOrAppIDByURL( + ExtensionURLInfo(frame->document().securityOrigin(), frame_url)); + } +} + void ExtensionDispatcher::WillReleaseScriptContext( WebFrame* frame, v8::Handle<v8::Context> v8_context, int world_id) { ChromeV8Context* context = v8_context_set_.GetByV8Context(v8_context); diff --git a/chrome/renderer/extensions/extension_dispatcher.h b/chrome/renderer/extensions/extension_dispatcher.h index ea48e03..9796430 100644 --- a/chrome/renderer/extensions/extension_dispatcher.h +++ b/chrome/renderer/extensions/extension_dispatcher.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -137,6 +137,10 @@ class ExtensionDispatcher : public content::RenderProcessObserver { const Extension* extension, const URLPatternSet& origins); + // Finds the extension ID for the current context. This is determined from + // |world_id| if it's non-zero, or the URL in |frame| if it is. + std::string GetExtensionID(WebKit::WebFrame* frame, int world_id); + // True if this renderer is running extensions. bool is_extension_process_; diff --git a/chrome/renderer/extensions/schema_generated_bindings.cc b/chrome/renderer/extensions/schema_generated_bindings.cc index baf484c..bd6fd47 100644 --- a/chrome/renderer/extensions/schema_generated_bindings.cc +++ b/chrome/renderer/extensions/schema_generated_bindings.cc @@ -195,8 +195,6 @@ class ExtensionImpl : public ChromeV8Extension { return v8::FunctionTemplate::New(GetNextRequestId); } else if (name->Equals(v8::String::New("OpenChannelToTab"))) { return v8::FunctionTemplate::New(OpenChannelToTab); - } else if (name->Equals(v8::String::New("GetNextContextMenuId"))) { - return v8::FunctionTemplate::New(GetNextContextMenuId); } else if (name->Equals(v8::String::New("GetNextSocketEventId"))) { return v8::FunctionTemplate::New(GetNextSocketEventId); } else if (name->Equals(v8::String::New("GetNextTtsEventId"))) { @@ -477,14 +475,6 @@ class ExtensionImpl : public ChromeV8Extension { return v8::Undefined(); } - static v8::Handle<v8::Value> GetNextContextMenuId(const v8::Arguments& args) { - // Note: this works because contextMenus.create() only works in the - // extension process. If that API is opened up to content scripts, this - // will need to change. See crbug.com/77023 - static int next_context_menu_id = 1; - return v8::Integer::New(next_context_menu_id++); - } - static v8::Handle<v8::Value> GetNextTtsEventId(const v8::Arguments& args) { // Note: this works because the TTS API only works in the // extension process, not content scripts. diff --git a/chrome/renderer/renderer_resources.grd b/chrome/renderer/renderer_resources.grd index d241093..abdc5bd 100644 --- a/chrome/renderer/renderer_resources.grd +++ b/chrome/renderer/renderer_resources.grd @@ -21,6 +21,7 @@ without changes to the corresponding grd file. fb9 --> <include name="IDR_FILE_BROWSER_PRIVATE_BINDINGS_JS" file="resources\extensions\file_browser_private.js" type="BINDATA" /> <include name="IDR_GREASEMONKEY_API_JS" file="resources\extensions\greasemonkey_api.js" type="BINDATA" /> <include name="IDR_JSON_SCHEMA_JS" file="resources\extensions\json_schema.js" type="BINDATA" /> + <include name="IDR_CONTEXTMENUS_CUSTOM_BINDINGS_JS" file="resources\extensions\contextMenus_custom_bindings.js" type="BINDATA" /> <include name="IDR_MISCELLANEOUS_BINDINGS_JS" file="resources\extensions\miscellaneous_bindings.js" type="BINDATA" /> <include name="IDR_SCHEMA_GENERATED_BINDINGS_JS" file="resources\extensions\schema_generated_bindings.js" type="BINDATA" /> <include name="IDR_NET_ERROR_HTML" file="resources\neterror.html" flattenhtml="true" type="BINDATA" /> diff --git a/chrome/renderer/resources/extensions/contextMenus_custom_bindings.js b/chrome/renderer/resources/extensions/contextMenus_custom_bindings.js new file mode 100644 index 0000000..c425447 --- /dev/null +++ b/chrome/renderer/resources/extensions/contextMenus_custom_bindings.js @@ -0,0 +1,94 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Custom bindings for the contextMenus API. + +(function() { + +native function GetChromeHidden(); +native function GetNextContextMenuId(); + +var chromeHidden = GetChromeHidden(); +var apiFunctions = chromeHidden.schemaGeneratedBindings.apiFunctions; +var sendRequest = chromeHidden.schemaGeneratedBindings.sendRequest; + +chromeHidden.onLoad.addListener( + function(extensionId, isExtensionProcess, isIncognitoProcess) { + chromeHidden.contextMenus = {}; + chromeHidden.contextMenus.handlers = {}; + var eventName = "contextMenus"; + chromeHidden.contextMenus.event = new chrome.Event(eventName); + chromeHidden.contextMenus.ensureListenerSetup = function() { + if (chromeHidden.contextMenus.listening) { + return; + } + chromeHidden.contextMenus.listening = true; + chromeHidden.contextMenus.event.addListener(function() { + // An extension context menu item has been clicked on - fire the onclick + // if there is one. + var id = arguments[0].menuItemId; + var onclick = chromeHidden.contextMenus.handlers[id]; + if (onclick) { + onclick.apply(null, arguments); + } + }); + }; + + apiFunctions.setHandleRequest("contextMenus.create", function() { + var args = arguments; + var id = GetNextContextMenuId(); + args[0].generatedId = id; + sendRequest(this.name, + args, + this.definition.parameters, + {customCallback: this.customCallback}); + return id; + }); + + apiFunctions.setCustomCallback("contextMenus.create", + function(name, request, response) { + if (chrome.extension.lastError) { + return; + } + + var id = request.args[0].generatedId; + + // Set up the onclick handler if we were passed one in the request. + var onclick = request.args.length ? request.args[0].onclick : null; + if (onclick) { + chromeHidden.contextMenus.ensureListenerSetup(); + chromeHidden.contextMenus.handlers[id] = onclick; + } + }); + + apiFunctions.setCustomCallback("contextMenus.remove", + function(name, request, response) { + if (chrome.extension.lastError) { + return; + } + var id = request.args[0]; + delete chromeHidden.contextMenus.handlers[id]; + }); + + apiFunctions.setCustomCallback("contextMenus.update", + function(name, request, response) { + if (chrome.extension.lastError) { + return; + } + var id = request.args[0]; + if (request.args[1].onclick) { + chromeHidden.contextMenus.handlers[id] = request.args[1].onclick; + } + }); + + apiFunctions.setCustomCallback("contextMenus.removeAll", + function(name, request, response) { + if (chrome.extension.lastError) { + return; + } + chromeHidden.contextMenus.handlers = {}; + }); +}); + +})(); diff --git a/chrome/renderer/resources/extensions/schema_generated_bindings.js b/chrome/renderer/resources/extensions/schema_generated_bindings.js index 5b95e3c..1286a1b 100644 --- a/chrome/renderer/resources/extensions/schema_generated_bindings.js +++ b/chrome/renderer/resources/extensions/schema_generated_bindings.js @@ -17,7 +17,6 @@ var chrome = chrome || {}; native function GetCurrentPageActions(extensionId); native function GetExtensionViews(); native function GetLocalFileSystem(name, path); - native function GetNextContextMenuId(); native function GetNextSocketEventId(); native function GetNextTtsEventId(); native function GetUniqueSubEventName(eventName); @@ -195,6 +194,48 @@ var chrome = chrome || {}; opt_args.forIOThread); } + // Stores the name and definition of each API function, with methods to + // modify their behaviour (such as a custom way to handle requests to the + // API, a custom callback, etc). + function APIFunctions() { + this._apiFunctions = {}; + } + APIFunctions.prototype.register = function(apiName, apiFunction) { + this._apiFunctions[apiName] = apiFunction; + }; + APIFunctions.prototype._setHook = + function(apiName, propertyName, customizedFunction) { + if (this._apiFunctions.hasOwnProperty(apiName)) + this._apiFunctions[apiName][propertyName] = customizedFunction; + }; + APIFunctions.prototype.setHandleRequest = + function(apiName, customizedFunction) { + return this._setHook(apiName, 'handleRequest', customizedFunction); + }; + APIFunctions.prototype.setUpdateArgumentsPostValidate = + function(apiName, customizedFunction) { + return this._setHook( + apiName, 'updateArgumentsPostValidate', customizedFunction); + }; + APIFunctions.prototype.setUpdateArgumentsPreValidate = + function(apiName, customizedFunction) { + return this._setHook( + apiName, 'updateArgumentsPreValidate', customizedFunction); + }; + APIFunctions.prototype.setCustomCallback = + function(apiName, customizedFunction) { + return this._setHook(apiName, 'customCallback', customizedFunction); + }; + + var apiFunctions = new APIFunctions(); + + // The public API of schema_generated_bindings, to be used by custom bindings + // JS files. + chromeHidden.schemaGeneratedBindings = { + sendRequest: sendRequest, + apiFunctions: apiFunctions + }; + // --- Setup additional api's not currently handled in common/extensions/api // WebRequestEvent object. This is used for special webRequest events with @@ -454,28 +495,6 @@ var chrome = chrome || {}; } } - function setupHiddenContextMenuEvent(extensionId) { - chromeHidden.contextMenus = {}; - chromeHidden.contextMenus.handlers = {}; - var eventName = "contextMenus"; - chromeHidden.contextMenus.event = new chrome.Event(eventName); - chromeHidden.contextMenus.ensureListenerSetup = function() { - if (chromeHidden.contextMenus.listening) { - return; - } - chromeHidden.contextMenus.listening = true; - chromeHidden.contextMenus.event.addListener(function() { - // An extension context menu item has been clicked on - fire the onclick - // if there is one. - var id = arguments[0].menuItemId; - var onclick = chromeHidden.contextMenus.handlers[id]; - if (onclick) { - onclick.apply(null, arguments); - } - }); - }; - } - // Remove invalid characters from |text| so that it is suitable to use // for |AutocompleteMatch::contents|. function sanitizeString(text, shouldTrim) { @@ -641,44 +660,6 @@ var chrome = chrome || {}; } }); - // Stores the name and definition of each API function, with methods to - // modify their behaviour (such as a custom way to handle requests to the - // API, a custom callback, etc). - function APIFunctions() { - this.apiFunctions_ = {}; - } - APIFunctions.prototype.register = function(apiName, apiFunction) { - this.apiFunctions_[apiName] = apiFunction; - }; - APIFunctions.prototype.setProperty = - function(apiName, propertyName, customizedFunction) { - // TODO(kalman): later, when this is asynchronous and we're only - // customizing exactly what we need, these should be held onto until - // this api function is registered. - if (this.apiFunctions_.hasOwnProperty(apiName)) - this.apiFunctions_[apiName][propertyName] = customizedFunction; - }; - APIFunctions.prototype.setHandleRequest = - function(apiName, customizedFunction) { - return this.setProperty(apiName, 'handleRequest', customizedFunction); - }; - APIFunctions.prototype.setUpdateArgumentsPostValidate = - function(apiName, customizedFunction) { - return this.setProperty( - apiName, 'updateArgumentsPostValidate', customizedFunction); - }; - APIFunctions.prototype.setUpdateArgumentsPreValidate = - function(apiName, customizedFunction) { - return this.setProperty( - apiName, 'updateArgumentsPreValidate', customizedFunction); - }; - APIFunctions.prototype.setCustomCallback = - function(apiName, customizedFunction) { - return this.setProperty(apiName, 'customCallback', customizedFunction); - }; - - var apiFunctions = new APIFunctions(); - // Read api definitions and setup api functions in the chrome namespace. // TODO(rafaelw): Consider defining a json schema for an api definition // and validating either here, in a unit_test or both. @@ -1021,16 +1002,6 @@ var chrome = chrome || {}; details, this.name, this.definition.parameters, "page action"); }); - apiFunctions.setHandleRequest("contextMenus.create", - function() { - var args = arguments; - var id = GetNextContextMenuId(); - args[0].generatedId = id; - sendRequest(this.name, args, this.definition.parameters, - {customCallback: this.customCallback}); - return id; - }); - apiFunctions.setHandleRequest("omnibox.setDefaultSuggestion", function(details) { var parseResult = parseOmniboxDescription(details.description); @@ -1058,50 +1029,6 @@ var chrome = chrome || {}; {forIOThread: true}); }); - apiFunctions.setCustomCallback("contextMenus.create", - function(name, request, response) { - if (chrome.extension.lastError) { - return; - } - - var id = request.args[0].generatedId; - - // Set up the onclick handler if we were passed one in the request. - var onclick = request.args.length ? request.args[0].onclick : null; - if (onclick) { - chromeHidden.contextMenus.ensureListenerSetup(); - chromeHidden.contextMenus.handlers[id] = onclick; - } - }); - - apiFunctions.setCustomCallback("contextMenus.remove", - function(name, request, response) { - if (chrome.extension.lastError) { - return; - } - var id = request.args[0]; - delete chromeHidden.contextMenus.handlers[id]; - }); - - apiFunctions.setCustomCallback("contextMenus.update", - function(name, request, response) { - if (chrome.extension.lastError) { - return; - } - var id = request.args[0]; - if (request.args[1].onclick) { - chromeHidden.contextMenus.handlers[id] = request.args[1].onclick; - } - }); - - apiFunctions.setCustomCallback("contextMenus.removeAll", - function(name, request, response) { - if (chrome.extension.lastError) { - return; - } - chromeHidden.contextMenus.handlers = {}; - }); - // TODO(skerner,mtytel): The next step to omitting optional arguments is the // replacement of this code with code that matches arguments by type. // Once this is working for captureVisibleTab() it can be enabled for @@ -1219,8 +1146,6 @@ var chrome = chrome || {}; chrome.test.getApiDefinitions = GetExtensionAPIDefinition; } - if (apiExists("contextMenus")) - setupHiddenContextMenuEvent(extensionId); if (apiExists("experimental.input.ime")) setupInputEvents(); if (apiExists("omnibox")) |