| 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 eventNatives = requireNative('event_natives'); | 5 var eventNatives = requireNative('event_natives'); |
| 6 var logging = requireNative('logging'); | 6 var logging = requireNative('logging'); |
| 7 var schemaRegistry = requireNative('schema_registry'); | 7 var schemaRegistry = requireNative('schema_registry'); |
| 8 var sendRequest = require('sendRequest').sendRequest; | 8 var sendRequest = require('sendRequest').sendRequest; |
| 9 var utils = require('utils'); | 9 var utils = require('utils'); |
| 10 var validate = require('schemaUtils').validate; | 10 var validate = require('schemaUtils').validate; |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 }; | 102 }; |
| 103 | 103 |
| 104 FilteredAttachmentStrategy.prototype.detach = function(manual) { | 104 FilteredAttachmentStrategy.prototype.detach = function(manual) { |
| 105 for (var i in this.listenerMap_) | 105 for (var i in this.listenerMap_) |
| 106 this.detachListener(this.listenerMap_[i], manual); | 106 this.detachListener(this.listenerMap_[i], manual); |
| 107 }; | 107 }; |
| 108 | 108 |
| 109 FilteredAttachmentStrategy.prototype.getListenersByIDs = function(ids) { | 109 FilteredAttachmentStrategy.prototype.getListenersByIDs = function(ids) { |
| 110 var result = []; | 110 var result = []; |
| 111 for (var i = 0; i < ids.length; i++) | 111 for (var i = 0; i < ids.length; i++) |
| 112 result.push(this.listenerMap_[ids[i]]); | 112 $Array.push(result, this.listenerMap_[ids[i]]); |
| 113 return result; | 113 return result; |
| 114 }; | 114 }; |
| 115 | 115 |
| 116 function parseEventOptions(opt_eventOptions) { | 116 function parseEventOptions(opt_eventOptions) { |
| 117 function merge(dest, src) { | 117 function merge(dest, src) { |
| 118 for (var k in src) { | 118 for (var k in src) { |
| 119 if (!dest.hasOwnProperty(k)) { | 119 if (!$Object.hasOwnProperty(dest, k)) { |
| 120 dest[k] = src[k]; | 120 dest[k] = src[k]; |
| 121 } | 121 } |
| 122 } | 122 } |
| 123 } | 123 } |
| 124 | 124 |
| 125 var options = opt_eventOptions || {}; | 125 var options = opt_eventOptions || {}; |
| 126 merge(options, | 126 merge(options, |
| 127 {supportsFilters: false, | 127 {supportsFilters: false, |
| 128 supportsListeners: true, | 128 supportsListeners: true, |
| 129 supportsRules: false, | 129 supportsRules: false, |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 this.getListenerCount() >= this.eventOptions_.maxListeners) | 217 this.getListenerCount() >= this.eventOptions_.maxListeners) |
| 218 throw new Error("Too many listeners for " + this.eventName_); | 218 throw new Error("Too many listeners for " + this.eventName_); |
| 219 if (filters) { | 219 if (filters) { |
| 220 if (!this.eventOptions_.supportsFilters) | 220 if (!this.eventOptions_.supportsFilters) |
| 221 throw new Error("This event does not support filters."); | 221 throw new Error("This event does not support filters."); |
| 222 if (filters.url && !(filters.url instanceof Array)) | 222 if (filters.url && !(filters.url instanceof Array)) |
| 223 throw new Error("filters.url should be an array"); | 223 throw new Error("filters.url should be an array"); |
| 224 } | 224 } |
| 225 var listener = {callback: cb, filters: filters}; | 225 var listener = {callback: cb, filters: filters}; |
| 226 this.attach_(listener); | 226 this.attach_(listener); |
| 227 this.listeners_.push(listener); | 227 $Array.push(this.listeners_, listener); |
| 228 }; | 228 }; |
| 229 | 229 |
| 230 Event.prototype.attach_ = function(listener) { | 230 Event.prototype.attach_ = function(listener) { |
| 231 this.attachmentStrategy_.onAddedListener(listener); | 231 this.attachmentStrategy_.onAddedListener(listener); |
| 232 if (this.listeners_.length == 0) { | 232 if (this.listeners_.length == 0) { |
| 233 allAttachedEvents[allAttachedEvents.length] = this; | 233 allAttachedEvents[allAttachedEvents.length] = this; |
| 234 if (!this.eventName_) | 234 if (!this.eventName_) |
| 235 return; | 235 return; |
| 236 | 236 |
| 237 if (attachedNamedEvents[this.eventName_]) | 237 if (attachedNamedEvents[this.eventName_]) |
| 238 throw new Error("Event '" + this.eventName_ + "' is already attached."); | 238 throw new Error("Event '" + this.eventName_ + "' is already attached."); |
| 239 | 239 |
| 240 attachedNamedEvents[this.eventName_] = this; | 240 attachedNamedEvents[this.eventName_] = this; |
| 241 } | 241 } |
| 242 }; | 242 }; |
| 243 | 243 |
| 244 // Unregisters a callback. | 244 // Unregisters a callback. |
| 245 Event.prototype.removeListener = function(cb) { | 245 Event.prototype.removeListener = function(cb) { |
| 246 if (!this.eventOptions_.supportsListeners) | 246 if (!this.eventOptions_.supportsListeners) |
| 247 throw new Error("This event does not support listeners."); | 247 throw new Error("This event does not support listeners."); |
| 248 var idx = this.findListener_(cb); | 248 var idx = this.findListener_(cb); |
| 249 if (idx == -1) | 249 if (idx == -1) |
| 250 return; | 250 return; |
| 251 | 251 |
| 252 var removedListener = this.listeners_.splice(idx, 1)[0]; | 252 var removedListener = $Array.splice(this.listeners_, idx, 1)[0]; |
| 253 this.attachmentStrategy_.onRemovedListener(removedListener); | 253 this.attachmentStrategy_.onRemovedListener(removedListener); |
| 254 | 254 |
| 255 if (this.listeners_.length == 0) { | 255 if (this.listeners_.length == 0) { |
| 256 var i = allAttachedEvents.indexOf(this); | 256 var i = allAttachedEvents.indexOf(this); |
| 257 if (i >= 0) | 257 if (i >= 0) |
| 258 delete allAttachedEvents[i]; | 258 delete allAttachedEvents[i]; |
| 259 if (!this.eventName_) | 259 if (!this.eventName_) |
| 260 return; | 260 return; |
| 261 | 261 |
| 262 if (!attachedNamedEvents[this.eventName_]) | 262 if (!attachedNamedEvents[this.eventName_]) |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 if (!this.eventOptions_.supportsListeners) | 301 if (!this.eventOptions_.supportsListeners) |
| 302 throw new Error("This event does not support listeners."); | 302 throw new Error("This event does not support listeners."); |
| 303 var validationErrors = this.validateEventArgs_(args); | 303 var validationErrors = this.validateEventArgs_(args); |
| 304 if (validationErrors) { | 304 if (validationErrors) { |
| 305 console.error(validationErrors); | 305 console.error(validationErrors); |
| 306 return {validationErrors: validationErrors}; | 306 return {validationErrors: validationErrors}; |
| 307 } | 307 } |
| 308 | 308 |
| 309 // Make a copy of the listeners in case the listener list is modified | 309 // Make a copy of the listeners in case the listener list is modified |
| 310 // while dispatching the event. | 310 // while dispatching the event. |
| 311 var listeners = | 311 var listeners = $Array.slice( |
| 312 this.attachmentStrategy_.getListenersByIDs(listenerIDs).slice(); | 312 this.attachmentStrategy_.getListenersByIDs(listenerIDs)); |
| 313 | 313 |
| 314 var results = []; | 314 var results = []; |
| 315 for (var i = 0; i < listeners.length; i++) { | 315 for (var i = 0; i < listeners.length; i++) { |
| 316 try { | 316 try { |
| 317 var result = this.dispatchToListener(listeners[i].callback, args); | 317 var result = this.dispatchToListener(listeners[i].callback, args); |
| 318 if (result !== undefined) | 318 if (result !== undefined) |
| 319 results.push(result); | 319 $Array.push(results, result); |
| 320 } catch (e) { | 320 } catch (e) { |
| 321 var errorMessage = "Error in event handler"; | 321 var errorMessage = "Error in event handler"; |
| 322 if (this.eventName_) | 322 if (this.eventName_) |
| 323 errorMessage += " for " + this.eventName_; | 323 errorMessage += " for " + this.eventName_; |
| 324 errorMessage += ": " + e; | 324 errorMessage += ": " + e; |
| 325 console.error(errorMessage); | 325 console.error(errorMessage); |
| 326 } | 326 } |
| 327 } | 327 } |
| 328 if (results.length) | 328 if (results.length) |
| 329 return {results: results}; | 329 return {results: results}; |
| 330 } | 330 } |
| 331 | 331 |
| 332 // Can be overridden to support custom dispatching. | 332 // Can be overridden to support custom dispatching. |
| 333 Event.prototype.dispatchToListener = function(callback, args) { | 333 Event.prototype.dispatchToListener = function(callback, args) { |
| 334 return callback.apply(null, args); | 334 return $Function.apply(callback, null, args); |
| 335 } | 335 } |
| 336 | 336 |
| 337 // Dispatches this event object to all listeners, passing all supplied | 337 // Dispatches this event object to all listeners, passing all supplied |
| 338 // arguments to this function each listener. | 338 // arguments to this function each listener. |
| 339 Event.prototype.dispatch = function(varargs) { | 339 Event.prototype.dispatch = function(varargs) { |
| 340 return this.dispatch_(Array.prototype.slice.call(arguments), undefined); | 340 return this.dispatch_($Array.slice(arguments), undefined); |
| 341 }; | 341 }; |
| 342 | 342 |
| 343 // Detaches this event object from its name. | 343 // Detaches this event object from its name. |
| 344 Event.prototype.detach_ = function() { | 344 Event.prototype.detach_ = function() { |
| 345 this.attachmentStrategy_.detach(false); | 345 this.attachmentStrategy_.detach(false); |
| 346 }; | 346 }; |
| 347 | 347 |
| 348 Event.prototype.destroy_ = function() { | 348 Event.prototype.destroy_ = function() { |
| 349 this.listeners_ = []; | 349 this.listeners_ = []; |
| 350 this.validateEventArgs_ = []; | 350 this.validateEventArgs_ = []; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 } | 389 } |
| 390 | 390 |
| 391 validateRules(rules, | 391 validateRules(rules, |
| 392 this.eventOptions_.conditions, | 392 this.eventOptions_.conditions, |
| 393 this.eventOptions_.actions); | 393 this.eventOptions_.actions); |
| 394 | 394 |
| 395 ensureRuleSchemasLoaded(); | 395 ensureRuleSchemasLoaded(); |
| 396 // We remove the first parameter from the validation to give the user more | 396 // We remove the first parameter from the validation to give the user more |
| 397 // meaningful error messages. | 397 // meaningful error messages. |
| 398 validate([rules, opt_cb], | 398 validate([rules, opt_cb], |
| 399 ruleFunctionSchemas.addRules.parameters.slice().splice(1)); | 399 $Array.splice( |
| 400 $Array.slice(ruleFunctionSchemas.addRules.parameters), 1)); |
| 400 sendRequest("events.addRules", [this.eventName_, rules, opt_cb], | 401 sendRequest("events.addRules", [this.eventName_, rules, opt_cb], |
| 401 ruleFunctionSchemas.addRules.parameters); | 402 ruleFunctionSchemas.addRules.parameters); |
| 402 } | 403 } |
| 403 | 404 |
| 404 Event.prototype.removeRules = function(ruleIdentifiers, opt_cb) { | 405 Event.prototype.removeRules = function(ruleIdentifiers, opt_cb) { |
| 405 if (!this.eventOptions_.supportsRules) | 406 if (!this.eventOptions_.supportsRules) |
| 406 throw new Error("This event does not support rules."); | 407 throw new Error("This event does not support rules."); |
| 407 ensureRuleSchemasLoaded(); | 408 ensureRuleSchemasLoaded(); |
| 408 // We remove the first parameter from the validation to give the user more | 409 // We remove the first parameter from the validation to give the user more |
| 409 // meaningful error messages. | 410 // meaningful error messages. |
| 410 validate([ruleIdentifiers, opt_cb], | 411 validate([ruleIdentifiers, opt_cb], |
| 411 ruleFunctionSchemas.removeRules.parameters.slice().splice(1)); | 412 $Array.splice( |
| 413 $Array.slice(ruleFunctionSchemas.removeRules.parameters), 1)); |
| 412 sendRequest("events.removeRules", | 414 sendRequest("events.removeRules", |
| 413 [this.eventName_, ruleIdentifiers, opt_cb], | 415 [this.eventName_, ruleIdentifiers, opt_cb], |
| 414 ruleFunctionSchemas.removeRules.parameters); | 416 ruleFunctionSchemas.removeRules.parameters); |
| 415 } | 417 } |
| 416 | 418 |
| 417 Event.prototype.getRules = function(ruleIdentifiers, cb) { | 419 Event.prototype.getRules = function(ruleIdentifiers, cb) { |
| 418 if (!this.eventOptions_.supportsRules) | 420 if (!this.eventOptions_.supportsRules) |
| 419 throw new Error("This event does not support rules."); | 421 throw new Error("This event does not support rules."); |
| 420 ensureRuleSchemasLoaded(); | 422 ensureRuleSchemasLoaded(); |
| 421 // We remove the first parameter from the validation to give the user more | 423 // We remove the first parameter from the validation to give the user more |
| 422 // meaningful error messages. | 424 // meaningful error messages. |
| 423 validate([ruleIdentifiers, cb], | 425 validate([ruleIdentifiers, cb], |
| 424 ruleFunctionSchemas.getRules.parameters.slice().splice(1)); | 426 $Array.splice( |
| 427 $Array.slice(ruleFunctionSchemas.getRules.parameters), 1)); |
| 425 | 428 |
| 426 sendRequest("events.getRules", | 429 sendRequest("events.getRules", |
| 427 [this.eventName_, ruleIdentifiers, cb], | 430 [this.eventName_, ruleIdentifiers, cb], |
| 428 ruleFunctionSchemas.getRules.parameters); | 431 ruleFunctionSchemas.getRules.parameters); |
| 429 } | 432 } |
| 430 | 433 |
| 431 unloadEvent.addListener(function() { | 434 unloadEvent.addListener(function() { |
| 432 for (var i = 0; i < allAttachedEvents.length; ++i) { | 435 for (var i = 0; i < allAttachedEvents.length; ++i) { |
| 433 var event = allAttachedEvents[i]; | 436 var event = allAttachedEvents[i]; |
| 434 if (event) | 437 if (event) |
| 435 event.detach_(); | 438 event.detach_(); |
| 436 } | 439 } |
| 437 }); | 440 }); |
| 438 | 441 |
| 439 // NOTE: Event is (lazily) exposed as chrome.Event from dispatcher.cc. | 442 // NOTE: Event is (lazily) exposed as chrome.Event from dispatcher.cc. |
| 440 exports.Event = Event; | 443 exports.Event = Event; |
| 441 | 444 |
| 442 exports.dispatchEvent = dispatchEvent; | 445 exports.dispatchEvent = dispatchEvent; |
| 443 exports.parseEventOptions = parseEventOptions; | 446 exports.parseEventOptions = parseEventOptions; |
| 444 exports.registerArgumentMassager = registerArgumentMassager; | 447 exports.registerArgumentMassager = registerArgumentMassager; |
| OLD | NEW |