diff options
author | dconnelly@chromium.org <dconnelly@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-04 12:11:21 +0000 |
---|---|---|
committer | dconnelly@chromium.org <dconnelly@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-04 12:11:21 +0000 |
commit | d46bd4d6b366af69c1dfaab0d6aef924d0c4cee9 (patch) | |
tree | 060cdb6b2f8fb34ae1812dbd00ef8dc3b21ad2bb /extensions | |
parent | 33743baa0cb90a708715160d01b3941284d16e6a (diff) | |
download | chromium_src-d46bd4d6b366af69c1dfaab0d6aef924d0c4cee9.zip chromium_src-d46bd4d6b366af69c1dfaab0d6aef924d0c4cee9.tar.gz chromium_src-d46bd4d6b366af69c1dfaab0d6aef924d0c4cee9.tar.bz2 |
Revert "Reland 274558 - Move some extensions renderer resources to extensions_renderer_resources.grd."
This reverts commit 43d0610ab216be636ccd80fe42ed338c326a6d81.
Broke Win build: http://build.chromium.org/p/chromium/builders/Win/builds/21536
BUG=none
TBR=yoz@chromium.org
Review URL: https://codereview.chromium.org/318683002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@274780 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'extensions')
31 files changed, 5 insertions, 4245 deletions
diff --git a/extensions/DEPS b/extensions/DEPS index d762dc4..f919975 100644 --- a/extensions/DEPS +++ b/extensions/DEPS @@ -2,7 +2,6 @@ include_rules = [ "+components/url_matcher", "+content/public/common", "+crypto", - "+grit/extensions_renderer_resources.h", "+grit/extensions_resources.h", "+testing", "+ui", @@ -14,6 +13,9 @@ include_rules = [ # # TODO(jamescook): Remove these. http://crbug.com/162530 "!chrome/browser/chrome_notification_types.h", + # This is needed for renderer JS sources which should eventually move to + # the extensions_resources target. + "!grit/renderer_resources.h", ] specific_include_rules = { diff --git a/extensions/extensions.gyp b/extensions/extensions.gyp index 52c299e..e00b987 100644 --- a/extensions/extensions.gyp +++ b/extensions/extensions.gyp @@ -526,31 +526,6 @@ 'renderer/request_sender.h', 'renderer/resource_bundle_source_map.cc', 'renderer/resource_bundle_source_map.h', - 'renderer/resources/app_runtime_custom_bindings.js', - 'renderer/resources/binding.js', - 'renderer/resources/context_menus_custom_bindings.js', - 'renderer/resources/entry_id_manager.js', - 'renderer/resources/event.js', - 'renderer/resources/extension_custom_bindings.js', - 'renderer/resources/greasemonkey_api.js', - 'renderer/resources/i18n_custom_bindings.js', - 'renderer/resources/image_util.js', - 'renderer/resources/json_schema.js', - 'renderer/resources/last_error.js', - 'renderer/resources/messaging.js', - 'renderer/resources/messaging_utils.js', - 'renderer/resources/permissions_custom_bindings.js', - 'renderer/resources/platform_app.css', - 'renderer/resources/platform_app.js', - 'renderer/resources/extensions/runtime_custom_bindings.js', - 'renderer/resources/schema_utils.js', - 'renderer/resources/send_request.js', - 'renderer/resources/set_icon.js', - 'renderer/resources/storage_area.js', - 'renderer/resources/test_custom_bindings.js', - 'renderer/resources/uncaught_exception_handler.js', - 'renderer/resources/unload_event.js', - 'renderer/resources/utils.js', 'renderer/runtime_custom_bindings.cc', 'renderer/runtime_custom_bindings.h', 'renderer/safe_builtins.cc', diff --git a/extensions/extensions_resources.gyp b/extensions/extensions_resources.gyp index dd0e1cd..856def8 100644 --- a/extensions/extensions_resources.gyp +++ b/extensions/extensions_resources.gyp @@ -18,20 +18,8 @@ }, 'includes': [ '../build/grit_action.gypi' ], }, - { - 'action_name': 'extensions_renderer_resources', - 'variables': { - 'grit_grd_file': 'renderer/resources/extensions_renderer_resources.grd', - }, - 'includes': [ '../build/grit_action.gypi' ], - }, ], 'includes': [ '../build/grit_target.gypi' ], - 'direct_dependent_settings': { - 'include_dirs': [ - '<(SHARED_INTERMEDIATE_DIR)/extensions', - ] - }, 'hard_dependency': 1, } ] diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index dde54db..0d11726 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc @@ -73,7 +73,7 @@ #include "extensions/renderer/user_script_slave.h" #include "extensions/renderer/utils_native_handler.h" #include "extensions/renderer/v8_context_native_handler.h" -#include "grit/extensions_renderer_resources.h" +#include "grit/renderer_resources.h" #include "third_party/WebKit/public/platform/WebString.h" #include "third_party/WebKit/public/platform/WebURLRequest.h" #include "third_party/WebKit/public/web/WebCustomElement.h" diff --git a/extensions/renderer/resources/app_runtime_custom_bindings.js b/extensions/renderer/resources/app_runtime_custom_bindings.js deleted file mode 100644 index f4fe24d..0000000 --- a/extensions/renderer/resources/app_runtime_custom_bindings.js +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2014 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 binding for the chrome.app.runtime API. - -var binding = require('binding').Binding.create('app.runtime'); - -var eventBindings = require('event_bindings'); -var fileSystemHelpers = requireNative('file_system_natives'); -var GetIsolatedFileSystem = fileSystemHelpers.GetIsolatedFileSystem; -var appNatives = requireNative('app_runtime'); -var DeserializeString = appNatives.DeserializeString; -var SerializeToString = appNatives.SerializeToString; -var CreateBlob = appNatives.CreateBlob; -var entryIdManager = require('entryIdManager'); - -eventBindings.registerArgumentMassager('app.runtime.onLaunched', - function(args, dispatch) { - var launchData = args[0]; - if (launchData.items) { - // An onLaunched corresponding to file_handlers in the app's manifest. - var items = []; - var numItems = launchData.items.length; - var itemLoaded = function(err, item) { - if (err) { - console.error('Error getting fileEntry, code: ' + err.code); - } else { - $Array.push(items, item); - } - if (--numItems === 0) { - var data = { isKioskSession: launchData.isKioskSession }; - if (items.length !== 0) { - data.id = launchData.id; - data.items = items; - } - dispatch([data]); - } - }; - $Array.forEach(launchData.items, function(item) { - var fs = GetIsolatedFileSystem(item.fileSystemId); - fs.root.getFile(item.baseName, {}, function(fileEntry) { - entryIdManager.registerEntry(item.entryId, fileEntry); - itemLoaded(null, { entry: fileEntry, type: item.mimeType }); - }, function(fileError) { - itemLoaded(fileError); - }); - }); - } else { - // Default case. This currently covers an onLaunched corresponding to - // url_handlers in the app's manifest. - dispatch([launchData]); - } -}); - -exports.binding = binding.generate(); diff --git a/extensions/renderer/resources/binding.js b/extensions/renderer/resources/binding.js deleted file mode 100644 index b0c6afa..0000000 --- a/extensions/renderer/resources/binding.js +++ /dev/null @@ -1,434 +0,0 @@ -// Copyright 2014 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. - -var Event = require('event_bindings').Event; -var forEach = require('utils').forEach; -var GetAvailability = requireNative('v8_context').GetAvailability; -var logActivity = requireNative('activityLogger'); -var logging = requireNative('logging'); -var process = requireNative('process'); -var schemaRegistry = requireNative('schema_registry'); -var schemaUtils = require('schemaUtils'); -var utils = require('utils'); -var sendRequestHandler = require('sendRequest'); - -var contextType = process.GetContextType(); -var extensionId = process.GetExtensionId(); -var manifestVersion = process.GetManifestVersion(); -var sendRequest = sendRequestHandler.sendRequest; - -// 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(namespace) { - this.apiFunctions_ = {}; - this.unavailableApiFunctions_ = {}; - this.namespace = namespace; -} - -APIFunctions.prototype.register = function(apiName, apiFunction) { - this.apiFunctions_[apiName] = apiFunction; -}; - -// Registers a function as existing but not available, meaning that calls to -// the set* methods that reference this function should be ignored rather -// than throwing Errors. -APIFunctions.prototype.registerUnavailable = function(apiName) { - this.unavailableApiFunctions_[apiName] = apiName; -}; - -APIFunctions.prototype.setHook_ = - function(apiName, propertyName, customizedFunction) { - if ($Object.hasOwnProperty(this.unavailableApiFunctions_, apiName)) - return; - if (!$Object.hasOwnProperty(this.apiFunctions_, apiName)) - throw new Error('Tried to set hook for unknown API "' + apiName + '"'); - this.apiFunctions_[apiName][propertyName] = customizedFunction; -}; - -APIFunctions.prototype.setHandleRequest = - function(apiName, customizedFunction) { - var prefix = this.namespace; - return this.setHook_(apiName, 'handleRequest', - function() { - var ret = $Function.apply(customizedFunction, this, arguments); - // Logs API calls to the Activity Log if it doesn't go through an - // ExtensionFunction. - if (!sendRequestHandler.getCalledSendRequest()) - logActivity.LogAPICall(extensionId, prefix + "." + apiName, - $Array.slice(arguments)); - return ret; - }); -}; - -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); -}; - -function CustomBindingsObject() { -} - -CustomBindingsObject.prototype.setSchema = function(schema) { - // The functions in the schema are in list form, so we move them into a - // dictionary for easier access. - var self = this; - self.functionSchemas = {}; - $Array.forEach(schema.functions, function(f) { - self.functionSchemas[f.name] = { - name: f.name, - definition: f - } - }); -}; - -// Get the platform from navigator.appVersion. -function getPlatform() { - var platforms = [ - [/CrOS Touch/, "chromeos touch"], - [/CrOS/, "chromeos"], - [/Linux/, "linux"], - [/Mac/, "mac"], - [/Win/, "win"], - ]; - - for (var i = 0; i < platforms.length; i++) { - if ($RegExp.test(platforms[i][0], navigator.appVersion)) { - return platforms[i][1]; - } - } - return "unknown"; -} - -function isPlatformSupported(schemaNode, platform) { - return !schemaNode.platforms || - schemaNode.platforms.indexOf(platform) > -1; -} - -function isManifestVersionSupported(schemaNode, manifestVersion) { - return !schemaNode.maximumManifestVersion || - manifestVersion <= schemaNode.maximumManifestVersion; -} - -function isSchemaNodeSupported(schemaNode, platform, manifestVersion) { - return isPlatformSupported(schemaNode, platform) && - isManifestVersionSupported(schemaNode, manifestVersion); -} - -function createCustomType(type) { - var jsModuleName = type.js_module; - logging.CHECK(jsModuleName, 'Custom type ' + type.id + - ' has no "js_module" property.'); - var jsModule = require(jsModuleName); - logging.CHECK(jsModule, 'No module ' + jsModuleName + ' found for ' + - type.id + '.'); - var customType = jsModule[jsModuleName]; - logging.CHECK(customType, jsModuleName + ' must export itself.'); - customType.prototype = new CustomBindingsObject(); - customType.prototype.setSchema(type); - return customType; -} - -var platform = getPlatform(); - -function Binding(schema) { - this.schema_ = schema; - this.apiFunctions_ = new APIFunctions(schema.namespace); - this.customEvent_ = null; - this.customHooks_ = []; -}; - -Binding.create = function(apiName) { - return new Binding(schemaRegistry.GetSchema(apiName)); -}; - -Binding.prototype = { - // The API through which the ${api_name}_custom_bindings.js files customize - // their API bindings beyond what can be generated. - // - // There are 2 types of customizations available: those which are required in - // order to do the schema generation (registerCustomEvent and - // registerCustomType), and those which can only run after the bindings have - // been generated (registerCustomHook). - - // Registers a custom event type for the API identified by |namespace|. - // |event| is the event's constructor. - registerCustomEvent: function(event) { - this.customEvent_ = event; - }, - - // Registers a function |hook| to run after the schema for all APIs has been - // generated. The hook is passed as its first argument an "API" object to - // interact with, and second the current extension ID. See where - // |customHooks| is used. - registerCustomHook: function(fn) { - $Array.push(this.customHooks_, fn); - }, - - // TODO(kalman/cduvall): Refactor this so |runHooks_| is not needed. - runHooks_: function(api) { - $Array.forEach(this.customHooks_, function(hook) { - if (!isSchemaNodeSupported(this.schema_, platform, manifestVersion)) - return; - - if (!hook) - return; - - hook({ - apiFunctions: this.apiFunctions_, - schema: this.schema_, - compiledApi: api - }, extensionId, contextType); - }, this); - }, - - // Generates the bindings from |this.schema_| and integrates any custom - // bindings that might be present. - generate: function() { - var schema = this.schema_; - - function shouldCheckUnprivileged() { - var shouldCheck = 'unprivileged' in schema; - if (shouldCheck) - return shouldCheck; - - $Array.forEach(['functions', 'events'], function(type) { - if ($Object.hasOwnProperty(schema, type)) { - $Array.forEach(schema[type], function(node) { - if ('unprivileged' in node) - shouldCheck = true; - }); - } - }); - if (shouldCheck) - return shouldCheck; - - for (var property in schema.properties) { - if ($Object.hasOwnProperty(schema, property) && - 'unprivileged' in schema.properties[property]) { - shouldCheck = true; - break; - } - } - return shouldCheck; - } - var checkUnprivileged = shouldCheckUnprivileged(); - - // TODO(kalman/cduvall): Make GetAvailability handle this, then delete the - // supporting code. - if (!isSchemaNodeSupported(schema, platform, manifestVersion)) { - console.error('chrome.' + schema.namespace + ' is not supported on ' + - 'this platform or manifest version'); - return undefined; - } - - var mod = {}; - - var namespaces = $String.split(schema.namespace, '.'); - for (var index = 0, name; name = namespaces[index]; index++) { - mod[name] = mod[name] || {}; - mod = mod[name]; - } - - // Add types to global schemaValidator, the types we depend on from other - // namespaces will be added as needed. - if (schema.types) { - $Array.forEach(schema.types, function(t) { - if (!isSchemaNodeSupported(t, platform, manifestVersion)) - return; - schemaUtils.schemaValidator.addTypes(t); - }, this); - } - - // TODO(cduvall): Take out when all APIs have been converted to features. - // Returns whether access to the content of a schema should be denied, - // based on the presence of "unprivileged" and whether this is an - // extension process (versus e.g. a content script). - function isSchemaAccessAllowed(itemSchema) { - return (contextType == 'BLESSED_EXTENSION') || - schema.unprivileged || - itemSchema.unprivileged; - }; - - // Setup Functions. - if (schema.functions) { - $Array.forEach(schema.functions, function(functionDef) { - if (functionDef.name in mod) { - throw new Error('Function ' + functionDef.name + - ' already defined in ' + schema.namespace); - } - - if (!isSchemaNodeSupported(functionDef, platform, manifestVersion)) { - this.apiFunctions_.registerUnavailable(functionDef.name); - return; - } - - var apiFunction = {}; - apiFunction.definition = functionDef; - apiFunction.name = schema.namespace + '.' + functionDef.name; - - if (!GetAvailability(apiFunction.name).is_available || - (checkUnprivileged && !isSchemaAccessAllowed(functionDef))) { - this.apiFunctions_.registerUnavailable(functionDef.name); - return; - } - - // TODO(aa): It would be best to run this in a unit test, but in order - // to do that we would need to better factor this code so that it - // doesn't depend on so much v8::Extension machinery. - if (logging.DCHECK_IS_ON() && - schemaUtils.isFunctionSignatureAmbiguous(apiFunction.definition)) { - throw new Error( - apiFunction.name + ' has ambiguous optional arguments. ' + - 'To implement custom disambiguation logic, add ' + - '"allowAmbiguousOptionalArguments" to the function\'s schema.'); - } - - this.apiFunctions_.register(functionDef.name, apiFunction); - - mod[functionDef.name] = $Function.bind(function() { - var args = $Array.slice(arguments); - if (this.updateArgumentsPreValidate) - args = $Function.apply(this.updateArgumentsPreValidate, this, args); - - args = schemaUtils.normalizeArgumentsAndValidate(args, this); - if (this.updateArgumentsPostValidate) { - args = $Function.apply(this.updateArgumentsPostValidate, - this, - args); - } - - sendRequestHandler.clearCalledSendRequest(); - - var retval; - if (this.handleRequest) { - retval = $Function.apply(this.handleRequest, this, args); - } else { - var optArgs = { - customCallback: this.customCallback - }; - retval = sendRequest(this.name, args, - this.definition.parameters, - optArgs); - } - sendRequestHandler.clearCalledSendRequest(); - - // Validate return value if in sanity check mode. - if (logging.DCHECK_IS_ON() && this.definition.returns) - schemaUtils.validate([retval], [this.definition.returns]); - return retval; - }, apiFunction); - }, this); - } - - // Setup Events - if (schema.events) { - $Array.forEach(schema.events, function(eventDef) { - if (eventDef.name in mod) { - throw new Error('Event ' + eventDef.name + - ' already defined in ' + schema.namespace); - } - if (!isSchemaNodeSupported(eventDef, platform, manifestVersion)) - return; - - var eventName = schema.namespace + "." + eventDef.name; - if (!GetAvailability(eventName).is_available || - (checkUnprivileged && !isSchemaAccessAllowed(eventDef))) { - return; - } - - var options = eventDef.options || {}; - if (eventDef.filters && eventDef.filters.length > 0) - options.supportsFilters = true; - - var parameters = eventDef.parameters; - if (this.customEvent_) { - mod[eventDef.name] = new this.customEvent_( - eventName, parameters, eventDef.extraParameters, options); - } else { - mod[eventDef.name] = new Event(eventName, parameters, options); - } - }, this); - } - - function addProperties(m, parentDef) { - var properties = parentDef.properties; - if (!properties) - return; - - forEach(properties, function(propertyName, propertyDef) { - if (propertyName in m) - return; // TODO(kalman): be strict like functions/events somehow. - if (!isSchemaNodeSupported(propertyDef, platform, manifestVersion)) - return; - if (!GetAvailability(schema.namespace + "." + - propertyName).is_available || - (checkUnprivileged && !isSchemaAccessAllowed(propertyDef))) { - return; - } - - var value = propertyDef.value; - if (value) { - // Values may just have raw types as defined in the JSON, such - // as "WINDOW_ID_NONE": { "value": -1 }. We handle this here. - // TODO(kalman): enforce that things with a "value" property can't - // define their own types. - var type = propertyDef.type || typeof(value); - if (type === 'integer' || type === 'number') { - value = parseInt(value); - } else if (type === 'boolean') { - value = value === 'true'; - } else if (propertyDef['$ref']) { - var ref = propertyDef['$ref']; - var type = utils.loadTypeSchema(propertyDef['$ref'], schema); - logging.CHECK(type, 'Schema for $ref type ' + ref + ' not found'); - var constructor = createCustomType(type); - var args = value; - // For an object propertyDef, |value| is an array of constructor - // arguments, but we want to pass the arguments directly (i.e. - // not as an array), so we have to fake calling |new| on the - // constructor. - value = { __proto__: constructor.prototype }; - $Function.apply(constructor, value, args); - // Recursively add properties. - addProperties(value, propertyDef); - } else if (type === 'object') { - // Recursively add properties. - addProperties(value, propertyDef); - } else if (type !== 'string') { - throw new Error('NOT IMPLEMENTED (extension_api.json error): ' + - 'Cannot parse values for type "' + type + '"'); - } - m[propertyName] = value; - } - }); - }; - - addProperties(mod, schema); - - var availability = GetAvailability(schema.namespace); - if (!availability.is_available && $Object.keys(mod).length == 0) { - console.error('chrome.' + schema.namespace + ' is not available: ' + - availability.message); - return; - } - - this.runHooks_(mod); - return mod; - } -}; - -exports.Binding = Binding; diff --git a/extensions/renderer/resources/context_menus_custom_bindings.js b/extensions/renderer/resources/context_menus_custom_bindings.js deleted file mode 100644 index 71a97a4..0000000 --- a/extensions/renderer/resources/context_menus_custom_bindings.js +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2014 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 binding for the contextMenus API. - -var binding = require('binding').Binding.create('contextMenus'); - -var contextMenuNatives = requireNative('context_menus'); -var sendRequest = require('sendRequest').sendRequest; -var Event = require('event_bindings').Event; - -binding.registerCustomHook(function(bindingsAPI) { - var apiFunctions = bindingsAPI.apiFunctions; - - var contextMenus = {}; - contextMenus.generatedIdHandlers = {}; - contextMenus.stringIdHandlers = {}; - var eventName = 'contextMenus'; - contextMenus.event = new Event(eventName); - contextMenus.getIdFromCreateProperties = function(prop) { - if (typeof(prop.id) !== 'undefined') - return prop.id; - return prop.generatedId; - }; - contextMenus.handlersForId = function(id) { - if (typeof(id) === 'number') - return contextMenus.generatedIdHandlers; - return contextMenus.stringIdHandlers; - }; - contextMenus.ensureListenerSetup = function() { - if (contextMenus.listening) { - return; - } - contextMenus.listening = true; - 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 = contextMenus.handlersForId(id)[id]; - if (onclick) { - $Function.apply(onclick, null, arguments); - } - }); - }; - - apiFunctions.setHandleRequest('create', function() { - var args = arguments; - var id = contextMenuNatives.GetNextContextMenuId(); - args[0].generatedId = id; - var optArgs = { - customCallback: this.customCallback, - }; - sendRequest(this.name, args, this.definition.parameters, optArgs); - return contextMenus.getIdFromCreateProperties(args[0]); - }); - - apiFunctions.setCustomCallback('create', function(name, request, response) { - if (chrome.runtime.lastError) { - return; - } - - var id = contextMenus.getIdFromCreateProperties(request.args[0]); - - // 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) { - contextMenus.ensureListenerSetup(); - contextMenus.handlersForId(id)[id] = onclick; - } - }); - - apiFunctions.setCustomCallback('remove', function(name, request, response) { - if (chrome.runtime.lastError) { - return; - } - var id = request.args[0]; - delete contextMenus.handlersForId(id)[id]; - }); - - apiFunctions.setCustomCallback('update', function(name, request, response) { - if (chrome.runtime.lastError) { - return; - } - var id = request.args[0]; - if (request.args[1].onclick) { - contextMenus.handlersForId(id)[id] = request.args[1].onclick; - } - }); - - apiFunctions.setCustomCallback('removeAll', - function(name, request, response) { - if (chrome.runtime.lastError) { - return; - } - contextMenus.generatedIdHandlers = {}; - contextMenus.stringIdHandlers = {}; - }); -}); - -exports.binding = binding.generate(); diff --git a/extensions/renderer/resources/entry_id_manager.js b/extensions/renderer/resources/entry_id_manager.js deleted file mode 100644 index 9fc2c14..0000000 --- a/extensions/renderer/resources/entry_id_manager.js +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2014 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. - -var fileSystemNatives = requireNative('file_system_natives'); - -var nameToIds = {}; -var idsToEntries = {}; - -function computeName(entry) { - return entry.filesystem.name + ':' + entry.fullPath; -} - -function computeId(entry) { - var fileSystemId = fileSystemNatives.CrackIsolatedFileSystemName( - entry.filesystem.name); - if (!fileSystemId) - return null; - // Strip the leading '/' from the path. - return fileSystemId + ':' + $String.slice(entry.fullPath, 1); -} - -function registerEntry(id, entry) { - var name = computeName(entry); - nameToIds[name] = id; - idsToEntries[id] = entry; -} - -function getEntryId(entry) { - var name = null; - try { - name = computeName(entry); - } catch(e) { - return null; - } - var id = nameToIds[name]; - if (id != null) - return id; - - // If an entry has not been registered, compute its id and register it. - id = computeId(entry); - registerEntry(id, entry); - return id; -} - -function getEntryById(id) { - return idsToEntries[id]; -} - -exports.registerEntry = registerEntry; -exports.getEntryId = getEntryId; -exports.getEntryById = getEntryById; diff --git a/extensions/renderer/resources/event.js b/extensions/renderer/resources/event.js deleted file mode 100644 index d82b9fb..0000000 --- a/extensions/renderer/resources/event.js +++ /dev/null @@ -1,528 +0,0 @@ -// Copyright 2014 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. - - var eventNatives = requireNative('event_natives'); - var handleUncaughtException = require('uncaught_exception_handler').handle; - var logging = requireNative('logging'); - var schemaRegistry = requireNative('schema_registry'); - var sendRequest = require('sendRequest').sendRequest; - var utils = require('utils'); - var validate = require('schemaUtils').validate; - var unloadEvent = require('unload_event'); - - // Schemas for the rule-style functions on the events API that - // only need to be generated occasionally, so populate them lazily. - var ruleFunctionSchemas = { - // These values are set lazily: - // addRules: {}, - // getRules: {}, - // removeRules: {} - }; - - // This function ensures that |ruleFunctionSchemas| is populated. - function ensureRuleSchemasLoaded() { - if (ruleFunctionSchemas.addRules) - return; - var eventsSchema = schemaRegistry.GetSchema("events"); - var eventType = utils.lookup(eventsSchema.types, 'id', 'events.Event'); - - ruleFunctionSchemas.addRules = - utils.lookup(eventType.functions, 'name', 'addRules'); - ruleFunctionSchemas.getRules = - utils.lookup(eventType.functions, 'name', 'getRules'); - ruleFunctionSchemas.removeRules = - utils.lookup(eventType.functions, 'name', 'removeRules'); - } - - // A map of event names to the event object that is registered to that name. - var attachedNamedEvents = {}; - - // An array of all attached event objects, used for detaching on unload. - var allAttachedEvents = []; - - // A map of functions that massage event arguments before they are dispatched. - // Key is event name, value is function. - var eventArgumentMassagers = {}; - - // An attachment strategy for events that aren't attached to the browser. - // This applies to events with the "unmanaged" option and events without - // names. - var NullAttachmentStrategy = function(event) { - this.event_ = event; - }; - NullAttachmentStrategy.prototype.onAddedListener = - function(listener) { - }; - NullAttachmentStrategy.prototype.onRemovedListener = - function(listener) { - }; - NullAttachmentStrategy.prototype.detach = function(manual) { - }; - NullAttachmentStrategy.prototype.getListenersByIDs = function(ids) { - // |ids| is for filtered events only. - return this.event_.listeners; - }; - - // Handles adding/removing/dispatching listeners for unfiltered events. - var UnfilteredAttachmentStrategy = function(event) { - this.event_ = event; - }; - - UnfilteredAttachmentStrategy.prototype.onAddedListener = - function(listener) { - // Only attach / detach on the first / last listener removed. - if (this.event_.listeners.length == 0) - eventNatives.AttachEvent(this.event_.eventName); - }; - - UnfilteredAttachmentStrategy.prototype.onRemovedListener = - function(listener) { - if (this.event_.listeners.length == 0) - this.detach(true); - }; - - UnfilteredAttachmentStrategy.prototype.detach = function(manual) { - eventNatives.DetachEvent(this.event_.eventName, manual); - }; - - UnfilteredAttachmentStrategy.prototype.getListenersByIDs = function(ids) { - // |ids| is for filtered events only. - return this.event_.listeners; - }; - - var FilteredAttachmentStrategy = function(event) { - this.event_ = event; - this.listenerMap_ = {}; - }; - - FilteredAttachmentStrategy.idToEventMap = {}; - - FilteredAttachmentStrategy.prototype.onAddedListener = function(listener) { - var id = eventNatives.AttachFilteredEvent(this.event_.eventName, - listener.filters || {}); - if (id == -1) - throw new Error("Can't add listener"); - listener.id = id; - this.listenerMap_[id] = listener; - FilteredAttachmentStrategy.idToEventMap[id] = this.event_; - }; - - FilteredAttachmentStrategy.prototype.onRemovedListener = function(listener) { - this.detachListener(listener, true); - }; - - FilteredAttachmentStrategy.prototype.detachListener = - function(listener, manual) { - if (listener.id == undefined) - throw new Error("listener.id undefined - '" + listener + "'"); - var id = listener.id; - delete this.listenerMap_[id]; - delete FilteredAttachmentStrategy.idToEventMap[id]; - eventNatives.DetachFilteredEvent(id, manual); - }; - - FilteredAttachmentStrategy.prototype.detach = function(manual) { - for (var i in this.listenerMap_) - this.detachListener(this.listenerMap_[i], manual); - }; - - FilteredAttachmentStrategy.prototype.getListenersByIDs = function(ids) { - var result = []; - for (var i = 0; i < ids.length; i++) - $Array.push(result, this.listenerMap_[ids[i]]); - return result; - }; - - function parseEventOptions(opt_eventOptions) { - function merge(dest, src) { - for (var k in src) { - if (!$Object.hasOwnProperty(dest, k)) { - dest[k] = src[k]; - } - } - } - - var options = opt_eventOptions || {}; - merge(options, { - // Event supports adding listeners with filters ("filtered events"), for - // example as used in the webNavigation API. - // - // event.addListener(listener, [filter1, filter2]); - supportsFilters: false, - - // Events supports vanilla events. Most APIs use these. - // - // event.addListener(listener); - supportsListeners: true, - - // Event supports adding rules ("declarative events") rather than - // listeners, for example as used in the declarativeWebRequest API. - // - // event.addRules([rule1, rule2]); - supportsRules: false, - - // Event is unmanaged in that the browser has no knowledge of its - // existence; it's never invoked, doesn't keep the renderer alive, and - // the bindings system has no knowledge of it. - // - // Both events created by user code (new chrome.Event()) and messaging - // events are unmanaged, though in the latter case the browser *does* - // interact indirectly with them via IPCs written by hand. - unmanaged: false, - }); - return options; - }; - - // Event object. If opt_eventName is provided, this object represents - // the unique instance of that named event, and dispatching an event - // with that name will route through this object's listeners. Note that - // opt_eventName is required for events that support rules. - // - // Example: - // var Event = require('event_bindings').Event; - // chrome.tabs.onChanged = new Event("tab-changed"); - // chrome.tabs.onChanged.addListener(function(data) { alert(data); }); - // Event.dispatch("tab-changed", "hi"); - // will result in an alert dialog that says 'hi'. - // - // If opt_eventOptions exists, it is a dictionary that contains the boolean - // entries "supportsListeners" and "supportsRules". - // If opt_webViewInstanceId exists, it is an integer uniquely identifying a - // <webview> tag within the embedder. If it does not exist, then this is an - // extension event rather than a <webview> event. - var EventImpl = function(opt_eventName, opt_argSchemas, opt_eventOptions, - opt_webViewInstanceId) { - this.eventName = opt_eventName; - this.argSchemas = opt_argSchemas; - this.listeners = []; - this.eventOptions = parseEventOptions(opt_eventOptions); - this.webViewInstanceId = opt_webViewInstanceId || 0; - - if (!this.eventName) { - if (this.eventOptions.supportsRules) - throw new Error("Events that support rules require an event name."); - // Events without names cannot be managed by the browser by definition - // (the browser has no way of identifying them). - this.eventOptions.unmanaged = true; - } - - // Track whether the event has been destroyed to help track down the cause - // of http://crbug.com/258526. - // This variable will eventually hold the stack trace of the destroy call. - // TODO(kalman): Delete this and replace with more sound logic that catches - // when events are used without being *attached*. - this.destroyed = null; - - if (this.eventOptions.unmanaged) - this.attachmentStrategy = new NullAttachmentStrategy(this); - else if (this.eventOptions.supportsFilters) - this.attachmentStrategy = new FilteredAttachmentStrategy(this); - else - this.attachmentStrategy = new UnfilteredAttachmentStrategy(this); - }; - - // callback is a function(args, dispatch). args are the args we receive from - // dispatchEvent(), and dispatch is a function(args) that dispatches args to - // its listeners. - function registerArgumentMassager(name, callback) { - if (eventArgumentMassagers[name]) - throw new Error("Massager already registered for event: " + name); - eventArgumentMassagers[name] = callback; - } - - // Dispatches a named event with the given argument array. The args array is - // the list of arguments that will be sent to the event callback. - function dispatchEvent(name, args, filteringInfo) { - var listenerIDs = []; - - if (filteringInfo) - listenerIDs = eventNatives.MatchAgainstEventFilter(name, filteringInfo); - - var event = attachedNamedEvents[name]; - if (!event) - return; - - var dispatchArgs = function(args) { - var result = event.dispatch_(args, listenerIDs); - if (result) - logging.DCHECK(!result.validationErrors, result.validationErrors); - return result; - }; - - if (eventArgumentMassagers[name]) - eventArgumentMassagers[name](args, dispatchArgs); - else - dispatchArgs(args); - } - - // Registers a callback to be called when this event is dispatched. - EventImpl.prototype.addListener = function(cb, filters) { - if (!this.eventOptions.supportsListeners) - throw new Error("This event does not support listeners."); - if (this.eventOptions.maxListeners && - this.getListenerCount_() >= this.eventOptions.maxListeners) { - throw new Error("Too many listeners for " + this.eventName); - } - if (filters) { - if (!this.eventOptions.supportsFilters) - throw new Error("This event does not support filters."); - if (filters.url && !(filters.url instanceof Array)) - throw new Error("filters.url should be an array."); - if (filters.serviceType && - !(typeof filters.serviceType === 'string')) { - throw new Error("filters.serviceType should be a string.") - } - } - var listener = {callback: cb, filters: filters}; - this.attach_(listener); - $Array.push(this.listeners, listener); - }; - - EventImpl.prototype.attach_ = function(listener) { - this.attachmentStrategy.onAddedListener(listener); - - if (this.listeners.length == 0) { - allAttachedEvents[allAttachedEvents.length] = this; - if (this.eventName) { - if (attachedNamedEvents[this.eventName]) { - throw new Error("Event '" + this.eventName + - "' is already attached."); - } - attachedNamedEvents[this.eventName] = this; - } - } - }; - - // Unregisters a callback. - EventImpl.prototype.removeListener = function(cb) { - if (!this.eventOptions.supportsListeners) - throw new Error("This event does not support listeners."); - - var idx = this.findListener_(cb); - if (idx == -1) - return; - - var removedListener = $Array.splice(this.listeners, idx, 1)[0]; - this.attachmentStrategy.onRemovedListener(removedListener); - - if (this.listeners.length == 0) { - var i = $Array.indexOf(allAttachedEvents, this); - if (i >= 0) - delete allAttachedEvents[i]; - if (this.eventName) { - if (!attachedNamedEvents[this.eventName]) { - throw new Error( - "Event '" + this.eventName + "' is not attached."); - } - delete attachedNamedEvents[this.eventName]; - } - } - }; - - // Test if the given callback is registered for this event. - EventImpl.prototype.hasListener = function(cb) { - if (!this.eventOptions.supportsListeners) - throw new Error("This event does not support listeners."); - return this.findListener_(cb) > -1; - }; - - // Test if any callbacks are registered for this event. - EventImpl.prototype.hasListeners = function() { - return this.getListenerCount_() > 0; - }; - - // Returns the number of listeners on this event. - EventImpl.prototype.getListenerCount_ = function() { - if (!this.eventOptions.supportsListeners) - throw new Error("This event does not support listeners."); - return this.listeners.length; - }; - - // Returns the index of the given callback if registered, or -1 if not - // found. - EventImpl.prototype.findListener_ = function(cb) { - for (var i = 0; i < this.listeners.length; i++) { - if (this.listeners[i].callback == cb) { - return i; - } - } - - return -1; - }; - - EventImpl.prototype.dispatch_ = function(args, listenerIDs) { - if (this.destroyed) { - throw new Error(this.eventName + ' was already destroyed at: ' + - this.destroyed); - } - if (!this.eventOptions.supportsListeners) - throw new Error("This event does not support listeners."); - - if (this.argSchemas && logging.DCHECK_IS_ON()) { - try { - validate(args, this.argSchemas); - } catch (e) { - e.message += ' in ' + this.eventName; - throw e; - } - } - - // Make a copy of the listeners in case the listener list is modified - // while dispatching the event. - var listeners = $Array.slice( - this.attachmentStrategy.getListenersByIDs(listenerIDs)); - - var results = []; - for (var i = 0; i < listeners.length; i++) { - try { - var result = this.wrapper.dispatchToListener(listeners[i].callback, - args); - if (result !== undefined) - $Array.push(results, result); - } catch (e) { - handleUncaughtException( - 'Error in event handler for ' + - (this.eventName ? this.eventName : '(unknown)') + - ': ' + e.message + '\nStack trace: ' + e.stack, - e); - } - } - if (results.length) - return {results: results}; - } - - // Can be overridden to support custom dispatching. - EventImpl.prototype.dispatchToListener = function(callback, args) { - return $Function.apply(callback, null, args); - } - - // Dispatches this event object to all listeners, passing all supplied - // arguments to this function each listener. - EventImpl.prototype.dispatch = function(varargs) { - return this.dispatch_($Array.slice(arguments), undefined); - }; - - // Detaches this event object from its name. - EventImpl.prototype.detach_ = function() { - this.attachmentStrategy.detach(false); - }; - - EventImpl.prototype.destroy_ = function() { - this.listeners.length = 0; - this.detach_(); - this.destroyed = new Error().stack; - }; - - EventImpl.prototype.addRules = function(rules, opt_cb) { - if (!this.eventOptions.supportsRules) - throw new Error("This event does not support rules."); - - // Takes a list of JSON datatype identifiers and returns a schema fragment - // that verifies that a JSON object corresponds to an array of only these - // data types. - function buildArrayOfChoicesSchema(typesList) { - return { - 'type': 'array', - 'items': { - 'choices': typesList.map(function(el) {return {'$ref': el};}) - } - }; - }; - - // Validate conditions and actions against specific schemas of this - // event object type. - // |rules| is an array of JSON objects that follow the Rule type of the - // declarative extension APIs. |conditions| is an array of JSON type - // identifiers that are allowed to occur in the conditions attribute of each - // rule. Likewise, |actions| is an array of JSON type identifiers that are - // allowed to occur in the actions attribute of each rule. - function validateRules(rules, conditions, actions) { - var conditionsSchema = buildArrayOfChoicesSchema(conditions); - var actionsSchema = buildArrayOfChoicesSchema(actions); - $Array.forEach(rules, function(rule) { - validate([rule.conditions], [conditionsSchema]); - validate([rule.actions], [actionsSchema]); - }); - }; - - if (!this.eventOptions.conditions || !this.eventOptions.actions) { - throw new Error('Event ' + this.eventName + ' misses ' + - 'conditions or actions in the API specification.'); - } - - validateRules(rules, - this.eventOptions.conditions, - this.eventOptions.actions); - - ensureRuleSchemasLoaded(); - // We remove the first parameter from the validation to give the user more - // meaningful error messages. - validate([this.webViewInstanceId, rules, opt_cb], - $Array.splice( - $Array.slice(ruleFunctionSchemas.addRules.parameters), 1)); - sendRequest( - "events.addRules", - [this.eventName, this.webViewInstanceId, rules, opt_cb], - ruleFunctionSchemas.addRules.parameters); - } - - EventImpl.prototype.removeRules = function(ruleIdentifiers, opt_cb) { - if (!this.eventOptions.supportsRules) - throw new Error("This event does not support rules."); - ensureRuleSchemasLoaded(); - // We remove the first parameter from the validation to give the user more - // meaningful error messages. - validate([this.webViewInstanceId, ruleIdentifiers, opt_cb], - $Array.splice( - $Array.slice(ruleFunctionSchemas.removeRules.parameters), 1)); - sendRequest("events.removeRules", - [this.eventName, - this.webViewInstanceId, - ruleIdentifiers, - opt_cb], - ruleFunctionSchemas.removeRules.parameters); - } - - EventImpl.prototype.getRules = function(ruleIdentifiers, cb) { - if (!this.eventOptions.supportsRules) - throw new Error("This event does not support rules."); - ensureRuleSchemasLoaded(); - // We remove the first parameter from the validation to give the user more - // meaningful error messages. - validate([this.webViewInstanceId, ruleIdentifiers, cb], - $Array.splice( - $Array.slice(ruleFunctionSchemas.getRules.parameters), 1)); - - sendRequest( - "events.getRules", - [this.eventName, this.webViewInstanceId, ruleIdentifiers, cb], - ruleFunctionSchemas.getRules.parameters); - } - - unloadEvent.addListener(function() { - for (var i = 0; i < allAttachedEvents.length; ++i) { - var event = allAttachedEvents[i]; - if (event) - event.detach_(); - } - }); - - var Event = utils.expose('Event', EventImpl, { functions: [ - 'addListener', - 'removeListener', - 'hasListener', - 'hasListeners', - 'dispatchToListener', - 'dispatch', - 'addRules', - 'removeRules', - 'getRules' - ] }); - - // NOTE: Event is (lazily) exposed as chrome.Event from dispatcher.cc. - exports.Event = Event; - - exports.dispatchEvent = dispatchEvent; - exports.parseEventOptions = parseEventOptions; - exports.registerArgumentMassager = registerArgumentMassager; diff --git a/extensions/renderer/resources/extension_custom_bindings.js b/extensions/renderer/resources/extension_custom_bindings.js deleted file mode 100644 index d114f52..0000000 --- a/extensions/renderer/resources/extension_custom_bindings.js +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2014 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 binding for the extension API. - -var binding = require('binding').Binding.create('extension'); - -var messaging = require('messaging'); -var runtimeNatives = requireNative('runtime'); -var GetExtensionViews = runtimeNatives.GetExtensionViews; -var OpenChannelToExtension = runtimeNatives.OpenChannelToExtension; -var OpenChannelToNativeApp = runtimeNatives.OpenChannelToNativeApp; -var chrome = requireNative('chrome').GetChrome(); - -var inIncognitoContext = requireNative('process').InIncognitoContext(); -var sendRequestIsDisabled = requireNative('process').IsSendRequestDisabled(); -var contextType = requireNative('process').GetContextType(); -var manifestVersion = requireNative('process').GetManifestVersion(); - -// This should match chrome.windows.WINDOW_ID_NONE. -// -// We can't use chrome.windows.WINDOW_ID_NONE directly because the -// chrome.windows API won't exist unless this extension has permission for it; -// which may not be the case. -var WINDOW_ID_NONE = -1; - -binding.registerCustomHook(function(bindingsAPI, extensionId) { - var extension = bindingsAPI.compiledApi; - if (manifestVersion < 2) { - chrome.self = extension; - extension.inIncognitoTab = inIncognitoContext; - } - extension.inIncognitoContext = inIncognitoContext; - - var apiFunctions = bindingsAPI.apiFunctions; - - apiFunctions.setHandleRequest('getViews', function(properties) { - var windowId = WINDOW_ID_NONE; - var type = 'ALL'; - if (properties) { - if (properties.type != null) { - type = properties.type; - } - if (properties.windowId != null) { - windowId = properties.windowId; - } - } - return GetExtensionViews(windowId, type); - }); - - apiFunctions.setHandleRequest('getBackgroundPage', function() { - return GetExtensionViews(-1, 'BACKGROUND')[0] || null; - }); - - apiFunctions.setHandleRequest('getExtensionTabs', function(windowId) { - if (windowId == null) - windowId = WINDOW_ID_NONE; - return GetExtensionViews(windowId, 'TAB'); - }); - - apiFunctions.setHandleRequest('getURL', function(path) { - path = String(path); - if (!path.length || path[0] != '/') - path = '/' + path; - return 'chrome-extension://' + extensionId + path; - }); - - // Alias several messaging deprecated APIs to their runtime counterparts. - var mayNeedAlias = [ - // Types - 'Port', - // Functions - 'connect', 'sendMessage', 'connectNative', 'sendNativeMessage', - // Events - 'onConnect', 'onConnectExternal', 'onMessage', 'onMessageExternal' - ]; - $Array.forEach(mayNeedAlias, function(alias) { - // Checking existence isn't enough since some functions are disabled via - // getters that throw exceptions. Assume that any getter is such a function. - if (chrome.runtime && - $Object.hasOwnProperty(chrome.runtime, alias) && - chrome.runtime.__lookupGetter__(alias) === undefined) { - extension[alias] = chrome.runtime[alias]; - } - }); - - apiFunctions.setUpdateArgumentsPreValidate('sendRequest', - $Function.bind(messaging.sendMessageUpdateArguments, - null, 'sendRequest', false /* hasOptionsArgument */)); - - apiFunctions.setHandleRequest('sendRequest', - function(targetId, request, responseCallback) { - if (sendRequestIsDisabled) - throw new Error(sendRequestIsDisabled); - var port = chrome.runtime.connect(targetId || extensionId, - {name: messaging.kRequestChannel}); - messaging.sendMessageImpl(port, request, responseCallback); - }); - - if (sendRequestIsDisabled) { - extension.onRequest.addListener = function() { - throw new Error(sendRequestIsDisabled); - }; - if (contextType == 'BLESSED_EXTENSION') { - extension.onRequestExternal.addListener = function() { - throw new Error(sendRequestIsDisabled); - }; - } - } -}); - -exports.binding = binding.generate(); diff --git a/extensions/renderer/resources/extensions_renderer_resources.grd b/extensions/renderer/resources/extensions_renderer_resources.grd deleted file mode 100644 index 4cf03e4b..0000000 --- a/extensions/renderer/resources/extensions_renderer_resources.grd +++ /dev/null @@ -1,45 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<grit latest_public_release="0" current_release="1"> - <outputs> - <output filename="grit/extensions_renderer_resources.h" type="rc_header"> - <emit emit_type='prepend'></emit> - </output> - <output filename="extensions_renderer_resources.pak" type="data_package" /> - </outputs> - <release seq="1"> - <includes> - <!-- Extension libraries. --> - <include name="IDR_ENTRY_ID_MANAGER" file="entry_id_manager.js" type="BINDATA" /> - <include name="IDR_EVENT_BINDINGS_JS" file="event.js" type="BINDATA" /> - <include name="IDR_IMAGE_UTIL_JS" file="image_util.js" type="BINDATA" /> - <include name="IDR_JSON_SCHEMA_JS" file="json_schema.js" type="BINDATA" /> - <include name="IDR_LAST_ERROR_JS" file="last_error.js" type="BINDATA" /> - <include name="IDR_MESSAGING_JS" file="messaging.js" type="BINDATA" /> - <include name="IDR_MESSAGING_UTILS_JS" file="messaging_utils.js" type="BINDATA" /> - <include name="IDR_SCHEMA_UTILS_JS" file="schema_utils.js" type="BINDATA" /> - <include name="IDR_SEND_REQUEST_JS" file="send_request.js" type="BINDATA" /> - <include name="IDR_SET_ICON_JS" file="set_icon.js" type="BINDATA" /> - <include name="IDR_TEST_CUSTOM_BINDINGS_JS" file="test_custom_bindings.js" type="BINDATA" /> - <include name="IDR_UNCAUGHT_EXCEPTION_HANDLER_JS" file="uncaught_exception_handler.js" type="BINDATA" /> - <include name="IDR_UNLOAD_EVENT_JS" file="unload_event.js" type="BINDATA" /> - <include name="IDR_UTILS_JS" file="utils.js" type="BINDATA" /> - - <!-- Custom bindings for APIs. --> - <include name="IDR_APP_RUNTIME_CUSTOM_BINDINGS_JS" file="app_runtime_custom_bindings.js" type="BINDATA" /> - <include name="IDR_CONTEXT_MENUS_CUSTOM_BINDINGS_JS" file="context_menus_custom_bindings.js" type="BINDATA" /> - <include name="IDR_EXTENSION_CUSTOM_BINDINGS_JS" file="extension_custom_bindings.js" type="BINDATA" /> - <include name="IDR_GREASEMONKEY_API_JS" file="greasemonkey_api.js" type="BINDATA" /> - <include name="IDR_I18N_CUSTOM_BINDINGS_JS" file="i18n_custom_bindings.js" type="BINDATA" /> - <include name="IDR_PERMISSIONS_CUSTOM_BINDINGS_JS" file="permissions_custom_bindings.js" type="BINDATA" /> - <include name="IDR_RUNTIME_CUSTOM_BINDINGS_JS" file="runtime_custom_bindings.js" type="BINDATA" /> - <include name="IDR_BINDING_JS" file="binding.js" type="BINDATA" /> - - <!-- Custom types for APIs. --> - <include name="IDR_STORAGE_AREA_JS" file="storage_area.js" type="BINDATA" /> - - <!-- Platform app support. --> - <include name="IDR_PLATFORM_APP_CSS" file="platform_app.css" type="BINDATA" /> - <include name="IDR_PLATFORM_APP_JS" file="platform_app.js" type="BINDATA" /> - </includes> - </release> -</grit> diff --git a/extensions/renderer/resources/greasemonkey_api.js b/extensions/renderer/resources/greasemonkey_api.js deleted file mode 100644 index bc09911..0000000 --- a/extensions/renderer/resources/greasemonkey_api.js +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2014 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. - -// ----------------------------------------------------------------------------- -// NOTE: If you change this file you need to touch renderer_resources.grd to -// have your change take effect. -// ----------------------------------------------------------------------------- - -// Partial implementation of the Greasemonkey API, see: -// http://wiki.greasespot.net/Greasemonkey_Manual:APIs - -function GM_addStyle(css) { - var parent = document.getElementsByTagName("head")[0]; - if (!parent) { - parent = document.documentElement; - } - var style = document.createElement("style"); - style.type = "text/css"; - var textNode = document.createTextNode(css); - style.appendChild(textNode); - parent.appendChild(style); -} - -function GM_xmlhttpRequest(details) { - function setupEvent(xhr, url, eventName, callback) { - xhr[eventName] = function () { - var isComplete = xhr.readyState == 4; - var responseState = { - responseText: xhr.responseText, - readyState: xhr.readyState, - responseHeaders: isComplete ? xhr.getAllResponseHeaders() : "", - status: isComplete ? xhr.status : 0, - statusText: isComplete ? xhr.statusText : "", - finalUrl: isComplete ? url : "" - }; - callback(responseState); - }; - } - - var xhr = new XMLHttpRequest(); - var eventNames = ["onload", "onerror", "onreadystatechange"]; - for (var i = 0; i < eventNames.length; i++ ) { - var eventName = eventNames[i]; - if (eventName in details) { - setupEvent(xhr, details.url, eventName, details[eventName]); - } - } - - xhr.open(details.method, details.url); - - if (details.overrideMimeType) { - xhr.overrideMimeType(details.overrideMimeType); - } - if (details.headers) { - for (var header in details.headers) { - xhr.setRequestHeader(header, details.headers[header]); - } - } - xhr.send(details.data ? details.data : null); -} - -function GM_openInTab(url) { - window.open(url, ""); -} - -function GM_log(message) { - window.console.log(message); -} - -(function() { - function generateGreasemonkeyStub(name) { - return function() { - console.log("%s is not supported.", name); - }; - } - - var apis = ["GM_getValue", "GM_setValue", "GM_registerMenuCommand"]; - for (var i = 0, api; api = apis[i]; i++) { - window[api] = generateGreasemonkeyStub(api); - } -})(); diff --git a/extensions/renderer/resources/i18n_custom_bindings.js b/extensions/renderer/resources/i18n_custom_bindings.js deleted file mode 100644 index 38570f3..0000000 --- a/extensions/renderer/resources/i18n_custom_bindings.js +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2014 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 binding for the i18n API. - -var binding = require('binding').Binding.create('i18n'); - -var i18nNatives = requireNative('i18n'); -var GetL10nMessage = i18nNatives.GetL10nMessage; -var GetL10nUILanguage = i18nNatives.GetL10nUILanguage; - -binding.registerCustomHook(function(bindingsAPI, extensionId) { - var apiFunctions = bindingsAPI.apiFunctions; - - apiFunctions.setUpdateArgumentsPreValidate('getMessage', function() { - var args = $Array.slice(arguments); - - // The first argument is the message, and should be a string. - var message = args[0]; - if (typeof(message) !== 'string') { - console.warn(extensionId + ': the first argument to getMessage should ' + - 'be type "string", was ' + message + - ' (type "' + typeof(message) + '")'); - args[0] = String(message); - } - - return args; - }); - - apiFunctions.setHandleRequest('getMessage', - function(messageName, substitutions) { - return GetL10nMessage(messageName, substitutions, extensionId); - }); - - apiFunctions.setHandleRequest('getUILanguage', function() { - return GetL10nUILanguage(); - }); -}); - -exports.binding = binding.generate(); diff --git a/extensions/renderer/resources/image_util.js b/extensions/renderer/resources/image_util.js deleted file mode 100644 index b6cd1b1..0000000 --- a/extensions/renderer/resources/image_util.js +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2014 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. - -// This function takes an object |imageSpec| with the key |path| - -// corresponding to the internet URL to be translated - and optionally -// |width| and |height| which are the maximum dimensions to be used when -// converting the image. -function loadImageData(imageSpec, callbacks) { - var path = imageSpec.path; - var img = new Image(); - if (typeof callbacks.onerror === 'function') { - img.onerror = function() { - callbacks.onerror({ problem: 'could_not_load', path: path }); - }; - } - img.onload = function() { - var canvas = document.createElement('canvas'); - - if (img.width <= 0 || img.height <= 0) { - callbacks.onerror({ problem: 'image_size_invalid', path: path}); - return; - } - - var scaleFactor = 1; - if (imageSpec.width && imageSpec.width < img.width) - scaleFactor = imageSpec.width / img.width; - - if (imageSpec.height && imageSpec.height < img.height) { - var heightScale = imageSpec.height / img.height; - if (heightScale < scaleFactor) - scaleFactor = heightScale; - } - - canvas.width = img.width * scaleFactor; - canvas.height = img.height * scaleFactor; - - var canvas_context = canvas.getContext('2d'); - canvas_context.clearRect(0, 0, canvas.width, canvas.height); - canvas_context.drawImage(img, 0, 0, canvas.width, canvas.height); - try { - var imageData = canvas_context.getImageData( - 0, 0, canvas.width, canvas.height); - if (typeof callbacks.oncomplete === 'function') { - callbacks.oncomplete( - imageData.width, imageData.height, imageData.data.buffer); - } - } catch (e) { - if (typeof callbacks.onerror === 'function') { - callbacks.onerror({ problem: 'data_url_unavailable', path: path }); - } - } - } - img.src = path; -} - -function on_complete_index(index, err, loading, finished, callbacks) { - return function(width, height, imageData) { - delete loading[index]; - finished[index] = { width: width, height: height, data: imageData }; - if (err) - callbacks.onerror(index); - if ($Object.keys(loading).length == 0) - callbacks.oncomplete(finished); - } -} - -function loadAllImages(imageSpecs, callbacks) { - var loading = {}, finished = [], - index, pathname; - - for (var index = 0; index < imageSpecs.length; index++) { - loading[index] = imageSpecs[index]; - loadImageData(imageSpecs[index], { - oncomplete: on_complete_index(index, false, loading, finished, callbacks), - onerror: on_complete_index(index, true, loading, finished, callbacks) - }); - } -} - -exports.loadImageData = loadImageData; -exports.loadAllImages = loadAllImages; diff --git a/extensions/renderer/resources/json_schema.js b/extensions/renderer/resources/json_schema.js deleted file mode 100644 index 67c30c9..0000000 --- a/extensions/renderer/resources/json_schema.js +++ /dev/null @@ -1,525 +0,0 @@ -// Copyright 2014 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. - -// ----------------------------------------------------------------------------- -// NOTE: If you change this file you need to touch -// extension_renderer_resources.grd to have your change take effect. -// ----------------------------------------------------------------------------- - -//============================================================================== -// This file contains a class that implements a subset of JSON Schema. -// See: http://www.json.com/json-schema-proposal/ for more details. -// -// The following features of JSON Schema are not implemented: -// - requires -// - unique -// - disallow -// - union types (but replaced with 'choices') -// -// The following properties are not applicable to the interface exposed by -// this class: -// - options -// - readonly -// - title -// - description -// - format -// - default -// - transient -// - hidden -// -// There are also these departures from the JSON Schema proposal: -// - function and undefined types are supported -// - null counts as 'unspecified' for optional values -// - added the 'choices' property, to allow specifying a list of possible types -// for a value -// - by default an "object" typed schema does not allow additional properties. -// if present, "additionalProperties" is to be a schema against which all -// additional properties will be validated. -//============================================================================== - -var loadTypeSchema = require('utils').loadTypeSchema; -var CHECK = requireNative('logging').CHECK; - -function isInstanceOfClass(instance, className) { - while ((instance = instance.__proto__)) { - if (instance.constructor.name == className) - return true; - } - return false; -} - -function isOptionalValue(value) { - return typeof(value) === 'undefined' || value === null; -} - -function enumToString(enumValue) { - if (enumValue.name === undefined) - return enumValue; - - return enumValue.name; -} - -/** - * Validates an instance against a schema and accumulates errors. Usage: - * - * var validator = new JSONSchemaValidator(); - * validator.validate(inst, schema); - * if (validator.errors.length == 0) - * console.log("Valid!"); - * else - * console.log(validator.errors); - * - * The errors property contains a list of objects. Each object has two - * properties: "path" and "message". The "path" property contains the path to - * the key that had the problem, and the "message" property contains a sentence - * describing the error. - */ -function JSONSchemaValidator() { - this.errors = []; - this.types = []; -} - -JSONSchemaValidator.messages = { - invalidEnum: "Value must be one of: [*].", - propertyRequired: "Property is required.", - unexpectedProperty: "Unexpected property.", - arrayMinItems: "Array must have at least * items.", - arrayMaxItems: "Array must not have more than * items.", - itemRequired: "Item is required.", - stringMinLength: "String must be at least * characters long.", - stringMaxLength: "String must not be more than * characters long.", - stringPattern: "String must match the pattern: *.", - numberFiniteNotNan: "Value must not be *.", - numberMinValue: "Value must not be less than *.", - numberMaxValue: "Value must not be greater than *.", - numberIntValue: "Value must fit in a 32-bit signed integer.", - numberMaxDecimal: "Value must not have more than * decimal places.", - invalidType: "Expected '*' but got '*'.", - invalidTypeIntegerNumber: - "Expected 'integer' but got 'number', consider using Math.round().", - invalidChoice: "Value does not match any valid type choices.", - invalidPropertyType: "Missing property type.", - schemaRequired: "Schema value required.", - unknownSchemaReference: "Unknown schema reference: *.", - notInstance: "Object must be an instance of *." -}; - -/** - * Builds an error message. Key is the property in the |errors| object, and - * |opt_replacements| is an array of values to replace "*" characters with. - */ -JSONSchemaValidator.formatError = function(key, opt_replacements) { - var message = this.messages[key]; - if (opt_replacements) { - for (var i = 0; i < opt_replacements.length; i++) { - message = message.replace("*", opt_replacements[i]); - } - } - return message; -}; - -/** - * Classifies a value as one of the JSON schema primitive types. Note that we - * don't explicitly disallow 'function', because we want to allow functions in - * the input values. - */ -JSONSchemaValidator.getType = function(value) { - var s = typeof value; - - if (s == "object") { - if (value === null) { - return "null"; - } else if (Object.prototype.toString.call(value) == "[object Array]") { - return "array"; - } else if (typeof(ArrayBuffer) != "undefined" && - value.constructor == ArrayBuffer) { - return "binary"; - } - } else if (s == "number") { - if (value % 1 == 0) { - return "integer"; - } - } - - return s; -}; - -/** - * Add types that may be referenced by validated schemas that reference them - * with "$ref": <typeId>. Each type must be a valid schema and define an - * "id" property. - */ -JSONSchemaValidator.prototype.addTypes = function(typeOrTypeList) { - function addType(validator, type) { - if (!type.id) - throw new Error("Attempt to addType with missing 'id' property"); - validator.types[type.id] = type; - } - - if (typeOrTypeList instanceof Array) { - for (var i = 0; i < typeOrTypeList.length; i++) { - addType(this, typeOrTypeList[i]); - } - } else { - addType(this, typeOrTypeList); - } -} - -/** - * Returns a list of strings of the types that this schema accepts. - */ -JSONSchemaValidator.prototype.getAllTypesForSchema = function(schema) { - var schemaTypes = []; - if (schema.type) - $Array.push(schemaTypes, schema.type); - if (schema.choices) { - for (var i = 0; i < schema.choices.length; i++) { - var choiceTypes = this.getAllTypesForSchema(schema.choices[i]); - schemaTypes = $Array.concat(schemaTypes, choiceTypes); - } - } - var ref = schema['$ref']; - if (ref) { - var type = this.getOrAddType(ref); - CHECK(type, 'Could not find type ' + ref); - schemaTypes = $Array.concat(schemaTypes, this.getAllTypesForSchema(type)); - } - return schemaTypes; -}; - -JSONSchemaValidator.prototype.getOrAddType = function(typeName) { - if (!this.types[typeName]) - this.types[typeName] = loadTypeSchema(typeName); - return this.types[typeName]; -}; - -/** - * Returns true if |schema| would accept an argument of type |type|. - */ -JSONSchemaValidator.prototype.isValidSchemaType = function(type, schema) { - if (type == 'any') - return true; - - // TODO(kalman): I don't understand this code. How can type be "null"? - if (schema.optional && (type == "null" || type == "undefined")) - return true; - - var schemaTypes = this.getAllTypesForSchema(schema); - for (var i = 0; i < schemaTypes.length; i++) { - if (schemaTypes[i] == "any" || type == schemaTypes[i] || - (type == "integer" && schemaTypes[i] == "number")) - return true; - } - - return false; -}; - -/** - * Returns true if there is a non-null argument that both |schema1| and - * |schema2| would accept. - */ -JSONSchemaValidator.prototype.checkSchemaOverlap = function(schema1, schema2) { - var schema1Types = this.getAllTypesForSchema(schema1); - for (var i = 0; i < schema1Types.length; i++) { - if (this.isValidSchemaType(schema1Types[i], schema2)) - return true; - } - return false; -}; - -/** - * Validates an instance against a schema. The instance can be any JavaScript - * value and will be validated recursively. When this method returns, the - * |errors| property will contain a list of errors, if any. - */ -JSONSchemaValidator.prototype.validate = function(instance, schema, opt_path) { - var path = opt_path || ""; - - if (!schema) { - this.addError(path, "schemaRequired"); - return; - } - - // If this schema defines itself as reference type, save it in this.types. - if (schema.id) - this.types[schema.id] = schema; - - // If the schema has an extends property, the instance must validate against - // that schema too. - if (schema.extends) - this.validate(instance, schema.extends, path); - - // If the schema has a $ref property, the instance must validate against - // that schema too. It must be present in this.types to be referenced. - var ref = schema["$ref"]; - if (ref) { - if (!this.getOrAddType(ref)) - this.addError(path, "unknownSchemaReference", [ ref ]); - else - this.validate(instance, this.getOrAddType(ref), path) - } - - // If the schema has a choices property, the instance must validate against at - // least one of the items in that array. - if (schema.choices) { - this.validateChoices(instance, schema, path); - return; - } - - // If the schema has an enum property, the instance must be one of those - // values. - if (schema.enum) { - if (!this.validateEnum(instance, schema, path)) - return; - } - - if (schema.type && schema.type != "any") { - if (!this.validateType(instance, schema, path)) - return; - - // Type-specific validation. - switch (schema.type) { - case "object": - this.validateObject(instance, schema, path); - break; - case "array": - this.validateArray(instance, schema, path); - break; - case "string": - this.validateString(instance, schema, path); - break; - case "number": - case "integer": - this.validateNumber(instance, schema, path); - break; - } - } -}; - -/** - * Validates an instance against a choices schema. The instance must match at - * least one of the provided choices. - */ -JSONSchemaValidator.prototype.validateChoices = - function(instance, schema, path) { - var originalErrors = this.errors; - - for (var i = 0; i < schema.choices.length; i++) { - this.errors = []; - this.validate(instance, schema.choices[i], path); - if (this.errors.length == 0) { - this.errors = originalErrors; - return; - } - } - - this.errors = originalErrors; - this.addError(path, "invalidChoice"); -}; - -/** - * Validates an instance against a schema with an enum type. Populates the - * |errors| property, and returns a boolean indicating whether the instance - * validates. - */ -JSONSchemaValidator.prototype.validateEnum = function(instance, schema, path) { - for (var i = 0; i < schema.enum.length; i++) { - if (instance === enumToString(schema.enum[i])) - return true; - } - - this.addError(path, "invalidEnum", - [schema.enum.map(enumToString).join(", ")]); - return false; -}; - -/** - * Validates an instance against an object schema and populates the errors - * property. - */ -JSONSchemaValidator.prototype.validateObject = - function(instance, schema, path) { - if (schema.properties) { - for (var prop in schema.properties) { - // It is common in JavaScript to add properties to Object.prototype. This - // check prevents such additions from being interpreted as required - // schema properties. - // TODO(aa): If it ever turns out that we actually want this to work, - // there are other checks we could put here, like requiring that schema - // properties be objects that have a 'type' property. - if (!$Object.hasOwnProperty(schema.properties, prop)) - continue; - - var propPath = path ? path + "." + prop : prop; - if (schema.properties[prop] == undefined) { - this.addError(propPath, "invalidPropertyType"); - } else if (prop in instance && !isOptionalValue(instance[prop])) { - this.validate(instance[prop], schema.properties[prop], propPath); - } else if (!schema.properties[prop].optional) { - this.addError(propPath, "propertyRequired"); - } - } - } - - // If "instanceof" property is set, check that this object inherits from - // the specified constructor (function). - if (schema.isInstanceOf) { - if (!isInstanceOfClass(instance, schema.isInstanceOf)) - this.addError(propPath, "notInstance", [schema.isInstanceOf]); - } - - // Exit early from additional property check if "type":"any" is defined. - if (schema.additionalProperties && - schema.additionalProperties.type && - schema.additionalProperties.type == "any") { - return; - } - - // By default, additional properties are not allowed on instance objects. This - // can be overridden by setting the additionalProperties property to a schema - // which any additional properties must validate against. - for (var prop in instance) { - if (schema.properties && prop in schema.properties) - continue; - - // Any properties inherited through the prototype are ignored. - if (!$Object.hasOwnProperty(instance, prop)) - continue; - - var propPath = path ? path + "." + prop : prop; - if (schema.additionalProperties) - this.validate(instance[prop], schema.additionalProperties, propPath); - else - this.addError(propPath, "unexpectedProperty"); - } -}; - -/** - * Validates an instance against an array schema and populates the errors - * property. - */ -JSONSchemaValidator.prototype.validateArray = function(instance, schema, path) { - var typeOfItems = JSONSchemaValidator.getType(schema.items); - - if (typeOfItems == 'object') { - if (schema.minItems && instance.length < schema.minItems) { - this.addError(path, "arrayMinItems", [schema.minItems]); - } - - if (typeof schema.maxItems != "undefined" && - instance.length > schema.maxItems) { - this.addError(path, "arrayMaxItems", [schema.maxItems]); - } - - // If the items property is a single schema, each item in the array must - // have that schema. - for (var i = 0; i < instance.length; i++) { - this.validate(instance[i], schema.items, path + "." + i); - } - } else if (typeOfItems == 'array') { - // If the items property is an array of schemas, each item in the array must - // validate against the corresponding schema. - for (var i = 0; i < schema.items.length; i++) { - var itemPath = path ? path + "." + i : String(i); - if (i in instance && !isOptionalValue(instance[i])) { - this.validate(instance[i], schema.items[i], itemPath); - } else if (!schema.items[i].optional) { - this.addError(itemPath, "itemRequired"); - } - } - - if (schema.additionalProperties) { - for (var i = schema.items.length; i < instance.length; i++) { - var itemPath = path ? path + "." + i : String(i); - this.validate(instance[i], schema.additionalProperties, itemPath); - } - } else { - if (instance.length > schema.items.length) { - this.addError(path, "arrayMaxItems", [schema.items.length]); - } - } - } -}; - -/** - * Validates a string and populates the errors property. - */ -JSONSchemaValidator.prototype.validateString = - function(instance, schema, path) { - if (schema.minLength && instance.length < schema.minLength) - this.addError(path, "stringMinLength", [schema.minLength]); - - if (schema.maxLength && instance.length > schema.maxLength) - this.addError(path, "stringMaxLength", [schema.maxLength]); - - if (schema.pattern && !schema.pattern.test(instance)) - this.addError(path, "stringPattern", [schema.pattern]); -}; - -/** - * Validates a number and populates the errors property. The instance is - * assumed to be a number. - */ -JSONSchemaValidator.prototype.validateNumber = - function(instance, schema, path) { - // Forbid NaN, +Infinity, and -Infinity. Our APIs don't use them, and - // JSON serialization encodes them as 'null'. Re-evaluate supporting - // them if we add an API that could reasonably take them as a parameter. - if (isNaN(instance) || - instance == Number.POSITIVE_INFINITY || - instance == Number.NEGATIVE_INFINITY ) - this.addError(path, "numberFiniteNotNan", [instance]); - - if (schema.minimum !== undefined && instance < schema.minimum) - this.addError(path, "numberMinValue", [schema.minimum]); - - if (schema.maximum !== undefined && instance > schema.maximum) - this.addError(path, "numberMaxValue", [schema.maximum]); - - // Check for integer values outside of -2^31..2^31-1. - if (schema.type === "integer" && (instance | 0) !== instance) - this.addError(path, "numberIntValue", []); - - if (schema.maxDecimal && instance * Math.pow(10, schema.maxDecimal) % 1) - this.addError(path, "numberMaxDecimal", [schema.maxDecimal]); -}; - -/** - * Validates the primitive type of an instance and populates the errors - * property. Returns true if the instance validates, false otherwise. - */ -JSONSchemaValidator.prototype.validateType = function(instance, schema, path) { - var actualType = JSONSchemaValidator.getType(instance); - if (schema.type == actualType || - (schema.type == "number" && actualType == "integer")) { - return true; - } else if (schema.type == "integer" && actualType == "number") { - this.addError(path, "invalidTypeIntegerNumber"); - return false; - } else { - this.addError(path, "invalidType", [schema.type, actualType]); - return false; - } -}; - -/** - * Adds an error message. |key| is an index into the |messages| object. - * |replacements| is an array of values to replace '*' characters in the - * message. - */ -JSONSchemaValidator.prototype.addError = function(path, key, replacements) { - $Array.push(this.errors, { - path: path, - message: JSONSchemaValidator.formatError(key, replacements) - }); -}; - -/** - * Resets errors to an empty list so you can call 'validate' again. - */ -JSONSchemaValidator.prototype.resetErrors = function() { - this.errors = []; -}; - -exports.JSONSchemaValidator = JSONSchemaValidator; diff --git a/extensions/renderer/resources/last_error.js b/extensions/renderer/resources/last_error.js deleted file mode 100644 index 8d53371..0000000 --- a/extensions/renderer/resources/last_error.js +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2014 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. - -var GetAvailability = requireNative('v8_context').GetAvailability; -var GetGlobal = requireNative('sendRequest').GetGlobal; - -// Utility for setting chrome.*.lastError. -// -// A utility here is useful for two reasons: -// 1. For backwards compatibility we need to set chrome.extension.lastError, -// but not all contexts actually have access to the extension namespace. -// 2. When calling across contexts, the global object that gets lastError set -// needs to be that of the caller. We force callers to explicitly specify -// the chrome object to try to prevent bugs here. - -/** - * Sets the last error for |name| on |targetChrome| to |message| with an - * optional |stack|. - */ -function set(name, message, stack, targetChrome) { - var errorMessage = name + ': ' + message; - if (stack != null && stack != '') - errorMessage += '\n' + stack; - - if (!targetChrome) - throw new Error('No chrome object to set error: ' + errorMessage); - clear(targetChrome); // in case somebody has set a sneaky getter/setter - - var errorObject = { message: message }; - if (GetAvailability('extension.lastError').is_available) - targetChrome.extension.lastError = errorObject; - - assertRuntimeIsAvailable(); - - // We check to see if developers access runtime.lastError in order to decide - // whether or not to log it in the (error) console. - privates(targetChrome.runtime).accessedLastError = false; - $Object.defineProperty(targetChrome.runtime, 'lastError', { - configurable: true, - get: function() { - privates(targetChrome.runtime).accessedLastError = true; - return errorObject; - }, - set: function(error) { - errorObject = errorObject; - }}); -}; - -/** - * Check if anyone has checked chrome.runtime.lastError since it was set. - * @param {Object} targetChrome the Chrome object to check. - * @return boolean True if the lastError property was set. - */ -function hasAccessed(targetChrome) { - assertRuntimeIsAvailable(); - return privates(targetChrome.runtime).accessedLastError === true; -} - -/** - * Check whether there is an error set on |targetChrome| without setting - * |accessedLastError|. - * @param {Object} targetChrome the Chrome object to check. - * @return boolean Whether lastError has been set. - */ -function hasError(targetChrome) { - if (!targetChrome) - throw new Error('No target chrome to check'); - - assertRuntimeIsAvailable(); - if ('lastError' in targetChrome.runtime) - return true; - - return false; -}; - -/** - * Clears the last error on |targetChrome|. - */ -function clear(targetChrome) { - if (!targetChrome) - throw new Error('No target chrome to clear error'); - - if (GetAvailability('extension.lastError').is_available) - delete targetChrome.extension.lastError; - - assertRuntimeIsAvailable(); - delete targetChrome.runtime.lastError; - delete privates(targetChrome.runtime).accessedLastError; -}; - -function assertRuntimeIsAvailable() { - // chrome.runtime should always be available, but maybe it's disappeared for - // some reason? Add debugging for http://crbug.com/258526. - var runtimeAvailability = GetAvailability('runtime.lastError'); - if (!runtimeAvailability.is_available) { - throw new Error('runtime.lastError is not available: ' + - runtimeAvailability.message); - } - if (!chrome.runtime) - throw new Error('runtime namespace is null or undefined'); -} - -/** - * Runs |callback(args)| with last error args as in set(). - * - * The target chrome object is the global object's of the callback, so this - * method won't work if the real callback has been wrapped (etc). - */ -function run(name, message, stack, callback, args) { - var targetChrome = GetGlobal(callback).chrome; - set(name, message, stack, targetChrome); - try { - $Function.apply(callback, undefined, args); - } finally { - clear(targetChrome); - } -} - -exports.clear = clear; -exports.hasAccessed = hasAccessed; -exports.hasError = hasError; -exports.set = set; -exports.run = run; diff --git a/extensions/renderer/resources/messaging.js b/extensions/renderer/resources/messaging.js deleted file mode 100644 index c7a45de..0000000 --- a/extensions/renderer/resources/messaging.js +++ /dev/null @@ -1,386 +0,0 @@ -// Copyright 2014 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. - -// This contains unprivileged javascript APIs for extensions and apps. It -// can be loaded by any extension-related context, such as content scripts or -// background pages. See user_script_slave.cc for script that is loaded by -// content scripts only. - - // TODO(kalman): factor requiring chrome out of here. - var chrome = requireNative('chrome').GetChrome(); - var Event = require('event_bindings').Event; - var lastError = require('lastError'); - var logActivity = requireNative('activityLogger'); - var messagingNatives = requireNative('messaging_natives'); - var processNatives = requireNative('process'); - var unloadEvent = require('unload_event'); - var utils = require('utils'); - var messagingUtils = require('messaging_utils'); - - // The reserved channel name for the sendRequest/send(Native)Message APIs. - // Note: sendRequest is deprecated. - var kRequestChannel = "chrome.extension.sendRequest"; - var kMessageChannel = "chrome.runtime.sendMessage"; - var kNativeMessageChannel = "chrome.runtime.sendNativeMessage"; - - // Map of port IDs to port object. - var ports = {}; - - // Map of port IDs to unloadEvent listeners. Keep track of these to free the - // unloadEvent listeners when ports are closed. - var portReleasers = {}; - - // Change even to odd and vice versa, to get the other side of a given - // channel. - function getOppositePortId(portId) { return portId ^ 1; } - - // Port object. Represents a connection to another script context through - // which messages can be passed. - function PortImpl(portId, opt_name) { - this.portId_ = portId; - this.name = opt_name; - - var portSchema = {name: 'port', $ref: 'runtime.Port'}; - var options = {unmanaged: true}; - this.onDisconnect = new Event(null, [portSchema], options); - this.onMessage = new Event( - null, - [{name: 'message', type: 'any', optional: true}, portSchema], - options); - this.onDestroy_ = null; - } - - // Sends a message asynchronously to the context on the other end of this - // port. - PortImpl.prototype.postMessage = function(msg) { - // JSON.stringify doesn't support a root object which is undefined. - if (msg === undefined) - msg = null; - msg = $JSON.stringify(msg); - if (msg === undefined) { - // JSON.stringify can fail with unserializable objects. Log an error and - // drop the message. - // - // TODO(kalman/mpcomplete): it would be better to do the same validation - // here that we do for runtime.sendMessage (and variants), i.e. throw an - // schema validation Error, but just maintain the old behaviour until - // there's a good reason not to (http://crbug.com/263077). - console.error('Illegal argument to Port.postMessage'); - return; - } - messagingNatives.PostMessage(this.portId_, msg); - }; - - // Disconnects the port from the other end. - PortImpl.prototype.disconnect = function() { - messagingNatives.CloseChannel(this.portId_, true); - this.destroy_(); - }; - - PortImpl.prototype.destroy_ = function() { - var portId = this.portId_; - - if (this.onDestroy_) - this.onDestroy_(); - privates(this.onDisconnect).impl.destroy_(); - privates(this.onMessage).impl.destroy_(); - - messagingNatives.PortRelease(portId); - unloadEvent.removeListener(portReleasers[portId]); - - delete ports[portId]; - delete portReleasers[portId]; - }; - - // Returns true if the specified port id is in this context. This is used by - // the C++ to avoid creating the javascript message for all the contexts that - // don't care about a particular message. - function hasPort(portId) { - return portId in ports; - }; - - // Hidden port creation function. We don't want to expose an API that lets - // people add arbitrary port IDs to the port list. - function createPort(portId, opt_name) { - if (ports[portId]) - throw new Error("Port '" + portId + "' already exists."); - var port = new Port(portId, opt_name); - ports[portId] = port; - portReleasers[portId] = $Function.bind(messagingNatives.PortRelease, - this, - portId); - unloadEvent.addListener(portReleasers[portId]); - messagingNatives.PortAddRef(portId); - return port; - }; - - // Helper function for dispatchOnRequest. - function handleSendRequestError(isSendMessage, - responseCallbackPreserved, - sourceExtensionId, - targetExtensionId, - sourceUrl) { - var errorMsg = []; - var eventName = isSendMessage ? "runtime.onMessage" : "extension.onRequest"; - if (isSendMessage && !responseCallbackPreserved) { - $Array.push(errorMsg, - "The chrome." + eventName + " listener must return true if you " + - "want to send a response after the listener returns"); - } else { - $Array.push(errorMsg, - "Cannot send a response more than once per chrome." + eventName + - " listener per document"); - } - $Array.push(errorMsg, "(message was sent by extension" + sourceExtensionId); - if (sourceExtensionId != "" && sourceExtensionId != targetExtensionId) - $Array.push(errorMsg, "for extension " + targetExtensionId); - if (sourceUrl != "") - $Array.push(errorMsg, "for URL " + sourceUrl); - lastError.set(eventName, errorMsg.join(" ") + ").", null, chrome); - } - - // Helper function for dispatchOnConnect - function dispatchOnRequest(portId, channelName, sender, - sourceExtensionId, targetExtensionId, sourceUrl, - isExternal) { - var isSendMessage = channelName == kMessageChannel; - var requestEvent = null; - if (isSendMessage) { - if (chrome.runtime) { - requestEvent = isExternal ? chrome.runtime.onMessageExternal - : chrome.runtime.onMessage; - } - } else { - if (chrome.extension) { - requestEvent = isExternal ? chrome.extension.onRequestExternal - : chrome.extension.onRequest; - } - } - if (!requestEvent) - return false; - if (!requestEvent.hasListeners()) - return false; - var port = createPort(portId, channelName); - - function messageListener(request) { - var responseCallbackPreserved = false; - var responseCallback = function(response) { - if (port) { - port.postMessage(response); - privates(port).impl.destroy_(); - port = null; - } else { - // We nulled out port when sending the response, and now the page - // is trying to send another response for the same request. - handleSendRequestError(isSendMessage, responseCallbackPreserved, - sourceExtensionId, targetExtensionId); - } - }; - // In case the extension never invokes the responseCallback, and also - // doesn't keep a reference to it, we need to clean up the port. Do - // so by attaching to the garbage collection of the responseCallback - // using some native hackery. - messagingNatives.BindToGC(responseCallback, function() { - if (port) { - privates(port).impl.destroy_(); - port = null; - } - }); - var rv = requestEvent.dispatch(request, sender, responseCallback); - if (isSendMessage) { - responseCallbackPreserved = - rv && rv.results && $Array.indexOf(rv.results, true) > -1; - if (!responseCallbackPreserved && port) { - // If they didn't access the response callback, they're not - // going to send a response, so clean up the port immediately. - privates(port).impl.destroy_(); - port = null; - } - } - } - - privates(port).impl.onDestroy_ = function() { - port.onMessage.removeListener(messageListener); - }; - port.onMessage.addListener(messageListener); - - var eventName = isSendMessage ? "runtime.onMessage" : "extension.onRequest"; - if (isExternal) - eventName += "External"; - logActivity.LogEvent(targetExtensionId, - eventName, - [sourceExtensionId, sourceUrl]); - return true; - } - - // Called by native code when a channel has been opened to this context. - function dispatchOnConnect(portId, - channelName, - sourceTab, - sourceExtensionId, - targetExtensionId, - sourceUrl, - tlsChannelId) { - // Only create a new Port if someone is actually listening for a connection. - // In addition to being an optimization, this also fixes a bug where if 2 - // channels were opened to and from the same process, closing one would - // close both. - var extensionId = processNatives.GetExtensionId(); - if (targetExtensionId != extensionId) - return false; // not for us - - if (ports[getOppositePortId(portId)]) - return false; // this channel was opened by us, so ignore it - - // Determine whether this is coming from another extension, so we can use - // the right event. - var isExternal = sourceExtensionId != extensionId; - - var sender = {}; - if (sourceExtensionId != '') - sender.id = sourceExtensionId; - if (sourceUrl) - sender.url = sourceUrl; - if (sourceTab) - sender.tab = sourceTab; - if (tlsChannelId !== undefined) - sender.tlsChannelId = tlsChannelId; - - // Special case for sendRequest/onRequest and sendMessage/onMessage. - if (channelName == kRequestChannel || channelName == kMessageChannel) { - return dispatchOnRequest(portId, channelName, sender, - sourceExtensionId, targetExtensionId, sourceUrl, - isExternal); - } - - var connectEvent = null; - if (chrome.runtime) { - connectEvent = isExternal ? chrome.runtime.onConnectExternal - : chrome.runtime.onConnect; - } - if (!connectEvent) - return false; - if (!connectEvent.hasListeners()) - return false; - - var port = createPort(portId, channelName); - port.sender = sender; - if (processNatives.manifestVersion < 2) - port.tab = port.sender.tab; - - var eventName = (isExternal ? - "runtime.onConnectExternal" : "runtime.onConnect"); - connectEvent.dispatch(port); - logActivity.LogEvent(targetExtensionId, - eventName, - [sourceExtensionId]); - return true; - }; - - // Called by native code when a channel has been closed. - function dispatchOnDisconnect(portId, errorMessage) { - var port = ports[portId]; - if (port) { - // Update the renderer's port bookkeeping, without notifying the browser. - messagingNatives.CloseChannel(portId, false); - if (errorMessage) - lastError.set('Port', errorMessage, null, chrome); - try { - port.onDisconnect.dispatch(port); - } finally { - privates(port).impl.destroy_(); - lastError.clear(chrome); - } - } - }; - - // Called by native code when a message has been sent to the given port. - function dispatchOnMessage(msg, portId) { - var port = ports[portId]; - if (port) { - if (msg) - msg = $JSON.parse(msg); - port.onMessage.dispatch(msg, port); - } - }; - - // Shared implementation used by tabs.sendMessage and runtime.sendMessage. - function sendMessageImpl(port, request, responseCallback) { - if (port.name != kNativeMessageChannel) - port.postMessage(request); - - if (port.name == kMessageChannel && !responseCallback) { - // TODO(mpcomplete): Do this for the old sendRequest API too, after - // verifying it doesn't break anything. - // Go ahead and disconnect immediately if the sender is not expecting - // a response. - port.disconnect(); - return; - } - - // Ensure the callback exists for the older sendRequest API. - if (!responseCallback) - responseCallback = function() {}; - - // Note: make sure to manually remove the onMessage/onDisconnect listeners - // that we added before destroying the Port, a workaround to a bug in Port - // where any onMessage/onDisconnect listeners added but not removed will - // be leaked when the Port is destroyed. - // http://crbug.com/320723 tracks a sustainable fix. - - function disconnectListener() { - // For onDisconnects, we only notify the callback if there was an error. - if (chrome.runtime && chrome.runtime.lastError) - responseCallback(); - } - - function messageListener(response) { - try { - responseCallback(response); - } finally { - port.disconnect(); - } - } - - privates(port).impl.onDestroy_ = function() { - port.onDisconnect.removeListener(disconnectListener); - port.onMessage.removeListener(messageListener); - }; - port.onDisconnect.addListener(disconnectListener); - port.onMessage.addListener(messageListener); - }; - - function sendMessageUpdateArguments(functionName, hasOptionsArgument) { - // skip functionName and hasOptionsArgument - var args = $Array.slice(arguments, 2); - var alignedArgs = messagingUtils.alignSendMessageArguments(args, - hasOptionsArgument); - if (!alignedArgs) - throw new Error('Invalid arguments to ' + functionName + '.'); - return alignedArgs; - } - -var Port = utils.expose('Port', PortImpl, { functions: [ - 'disconnect', - 'postMessage' - ], - properties: [ - 'name', - 'onDisconnect', - 'onMessage' - ] }); - -exports.kRequestChannel = kRequestChannel; -exports.kMessageChannel = kMessageChannel; -exports.kNativeMessageChannel = kNativeMessageChannel; -exports.Port = Port; -exports.createPort = createPort; -exports.sendMessageImpl = sendMessageImpl; -exports.sendMessageUpdateArguments = sendMessageUpdateArguments; - -// For C++ code to call. -exports.hasPort = hasPort; -exports.dispatchOnConnect = dispatchOnConnect; -exports.dispatchOnDisconnect = dispatchOnDisconnect; -exports.dispatchOnMessage = dispatchOnMessage; diff --git a/extensions/renderer/resources/messaging_utils.js b/extensions/renderer/resources/messaging_utils.js deleted file mode 100644 index d1b563d..0000000 --- a/extensions/renderer/resources/messaging_utils.js +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2014 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. - -// Routines used to normalize arguments to messaging functions. - -function alignSendMessageArguments(args, hasOptionsArgument) { - // Align missing (optional) function arguments with the arguments that - // schema validation is expecting, e.g. - // extension.sendRequest(req) -> extension.sendRequest(null, req) - // extension.sendRequest(req, cb) -> extension.sendRequest(null, req, cb) - if (!args || !args.length) - return null; - var lastArg = args.length - 1; - - // responseCallback (last argument) is optional. - var responseCallback = null; - if (typeof args[lastArg] == 'function') - responseCallback = args[lastArg--]; - - var options = null; - if (hasOptionsArgument && lastArg >= 1) { - // options (third argument) is optional. It can also be ambiguous which - // argument it should match. If there are more than two arguments remaining, - // options is definitely present: - if (lastArg > 1) { - options = args[lastArg--]; - } else { - // Exactly two arguments remaining. If the first argument is a string, - // it should bind to targetId, and the second argument should bind to - // request, which is required. In other words, when two arguments remain, - // only bind options when the first argument cannot bind to targetId. - if (!(args[0] === null || typeof args[0] == 'string')) - options = args[lastArg--]; - } - } - - // request (second argument) is required. - var request = args[lastArg--]; - - // targetId (first argument, extensionId in the manifest) is optional. - var targetId = null; - if (lastArg >= 0) - targetId = args[lastArg--]; - - if (lastArg != -1) - return null; - if (hasOptionsArgument) - return [targetId, request, options, responseCallback]; - return [targetId, request, responseCallback]; -} - -exports.alignSendMessageArguments = alignSendMessageArguments; diff --git a/extensions/renderer/resources/permissions_custom_bindings.js b/extensions/renderer/resources/permissions_custom_bindings.js deleted file mode 100644 index 60edfaa..0000000 --- a/extensions/renderer/resources/permissions_custom_bindings.js +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2014 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 binding for the Permissions API. - -var binding = require('binding').Binding.create('permissions'); - -var Event = require('event_bindings').Event; - -// These custom binding are only necessary because it is not currently -// possible to have a union of types as the type of the items in an array. -// Once that is fixed, this entire file should go away. -// See, -// https://code.google.com/p/chromium/issues/detail?id=162044 -// https://code.google.com/p/chromium/issues/detail?id=162042 -// TODO(bryeung): delete this file. -binding.registerCustomHook(function(api) { - var apiFunctions = api.apiFunctions; - var permissions = api.compiledApi; - - function maybeConvertToObject(str) { - var parts = $String.split(str, '|'); - if (parts.length != 2) - return str; - - var ret = {}; - ret[parts[0]] = JSON.parse(parts[1]); - return ret; - } - - function convertObjectPermissionsToStrings() { - if (arguments.length < 1) - return arguments; - - var args = arguments[0].permissions; - if (!args) - return arguments; - - for (var i = 0; i < args.length; i += 1) { - if (typeof(args[i]) == 'object') { - var a = args[i]; - var keys = $Object.keys(a); - if (keys.length != 1) { - throw new Error("Too many keys in object-style permission."); - } - arguments[0].permissions[i] = keys[0] + '|' + - JSON.stringify(a[keys[0]]); - } - } - - return arguments; - } - - // Convert complex permissions to strings so they validate against the schema - apiFunctions.setUpdateArgumentsPreValidate( - 'contains', convertObjectPermissionsToStrings); - apiFunctions.setUpdateArgumentsPreValidate( - 'remove', convertObjectPermissionsToStrings); - apiFunctions.setUpdateArgumentsPreValidate( - 'request', convertObjectPermissionsToStrings); - - // Convert complex permissions back to objects - apiFunctions.setCustomCallback('getAll', - function(name, request, response) { - for (var i = 0; i < response.permissions.length; i += 1) { - response.permissions[i] = - maybeConvertToObject(response.permissions[i]); - } - - // Since the schema says Permissions.permissions contains strings and - // not objects, validation will fail after the for-loop above. This - // skips validation and calls the callback directly, then clears it so - // that handleResponse doesn't call it again. - try { - if (request.callback) - $Function.apply(request.callback, request, [response]); - } finally { - delete request.callback; - } - }); - - // Also convert complex permissions back to objects for events. The - // dispatchToListener call happens after argument validation, which works - // around the problem that Permissions.permissions is supposed to be a list - // of strings. - permissions.onAdded.dispatchToListener = function(callback, args) { - for (var i = 0; i < args[0].permissions.length; i += 1) { - args[0].permissions[i] = maybeConvertToObject(args[0].permissions[i]); - } - $Function.call(Event.prototype.dispatchToListener, this, callback, args); - }; - permissions.onRemoved.dispatchToListener = - permissions.onAdded.dispatchToListener; -}); - -exports.binding = binding.generate(); diff --git a/extensions/renderer/resources/platform_app.css b/extensions/renderer/resources/platform_app.css deleted file mode 100644 index eb241de..0000000 --- a/extensions/renderer/resources/platform_app.css +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2014 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. - * - * A style sheet for Chrome apps. - */ - -@namespace "http://www.w3.org/1999/xhtml"; - -body { - -webkit-user-select: none; - cursor: default; - font-family: $FONTFAMILY; - font-size: $FONTSIZE; -} - -webview, adview { - display: inline-block; - width: 300px; - height: 300px; -} - -html, body { - overflow: hidden; -} - -img, a { - -webkit-user-drag: none; -} - -[contenteditable], input { - -webkit-user-select: auto; -} - diff --git a/extensions/renderer/resources/platform_app.js b/extensions/renderer/resources/platform_app.js deleted file mode 100644 index 16470a5..0000000 --- a/extensions/renderer/resources/platform_app.js +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright 2014 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. - -var $console = window.console; - -/** - * Returns a function that logs a 'not available' error to the console and - * returns undefined. - * - * @param {string} messagePrefix text to prepend to the exception message. - */ -function generateDisabledMethodStub(messagePrefix, opt_messageSuffix) { - var message = messagePrefix + ' is not available in packaged apps.'; - if (opt_messageSuffix) message = message + ' ' + opt_messageSuffix; - return function() { - $console.error(message); - return; - }; -} - -/** - * Returns a function that throws a 'not available' error. - * - * @param {string} messagePrefix text to prepend to the exception message. - */ -function generateThrowingMethodStub(messagePrefix, opt_messageSuffix) { - var message = messagePrefix + ' is not available in packaged apps.'; - if (opt_messageSuffix) message = message + ' ' + opt_messageSuffix; - return function() { - throw new Error(message); - }; -} - -/** - * Replaces the given methods of the passed in object with stubs that log - * 'not available' errors to the console and return undefined. - * - * This should be used on methods attached via non-configurable properties, - * such as window.alert. disableGetters should be used when possible, because - * it is friendlier towards feature detection. - * - * In most cases, the useThrowingStubs should be false, so the stubs used to - * replace the methods log an error to the console, but allow the calling code - * to continue. We shouldn't break library code that uses feature detection - * responsibly, such as: - * if(window.confirm) { - * var result = window.confirm('Are you sure you want to delete ...?'); - * ... - * } - * - * useThrowingStubs should only be true for methods that are deprecated in the - * Web platform, and should not be used by a responsible library, even in - * conjunction with feature detection. A great example is document.write(), as - * the HTML5 specification recommends against using it, and says that its - * behavior is unreliable. No reasonable library code should ever use it. - * HTML5 spec: http://www.w3.org/TR/html5/dom.html#dom-document-write - * - * @param {Object} object The object with methods to disable. The prototype is - * preferred. - * @param {string} objectName The display name to use in the error message - * thrown by the stub (this is the name that the object is commonly referred - * to by web developers, e.g. "document" instead of "HTMLDocument"). - * @param {Array.<string>} methodNames names of methods to disable. - * @param {Boolean} useThrowingStubs if true, the replaced methods will throw - * an error instead of silently returning undefined - */ -function disableMethods(object, objectName, methodNames, useThrowingStubs) { - $Array.forEach(methodNames, function(methodName) { - var messagePrefix = objectName + '.' + methodName + '()'; - object[methodName] = useThrowingStubs ? - generateThrowingMethodStub(messagePrefix) : - generateDisabledMethodStub(messagePrefix); - }); -} - -/** - * Replaces the given properties of the passed in object with stubs that log - * 'not available' warnings to the console and return undefined when gotten. If - * a property's setter is later invoked, the getter and setter are restored to - * default behaviors. - * - * @param {Object} object The object with properties to disable. The prototype - * is preferred. - * @param {string} objectName The display name to use in the error message - * thrown by the getter stub (this is the name that the object is commonly - * referred to by web developers, e.g. "document" instead of - * "HTMLDocument"). - * @param {Array.<string>} propertyNames names of properties to disable. - */ -function disableGetters(object, objectName, propertyNames, opt_messageSuffix) { - $Array.forEach(propertyNames, function(propertyName) { - var stub = generateDisabledMethodStub(objectName + '.' + propertyName, - opt_messageSuffix); - stub._is_platform_app_disabled_getter = true; - $Object.defineProperty(object, propertyName, { - configurable: true, - enumerable: false, - get: stub, - set: function(value) { - var descriptor = $Object.getOwnPropertyDescriptor(this, propertyName); - if (!descriptor || !descriptor.get || - descriptor.get._is_platform_app_disabled_getter) { - // The stub getter is still defined. Blow-away the property to - // restore default getter/setter behaviors and re-create it with the - // given value. - delete this[propertyName]; - this[propertyName] = value; - } else { - // Do nothing. If some custom getter (not ours) has been defined, - // there would be no way to read back the value stored by a default - // setter. Also, the only way to clear a custom getter is to first - // delete the property. Therefore, the value we have here should - // just go into a black hole. - } - } - }); - }); -} - -/** - * Replaces the given properties of the passed in object with stubs that log - * 'not available' warnings to the console when set. - * - * @param {Object} object The object with properties to disable. The prototype - * is preferred. - * @param {string} objectName The display name to use in the error message - * thrown by the setter stub (this is the name that the object is commonly - * referred to by web developers, e.g. "document" instead of - * "HTMLDocument"). - * @param {Array.<string>} propertyNames names of properties to disable. - */ -function disableSetters(object, objectName, propertyNames, opt_messageSuffix) { - $Array.forEach(propertyNames, function(propertyName) { - var stub = generateDisabledMethodStub(objectName + '.' + propertyName, - opt_messageSuffix); - $Object.defineProperty(object, propertyName, { - configurable: true, - enumerable: false, - get: function() { - return; - }, - set: stub - }); - }); -} - -// Disable benign Document methods. -disableMethods(HTMLDocument.prototype, 'document', ['open', 'clear', 'close']); - -// Replace evil Document methods with exception-throwing stubs. -disableMethods(HTMLDocument.prototype, 'document', ['write', 'writeln'], true); - -// Disable history. -Object.defineProperty(window, "history", { value: {} }); -disableGetters(window.history, 'history', ['back', 'forward', 'go', 'length']); - -// Disable find. -disableMethods(Window.prototype, 'window', ['find']); - -// Disable modal dialogs. Shell windows disable these anyway, but it's nice to -// warn. -disableMethods(Window.prototype, 'window', ['alert', 'confirm', 'prompt']); - -// Disable window.*bar. -disableGetters(window, 'window', - ['locationbar', 'menubar', 'personalbar', 'scrollbars', 'statusbar', - 'toolbar']); - -// Disable window.localStorage. -// Sometimes DOM security policy prevents us from doing this (e.g. for data: -// URLs) so wrap in try-catch. -try { - disableGetters(window, 'window', - ['localStorage'], - 'Use chrome.storage.local instead.'); -} catch (e) {} - -// Document instance properties that we wish to disable need to be set when -// the document begins loading, since only then will the "document" reference -// point to the page's document (it will be reset between now and then). -// We can't listen for the "readystatechange" event on the document (because -// the object that it's dispatched on doesn't exist yet), but we can instead -// do it at the window level in the capturing phase. -window.addEventListener('readystatechange', function(event) { - if (document.readyState != 'loading') - return; - - // Deprecated document properties from - // https://developer.mozilla.org/en/DOM/document. - // To deprecate document.all, simply changing its getter and setter would - // activate its cache mechanism, and degrade the performance. Here we assign - // it first to 'undefined' to avoid this. - document.all = undefined; - disableGetters(document, 'document', - ['alinkColor', 'all', 'bgColor', 'fgColor', 'linkColor', 'vlinkColor']); -}, true); - -// Disable onunload, onbeforeunload. -disableSetters(Window.prototype, 'window', ['onbeforeunload', 'onunload']); -var windowAddEventListener = Window.prototype.addEventListener; -Window.prototype.addEventListener = function(type) { - if (type === 'unload' || type === 'beforeunload') - generateDisabledMethodStub(type)(); - else - return $Function.apply(windowAddEventListener, window, arguments); -}; diff --git a/extensions/renderer/resources/runtime_custom_bindings.js b/extensions/renderer/resources/runtime_custom_bindings.js deleted file mode 100644 index 88f4f5e..0000000 --- a/extensions/renderer/resources/runtime_custom_bindings.js +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright 2014 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 binding for the runtime API. - -var binding = require('binding').Binding.create('runtime'); - -var messaging = require('messaging'); -var runtimeNatives = requireNative('runtime'); -var unloadEvent = require('unload_event'); -var process = requireNative('process'); -var forEach = require('utils').forEach; - -var backgroundPage = window; -var backgroundRequire = require; -var contextType = process.GetContextType(); -if (contextType == 'BLESSED_EXTENSION' || - contextType == 'UNBLESSED_EXTENSION') { - var manifest = runtimeNatives.GetManifest(); - if (manifest.app && manifest.app.background) { - // Get the background page if one exists. Otherwise, default to the current - // window. - backgroundPage = runtimeNatives.GetExtensionViews(-1, 'BACKGROUND')[0]; - if (backgroundPage) { - var GetModuleSystem = requireNative('v8_context').GetModuleSystem; - backgroundRequire = GetModuleSystem(backgroundPage).require; - } else { - backgroundPage = window; - } - } -} - -// For packaged apps, all windows use the bindFileEntryCallback from the -// background page so their FileEntry objects have the background page's context -// as their own. This allows them to be used from other windows (including the -// background page) after the original window is closed. -if (window == backgroundPage) { - var lastError = require('lastError'); - var fileSystemNatives = requireNative('file_system_natives'); - var GetIsolatedFileSystem = fileSystemNatives.GetIsolatedFileSystem; - var bindDirectoryEntryCallback = function(functionName, apiFunctions) { - apiFunctions.setCustomCallback(functionName, - function(name, request, response) { - if (request.callback && response) { - var callback = request.callback; - request.callback = null; - - var fileSystemId = response.fileSystemId; - var baseName = response.baseName; - var fs = GetIsolatedFileSystem(fileSystemId); - - try { - fs.root.getDirectory(baseName, {}, callback, function(fileError) { - lastError.run('runtime.' + functionName, - 'Error getting Entry, code: ' + fileError.code, - request.stack, - callback); - }); - } catch (e) { - lastError.run('runtime.' + functionName, - 'Error: ' + e.stack, - request.stack, - callback); - } - } - }); - }; -} else { - // Force the runtime API to be loaded in the background page. Using - // backgroundPageModuleSystem.require('runtime') is insufficient as - // requireNative is only allowed while lazily loading an API. - backgroundPage.chrome.runtime; - var bindDirectoryEntryCallback = backgroundRequire( - 'runtime').bindDirectoryEntryCallback; -} - -binding.registerCustomHook(function(binding, id, contextType) { - var apiFunctions = binding.apiFunctions; - var runtime = binding.compiledApi; - - // - // Unprivileged APIs. - // - - runtime.id = id; - - apiFunctions.setHandleRequest('getManifest', function() { - return runtimeNatives.GetManifest(); - }); - - apiFunctions.setHandleRequest('getURL', function(path) { - path = String(path); - if (!path.length || path[0] != '/') - path = '/' + path; - return 'chrome-extension://' + id + path; - }); - - var sendMessageUpdateArguments = messaging.sendMessageUpdateArguments; - apiFunctions.setUpdateArgumentsPreValidate('sendMessage', - $Function.bind(sendMessageUpdateArguments, null, 'sendMessage', - true /* hasOptionsArgument */)); - apiFunctions.setUpdateArgumentsPreValidate('sendNativeMessage', - $Function.bind(sendMessageUpdateArguments, null, 'sendNativeMessage', - false /* hasOptionsArgument */)); - - apiFunctions.setHandleRequest('sendMessage', - function(targetId, message, options, responseCallback) { - var connectOptions = {name: messaging.kMessageChannel}; - forEach(options, function(k, v) { - connectOptions[k] = v; - }); - var port = runtime.connect(targetId || runtime.id, connectOptions); - messaging.sendMessageImpl(port, message, responseCallback); - }); - - apiFunctions.setHandleRequest('sendNativeMessage', - function(targetId, message, responseCallback) { - var port = runtime.connectNative(targetId); - messaging.sendMessageImpl(port, message, responseCallback); - }); - - apiFunctions.setUpdateArgumentsPreValidate('connect', function() { - // Align missing (optional) function arguments with the arguments that - // schema validation is expecting, e.g. - // runtime.connect() -> runtime.connect(null, null) - // runtime.connect({}) -> runtime.connect(null, {}) - var nextArg = 0; - - // targetId (first argument) is optional. - var targetId = null; - if (typeof(arguments[nextArg]) == 'string') - targetId = arguments[nextArg++]; - - // connectInfo (second argument) is optional. - var connectInfo = null; - if (typeof(arguments[nextArg]) == 'object') - connectInfo = arguments[nextArg++]; - - if (nextArg != arguments.length) - throw new Error('Invalid arguments to connect.'); - return [targetId, connectInfo]; - }); - - apiFunctions.setUpdateArgumentsPreValidate('connectNative', - function(appName) { - if (typeof(appName) !== 'string') { - throw new Error('Invalid arguments to connectNative.'); - } - return [appName]; - }); - - apiFunctions.setHandleRequest('connect', function(targetId, connectInfo) { - // Don't let orphaned content scripts communicate with their extension. - // http://crbug.com/168263 - if (unloadEvent.wasDispatched) - throw new Error('Error connecting to extension ' + targetId); - - if (!targetId) - targetId = runtime.id; - - var name = ''; - if (connectInfo && connectInfo.name) - name = connectInfo.name; - - var includeTlsChannelId = - !!(connectInfo && connectInfo.includeTlsChannelId); - - var portId = runtimeNatives.OpenChannelToExtension(targetId, name, - includeTlsChannelId); - if (portId >= 0) - return messaging.createPort(portId, name); - }); - - // - // Privileged APIs. - // - if (contextType != 'BLESSED_EXTENSION') - return; - - apiFunctions.setHandleRequest('connectNative', - function(nativeAppName) { - if (!unloadEvent.wasDispatched) { - var portId = runtimeNatives.OpenChannelToNativeApp(runtime.id, - nativeAppName); - if (portId >= 0) - return messaging.createPort(portId, ''); - } - throw new Error('Error connecting to native app: ' + nativeAppName); - }); - - apiFunctions.setCustomCallback('getBackgroundPage', - function(name, request, response) { - if (request.callback) { - var bg = runtimeNatives.GetExtensionViews(-1, 'BACKGROUND')[0] || null; - request.callback(bg); - } - request.callback = null; - }); - - bindDirectoryEntryCallback('getPackageDirectoryEntry', apiFunctions); -}); - -exports.bindDirectoryEntryCallback = bindDirectoryEntryCallback; -exports.binding = binding.generate(); diff --git a/extensions/renderer/resources/schema_utils.js b/extensions/renderer/resources/schema_utils.js deleted file mode 100644 index c0cb777..0000000 --- a/extensions/renderer/resources/schema_utils.js +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2014 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. - -// Routines used to validate and normalize arguments. -// TODO(benwells): unit test this file. - -var JSONSchemaValidator = require('json_schema').JSONSchemaValidator; - -var schemaValidator = new JSONSchemaValidator(); - -// Validate arguments. -function validate(args, parameterSchemas) { - if (args.length > parameterSchemas.length) - throw new Error("Too many arguments."); - for (var i = 0; i < parameterSchemas.length; i++) { - if (i in args && args[i] !== null && args[i] !== undefined) { - schemaValidator.resetErrors(); - schemaValidator.validate(args[i], parameterSchemas[i]); - if (schemaValidator.errors.length == 0) - continue; - var message = "Invalid value for argument " + (i + 1) + ". "; - for (var i = 0, err; - err = schemaValidator.errors[i]; i++) { - if (err.path) { - message += "Property '" + err.path + "': "; - } - message += err.message; - message = message.substring(0, message.length - 1); - message += ", "; - } - message = message.substring(0, message.length - 2); - message += "."; - throw new Error(message); - } else if (!parameterSchemas[i].optional) { - throw new Error("Parameter " + (i + 1) + " (" + - parameterSchemas[i].name + ") is required."); - } - } -} - -// Generate all possible signatures for a given API function. -function getSignatures(parameterSchemas) { - if (parameterSchemas.length === 0) - return [[]]; - var signatures = []; - var remaining = getSignatures($Array.slice(parameterSchemas, 1)); - for (var i = 0; i < remaining.length; i++) - $Array.push(signatures, $Array.concat([parameterSchemas[0]], remaining[i])) - if (parameterSchemas[0].optional) - return $Array.concat(signatures, remaining); - return signatures; -}; - -// Return true if arguments match a given signature's schema. -function argumentsMatchSignature(args, candidateSignature) { - if (args.length != candidateSignature.length) - return false; - for (var i = 0; i < candidateSignature.length; i++) { - var argType = JSONSchemaValidator.getType(args[i]); - if (!schemaValidator.isValidSchemaType(argType, - candidateSignature[i])) - return false; - } - return true; -}; - -// Finds the function signature for the given arguments. -function resolveSignature(args, definedSignature) { - var candidateSignatures = getSignatures(definedSignature); - for (var i = 0; i < candidateSignatures.length; i++) { - if (argumentsMatchSignature(args, candidateSignatures[i])) - return candidateSignatures[i]; - } - return null; -}; - -// Returns a string representing the defined signature of the API function. -// Example return value for chrome.windows.getCurrent: -// "windows.getCurrent(optional object populate, function callback)" -function getParameterSignatureString(name, definedSignature) { - var getSchemaTypeString = function(schema) { - var schemaTypes = schemaValidator.getAllTypesForSchema(schema); - var typeName = schemaTypes.join(" or ") + " " + schema.name; - if (schema.optional) - return "optional " + typeName; - return typeName; - }; - var typeNames = definedSignature.map(getSchemaTypeString); - return name + "(" + typeNames.join(", ") + ")"; -}; - -// Returns a string representing a call to an API function. -// Example return value for call: chrome.windows.get(1, callback) is: -// "windows.get(int, function)" -function getArgumentSignatureString(name, args) { - var typeNames = args.map(JSONSchemaValidator.getType); - return name + "(" + typeNames.join(", ") + ")"; -}; - -// Finds the correct signature for the given arguments, then validates the -// arguments against that signature. Returns a 'normalized' arguments list -// where nulls are inserted where optional parameters were omitted. -// |args| is expected to be an array. -function normalizeArgumentsAndValidate(args, funDef) { - if (funDef.allowAmbiguousOptionalArguments) { - validate(args, funDef.definition.parameters); - return args; - } - var definedSignature = funDef.definition.parameters; - var resolvedSignature = resolveSignature(args, definedSignature); - if (!resolvedSignature) - throw new Error("Invocation of form " + - getArgumentSignatureString(funDef.name, args) + - " doesn't match definition " + - getParameterSignatureString(funDef.name, definedSignature)); - validate(args, resolvedSignature); - var normalizedArgs = []; - var ai = 0; - for (var si = 0; si < definedSignature.length; si++) { - if (definedSignature[si] === resolvedSignature[ai]) - $Array.push(normalizedArgs, args[ai++]); - else - $Array.push(normalizedArgs, null); - } - return normalizedArgs; -}; - -// Validates that a given schema for an API function is not ambiguous. -function isFunctionSignatureAmbiguous(functionDef) { - if (functionDef.allowAmbiguousOptionalArguments) - return false; - var signaturesAmbiguous = function(signature1, signature2) { - if (signature1.length != signature2.length) - return false; - for (var i = 0; i < signature1.length; i++) { - if (!schemaValidator.checkSchemaOverlap( - signature1[i], signature2[i])) - return false; - } - return true; - }; - var candidateSignatures = getSignatures(functionDef.parameters); - for (var i = 0; i < candidateSignatures.length; i++) { - for (var j = i + 1; j < candidateSignatures.length; j++) { - if (signaturesAmbiguous(candidateSignatures[i], candidateSignatures[j])) - return true; - } - } - return false; -}; - -exports.isFunctionSignatureAmbiguous = isFunctionSignatureAmbiguous; -exports.normalizeArgumentsAndValidate = normalizeArgumentsAndValidate; -exports.schemaValidator = schemaValidator; -exports.validate = validate; diff --git a/extensions/renderer/resources/send_request.js b/extensions/renderer/resources/send_request.js deleted file mode 100644 index 8402843..0000000 --- a/extensions/renderer/resources/send_request.js +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright 2014 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. - -var handleUncaughtException = require('uncaught_exception_handler').handle; -var lastError = require('lastError'); -var logging = requireNative('logging'); -var natives = requireNative('sendRequest'); -var processNatives = requireNative('process'); -var validate = require('schemaUtils').validate; - -// All outstanding requests from sendRequest(). -var requests = {}; - -// Used to prevent double Activity Logging for API calls that use both custom -// bindings and ExtensionFunctions (via sendRequest). -var calledSendRequest = false; - -// Runs a user-supplied callback safely. -function safeCallbackApply(name, request, callback, args) { - try { - $Function.apply(callback, request, args); - } catch (e) { - var errorMessage = "Error in response to " + name + ": " + e; - if (request.stack && request.stack != '') - errorMessage += "\n" + request.stack; - handleUncaughtException(errorMessage, e); - } -} - -// Callback handling. -function handleResponse(requestId, name, success, responseList, error) { - // The chrome objects we will set lastError on. Really we should only be - // setting this on the callback's chrome object, but set on ours too since - // it's conceivable that something relies on that. - var callerChrome = chrome; - - try { - var request = requests[requestId]; - logging.DCHECK(request != null); - - // lastError needs to be set on the caller's chrome object no matter what, - // though chances are it's the same as ours (it will be different when - // calling API methods on other contexts). - if (request.callback) - callerChrome = natives.GetGlobal(request.callback).chrome; - - lastError.clear(chrome); - if (callerChrome !== chrome) - lastError.clear(callerChrome); - - if (!success) { - if (!error) - error = "Unknown error."; - lastError.set(name, error, request.stack, chrome); - if (callerChrome !== chrome) - lastError.set(name, error, request.stack, callerChrome); - } - - if (request.customCallback) { - safeCallbackApply(name, - request, - request.customCallback, - $Array.concat([name, request], responseList)); - } - - if (request.callback) { - // Validate callback in debug only -- and only when the - // caller has provided a callback. Implementations of api - // calls may not return data if they observe the caller - // has not provided a callback. - if (logging.DCHECK_IS_ON() && !error) { - if (!request.callbackSchema.parameters) - throw new Error(name + ": no callback schema defined"); - validate(responseList, request.callbackSchema.parameters); - } - safeCallbackApply(name, request, request.callback, responseList); - } - - if (error && - !lastError.hasAccessed(chrome) && - !lastError.hasAccessed(callerChrome)) { - // The native call caused an error, but the developer didn't check - // runtime.lastError. - // Notify the developer of the error via the (error) console. - console.error("Unchecked runtime.lastError while running " + - (name || "unknown") + ": " + error + - (request.stack ? "\n" + request.stack : "")); - } - } finally { - delete requests[requestId]; - lastError.clear(chrome); - if (callerChrome !== chrome) - lastError.clear(callerChrome); - } -}; - -function getExtensionStackTrace(call_name) { - var stack = $String.split(new Error().stack, '\n'); - var id = processNatives.GetExtensionId(); - - // Remove stack frames before and after that weren't associated with the - // extension. - return $Array.join(stack.filter(function(line) { - return line.indexOf(id) != -1; - }), '\n'); -} - -function prepareRequest(args, argSchemas) { - var request = {}; - var argCount = args.length; - - // Look for callback param. - if (argSchemas.length > 0 && - argSchemas[argSchemas.length - 1].type == "function") { - request.callback = args[args.length - 1]; - request.callbackSchema = argSchemas[argSchemas.length - 1]; - --argCount; - } - - request.args = []; - for (var k = 0; k < argCount; k++) { - request.args[k] = args[k]; - } - - return request; -} - -// Send an API request and optionally register a callback. -// |optArgs| is an object with optional parameters as follows: -// - customCallback: a callback that should be called instead of the standard -// callback. -// - nativeFunction: the v8 native function to handle the request, or -// StartRequest if missing. -// - forIOThread: true if this function should be handled on the browser IO -// thread. -// - preserveNullInObjects: true if it is safe for null to be in objects. -function sendRequest(functionName, args, argSchemas, optArgs) { - calledSendRequest = true; - if (!optArgs) - optArgs = {}; - var request = prepareRequest(args, argSchemas); - request.stack = getExtensionStackTrace(); - if (optArgs.customCallback) { - request.customCallback = optArgs.customCallback; - } - - var nativeFunction = optArgs.nativeFunction || natives.StartRequest; - - var requestId = natives.GetNextRequestId(); - request.id = requestId; - requests[requestId] = request; - - var hasCallback = request.callback || optArgs.customCallback; - return nativeFunction(functionName, - request.args, - requestId, - hasCallback, - optArgs.forIOThread, - optArgs.preserveNullInObjects); -} - -function getCalledSendRequest() { - return calledSendRequest; -} - -function clearCalledSendRequest() { - calledSendRequest = false; -} - -exports.sendRequest = sendRequest; -exports.getCalledSendRequest = getCalledSendRequest; -exports.clearCalledSendRequest = clearCalledSendRequest; -exports.safeCallbackApply = safeCallbackApply; -exports.getExtensionStackTrace = getExtensionStackTrace; - -// Called by C++. -exports.handleResponse = handleResponse; diff --git a/extensions/renderer/resources/set_icon.js b/extensions/renderer/resources/set_icon.js deleted file mode 100644 index 883fd67..0000000 --- a/extensions/renderer/resources/set_icon.js +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2014 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. - -var SetIconCommon = requireNative('setIcon').SetIconCommon; -var sendRequest = require('sendRequest').sendRequest; - -function loadImagePath(path, iconSize, actionType, callback) { - var img = new Image(); - img.onerror = function() { - console.error('Could not load ' + actionType + ' icon \'' + - path + '\'.'); - }; - img.onload = function() { - var canvas = document.createElement('canvas'); - canvas.width = img.width > iconSize ? iconSize : img.width; - canvas.height = img.height > iconSize ? iconSize : img.height; - - var canvas_context = canvas.getContext('2d'); - canvas_context.clearRect(0, 0, canvas.width, canvas.height); - canvas_context.drawImage(img, 0, 0, canvas.width, canvas.height); - var imageData = canvas_context.getImageData(0, 0, canvas.width, - canvas.height); - callback(imageData); - }; - img.src = path; -} - -function verifyImageData(imageData, iconSize) { - // Verify that this at least looks like an ImageData element. - // Unfortunately, we cannot use instanceof because the ImageData - // constructor is not public. - // - // We do this manually instead of using JSONSchema to avoid having these - // properties show up in the doc. - if (!('width' in imageData) || - !('height' in imageData) || - !('data' in imageData)) { - throw new Error( - 'The imageData property must contain an ImageData object or' + - ' dictionary of ImageData objects.'); - } - - if (imageData.width > iconSize || - imageData.height > iconSize) { - throw new Error( - 'The imageData property must contain an ImageData object that ' + - 'is no larger than ' + iconSize + ' pixels square.'); - } -} - -function setIcon(details, callback, name, parameters, actionType) { - var iconSizes = [19, 38]; - if ('iconIndex' in details) { - sendRequest(name, [details, callback], parameters); - } else if ('imageData' in details) { - if (typeof details.imageData == 'object') { - var isEmpty = true; - for (var i = 0; i < iconSizes.length; i++) { - var sizeKey = iconSizes[i].toString(); - if (sizeKey in details.imageData) { - verifyImageData(details.imageData[sizeKey], iconSizes[i]); - isEmpty =false; - } - } - - if (!isEmpty) { - sendRequest(name, [details, callback], parameters, - {nativeFunction: SetIconCommon}); - } else { - // If details.imageData is not dictionary with keys in set {'19', '38'}, - // it must be an ImageData object. - var sizeKey = iconSizes[0].toString(); - var imageData = details.imageData; - details.imageData = {}; - details.imageData[sizeKey] = imageData; - verifyImageData(details.imageData[sizeKey], iconSizes[0]); - sendRequest(name, [details, callback], parameters, - {nativeFunction: SetIconCommon}); - } - } else { - throw new Error('imageData property has unexpected type.'); - } - } else if ('path' in details) { - if (typeof details.path == 'object') { - details.imageData = {}; - var isEmpty = true; - var processIconSize = function(index) { - if (index == iconSizes.length) { - delete details.path; - if (isEmpty) - throw new Error('The path property must not be empty.'); - sendRequest(name, [details, callback], parameters, - {nativeFunction: SetIconCommon}); - return; - } - var sizeKey = iconSizes[index].toString(); - if (!(sizeKey in details.path)) { - processIconSize(index + 1); - return; - } - isEmpty = false; - loadImagePath(details.path[sizeKey], iconSizes[index], actionType, - function(imageData) { - details.imageData[sizeKey] = imageData; - processIconSize(index + 1); - }); - } - - processIconSize(0); - } else if (typeof details.path == 'string') { - var sizeKey = iconSizes[0].toString(); - details.imageData = {}; - loadImagePath(details.path, iconSizes[0], actionType, - function(imageData) { - details.imageData[sizeKey] = imageData; - delete details.path; - sendRequest(name, [details, callback], parameters, - {nativeFunction: SetIconCommon}); - }); - } else { - throw new Error('The path property should contain either string or ' + - 'dictionary of strings.'); - } - } else { - throw new Error( - 'Either the path or imageData property must be specified.'); - } -} - -exports.setIcon = setIcon; diff --git a/extensions/renderer/resources/storage_area.js b/extensions/renderer/resources/storage_area.js deleted file mode 100644 index de737ab..0000000 --- a/extensions/renderer/resources/storage_area.js +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2014 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. - -var normalizeArgumentsAndValidate = - require('schemaUtils').normalizeArgumentsAndValidate -var sendRequest = require('sendRequest').sendRequest; - -function extendSchema(schema) { - var extendedSchema = $Array.slice(schema); - extendedSchema.unshift({'type': 'string'}); - return extendedSchema; -} - -function StorageArea(namespace, schema) { - // Binds an API function for a namespace to its browser-side call, e.g. - // storage.sync.get('foo') -> (binds to) -> - // storage.get('sync', 'foo'). - // - // TODO(kalman): Put as a method on CustombindingObject and re-use (or - // even generate) for other APIs that need to do this. Same for other - // callers of registerCustomType(). - var self = this; - function bindApiFunction(functionName) { - self[functionName] = function() { - var funSchema = this.functionSchemas[functionName]; - var args = $Array.slice(arguments); - args = normalizeArgumentsAndValidate(args, funSchema); - return sendRequest( - 'storage.' + functionName, - $Array.concat([namespace], args), - extendSchema(funSchema.definition.parameters), - {preserveNullInObjects: true}); - }; - } - var apiFunctions = ['get', 'set', 'remove', 'clear', 'getBytesInUse']; - $Array.forEach(apiFunctions, bindApiFunction); -} - -exports.StorageArea = StorageArea; diff --git a/extensions/renderer/resources/test_custom_bindings.js b/extensions/renderer/resources/test_custom_bindings.js deleted file mode 100644 index 6e94b0c..0000000 --- a/extensions/renderer/resources/test_custom_bindings.js +++ /dev/null @@ -1,353 +0,0 @@ -// Copyright 2014 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. - -// test_custom_bindings.js -// mini-framework for ExtensionApiTest browser tests - -var binding = require('binding').Binding.create('test'); - -var chrome = requireNative('chrome').GetChrome(); -var GetExtensionAPIDefinitionsForTest = - requireNative('apiDefinitions').GetExtensionAPIDefinitionsForTest; -var GetAvailability = requireNative('v8_context').GetAvailability; -var GetAPIFeatures = requireNative('test_features').GetAPIFeatures; -var uncaughtExceptionHandler = require('uncaught_exception_handler'); -var userGestures = requireNative('user_gestures'); - -binding.registerCustomHook(function(api) { - var chromeTest = api.compiledApi; - var apiFunctions = api.apiFunctions; - - chromeTest.tests = chromeTest.tests || []; - - var currentTest = null; - var lastTest = null; - var testsFailed = 0; - var testCount = 1; - var failureException = 'chrome.test.failure'; - - // Helper function to get around the fact that function names in javascript - // are read-only, and you can't assign one to anonymous functions. - function testName(test) { - return test ? (test.name || test.generatedName) : "(no test)"; - } - - function testDone() { - // Use setTimeout here to allow previous test contexts to be - // eligible for garbage collection. - setTimeout(chromeTest.runNextTest, 0); - } - - function allTestsDone() { - if (testsFailed == 0) { - chromeTest.notifyPass(); - } else { - chromeTest.notifyFail('Failed ' + testsFailed + ' of ' + - testCount + ' tests'); - } - } - - var pendingCallbacks = 0; - - apiFunctions.setHandleRequest('callbackAdded', function() { - pendingCallbacks++; - - var called = null; - return function() { - if (called != null) { - var redundantPrefix = 'Error\n'; - chrome.test.fail( - 'Callback has already been run. ' + - 'First call:\n' + - $String.slice(called, redundantPrefix.length) + '\n' + - 'Second call:\n' + - $String.slice(new Error().stack, redundantPrefix.length)); - } - called = new Error().stack; - - pendingCallbacks--; - if (pendingCallbacks == 0) { - chromeTest.succeed(); - } - }; - }); - - apiFunctions.setHandleRequest('runNextTest', function() { - // There may have been callbacks which were interrupted by failure - // exceptions. - pendingCallbacks = 0; - - lastTest = currentTest; - currentTest = chromeTest.tests.shift(); - - if (!currentTest) { - allTestsDone(); - return; - } - - try { - chromeTest.log("( RUN ) " + testName(currentTest)); - uncaughtExceptionHandler.setHandler(function(message, e) { - if (e !== failureException) - chromeTest.fail('uncaught exception: ' + message); - }); - currentTest.call(); - } catch (e) { - uncaughtExceptionHandler.handle(e.message, e); - } - }); - - apiFunctions.setHandleRequest('fail', function(message) { - chromeTest.log("( FAILED ) " + testName(currentTest)); - - var stack = {}; - Error.captureStackTrace(stack, chromeTest.fail); - - if (!message) - message = "FAIL (no message)"; - - message += "\n" + stack.stack; - console.log("[FAIL] " + testName(currentTest) + ": " + message); - testsFailed++; - testDone(); - - // Interrupt the rest of the test. - throw failureException; - }); - - apiFunctions.setHandleRequest('succeed', function() { - console.log("[SUCCESS] " + testName(currentTest)); - chromeTest.log("( SUCCESS )"); - testDone(); - }); - - apiFunctions.setHandleRequest('assertTrue', function(test, message) { - chromeTest.assertBool(test, true, message); - }); - - apiFunctions.setHandleRequest('assertFalse', function(test, message) { - chromeTest.assertBool(test, false, message); - }); - - apiFunctions.setHandleRequest('assertBool', - function(test, expected, message) { - if (test !== expected) { - if (typeof(test) == "string") { - if (message) - message = test + "\n" + message; - else - message = test; - } - chromeTest.fail(message); - } - }); - - apiFunctions.setHandleRequest('checkDeepEq', function(expected, actual) { - if ((expected === null) != (actual === null)) - return false; - - if (expected === actual) - return true; - - if (typeof(expected) !== typeof(actual)) - return false; - - for (var p in actual) { - if ($Object.hasOwnProperty(actual, p) && - !$Object.hasOwnProperty(expected, p)) { - return false; - } - } - for (var p in expected) { - if ($Object.hasOwnProperty(expected, p) && - !$Object.hasOwnProperty(actual, p)) { - return false; - } - } - - for (var p in expected) { - var eq = true; - switch (typeof(expected[p])) { - case 'object': - eq = chromeTest.checkDeepEq(expected[p], actual[p]); - break; - case 'function': - eq = (typeof(actual[p]) != 'undefined' && - expected[p].toString() == actual[p].toString()); - break; - default: - eq = (expected[p] == actual[p] && - typeof(expected[p]) == typeof(actual[p])); - break; - } - if (!eq) - return false; - } - return true; - }); - - apiFunctions.setHandleRequest('assertEq', - function(expected, actual, message) { - var error_msg = "API Test Error in " + testName(currentTest); - if (message) - error_msg += ": " + message; - if (typeof(expected) == 'object') { - if (!chromeTest.checkDeepEq(expected, actual)) { - // Note: these JSON.stringify calls may fail in tests that explicitly - // override JSON.stringfy, so surround in try-catch. - try { - error_msg += "\nActual: " + JSON.stringify(actual) + - "\nExpected: " + JSON.stringify(expected); - } catch (e) {} - chromeTest.fail(error_msg); - } - return; - } - if (expected != actual) { - chromeTest.fail(error_msg + - "\nActual: " + actual + "\nExpected: " + expected); - } - if (typeof(expected) != typeof(actual)) { - chromeTest.fail(error_msg + - " (type mismatch)\nActual Type: " + typeof(actual) + - "\nExpected Type:" + typeof(expected)); - } - }); - - apiFunctions.setHandleRequest('assertNoLastError', function() { - if (chrome.runtime.lastError != undefined) { - chromeTest.fail("lastError.message == " + - chrome.runtime.lastError.message); - } - }); - - apiFunctions.setHandleRequest('assertLastError', function(expectedError) { - chromeTest.assertEq(typeof(expectedError), 'string'); - chromeTest.assertTrue(chrome.runtime.lastError != undefined, - "No lastError, but expected " + expectedError); - chromeTest.assertEq(expectedError, chrome.runtime.lastError.message); - }); - - apiFunctions.setHandleRequest('assertThrows', - function(fn, self, args, message) { - chromeTest.assertTrue(typeof fn == 'function'); - try { - fn.apply(self, args); - chromeTest.fail('Did not throw error: ' + fn); - } catch (e) { - if (e != failureException && message !== undefined) { - if (message instanceof RegExp) { - chromeTest.assertTrue(message.test(e.message), - e.message + ' should match ' + message) - } else { - chromeTest.assertEq(message, e.message); - } - } - } - }); - - function safeFunctionApply(func, args) { - try { - if (func) - return $Function.apply(func, undefined, args); - } catch (e) { - var msg = "uncaught exception " + e; - chromeTest.fail(msg); - } - }; - - // Wrapper for generating test functions, that takes care of calling - // assertNoLastError() and (optionally) succeed() for you. - apiFunctions.setHandleRequest('callback', function(func, expectedError) { - if (func) { - chromeTest.assertEq(typeof(func), 'function'); - } - var callbackCompleted = chromeTest.callbackAdded(); - - return function() { - if (expectedError == null) { - chromeTest.assertNoLastError(); - } else { - chromeTest.assertLastError(expectedError); - } - - var result; - if (func) { - result = safeFunctionApply(func, arguments); - } - - callbackCompleted(); - return result; - }; - }); - - apiFunctions.setHandleRequest('listenOnce', function(event, func) { - var callbackCompleted = chromeTest.callbackAdded(); - var listener = function() { - event.removeListener(listener); - safeFunctionApply(func, arguments); - callbackCompleted(); - }; - event.addListener(listener); - }); - - apiFunctions.setHandleRequest('listenForever', function(event, func) { - var callbackCompleted = chromeTest.callbackAdded(); - - var listener = function() { - safeFunctionApply(func, arguments); - }; - - var done = function() { - event.removeListener(listener); - callbackCompleted(); - }; - - event.addListener(listener); - return done; - }); - - apiFunctions.setHandleRequest('callbackPass', function(func) { - return chromeTest.callback(func); - }); - - apiFunctions.setHandleRequest('callbackFail', function(expectedError, func) { - return chromeTest.callback(func, expectedError); - }); - - apiFunctions.setHandleRequest('runTests', function(tests) { - chromeTest.tests = tests; - testCount = chromeTest.tests.length; - chromeTest.runNextTest(); - }); - - apiFunctions.setHandleRequest('getApiDefinitions', function() { - return GetExtensionAPIDefinitionsForTest(); - }); - - apiFunctions.setHandleRequest('getApiFeatures', function() { - return GetAPIFeatures(); - }); - - apiFunctions.setHandleRequest('isProcessingUserGesture', function() { - return userGestures.IsProcessingUserGesture(); - }); - - apiFunctions.setHandleRequest('runWithUserGesture', function(callback) { - chromeTest.assertEq(typeof(callback), 'function'); - return userGestures.RunWithUserGesture(callback); - }); - - apiFunctions.setHandleRequest('runWithoutUserGesture', function(callback) { - chromeTest.assertEq(typeof(callback), 'function'); - return userGestures.RunWithoutUserGesture(callback); - }); - - apiFunctions.setHandleRequest('setExceptionHandler', function(callback) { - chromeTest.assertEq(typeof(callback), 'function'); - uncaughtExceptionHandler.setHandler(callback); - }); -}); - -exports.binding = binding.generate(); diff --git a/extensions/renderer/resources/uncaught_exception_handler.js b/extensions/renderer/resources/uncaught_exception_handler.js deleted file mode 100644 index a3709b5..0000000 --- a/extensions/renderer/resources/uncaught_exception_handler.js +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2014 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. - -// Handles uncaught exceptions thrown by extensions. By default this is to -// log an error message, but tests may override this behaviour. - -var handler = function(message, e) { - console.error(message); -}; - -// |message| The message associated with the error. -// |e| The object that was thrown. -exports.handle = function(message, e) { - handler(message, e); -}; - -// |newHandler| A function which matches |exports.handle|. -exports.setHandler = function(newHandler) { - handler = newHandler; -}; diff --git a/extensions/renderer/resources/unload_event.js b/extensions/renderer/resources/unload_event.js deleted file mode 100644 index 753c2f0..0000000 --- a/extensions/renderer/resources/unload_event.js +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2014 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. - -// Special unload event. We don't use the DOM unload because that slows down -// tab shutdown. On the other hand, onUnload might not always fire, since -// Chrome will terminate renderers on shutdown (SuddenTermination). - -// Implement a primitive subset of the Event interface as needed, since if this -// was to use the real event object there would be a circular dependency. -var listeners = []; - -exports.addListener = function(listener) { - $Array.push(listeners, listener); -}; - -exports.removeListener = function(listener) { - for (var i = 0; i < listeners.length; ++i) { - if (listeners[i] == listener) { - $Array.splice(listeners, i, 1); - return; - } - } -}; - -exports.wasDispatched = false; - -// dispatch() is called from C++. -exports.dispatch = function() { - exports.wasDispatched = true; - for (var i = 0; i < listeners.length; ++i) - listeners[i](); -}; diff --git a/extensions/renderer/resources/utils.js b/extensions/renderer/resources/utils.js deleted file mode 100644 index dd1ec2a..0000000 --- a/extensions/renderer/resources/utils.js +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright 2014 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. - -var createClassWrapper = requireNative('utils').createClassWrapper; -var schemaRegistry = requireNative('schema_registry'); -var CHECK = requireNative('logging').CHECK; -var WARNING = requireNative('logging').WARNING; - -/** - * An object forEach. Calls |f| with each (key, value) pair of |obj|, using - * |self| as the target. - * @param {Object} obj The object to iterate over. - * @param {function} f The function to call in each iteration. - * @param {Object} self The object to use as |this| in each function call. - */ -function forEach(obj, f, self) { - for (var key in obj) { - if ($Object.hasOwnProperty(obj, key)) - $Function.call(f, self, key, obj[key]); - } -} - -/** - * Assuming |array_of_dictionaries| is structured like this: - * [{id: 1, ... }, {id: 2, ...}, ...], you can use - * lookup(array_of_dictionaries, 'id', 2) to get the dictionary with id == 2. - * @param {Array.<Object.<string, ?>>} array_of_dictionaries - * @param {string} field - * @param {?} value - */ -function lookup(array_of_dictionaries, field, value) { - var filter = function (dict) {return dict[field] == value;}; - var matches = array_of_dictionaries.filter(filter); - if (matches.length == 0) { - return undefined; - } else if (matches.length == 1) { - return matches[0] - } else { - throw new Error("Failed lookup of field '" + field + "' with value '" + - value + "'"); - } -} - -function loadTypeSchema(typeName, defaultSchema) { - var parts = $String.split(typeName, '.'); - if (parts.length == 1) { - if (defaultSchema == null) { - WARNING('Trying to reference "' + typeName + '" ' + - 'with neither namespace nor default schema.'); - return null; - } - var types = defaultSchema.types; - } else { - var schemaName = $Array.join($Array.slice(parts, 0, parts.length - 1), '.'); - var types = schemaRegistry.GetSchema(schemaName).types; - } - for (var i = 0; i < types.length; ++i) { - if (types[i].id == typeName) - return types[i]; - } - return null; -} - -/** - * Takes a private class implementation |cls| and exposes a subset of its - * methods |functions| and properties |properties| and |readonly| in a public - * wrapper class that it returns. Within bindings code, you can access the - * implementation from an instance of the wrapper class using - * privates(instance).impl, and from the implementation class you can access - * the wrapper using this.wrapper (or implInstance.wrapper if you have another - * instance of the implementation class). - * @param {string} name The name of the exposed wrapper class. - * @param {Object} cls The class implementation. - * @param {{functions: ?Array.<string>, - * properties: ?Array.<string>, - * readonly: ?Array.<string>}} exposed The names of properties on the - * implementation class to be exposed. |functions| represents the names of - * functions which should be delegated to the implementation; |properties| - * are gettable/settable properties and |readonly| are read-only properties. - */ -function expose(name, cls, exposed) { - var publicClass = createClassWrapper(name, cls); - - if ('functions' in exposed) { - $Array.forEach(exposed.functions, function(func) { - publicClass.prototype[func] = function() { - var impl = privates(this).impl; - return $Function.apply(impl[func], impl, arguments); - }; - }); - } - - if ('properties' in exposed) { - $Array.forEach(exposed.properties, function(prop) { - $Object.defineProperty(publicClass.prototype, prop, { - enumerable: true, - get: function() { - return privates(this).impl[prop]; - }, - set: function(value) { - var impl = privates(this).impl; - delete impl[prop]; - impl[prop] = value; - } - }); - }); - } - - if ('readonly' in exposed) { - $Array.forEach(exposed.readonly, function(readonly) { - $Object.defineProperty(publicClass.prototype, readonly, { - enumerable: true, - get: function() { - return privates(this).impl[readonly]; - }, - }); - }); - } - - return publicClass; -} - -exports.forEach = forEach; -exports.loadTypeSchema = loadTypeSchema; -exports.lookup = lookup; -exports.expose = expose; diff --git a/extensions/renderer/script_injection.cc b/extensions/renderer/script_injection.cc index 036dfc7..d3113cd 100644 --- a/extensions/renderer/script_injection.cc +++ b/extensions/renderer/script_injection.cc @@ -19,7 +19,7 @@ #include "extensions/renderer/extension_helper.h" #include "extensions/renderer/script_context.h" #include "extensions/renderer/user_script_slave.h" -#include "grit/extensions_renderer_resources.h" +#include "grit/renderer_resources.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebScriptSource.h" |