Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 var Event = require('event_bindings').Event; | 5 var Event = require('event_bindings').Event; |
| 6 var forEach = require('utils').forEach; | 6 var forEach = require('utils').forEach; |
| 7 var GetAvailability = requireNative('v8_context').GetAvailability; | 7 var GetAvailability = requireNative('v8_context').GetAvailability; |
| 8 var getExtensionStackTrace = | 8 var getExtensionStackTrace = |
| 9 require('uncaught_exception_handler').getExtensionStackTrace; | 9 require('uncaught_exception_handler').getExtensionStackTrace; |
| 10 var lastError = require('lastError'); | 10 var lastError = require('lastError'); |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 39 // than throwing Errors. | 39 // than throwing Errors. |
| 40 APIFunctions.prototype.registerUnavailable = function(apiName) { | 40 APIFunctions.prototype.registerUnavailable = function(apiName) { |
| 41 this.unavailableApiFunctions_[apiName] = apiName; | 41 this.unavailableApiFunctions_[apiName] = apiName; |
| 42 }; | 42 }; |
| 43 | 43 |
| 44 APIFunctions.prototype.setHook_ = | 44 APIFunctions.prototype.setHook_ = |
| 45 function(apiName, propertyName, customizedFunction) { | 45 function(apiName, propertyName, customizedFunction) { |
| 46 if ($Object.hasOwnProperty(this.unavailableApiFunctions_, apiName)) | 46 if ($Object.hasOwnProperty(this.unavailableApiFunctions_, apiName)) |
| 47 return; | 47 return; |
| 48 if (!$Object.hasOwnProperty(this.apiFunctions_, apiName)) | 48 if (!$Object.hasOwnProperty(this.apiFunctions_, apiName)) |
| 49 throw new Error('Tried to set hook for unknown API "' + apiName + '"'); | 49 throw new $Error.self( |
| 50 'Tried to set hook for unknown API "' + apiName + '"'); | |
| 50 this.apiFunctions_[apiName][propertyName] = customizedFunction; | 51 this.apiFunctions_[apiName][propertyName] = customizedFunction; |
| 51 }; | 52 }; |
| 52 | 53 |
| 53 APIFunctions.prototype.setHandleRequest = | 54 APIFunctions.prototype.setHandleRequest = |
| 54 function(apiName, customizedFunction) { | 55 function(apiName, customizedFunction) { |
| 55 var prefix = this.namespace; | 56 var prefix = this.namespace; |
| 56 return this.setHook_(apiName, 'handleRequest', | 57 return this.setHook_(apiName, 'handleRequest', |
| 57 function() { | 58 function() { |
| 58 var ret = $Function.apply(customizedFunction, this, arguments); | 59 var ret = $Function.apply(customizedFunction, this, arguments); |
| 59 // Logs API calls to the Activity Log if it doesn't go through an | 60 // Logs API calls to the Activity Log if it doesn't go through an |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 129 for (var i = 0; i < platforms.length; i++) { | 130 for (var i = 0; i < platforms.length; i++) { |
| 130 if ($RegExp.test(platforms[i][0], navigator.appVersion)) { | 131 if ($RegExp.test(platforms[i][0], navigator.appVersion)) { |
| 131 return platforms[i][1]; | 132 return platforms[i][1]; |
| 132 } | 133 } |
| 133 } | 134 } |
| 134 return "unknown"; | 135 return "unknown"; |
| 135 } | 136 } |
| 136 | 137 |
| 137 function isPlatformSupported(schemaNode, platform) { | 138 function isPlatformSupported(schemaNode, platform) { |
| 138 return !schemaNode.platforms || | 139 return !schemaNode.platforms || |
| 139 schemaNode.platforms.indexOf(platform) > -1; | 140 $Array.indexOf(schemaNode.platforms, platform) > -1; |
| 140 } | 141 } |
| 141 | 142 |
| 142 function isManifestVersionSupported(schemaNode, manifestVersion) { | 143 function isManifestVersionSupported(schemaNode, manifestVersion) { |
| 143 return !schemaNode.maximumManifestVersion || | 144 return !schemaNode.maximumManifestVersion || |
| 144 manifestVersion <= schemaNode.maximumManifestVersion; | 145 manifestVersion <= schemaNode.maximumManifestVersion; |
| 145 } | 146 } |
| 146 | 147 |
| 147 function isSchemaNodeSupported(schemaNode, platform, manifestVersion) { | 148 function isSchemaNodeSupported(schemaNode, platform, manifestVersion) { |
| 148 return isPlatformSupported(schemaNode, platform) && | 149 return isPlatformSupported(schemaNode, platform) && |
| 149 isManifestVersionSupported(schemaNode, manifestVersion); | 150 isManifestVersionSupported(schemaNode, manifestVersion); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 281 function isSchemaAccessAllowed(itemSchema) { | 282 function isSchemaAccessAllowed(itemSchema) { |
| 282 return (contextType == 'BLESSED_EXTENSION') || | 283 return (contextType == 'BLESSED_EXTENSION') || |
| 283 schema.unprivileged || | 284 schema.unprivileged || |
| 284 itemSchema.unprivileged; | 285 itemSchema.unprivileged; |
| 285 }; | 286 }; |
| 286 | 287 |
| 287 // Setup Functions. | 288 // Setup Functions. |
| 288 if (schema.functions) { | 289 if (schema.functions) { |
| 289 $Array.forEach(schema.functions, function(functionDef) { | 290 $Array.forEach(schema.functions, function(functionDef) { |
| 290 if (functionDef.name in mod) { | 291 if (functionDef.name in mod) { |
| 291 throw new Error('Function ' + functionDef.name + | 292 throw new $Error.self('Function ' + functionDef.name + |
| 292 ' already defined in ' + schema.namespace); | 293 ' already defined in ' + schema.namespace); |
| 293 } | 294 } |
| 294 | 295 |
| 295 if (!isSchemaNodeSupported(functionDef, platform, manifestVersion)) { | 296 if (!isSchemaNodeSupported(functionDef, platform, manifestVersion)) { |
| 296 this.apiFunctions_.registerUnavailable(functionDef.name); | 297 this.apiFunctions_.registerUnavailable(functionDef.name); |
| 297 return; | 298 return; |
| 298 } | 299 } |
| 299 | 300 |
| 300 var apiFunction = {}; | 301 var apiFunction = {}; |
| 301 apiFunction.definition = functionDef; | 302 apiFunction.definition = functionDef; |
| 302 apiFunction.name = schema.namespace + '.' + functionDef.name; | 303 apiFunction.name = schema.namespace + '.' + functionDef.name; |
| 303 | 304 |
| 304 if (!GetAvailability(apiFunction.name).is_available || | 305 if (!GetAvailability(apiFunction.name).is_available || |
| 305 (checkUnprivileged && !isSchemaAccessAllowed(functionDef))) { | 306 (checkUnprivileged && !isSchemaAccessAllowed(functionDef))) { |
| 306 this.apiFunctions_.registerUnavailable(functionDef.name); | 307 this.apiFunctions_.registerUnavailable(functionDef.name); |
| 307 return; | 308 return; |
| 308 } | 309 } |
| 309 | 310 |
| 310 // TODO(aa): It would be best to run this in a unit test, but in order | 311 // TODO(aa): It would be best to run this in a unit test, but in order |
| 311 // to do that we would need to better factor this code so that it | 312 // to do that we would need to better factor this code so that it |
| 312 // doesn't depend on so much v8::Extension machinery. | 313 // doesn't depend on so much v8::Extension machinery. |
| 313 if (logging.DCHECK_IS_ON() && | 314 if (logging.DCHECK_IS_ON() && |
| 314 schemaUtils.isFunctionSignatureAmbiguous(apiFunction.definition)) { | 315 schemaUtils.isFunctionSignatureAmbiguous(apiFunction.definition)) { |
| 315 throw new Error( | 316 throw new $Error.self( |
| 316 apiFunction.name + ' has ambiguous optional arguments. ' + | 317 apiFunction.name + ' has ambiguous optional arguments. ' + |
| 317 'To implement custom disambiguation logic, add ' + | 318 'To implement custom disambiguation logic, add ' + |
| 318 '"allowAmbiguousOptionalArguments" to the function\'s schema.'); | 319 '"allowAmbiguousOptionalArguments" to the function\'s schema.'); |
| 319 } | 320 } |
| 320 | 321 |
| 321 this.apiFunctions_.register(functionDef.name, apiFunction); | 322 this.apiFunctions_.register(functionDef.name, apiFunction); |
| 322 | 323 |
| 323 mod[functionDef.name] = $Function.bind(function() { | 324 mod[functionDef.name] = $Function.bind(function() { |
| 324 var args = $Array.slice(arguments); | 325 var args = $Array.slice(arguments); |
| 325 if (this.updateArgumentsPreValidate) | 326 if (this.updateArgumentsPreValidate) |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 352 schemaUtils.validate([retval], [this.definition.returns]); | 353 schemaUtils.validate([retval], [this.definition.returns]); |
| 353 return retval; | 354 return retval; |
| 354 }, apiFunction); | 355 }, apiFunction); |
| 355 }, this); | 356 }, this); |
| 356 } | 357 } |
| 357 | 358 |
| 358 // Setup Events | 359 // Setup Events |
| 359 if (schema.events) { | 360 if (schema.events) { |
| 360 $Array.forEach(schema.events, function(eventDef) { | 361 $Array.forEach(schema.events, function(eventDef) { |
| 361 if (eventDef.name in mod) { | 362 if (eventDef.name in mod) { |
| 362 throw new Error('Event ' + eventDef.name + | 363 throw new $Error.self('Event ' + eventDef.name + |
| 363 ' already defined in ' + schema.namespace); | 364 ' already defined in ' + schema.namespace); |
|
not at google - send to devlin
2014/08/19 16:45:54
Fix indentation.
| |
| 364 } | 365 } |
| 365 if (!isSchemaNodeSupported(eventDef, platform, manifestVersion)) | 366 if (!isSchemaNodeSupported(eventDef, platform, manifestVersion)) |
| 366 return; | 367 return; |
| 367 | 368 |
| 368 var eventName = schema.namespace + "." + eventDef.name; | 369 var eventName = schema.namespace + "." + eventDef.name; |
| 369 if (!GetAvailability(eventName).is_available || | 370 if (!GetAvailability(eventName).is_available || |
| 370 (checkUnprivileged && !isSchemaAccessAllowed(eventDef))) { | 371 (checkUnprivileged && !isSchemaAccessAllowed(eventDef))) { |
| 371 return; | 372 return; |
| 372 } | 373 } |
| 373 | 374 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 423 // not as an array), so we have to fake calling |new| on the | 424 // not as an array), so we have to fake calling |new| on the |
| 424 // constructor. | 425 // constructor. |
| 425 value = { __proto__: constructor.prototype }; | 426 value = { __proto__: constructor.prototype }; |
| 426 $Function.apply(constructor, value, args); | 427 $Function.apply(constructor, value, args); |
| 427 // Recursively add properties. | 428 // Recursively add properties. |
| 428 addProperties(value, propertyDef); | 429 addProperties(value, propertyDef); |
| 429 } else if (type === 'object') { | 430 } else if (type === 'object') { |
| 430 // Recursively add properties. | 431 // Recursively add properties. |
| 431 addProperties(value, propertyDef); | 432 addProperties(value, propertyDef); |
| 432 } else if (type !== 'string') { | 433 } else if (type !== 'string') { |
| 433 throw new Error('NOT IMPLEMENTED (extension_api.json error): ' + | 434 throw new $Error.self( |
| 435 'NOT IMPLEMENTED (extension_api.json error): ' + | |
| 434 'Cannot parse values for type "' + type + '"'); | 436 'Cannot parse values for type "' + type + '"'); |
| 435 } | 437 } |
| 436 m[propertyName] = value; | 438 m[propertyName] = value; |
| 437 } | 439 } |
| 438 }); | 440 }); |
| 439 }; | 441 }; |
| 440 | 442 |
| 441 addProperties(mod, schema); | 443 addProperties(mod, schema); |
| 442 | 444 |
| 443 // This generate() call is considered successful if any functions, | 445 // This generate() call is considered successful if any functions, |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 472 availability.message); | 474 availability.message); |
| 473 return; | 475 return; |
| 474 } | 476 } |
| 475 | 477 |
| 476 this.runHooks_(mod); | 478 this.runHooks_(mod); |
| 477 return mod; | 479 return mod; |
| 478 } | 480 } |
| 479 }; | 481 }; |
| 480 | 482 |
| 481 exports.Binding = Binding; | 483 exports.Binding = Binding; |
| OLD | NEW |