| Index: chrome/renderer/resources/extension_process_bindings.js
|
| diff --git a/chrome/renderer/resources/extension_process_bindings.js b/chrome/renderer/resources/extension_process_bindings.js
|
| index d6e08fe4cba5d686171258dc6986a7f963dadc15..94acceedb4c6c568a6934c7ad0d54b3c08eecbc4 100644
|
| --- a/chrome/renderer/resources/extension_process_bindings.js
|
| +++ b/chrome/renderer/resources/extension_process_bindings.js
|
| @@ -38,6 +38,13 @@ var chrome = chrome || {};
|
| if (!chrome)
|
| chrome = {};
|
|
|
| + function forEach(dict, f) {
|
| + for (key in dict) {
|
| + if (dict.hasOwnProperty(key))
|
| + f(key, dict[key]);
|
| + }
|
| + }
|
| +
|
| // Validate arguments.
|
| chromeHidden.validationTypes = [];
|
| chromeHidden.validate = function(args, schemas) {
|
| @@ -292,6 +299,49 @@ var chrome = chrome || {};
|
| return -1;
|
| };
|
|
|
| + 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.parameters = {};
|
| + schema.functions.forEach(function(f) {
|
| + self.parameters[f.name] = f.parameters;
|
| + });
|
| + };
|
| +
|
| + function extendSchema(schema) {
|
| + var extendedSchema = schema.slice();
|
| + extendedSchema.unshift({'type': 'string'});
|
| + return extendedSchema;
|
| + }
|
| +
|
| + var customBindings = {};
|
| +
|
| + function setupPreferences() {
|
| + customBindings['Preference'] = function(prefKey, valueSchema) {
|
| + var getSchema = this.parameters.get;
|
| + var extendedGetSchema = extendSchema(getSchema);
|
| + this.get = function(details, callback) {
|
| + chromeHidden.validate([details, callback], getSchema);
|
| + return sendRequest('experimental.preferences.get',
|
| + [prefKey, details, callback],
|
| + extendedGetSchema);
|
| + };
|
| + var setSchema = this.parameters.set.slice();
|
| + setSchema[0].properties.value = valueSchema;
|
| + var extendedSetSchema = extendSchema(setSchema);
|
| + this.set = function(details, callback) {
|
| + chromeHidden.validate([details, callback], setSchema);
|
| + return sendRequest('experimental.preferences.set',
|
| + [prefKey, details, callback],
|
| + extendedSetSchema);
|
| + };
|
| + };
|
| + customBindings['Preference'].prototype = new CustomBindingsObject();
|
| + }
|
| +
|
| // Page action events send (pageActionId, {tabId, tabUrl}).
|
| function setupPageActionEvents(extensionId) {
|
| var pageActions = GetCurrentPageActions(extensionId);
|
| @@ -422,6 +472,10 @@ var chrome = chrome || {};
|
| }
|
| chrome.initExtension(extensionId, false, IsIncognitoProcess());
|
|
|
| + // Setup the Preference class so we can use it to construct Preference
|
| + // objects from the API definition.
|
| + setupPreferences();
|
| +
|
| // |apiFunctions| is a hash of name -> object that stores the
|
| // name & definition of the apiFunction. Custom handling of api functions
|
| // is implemented by adding a "handleRequest" function to the object.
|
| @@ -447,6 +501,9 @@ var chrome = chrome || {};
|
| if (apiDef.types) {
|
| apiDef.types.forEach(function(t) {
|
| chromeHidden.validationTypes.push(t);
|
| + if (t.type == 'object' && customBindings[t.id]) {
|
| + customBindings[t.id].prototype.setSchema(t);
|
| + }
|
| });
|
| }
|
|
|
| @@ -514,24 +571,29 @@ var chrome = chrome || {};
|
|
|
| // Parse any values defined for properties.
|
| if (apiDef.properties) {
|
| - for (var prop in apiDef.properties) {
|
| - if (!apiDef.properties.hasOwnProperty(prop))
|
| - continue;
|
| -
|
| - var property = apiDef.properties[prop];
|
| + forEach(apiDef.properties, function(prop, property) {
|
| if (property.value) {
|
| var value = property.value;
|
| if (property.type === 'integer') {
|
| value = parseInt(value);
|
| } else if (property.type === 'boolean') {
|
| value = value === "true";
|
| + } else if (property["$ref"]) {
|
| + var constructor = customBindings[property["$ref"]];
|
| + var args = value;
|
| + // For an object property, |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 };
|
| + constructor.apply(value, args);
|
| } else if (property.type !== 'string') {
|
| throw "NOT IMPLEMENTED (extension_api.json error): Cannot " +
|
| "parse values for type \"" + property.type + "\"";
|
| }
|
| module[prop] = value;
|
| }
|
| - }
|
| + });
|
| }
|
|
|
| // getTabContentses is retained for backwards compatibility
|
|
|