Last active
January 24, 2016 23:04
-
-
Save carlosascari/74d5e6e63b18896d0b16 to your computer and use it in GitHub Desktop.
Function that allows any object to function as a synchronous Event Emitter.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Provides an EventEmitter Trait | |
* | |
* USAGE @example | |
* | |
* function YourClass(){ | |
* EventEmitterTrait(this) // or any object | |
* } | |
* | |
* var yourObject = new YourClass() | |
* | |
* ### Exposes the following properties: | |
* | |
* <yourObject> yourObject.on(String, Function) | |
* Add an event handler | |
* | |
* <yourObject> yourObject.off(String, [Function]) | |
* Remove an event handler, or all handlers if the callback is | |
* not specified. | |
* | |
* <yourObject> yourObject.one(String, Function) | |
* Add an event handler that will remove itself upon executing. | |
* | |
* <yourObject> yourObject.emit(String, ...) | |
* Emit an event, all registered callbacks will be executed in sync | |
* with the handlers registered first, being executed first. Any argument | |
* after the eventName (first argument) is passed to the event handler(s). | |
* | |
* <yourObject> yourObject.clearEvents() | |
* Remove all event handlers | |
* | |
* <Object> yourObject.__events__ | |
* All registered events | |
* | |
* @module Traits | |
* @submodule EventEmitterTrait | |
*/ | |
var EventEmitterTrait = (function () { | |
/** | |
* @private | |
* @method isArray | |
* @param object {Mixed} | |
* @return Boolean | |
*/ | |
function isArray (object) | |
{ | |
return object && Object.prototype.toString.call(object) === '[object Array]' | |
} | |
/** | |
* @method EventEmitterTrait | |
* @param instance {Object} | |
* @return Object | |
*/ | |
function EventEmitterTrait (instance) { | |
/** | |
* @private | |
* @property events | |
* @type Object | |
*/ | |
var events = {} | |
/** | |
* @method on | |
* @param eventName {String} | |
* @param callback {Function} | |
* @return this | |
*/ | |
Object.defineProperty(instance, 'on', { | |
configurable: false, enumerable: true, | |
value: function EventEmitterTrait__on (eventName, callback) { | |
if (typeof callback !== 'function') | |
{ | |
throw new Error('callback must be a Function') | |
} | |
if (isArray(events[eventName])) | |
{ | |
events[eventName].push(callback) | |
} | |
else | |
{ | |
events[eventName] = [callback] | |
} | |
return instance | |
} | |
}) | |
/** | |
* @method off | |
* @param eventName {String} | |
* @param [callback] {Function} | |
* @return this | |
*/ | |
Object.defineProperty(instance, 'off', { | |
configurable: false, enumerable: true, | |
value: function EventEmitterTrait__off (eventName, callback) { | |
if (events[eventName] && events[eventName].length) | |
{ | |
if (typeof callback === 'function') | |
{ | |
var index = events[eventName].indexOf(callback) | |
if (index !== -1) | |
{ | |
events[eventName].splice(index, 1) | |
} | |
} | |
else | |
{ | |
events[eventName] = [] | |
} | |
} | |
return instance | |
} | |
}) | |
/** | |
* @method one | |
* @param eventName {String} | |
* @param callback {Function} | |
* @return this | |
*/ | |
Object.defineProperty(instance, 'one', { | |
configurable: false, enumerable: true, | |
value: function EventEmitterTrait__one (eventName, callback) { | |
function _on (){ | |
callback.apply(callback, arguments) | |
setTimeout(_off, 0) | |
} | |
function _off (){ | |
instance.off(eventName, _on) | |
} | |
instance.on(eventName, _on) | |
return instance | |
} | |
}) | |
/** | |
* @method emit | |
* @param eventName {String} | |
* @param [...] {Mixed} | |
* @return this | |
*/ | |
Object.defineProperty(instance, 'emit', { | |
configurable: false, enumerable: true, | |
value: function EventEmitterTrait__emit (eventName) { | |
if (events[eventName] && events[eventName].length) | |
{ | |
var args = Array.prototype.slice.call(arguments, 1) | |
var count = events[eventName].length | |
for (var i = 0; i < count; i++) | |
{ | |
if (events[eventName][i]) | |
{ | |
events[eventName][i].apply(instance, args) | |
} | |
} | |
} | |
return instance | |
} | |
}) | |
/** | |
* @method clearEvents | |
* @return this | |
*/ | |
Object.defineProperty(instance, 'clearEvents', { | |
configurable: false, enumerable: true, | |
value: function EventEmitterTrait__clearEvents () { | |
var eventNames = Object.keys(events) | |
for (var i = 0, l = eventNames.length; i < l; i++) | |
{ | |
instance.off(eventNames[i]) | |
} | |
return instance | |
} | |
}) | |
Object.defineProperty(instance, '__events__', { | |
configurable: false, enumerable: false, | |
get: function EventEmitterTrait__get___events__ () { | |
return events | |
} | |
}) | |
} | |
return EventEmitterTrait | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment