/**
* Module Dependencies
*/
var events = require('evt');
/**
* Local vars
*/
var listenerMap = {};
/**
* Registers a event listener.
*
* @param {String} name
* @param {String} module
* @param {Function} cb
* @return {View}
*/
exports.on = function(name, module, cb) {
var l;
// cb can be passed as
// the second or third argument
if (typeof module !== 'string') {
cb = module;
module = null;
}
// if a module is provided
// pass in a special callback
// function that checks the
// module
if (module) {
if (!listenerMap[name]) listenerMap[name] = [];
l = listenerMap[name].push({
orig: cb,
cb: function() {
if (this.event.target.module() === module) {
cb.apply(this, arguments);
}
}
});
events.prototype.on.call(this, name, listenerMap[name][l-1].cb);
} else {
events.prototype.on.call(this, name, cb);
}
return this;
};
/**
* Unregisters a event listener.
*
* @param {String} name
* @param {String} module
* @param {Function} cb
* @return {View}
*/
exports.off = function(name, module, cb) {
// cb can be passed as
// the second or third argument
if (typeof module !== 'string') {
cb = module;
module = null;
}
if (listenerMap[name]) {
listenerMap[name] = listenerMap[name].filter(function(map) {
// If a callback provided, keep it
// in the listener map if it doesn't match
if (cb && map.orig !== cb) {
return true;
// Otherwise remove it from the listener
// map and unbind the event listener
} else {
events.prototype.off.call(this, name, map.cb);
return false;
}
}, this);
}
if (!module) {
events.prototype.off.call(this, name, cb);
}
return this;
};
/**
* Fires an event on a view.
*
* @param {String} name
* @return {View}
*/
exports.fire = function(name) {
var _event = this.event;
var event = {
target: this,
propagate: true,
stopPropagation: function(){ this.propagate = false; }
};
propagate(this, arguments, event);
// COMPLEX:
// If an earlier event object was
// cached, restore the the event
// back onto the view. If there
// wasn't an earlier event, make
// sure the `event` key has been
// deleted off the view.
if (_event) this.event = _event;
else delete this.event;
// Allow chaining
return this;
};
function propagate(view, args, event) {
if (!view || !event.propagate) return;
view.event = event;
events.prototype.fire.apply(view, args);
propagate(view.parent, args, event);
}
exports.fireStatic = events.prototype.fire;
|