Chromium Code Reviews| Index: chrome/renderer/resources/extensions/event.js |
| diff --git a/chrome/renderer/resources/extensions/event.js b/chrome/renderer/resources/extensions/event.js |
| index 5288b6e26e22df6178452ac42f54934be2adaf80..06a0a9b3b2a9d9a30f59d374bbb3040be5645fea 100644 |
| --- a/chrome/renderer/resources/extensions/event.js |
| +++ b/chrome/renderer/resources/extensions/event.js |
| @@ -6,6 +6,7 @@ |
| var AttachEvent = eventBindingsNatives.AttachEvent; |
| var DetachEvent = eventBindingsNatives.DetachEvent; |
| var Print = eventBindingsNatives.Print; |
| + var sendRequest = require('sendRequest').sendRequest; |
|
Aaron Boodman
2012/05/09 19:29:46
TODO(aa): Look at this file more closely.
|
| var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); |
| @@ -60,21 +61,24 @@ |
| // |
| // If opt_eventOptions exists, it is a dictionary that contains the boolean |
| // entries "supportsListeners" and "supportsRules". |
| - chrome.Event = function(opt_eventName, opt_argSchemas, opt_eventOptions) { |
| + chrome.Event = function(opt_eventName, opt_argSchemas, opt_eventOptions, |
|
not at google - send to devlin
2012/05/10 09:01:25
nit: arguments should line up or fix on 1 line :(
battre
2012/05/10 16:40:29
According to the JavaScript Style Guide, the rule
|
| + opt_eventsSchema) { |
| this.eventName_ = opt_eventName; |
| this.listeners_ = []; |
| this.eventOptions_ = opt_eventOptions || |
| {"supportsListeners": true, "supportsRules": false}; |
| + this.eventsSchema_ = opt_eventsSchema; |
| if (this.eventOptions_.supportsRules && !opt_eventName) |
| throw new Error("Events that support rules require an event name."); |
| - // Validate event parameters if we are in debug. |
| + // Validate event arguments (the data that is passed to the callbacks) |
| + // if we are in debug. |
| if (opt_argSchemas && |
| chromeHidden.validateCallbacks && |
| chromeHidden.validate) { |
| - this.validate_ = function(args) { |
| + this.validateEventArgs_ = function(args) { |
| try { |
| chromeHidden.validate(args, opt_argSchemas); |
| } catch (exception) { |
| @@ -83,7 +87,27 @@ |
| } |
| }; |
| } else { |
| - this.validate_ = function() {} |
| + this.validateEventArgs_ = function() {} |
| + } |
| + |
| + if (this.eventOptions_.supportsRules) { |
| + if (!this.eventsSchema_) { |
| + throw new Error("Events with rules support require the schema of the " + |
| + "chrome.events namespace"); |
| + } |
| + // Determine schemas of function parameters. |
| + var eventType = chromeHidden.lookup(this.eventsSchema_.types, |
| + 'id', 'Event'); |
|
not at google - send to devlin
2012/05/10 09:01:25
nit: argument lineup thing (and on the lines below
battre
2012/05/10 16:40:29
See above
|
| + this.addRulesParams_ = chromeHidden.lookup(eventType.functions, |
| + 'name', 'addRules').parameters; |
| + this.getRulesParams_ = chromeHidden.lookup(eventType.functions, |
| + 'name', 'getRules').parameters; |
| + this.removeRulesParams_ = chromeHidden.lookup(eventType.functions, |
| + 'name', 'removeRules').parameters; |
| + } else { |
| + this.addRulesParams_ = []; |
| + this.getRulesParams_ = []; |
| + this.removeRulesParams_ = []; |
| } |
| }; |
| @@ -193,7 +217,7 @@ |
| if (!this.eventOptions_.supportsListeners) |
| throw new Error("This event does not support listeners."); |
| var args = Array.prototype.slice.call(arguments); |
| - var validationErrors = this.validate_(args); |
| + var validationErrors = this.validateEventArgs_(args); |
| if (validationErrors) { |
| return {validationErrors: validationErrors}; |
| } |
| @@ -247,49 +271,69 @@ |
| chrome.Event.prototype.destroy_ = function() { |
| this.listeners_ = []; |
| - this.validate_ = []; |
| + this.validateEventArgs_ = []; |
| this.detach_(false); |
| }; |
| - // Gets the declarative API object, or undefined if this extension doesn't |
| - // have access to it. |
| - // |
| - // This is defined as a function (rather than a variable) because it isn't |
| - // accessible until the schema bindings have been generated. |
| - function getDeclarativeAPI() { |
| - return chromeHidden.internalAPIs.declarative; |
| - } |
| - |
| chrome.Event.prototype.addRules = function(rules, opt_cb) { |
| if (!this.eventOptions_.supportsRules) |
| throw new Error("This event does not support rules."); |
| - if (!getDeclarativeAPI()) { |
| - throw new Error("You must have permission to use the declarative " + |
| - "API to support rules in events"); |
| + |
| + // Takes a list of JSON datatype identifiers and returns a schema fragment |
| + // that verifies that a JSON object corresponds to an array of only these |
| + // data types. |
| + function buildArrayOfChoicesSchema(typesList) { |
| + return { |
| + 'type': 'array', |
| + 'items': { |
| + 'choices': typesList.map(function(el) {return {'$ref': el};}) |
| + } |
| + }; |
| + }; |
| + |
| + // Validate conditions and actions against specific schemas of this |
| + // event object type. |
| + // |rules| is an array of JSON objects that follow the Rule type of the |
| + // declarative extension APIs. |conditions| is an array of JSON type |
| + // identifiers that are allowed to occur in the conditions attribute of each |
| + // rule. Likewise, |actions| is an array of JSON type identifiers that are |
| + // allowed to occur in the actions attribute of each rule. |
| + function validateRules(rules, conditions, actions) { |
| + var conditionsSchema = buildArrayOfChoicesSchema(conditions); |
| + var actionsSchema = buildArrayOfChoicesSchema(actions); |
| + rules.forEach(function(rule) { |
| + chromeHidden.validate([rule.conditions], [conditionsSchema]); |
| + chromeHidden.validate([rule.actions], [actionsSchema]); |
| + }) |
| + }; |
| + |
| + if (!this.eventOptions_.conditions || !this.eventOptions_.actions) { |
| + throw new Error('Event ' + this.eventName_ + ' misses conditions or ' + |
| + 'actions in the API specification.'); |
| } |
| - getDeclarativeAPI().addRules(this.eventName_, rules, opt_cb); |
| + |
| + validateRules(rules, |
| + this.eventOptions_.conditions, |
| + this.eventOptions_.actions); |
| + |
| + sendRequest("events.addRules", [this.eventName_, rules, opt_cb], |
| + this.addRulesParams_); |
|
not at google - send to devlin
2012/05/10 09:01:25
did we lose the ability to do chromeHidden.interna
battre
2012/05/10 16:40:29
Yes, because there is no such function anymore. "e
|
| } |
| chrome.Event.prototype.removeRules = function(ruleIdentifiers, opt_cb) { |
| if (!this.eventOptions_.supportsRules) |
| throw new Error("This event does not support rules."); |
| - if (!getDeclarativeAPI()) { |
| - throw new Error("You must have permission to use the declarative " + |
| - "API to support rules in events"); |
| - } |
| - getDeclarativeAPI().removeRules( |
| - this.eventName_, ruleIdentifiers, opt_cb); |
| + sendRequest("events.removeRules", |
| + [this.eventName_, ruleIdentifiers, opt_cb], |
| + this.removeRulesParams_); |
| } |
| chrome.Event.prototype.getRules = function(ruleIdentifiers, cb) { |
| if (!this.eventOptions_.supportsRules) |
| throw new Error("This event does not support rules."); |
| - if (!getDeclarativeAPI()) { |
| - throw new Error("You must have permission to use the declarative " + |
| - "API to support rules in events"); |
| - } |
| - getDeclarativeAPI().getRules( |
| - this.eventName_, ruleIdentifiers, cb); |
| + sendRequest("events.getRules", |
| + [this.eventName_, ruleIdentifiers, cb], |
| + this.getRulesParams_); |
| } |
| // Special load events: we don't use the DOM unload because that slows |