golden-layout
Version:
A multi-screen javascript Layout manager https://golden-layout.com
130 lines (115 loc) • 3.29 kB
JavaScript
/**
* A generic and very fast EventEmitter
* implementation. On top of emitting the
* actual event it emits an
*
* lm.utils.EventEmitter.ALL_EVENT
*
* event for every event triggered. This allows
* to hook into it and proxy events forwards
*
* @constructor
*/
lm.utils.EventEmitter = function()
{
this._mSubscriptions = { };
this._mSubscriptions[ lm.utils.EventEmitter.ALL_EVENT ] = [];
/**
* Listen for events
*
* @param {String} sEvent The name of the event to listen to
* @param {Function} fCallback The callback to execute when the event occurs
* @param {[Object]} oContext The value of the this pointer within the callback function
*
* @returns {void}
*/
this.on = function( sEvent, fCallback, oContext )
{
if ( !lm.utils.isFunction(fCallback) ) {
throw new Error( 'Tried to listen to event ' + sEvent + ' with non-function callback ' + fCallback );
}
if( !this._mSubscriptions[ sEvent ] )
{
this._mSubscriptions[ sEvent ] = [];
}
this._mSubscriptions[ sEvent ].push({ fn: fCallback, ctx: oContext });
};
/**
* Emit an event and notify listeners
*
* @param {String} sEvent The name of the event
* @param {Mixed} various additional arguments that will be passed to the listener
*
* @returns {void}
*/
this.emit = function( sEvent )
{
var i, ctx, args;
args = Array.prototype.slice.call( arguments, 1 );
if( this._mSubscriptions[ sEvent ] ) {
for( i = 0; i < this._mSubscriptions[ sEvent ].length; i++ )
{
ctx = this._mSubscriptions[ sEvent ][ i ].ctx || {};
this._mSubscriptions[ sEvent ][ i ].fn.apply( ctx, args );
}
}
args.unshift( sEvent );
for( i = 0; i < this._mSubscriptions[ lm.utils.EventEmitter.ALL_EVENT ].length; i++ )
{
ctx = this._mSubscriptions[ lm.utils.EventEmitter.ALL_EVENT ][ i ].ctx || {};
this._mSubscriptions[ lm.utils.EventEmitter.ALL_EVENT ][ i ].fn.apply( ctx, args );
}
};
/**
* Removes a listener for an event, or all listeners if no callback and context is provided.
*
* @param {String} sEvent The name of the event
* @param {Function} fCallback The previously registered callback method (optional)
* @param {Object} oContext The previously registered context (optional)
*
* @returns {void}
*/
this.unbind = function( sEvent, fCallback, oContext )
{
if( !this._mSubscriptions[ sEvent ] ) {
throw new Error( 'No subscribtions to unsubscribe for event ' + sEvent );
}
var i, bUnbound = false;
for( i = 0; i < this._mSubscriptions[ sEvent ].length; i++ )
{
if
(
( !fCallback || this._mSubscriptions[ sEvent ][ i ].fn === fCallback ) &&
( !oContext || oContext === this._mSubscriptions[ sEvent ][ i ].ctx )
)
{
this._mSubscriptions[ sEvent ].splice( i, 1 );
bUnbound = true;
}
}
if( bUnbound === false )
{
throw new Error( 'Nothing to unbind for ' + sEvent );
}
};
/**
* Alias for unbind
*/
this.off = this.unbind;
/**
* Alias for emit
*/
this.trigger = this.emit;
};
/**
* The name of the event that's triggered for every other event
*
* usage
*
* myEmitter.on( lm.utils.EventEmitter.ALL_EVENT, function( eventName, argsArray ){
* //do stuff
* });
*
* @type {String}
*/
lm.utils.EventEmitter.ALL_EVENT = '__all';