188 lines
4.7 KiB
JavaScript
188 lines
4.7 KiB
JavaScript
(function (self, factory) {
|
|
if (typeof define === 'function' && define.amd) {
|
|
// AMD. Register as an anonymous module.
|
|
define([], factory);
|
|
} else if (typeof exports === 'object') { // Node
|
|
module.exports = factory();
|
|
} else {
|
|
// Attaches to the current context
|
|
self.castrato = factory;
|
|
}
|
|
}(this, (function () {
|
|
var
|
|
/**
|
|
* Contains the next unique node id.
|
|
*
|
|
* @property index
|
|
* @type {Integer}
|
|
* @private
|
|
*/
|
|
index = 0,
|
|
|
|
/**
|
|
* Contains all subscriptions
|
|
*
|
|
* @property subs
|
|
* @type {Object}
|
|
* @private
|
|
*/
|
|
subs = {},
|
|
|
|
/**
|
|
* An empty function.
|
|
* This method does not accept any arguments.
|
|
*
|
|
* @property noop
|
|
* @type {function}
|
|
* @private
|
|
*/
|
|
noop = function () {};
|
|
|
|
/**
|
|
* Creates a new entry in the `subs` object.
|
|
*
|
|
* @method on
|
|
* @private
|
|
* @param {Integer} fromId The unique subscriber ID.
|
|
* @param {String} event The event to subscribe to.
|
|
* @param {Function} func A function to execute when the event is triggered.
|
|
*/
|
|
function on (fromId, event, func) {
|
|
(subs[event] || (subs[event] = [])).push([fromId, func, func.length]);
|
|
}
|
|
|
|
/**
|
|
* Removes all event handlers originating from `fromId` and optionally filter by handler.
|
|
*
|
|
* @method off
|
|
* @private
|
|
* @param {Integer} fromId The unique subscriber ID.
|
|
* @param {String} event The event to unsubscribe from.
|
|
* @param {Function} [func=null] The original handler that was attached to this event. If not passed, all subscriptions will be removed.
|
|
*/
|
|
function off (fromId, event, func) {
|
|
var sub,
|
|
i = 0,
|
|
toSubs = subs[event];
|
|
|
|
if (toSubs) {
|
|
while ((sub = toSubs[i++])) {
|
|
if (sub[0] === fromId && (!func || func === sub[1])) {
|
|
toSubs.splice(--i, 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Loops through all subscriptions, calling all handlers attached to given `event`.
|
|
*
|
|
* @method emit
|
|
* @private
|
|
* @param {Integer} fromId The unique subscriber ID.
|
|
* @param {String} event The event to emit
|
|
* @param {Object} [data=undefined] Parameters to pass along to the event handler.
|
|
* @param {Function} [func=undefined] A function to execute when all event handlers has returned.
|
|
*/
|
|
function emit (persistent, event, data, func) {
|
|
var sub,
|
|
toSubs = subs[event] || [],
|
|
total = toSubs.length,
|
|
left = total,
|
|
loop = total,
|
|
answers = [],
|
|
done;
|
|
|
|
if (loop) {
|
|
done = !func ? noop : function (data) {
|
|
if (data) {
|
|
answers.push(data);
|
|
}
|
|
|
|
if (!--left) {
|
|
func(answers, total);
|
|
func = 0;
|
|
}
|
|
};
|
|
|
|
while ((sub = toSubs[--loop])) {
|
|
sub[1](data, (sub[2] > 1) ? done : left--);
|
|
}
|
|
}
|
|
|
|
// `func` get destructed when called.
|
|
// It has to be called at least once - even if no one was subscribing.
|
|
// Execute it if it still exists.
|
|
if (func) {
|
|
func(answers, total);
|
|
}
|
|
}
|
|
|
|
return function () {
|
|
var nodeId = index++;
|
|
|
|
return {
|
|
/**
|
|
* Execute all handlers attached to the given event.
|
|
*
|
|
* @method emit
|
|
* @param {String} event The event to emit
|
|
* @param {Object} [data=undefined] Parameters to pass along to the event handler.
|
|
* @param {Function} [func=undefined] A function to execute when all event handlers has returned.
|
|
* @return {Object} `this`
|
|
* @example
|
|
* $.emit('something');
|
|
* $.emit('something', { foo: 'bar' });
|
|
* $.emit('something', { foo: 'bar' }, function (data, subscribers) {
|
|
* console.log('Emit done, a total of ' + subscribers + ' subscribers returned: ', data);
|
|
* });
|
|
*/
|
|
emit: function (persistent, event, data, func) {
|
|
// emit('something', { data: true }, function () {});
|
|
if (persistent !== true || persistent !== false) {
|
|
func = data;
|
|
data = event;
|
|
event = persistent;
|
|
persistent = false;
|
|
}
|
|
|
|
emit(persistent, event, data, func);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Attach an event handler function for one event.
|
|
*
|
|
* @method on
|
|
* @param {String} event The event to subscribe to.
|
|
* @param {Function} func A function to execute when the event is triggered.
|
|
* @return {Object} `this`
|
|
* @example
|
|
* $.on('something', function (data) {
|
|
* console.log('Got something!', data);
|
|
* });
|
|
*/
|
|
on: function (event, func) {
|
|
on(nodeId, event, func);
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Removes an event handler function for one event.
|
|
*
|
|
* @method off
|
|
* @param {String} event The event to unsubscribe from.
|
|
* @param {Function} [func=null] The original handler that was attached to this event. If not passed, all subscriptions will be removed.
|
|
* @return {Object} `this`
|
|
* @example
|
|
* $.off('something');
|
|
* $.off('something else', handler);
|
|
*/
|
|
off: function (event) {
|
|
off(nodeId, event);
|
|
return this;
|
|
}
|
|
};
|
|
};
|
|
}()))); |