Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: chrome/renderer/resources/extensions/binding.js

Issue 17451011: Make the externally connectable browser test clobber all of the builtins, (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698