src/Emitter.js
function listen(eventIdentifier, callback, context) {
		if (typeof callback !== 'function') { throw new TypeError('on: Illegal Argument: callback must be a function, was ' + (typeof callback)); }

		// This allows us to work even if the constructor hasn't been called.  Useful for mixins.
		if (this._emitterListeners === undefined) {
			this._emitterListeners = new MultiMap();
		}

		if (typeof eventIdentifier === 'function' && (eventIdentifier.prototype instanceof metaEvents.MetaEvent || eventIdentifier === metaEvents.MetaEvent)) {
			// Since triggering meta events can be expensive, we only
			// do so if a listener has been added to listen to them.
			this._emitterMetaEventsOn = true;
		}

		var currentListeners = this._emitterListeners.getValues(eventIdentifier);
		currentListeners = currentListeners.filter(function(listenerRecord) {
			return listenerRecord.registeredContext === context
				&& (listenerRecord.callback === callback
					|| (listenerRecord.callback._wrappedCallback !== undefined
						&& listenerRecord.callback._wrappedCallback === callback._wrappedCallback));
		});
		if (currentListeners.length > 0) {
			throw new Error('This callback is already listening to this event.');
		}

		this._emitterListeners.add(eventIdentifier, {
			eventIdentifier: eventIdentifier,
			callback: callback,
			registeredContext: context,
			context: context !== undefined ? context : this
		});

		if (this._emitterMetaEventsOn === true) {
			this.trigger(new metaEvents.AddListenerEvent(eventIdentifier, callback._onceFunctionMarker === ONCE_FUNCTION_MARKER ? callback._wrappedCallback : callback, context));
		}
	}
function listen(eventIdentifier, callback, context) {
		if (typeof callback !== 'function') { throw new TypeError('on: Illegal Argument: callback must be a function, was ' + (typeof callback)); }

		// This allows us to work even if the constructor hasn't been called.  Useful for mixins.
		if (this._emitterListeners === undefined) {
			this._emitterListeners = new MultiMap();
		}

		if (typeof eventIdentifier === 'function' && (eventIdentifier.prototype instanceof metaEvents.MetaEvent || eventIdentifier === metaEvents.MetaEvent)) {
			// Since triggering meta events can be expensive, we only
			// do so if a listener has been added to listen to them.
			this._emitterMetaEventsOn = true;
		}

		var currentListeners = this._emitterListeners.getValues(eventIdentifier);
		currentListeners = currentListeners.filter(function(listenerRecord) {
			return listenerRecord.registeredContext === context
				&& (listenerRecord.callback === callback
					|| (listenerRecord.callback._wrappedCallback !== undefined
						&& listenerRecord.callback._wrappedCallback === callback._wrappedCallback));
		});
		if (currentListeners.length > 0) {
			throw new Error('This callback is already listening to this event.');
		}

		this._emitterListeners.add(eventIdentifier, {
			eventIdentifier: eventIdentifier,
			callback: callback,
			registeredContext: context,
			context: context !== undefined ? context : this
		});

		if (this._emitterMetaEventsOn === true) {
			this.trigger(new metaEvents.AddListenerEvent(eventIdentifier, callback._onceFunctionMarker === ONCE_FUNCTION_MARKER ? callback._wrappedCallback : callback, context));
		}
	}
function listen ( eventIdentifier , callback , context ) { if ( typeof callback !== 'function' ) { throw new TypeError ( 'on: Illegal Argument: callback must be a function, was ' + ( typeof callback ) ) ; } // This allows us to work even if the constructor hasn't been called.  Useful for mixins. if ( this . _emitterListeners === undefined ) { this . _emitterListeners = new MultiMap ( ) ; } if ( typeof eventIdentifier === 'function' && ( eventIdentifier . prototype instanceof metaEvents . MetaEvent || eventIdentifier === metaEvents . MetaEvent ) ) { // Since triggering meta events can be expensive, we only // do so if a listener has been added to listen to them. this . _emitterMetaEventsOn = true ; } var currentListeners = this . _emitterListeners . getValues ( eventIdentifier ) ; currentListeners = currentListeners . filter ( function ( listenerRecord ) { return listenerRecord . registeredContext === context && ( listenerRecord . callback === callback || ( listenerRecord . callback . _wrappedCallback !== undefined && listenerRecord . callback . _wrappedCallback === callback . _wrappedCallback ) ) ; } ) ; if ( currentListeners . length > 0 ) { throw new Error ( 'This callback is already listening to this event.' ) ; } this . _emitterListeners . add ( eventIdentifier , { eventIdentifier : eventIdentifier , callback : callback , registeredContext : context , context : context !== undefined ? context : this } ) ; if ( this . _emitterMetaEventsOn === true ) { this . trigger ( new metaEvents . AddListenerEvent ( eventIdentifier , callback . _onceFunctionMarker === ONCE_FUNCTION_MARKER ? callback . _wrappedCallback : callback , context ) ) ; } }
Registers a listener for an event.

If context is provided, then the <code>this</code> pointer will refer to it
inside the callback.

@param {*} eventIdentifier The identifier of the event that the callback should listen to.
@param {function} callback The function that should be called whenever the event is triggered.  May not be null.
@param {?Object} [context] An optional context that defines what 'this' should be inside the callback.
Registers a listener for an event .