binding.js revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)var Event = require('event_bindings').Event; 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)var forEach = require('utils').forEach; 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)var GetAvailability = requireNative('v8_context').GetAvailability; 87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)var logActivity = requireNative('activityLogger'); 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)var logging = requireNative('logging'); 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)var process = requireNative('process'); 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)var schemaRegistry = requireNative('schema_registry'); 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)var schemaUtils = require('schemaUtils'); 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)var utils = require('utils'); 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)var sendRequestHandler = require('sendRequest'); 157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)var contextType = process.GetContextType(); 177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)var extensionId = process.GetExtensionId(); 187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)var manifestVersion = process.GetManifestVersion(); 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)var sendRequest = sendRequestHandler.sendRequest; 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Stores the name and definition of each API function, with methods to 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// modify their behaviour (such as a custom way to handle requests to the 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// API, a custom callback, etc). 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)function APIFunctions(namespace) { 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.apiFunctions_ = {}; 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.unavailableApiFunctions_ = {}; 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this.namespace = namespace; 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)APIFunctions.prototype.register = function(apiName, apiFunction) { 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.apiFunctions_[apiName] = apiFunction; 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Registers a function as existing but not available, meaning that calls to 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// the set* methods that reference this function should be ignored rather 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// than throwing Errors. 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)APIFunctions.prototype.registerUnavailable = function(apiName) { 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.unavailableApiFunctions_[apiName] = apiName; 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)APIFunctions.prototype.setHook_ = 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function(apiName, propertyName, customizedFunction) { 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if ($Object.hasOwnProperty(this.unavailableApiFunctions_, apiName)) 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!$Object.hasOwnProperty(this.apiFunctions_, apiName)) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) throw new Error('Tried to set hook for unknown API "' + apiName + '"'); 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.apiFunctions_[apiName][propertyName] = customizedFunction; 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)APIFunctions.prototype.setHandleRequest = 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function(apiName, customizedFunction) { 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) var prefix = this.namespace; 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return this.setHook_(apiName, 'handleRequest', 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) function() { 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch var ret = $Function.apply(customizedFunction, this, arguments); 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Logs API calls to the Activity Log if it doesn't go through an 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // ExtensionFunction. 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!sendRequestHandler.getCalledSendRequest()) 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) logActivity.LogAPICall(extensionId, prefix + "." + apiName, 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch $Array.slice(arguments)); 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return ret; 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }); 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)APIFunctions.prototype.setUpdateArgumentsPostValidate = 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function(apiName, customizedFunction) { 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return this.setHook_( 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apiName, 'updateArgumentsPostValidate', customizedFunction); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)APIFunctions.prototype.setUpdateArgumentsPreValidate = 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function(apiName, customizedFunction) { 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return this.setHook_( 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apiName, 'updateArgumentsPreValidate', customizedFunction); 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)APIFunctions.prototype.setCustomCallback = 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function(apiName, customizedFunction) { 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return this.setHook_(apiName, 'customCallback', customizedFunction); 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function CustomBindingsObject() { 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CustomBindingsObject.prototype.setSchema = function(schema) { 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The functions in the schema are in list form, so we move them into a 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // dictionary for easier access. 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var self = this; 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.functionSchemas = {}; 907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) $Array.forEach(schema.functions, function(f) { 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self.functionSchemas[f.name] = { 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) name: f.name, 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) definition: f 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Get the platform from navigator.appVersion. 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function getPlatform() { 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var platforms = [ 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) [/CrOS Touch/, "chromeos touch"], 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) [/CrOS/, "chromeos"], 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) [/Linux/, "linux"], 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) [/Mac/, "mac"], 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) [/Win/, "win"], 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ]; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (var i = 0; i < platforms.length; i++) { 109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if ($RegExp.test(platforms[i][0], navigator.appVersion)) { 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return platforms[i][1]; 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "unknown"; 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function isPlatformSupported(schemaNode, platform) { 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return !schemaNode.platforms || 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) schemaNode.platforms.indexOf(platform) > -1; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function isManifestVersionSupported(schemaNode, manifestVersion) { 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return !schemaNode.maximumManifestVersion || 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) manifestVersion <= schemaNode.maximumManifestVersion; 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function isSchemaNodeSupported(schemaNode, platform, manifestVersion) { 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return isPlatformSupported(schemaNode, platform) && 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) isManifestVersionSupported(schemaNode, manifestVersion); 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function createCustomType(type) { 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var jsModuleName = type.js_module; 1337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) logging.CHECK(jsModuleName, 'Custom type ' + type.id + 1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ' has no "js_module" property.'); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var jsModule = require(jsModuleName); 1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) logging.CHECK(jsModule, 'No module ' + jsModuleName + ' found for ' + 1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) type.id + '.'); 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var customType = jsModule[jsModuleName]; 1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) logging.CHECK(customType, jsModuleName + ' must export itself.'); 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) customType.prototype = new CustomBindingsObject(); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) customType.prototype.setSchema(type); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return customType; 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)var platform = getPlatform(); 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function Binding(schema) { 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.schema_ = schema; 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this.apiFunctions_ = new APIFunctions(schema.namespace); 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.customEvent_ = null; 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.customHooks_ = []; 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Binding.create = function(apiName) { 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new Binding(schemaRegistry.GetSchema(apiName)); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Binding.prototype = { 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The API through which the ${api_name}_custom_bindings.js files customize 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // their API bindings beyond what can be generated. 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // There are 2 types of customizations available: those which are required in 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // order to do the schema generation (registerCustomEvent and 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // registerCustomType), and those which can only run after the bindings have 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // been generated (registerCustomHook). 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Registers a custom event type for the API identified by |namespace|. 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |event| is the event's constructor. 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registerCustomEvent: function(event) { 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.customEvent_ = event; 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }, 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Registers a function |hook| to run after the schema for all APIs has been 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // generated. The hook is passed as its first argument an "API" object to 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // interact with, and second the current extension ID. See where 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |customHooks| is used. 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registerCustomHook: function(fn) { 178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch $Array.push(this.customHooks_, fn); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }, 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(kalman/cduvall): Refactor this so |runHooks_| is not needed. 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) runHooks_: function(api) { 1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) $Array.forEach(this.customHooks_, function(hook) { 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!isSchemaNodeSupported(this.schema_, platform, manifestVersion)) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!hook) 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hook({ 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apiFunctions: this.apiFunctions_, 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) schema: this.schema_, 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) compiledApi: api 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }, extensionId, contextType); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }, this); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }, 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Generates the bindings from |this.schema_| and integrates any custom 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // bindings that might be present. 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) generate: function() { 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var schema = this.schema_; 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 203b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) function shouldCheckUnprivileged() { 204b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) var shouldCheck = 'unprivileged' in schema; 205b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (shouldCheck) 206b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return shouldCheck; 207b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 2087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) $Array.forEach(['functions', 'events'], function(type) { 209eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if ($Object.hasOwnProperty(schema, type)) { 2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) $Array.forEach(schema[type], function(node) { 211b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if ('unprivileged' in node) 212b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) shouldCheck = true; 213b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) }); 214b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 215b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) }); 216b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (shouldCheck) 217b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return shouldCheck; 218b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 219b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) for (var property in schema.properties) { 220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if ($Object.hasOwnProperty(schema, property) && 221b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 'unprivileged' in schema.properties[property]) { 222b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) shouldCheck = true; 223b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) break; 224b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 225b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 226b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return shouldCheck; 227b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 228b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) var checkUnprivileged = shouldCheckUnprivileged(); 229b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(kalman/cduvall): Make GetAvailability handle this, then delete the 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // supporting code. 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!isSchemaNodeSupported(schema, platform, manifestVersion)) { 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) console.error('chrome.' + schema.namespace + ' is not supported on ' + 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'this platform or manifest version'); 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return undefined; 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var mod = {}; 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch var namespaces = $String.split(schema.namespace, '.'); 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (var index = 0, name; name = namespaces[index]; index++) { 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mod[name] = mod[name] || {}; 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mod = mod[name]; 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Add types to global schemaValidator, the types we depend on from other 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // namespaces will be added as needed. 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (schema.types) { 2497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) $Array.forEach(schema.types, function(t) { 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!isSchemaNodeSupported(t, platform, manifestVersion)) 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) schemaUtils.schemaValidator.addTypes(t); 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }, this); 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 256b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // TODO(cduvall): Take out when all APIs have been converted to features. 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Returns whether access to the content of a schema should be denied, 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // based on the presence of "unprivileged" and whether this is an 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // extension process (versus e.g. a content script). 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function isSchemaAccessAllowed(itemSchema) { 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (contextType == 'BLESSED_EXTENSION') || 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) schema.unprivileged || 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) itemSchema.unprivileged; 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Setup Functions. 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (schema.functions) { 2687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) $Array.forEach(schema.functions, function(functionDef) { 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (functionDef.name in mod) { 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) throw new Error('Function ' + functionDef.name + 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ' already defined in ' + schema.namespace); 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!isSchemaNodeSupported(functionDef, platform, manifestVersion)) { 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.apiFunctions_.registerUnavailable(functionDef.name); 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var apiFunction = {}; 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apiFunction.definition = functionDef; 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apiFunction.name = schema.namespace + '.' + functionDef.name; 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 283b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!GetAvailability(apiFunction.name).is_available || 284b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) (checkUnprivileged && !isSchemaAccessAllowed(functionDef))) { 285b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) this.apiFunctions_.registerUnavailable(functionDef.name); 286b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return; 287b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 288b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(aa): It would be best to run this in a unit test, but in order 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to do that we would need to better factor this code so that it 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // doesn't depend on so much v8::Extension machinery. 292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (logging.DCHECK_IS_ON() && 293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) schemaUtils.isFunctionSignatureAmbiguous(apiFunction.definition)) { 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) throw new Error( 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apiFunction.name + ' has ambiguous optional arguments. ' + 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'To implement custom disambiguation logic, add ' + 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) '"allowAmbiguousOptionalArguments" to the function\'s schema.'); 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.apiFunctions_.register(functionDef.name, apiFunction); 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) mod[functionDef.name] = $Function.bind(function() { 303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch var args = $Array.slice(arguments); 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (this.updateArgumentsPreValidate) 305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch args = $Function.apply(this.updateArgumentsPreValidate, this, args); 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args = schemaUtils.normalizeArgumentsAndValidate(args, this); 308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (this.updateArgumentsPostValidate) { 309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch args = $Function.apply(this.updateArgumentsPostValidate, 310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch this, 311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch args); 312eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) sendRequestHandler.clearCalledSendRequest(); 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var retval; 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (this.handleRequest) { 318eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = $Function.apply(this.handleRequest, this, args); 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var optArgs = { 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) customCallback: this.customCallback 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) retval = sendRequest(this.name, args, 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.definition.parameters, 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) optArgs); 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) sendRequestHandler.clearCalledSendRequest(); 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Validate return value if in sanity check mode. 330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (logging.DCHECK_IS_ON() && this.definition.returns) 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) schemaUtils.validate([retval], [this.definition.returns]); 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return retval; 3337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) }, apiFunction); 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }, this); 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Setup Events 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (schema.events) { 3397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) $Array.forEach(schema.events, function(eventDef) { 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (eventDef.name in mod) { 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) throw new Error('Event ' + eventDef.name + 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ' already defined in ' + schema.namespace); 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!isSchemaNodeSupported(eventDef, platform, manifestVersion)) 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 346b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 347b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) var eventName = schema.namespace + "." + eventDef.name; 348b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!GetAvailability(eventName).is_available || 349b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) (checkUnprivileged && !isSchemaAccessAllowed(eventDef))) { 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var options = eventDef.options || {}; 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (eventDef.filters && eventDef.filters.length > 0) 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) options.supportsFilters = true; 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (this.customEvent_) { 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mod[eventDef.name] = new this.customEvent_( 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) eventName, eventDef.parameters, eventDef.extraParameters, 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) options); 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (eventDef.anonymous) { 362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) mod[eventDef.name] = new Event(); 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) mod[eventDef.name] = new Event( 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) eventName, eventDef.parameters, options); 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }, this); 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function addProperties(m, parentDef) { 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var properties = parentDef.properties; 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!properties) 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) forEach(properties, function(propertyName, propertyDef) { 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (propertyName in m) 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; // TODO(kalman): be strict like functions/events somehow. 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!isSchemaNodeSupported(propertyDef, platform, manifestVersion)) 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 380b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!GetAvailability(schema.namespace + "." + 381b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) propertyName).is_available || 382b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) (checkUnprivileged && !isSchemaAccessAllowed(propertyDef))) { 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var value = propertyDef.value; 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (value) { 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Values may just have raw types as defined in the JSON, such 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // as "WINDOW_ID_NONE": { "value": -1 }. We handle this here. 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(kalman): enforce that things with a "value" property can't 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // define their own types. 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var type = propertyDef.type || typeof(value); 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (type === 'integer' || type === 'number') { 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value = parseInt(value); 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (type === 'boolean') { 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value = value === 'true'; 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (propertyDef['$ref']) { 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var ref = propertyDef['$ref']; 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var type = utils.loadTypeSchema(propertyDef['$ref'], schema); 4007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) logging.CHECK(type, 'Schema for $ref type ' + ref + ' not found'); 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var constructor = createCustomType(type); 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var args = value; 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For an object propertyDef, |value| is an array of constructor 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // arguments, but we want to pass the arguments directly (i.e. 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // not as an array), so we have to fake calling |new| on the 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // constructor. 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value = { __proto__: constructor.prototype }; 408eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch $Function.apply(constructor, value, args); 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Recursively add properties. 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) addProperties(value, propertyDef); 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (type === 'object') { 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Recursively add properties. 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) addProperties(value, propertyDef); 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (type !== 'string') { 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) throw new Error('NOT IMPLEMENTED (extension_api.json error): ' + 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 'Cannot parse values for type "' + type + '"'); 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) m[propertyName] = value; 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }); 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) addProperties(mod, schema); 424b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 425b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) var availability = GetAvailability(schema.namespace); 426eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!availability.is_available && $Object.keys(mod).length == 0) { 427b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) console.error('chrome.' + schema.namespace + ' is not available: ' + 428b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) availability.message); 429b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return; 430b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 431b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.runHooks_(mod); 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return mod; 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)exports.Binding = Binding; 438