OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 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 logActivity = requireNative('activityLogger'); | 8 var logActivity = requireNative('activityLogger'); |
9 var logging = requireNative('logging'); | 9 var logging = requireNative('logging'); |
10 var process = requireNative('process'); | 10 var process = requireNative('process'); |
(...skipping 22 matching lines...) Expand all Loading... |
33 | 33 |
34 // Registers a function as existing but not available, meaning that calls to | 34 // Registers a function as existing but not available, meaning that calls to |
35 // the set* methods that reference this function should be ignored rather | 35 // the set* methods that reference this function should be ignored rather |
36 // than throwing Errors. | 36 // than throwing Errors. |
37 APIFunctions.prototype.registerUnavailable = function(apiName) { | 37 APIFunctions.prototype.registerUnavailable = function(apiName) { |
38 this.unavailableApiFunctions_[apiName] = apiName; | 38 this.unavailableApiFunctions_[apiName] = apiName; |
39 }; | 39 }; |
40 | 40 |
41 APIFunctions.prototype.setHook_ = | 41 APIFunctions.prototype.setHook_ = |
42 function(apiName, propertyName, customizedFunction) { | 42 function(apiName, propertyName, customizedFunction) { |
43 if (this.unavailableApiFunctions_.hasOwnProperty(apiName)) | 43 if ($Object.hasOwnProperty(this.unavailableApiFunctions_, apiName)) |
44 return; | 44 return; |
45 if (!this.apiFunctions_.hasOwnProperty(apiName)) | 45 if (!$Object.hasOwnProperty(this.apiFunctions_, apiName)) |
46 throw new Error('Tried to set hook for unknown API "' + apiName + '"'); | 46 throw new Error('Tried to set hook for unknown API "' + apiName + '"'); |
47 this.apiFunctions_[apiName][propertyName] = customizedFunction; | 47 this.apiFunctions_[apiName][propertyName] = customizedFunction; |
48 }; | 48 }; |
49 | 49 |
50 APIFunctions.prototype.setHandleRequest = | 50 APIFunctions.prototype.setHandleRequest = |
51 function(apiName, customizedFunction) { | 51 function(apiName, customizedFunction) { |
52 var prefix = this.namespace; | 52 var prefix = this.namespace; |
53 // TODO(ataly): Need to replace/redefine apply and slice. | |
54 return this.setHook_(apiName, 'handleRequest', | 53 return this.setHook_(apiName, 'handleRequest', |
55 function() { | 54 function() { |
56 var ret = customizedFunction.apply(this, arguments); | 55 var ret = $Function.apply(customizedFunction, this, arguments); |
57 // Logs API calls to the Activity Log if it doesn't go through an | 56 // Logs API calls to the Activity Log if it doesn't go through an |
58 // ExtensionFunction. | 57 // ExtensionFunction. |
59 if (!sendRequestHandler.getCalledSendRequest()) | 58 if (!sendRequestHandler.getCalledSendRequest()) |
60 logActivity.LogAPICall(extensionId, prefix + "." + apiName, | 59 logActivity.LogAPICall(extensionId, prefix + "." + apiName, |
61 Array.prototype.slice.call(arguments)); | 60 $Array.slice(arguments)); |
62 return ret; | 61 return ret; |
63 }); | 62 }); |
64 }; | 63 }; |
65 | 64 |
66 APIFunctions.prototype.setUpdateArgumentsPostValidate = | 65 APIFunctions.prototype.setUpdateArgumentsPostValidate = |
67 function(apiName, customizedFunction) { | 66 function(apiName, customizedFunction) { |
68 return this.setHook_( | 67 return this.setHook_( |
69 apiName, 'updateArgumentsPostValidate', customizedFunction); | 68 apiName, 'updateArgumentsPostValidate', customizedFunction); |
70 }; | 69 }; |
71 | 70 |
(...skipping 28 matching lines...) Expand all Loading... |
100 function getPlatform() { | 99 function getPlatform() { |
101 var platforms = [ | 100 var platforms = [ |
102 [/CrOS Touch/, "chromeos touch"], | 101 [/CrOS Touch/, "chromeos touch"], |
103 [/CrOS/, "chromeos"], | 102 [/CrOS/, "chromeos"], |
104 [/Linux/, "linux"], | 103 [/Linux/, "linux"], |
105 [/Mac/, "mac"], | 104 [/Mac/, "mac"], |
106 [/Win/, "win"], | 105 [/Win/, "win"], |
107 ]; | 106 ]; |
108 | 107 |
109 for (var i = 0; i < platforms.length; i++) { | 108 for (var i = 0; i < platforms.length; i++) { |
110 if (platforms[i][0].test(navigator.appVersion)) { | 109 if ($RegExp.test(platforms[i][0], navigator.appVersion)) { |
111 return platforms[i][1]; | 110 return platforms[i][1]; |
112 } | 111 } |
113 } | 112 } |
114 return "unknown"; | 113 return "unknown"; |
115 } | 114 } |
116 | 115 |
117 function isPlatformSupported(schemaNode, platform) { | 116 function isPlatformSupported(schemaNode, platform) { |
118 return !schemaNode.platforms || | 117 return !schemaNode.platforms || |
119 schemaNode.platforms.indexOf(platform) > -1; | 118 schemaNode.platforms.indexOf(platform) > -1; |
120 } | 119 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 // |event| is the event's constructor. | 168 // |event| is the event's constructor. |
170 registerCustomEvent: function(event) { | 169 registerCustomEvent: function(event) { |
171 this.customEvent_ = event; | 170 this.customEvent_ = event; |
172 }, | 171 }, |
173 | 172 |
174 // Registers a function |hook| to run after the schema for all APIs has been | 173 // Registers a function |hook| to run after the schema for all APIs has been |
175 // generated. The hook is passed as its first argument an "API" object to | 174 // generated. The hook is passed as its first argument an "API" object to |
176 // interact with, and second the current extension ID. See where | 175 // interact with, and second the current extension ID. See where |
177 // |customHooks| is used. | 176 // |customHooks| is used. |
178 registerCustomHook: function(fn) { | 177 registerCustomHook: function(fn) { |
179 this.customHooks_.push(fn); | 178 $Array.push(this.customHooks_, fn); |
180 }, | 179 }, |
181 | 180 |
182 // TODO(kalman/cduvall): Refactor this so |runHooks_| is not needed. | 181 // TODO(kalman/cduvall): Refactor this so |runHooks_| is not needed. |
183 runHooks_: function(api) { | 182 runHooks_: function(api) { |
184 $Array.forEach(this.customHooks_, function(hook) { | 183 $Array.forEach(this.customHooks_, function(hook) { |
185 if (!isSchemaNodeSupported(this.schema_, platform, manifestVersion)) | 184 if (!isSchemaNodeSupported(this.schema_, platform, manifestVersion)) |
186 return; | 185 return; |
187 | 186 |
188 if (!hook) | 187 if (!hook) |
189 return; | 188 return; |
(...skipping 10 matching lines...) Expand all Loading... |
200 // bindings that might be present. | 199 // bindings that might be present. |
201 generate: function() { | 200 generate: function() { |
202 var schema = this.schema_; | 201 var schema = this.schema_; |
203 | 202 |
204 function shouldCheckUnprivileged() { | 203 function shouldCheckUnprivileged() { |
205 var shouldCheck = 'unprivileged' in schema; | 204 var shouldCheck = 'unprivileged' in schema; |
206 if (shouldCheck) | 205 if (shouldCheck) |
207 return shouldCheck; | 206 return shouldCheck; |
208 | 207 |
209 $Array.forEach(['functions', 'events'], function(type) { | 208 $Array.forEach(['functions', 'events'], function(type) { |
210 if (schema.hasOwnProperty(type)) { | 209 if ($Object.hasOwnProperty(schema, type)) { |
211 $Array.forEach(schema[type], function(node) { | 210 $Array.forEach(schema[type], function(node) { |
212 if ('unprivileged' in node) | 211 if ('unprivileged' in node) |
213 shouldCheck = true; | 212 shouldCheck = true; |
214 }); | 213 }); |
215 } | 214 } |
216 }); | 215 }); |
217 if (shouldCheck) | 216 if (shouldCheck) |
218 return shouldCheck; | 217 return shouldCheck; |
219 | 218 |
220 for (var property in schema.properties) { | 219 for (var property in schema.properties) { |
221 if (schema.hasOwnProperty(property) && | 220 if ($Object.hasOwnProperty(schema, property) && |
222 'unprivileged' in schema.properties[property]) { | 221 'unprivileged' in schema.properties[property]) { |
223 shouldCheck = true; | 222 shouldCheck = true; |
224 break; | 223 break; |
225 } | 224 } |
226 } | 225 } |
227 return shouldCheck; | 226 return shouldCheck; |
228 } | 227 } |
229 var checkUnprivileged = shouldCheckUnprivileged(); | 228 var checkUnprivileged = shouldCheckUnprivileged(); |
230 | 229 |
231 // TODO(kalman/cduvall): Make GetAvailability handle this, then delete the | 230 // TODO(kalman/cduvall): Make GetAvailability handle this, then delete the |
232 // supporting code. | 231 // supporting code. |
233 if (!isSchemaNodeSupported(schema, platform, manifestVersion)) { | 232 if (!isSchemaNodeSupported(schema, platform, manifestVersion)) { |
234 console.error('chrome.' + schema.namespace + ' is not supported on ' + | 233 console.error('chrome.' + schema.namespace + ' is not supported on ' + |
235 'this platform or manifest version'); | 234 'this platform or manifest version'); |
236 return undefined; | 235 return undefined; |
237 } | 236 } |
238 | 237 |
239 var mod = {}; | 238 var mod = {}; |
240 | 239 |
241 var namespaces = schema.namespace.split('.'); | 240 var namespaces = $String.split(schema.namespace, '.'); |
242 for (var index = 0, name; name = namespaces[index]; index++) { | 241 for (var index = 0, name; name = namespaces[index]; index++) { |
243 mod[name] = mod[name] || {}; | 242 mod[name] = mod[name] || {}; |
244 mod = mod[name]; | 243 mod = mod[name]; |
245 } | 244 } |
246 | 245 |
247 // Add types to global schemaValidator, the types we depend on from other | 246 // Add types to global schemaValidator, the types we depend on from other |
248 // namespaces will be added as needed. | 247 // namespaces will be added as needed. |
249 if (schema.types) { | 248 if (schema.types) { |
250 $Array.forEach(schema.types, function(t) { | 249 $Array.forEach(schema.types, function(t) { |
251 if (!isSchemaNodeSupported(t, platform, manifestVersion)) | 250 if (!isSchemaNodeSupported(t, platform, manifestVersion)) |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 schemaUtils.isFunctionSignatureAmbiguous(apiFunction.definition)) { | 293 schemaUtils.isFunctionSignatureAmbiguous(apiFunction.definition)) { |
295 throw new Error( | 294 throw new Error( |
296 apiFunction.name + ' has ambiguous optional arguments. ' + | 295 apiFunction.name + ' has ambiguous optional arguments. ' + |
297 'To implement custom disambiguation logic, add ' + | 296 'To implement custom disambiguation logic, add ' + |
298 '"allowAmbiguousOptionalArguments" to the function\'s schema.'); | 297 '"allowAmbiguousOptionalArguments" to the function\'s schema.'); |
299 } | 298 } |
300 | 299 |
301 this.apiFunctions_.register(functionDef.name, apiFunction); | 300 this.apiFunctions_.register(functionDef.name, apiFunction); |
302 | 301 |
303 mod[functionDef.name] = $Function.bind(function() { | 302 mod[functionDef.name] = $Function.bind(function() { |
304 var args = Array.prototype.slice.call(arguments); | 303 var args = $Array.slice(arguments); |
305 if (this.updateArgumentsPreValidate) | 304 if (this.updateArgumentsPreValidate) |
306 args = this.updateArgumentsPreValidate.apply(this, args); | 305 args = $Function.apply(this.updateArgumentsPreValidate, this, args); |
307 | 306 |
308 args = schemaUtils.normalizeArgumentsAndValidate(args, this); | 307 args = schemaUtils.normalizeArgumentsAndValidate(args, this); |
309 if (this.updateArgumentsPostValidate) | 308 if (this.updateArgumentsPostValidate) { |
310 args = this.updateArgumentsPostValidate.apply(this, args); | 309 args = $Function.apply(this.updateArgumentsPostValidate, |
| 310 this, |
| 311 args); |
| 312 } |
311 | 313 |
312 sendRequestHandler.clearCalledSendRequest(); | 314 sendRequestHandler.clearCalledSendRequest(); |
313 | 315 |
314 var retval; | 316 var retval; |
315 if (this.handleRequest) { | 317 if (this.handleRequest) { |
316 retval = this.handleRequest.apply(this, args); | 318 retval = $Function.apply(this.handleRequest, this, args); |
317 } else { | 319 } else { |
318 var optArgs = { | 320 var optArgs = { |
319 customCallback: this.customCallback | 321 customCallback: this.customCallback |
320 }; | 322 }; |
321 retval = sendRequest(this.name, args, | 323 retval = sendRequest(this.name, args, |
322 this.definition.parameters, | 324 this.definition.parameters, |
323 optArgs); | 325 optArgs); |
324 } | 326 } |
325 sendRequestHandler.clearCalledSendRequest(); | 327 sendRequestHandler.clearCalledSendRequest(); |
326 | 328 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 var ref = propertyDef['$ref']; | 398 var ref = propertyDef['$ref']; |
397 var type = utils.loadTypeSchema(propertyDef['$ref'], schema); | 399 var type = utils.loadTypeSchema(propertyDef['$ref'], schema); |
398 logging.CHECK(type, 'Schema for $ref type ' + ref + ' not found'); | 400 logging.CHECK(type, 'Schema for $ref type ' + ref + ' not found'); |
399 var constructor = createCustomType(type); | 401 var constructor = createCustomType(type); |
400 var args = value; | 402 var args = value; |
401 // For an object propertyDef, |value| is an array of constructor | 403 // For an object propertyDef, |value| is an array of constructor |
402 // arguments, but we want to pass the arguments directly (i.e. | 404 // arguments, but we want to pass the arguments directly (i.e. |
403 // not as an array), so we have to fake calling |new| on the | 405 // not as an array), so we have to fake calling |new| on the |
404 // constructor. | 406 // constructor. |
405 value = { __proto__: constructor.prototype }; | 407 value = { __proto__: constructor.prototype }; |
406 constructor.apply(value, args); | 408 $Function.apply(constructor, value, args); |
407 // Recursively add properties. | 409 // Recursively add properties. |
408 addProperties(value, propertyDef); | 410 addProperties(value, propertyDef); |
409 } else if (type === 'object') { | 411 } else if (type === 'object') { |
410 // Recursively add properties. | 412 // Recursively add properties. |
411 addProperties(value, propertyDef); | 413 addProperties(value, propertyDef); |
412 } else if (type !== 'string') { | 414 } else if (type !== 'string') { |
413 throw new Error('NOT IMPLEMENTED (extension_api.json error): ' + | 415 throw new Error('NOT IMPLEMENTED (extension_api.json error): ' + |
414 'Cannot parse values for type "' + type + '"'); | 416 'Cannot parse values for type "' + type + '"'); |
415 } | 417 } |
416 m[propertyName] = value; | 418 m[propertyName] = value; |
417 } | 419 } |
418 }); | 420 }); |
419 }; | 421 }; |
420 | 422 |
421 addProperties(mod, schema); | 423 addProperties(mod, schema); |
422 | 424 |
423 var availability = GetAvailability(schema.namespace); | 425 var availability = GetAvailability(schema.namespace); |
424 if (!availability.is_available && Object.keys(mod).length == 0) { | 426 if (!availability.is_available && $Object.keys(mod).length == 0) { |
425 console.error('chrome.' + schema.namespace + ' is not available: ' + | 427 console.error('chrome.' + schema.namespace + ' is not available: ' + |
426 availability.message); | 428 availability.message); |
427 return; | 429 return; |
428 } | 430 } |
429 | 431 |
430 this.runHooks_(mod); | 432 this.runHooks_(mod); |
431 return mod; | 433 return mod; |
432 } | 434 } |
433 }; | 435 }; |
434 | 436 |
435 exports.Binding = Binding; | 437 exports.Binding = Binding; |
OLD | NEW |