/** * @generated SignedSource<> * * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * !! This file is a check-in of a static_upstream project! !! * !! !! * !! You should not modify this file directly. Instead: !! * !! 1) Use `fjs use-upstream` to temporarily replace this with !! * !! the latest version from upstream. !! * !! 2) Make your changes, test them, etc. !! * !! 3) Use `fjs push-upstream` to copy your changes back to !! * !! static_upstream. !! * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * * @providesModule EventEmitterWithHolding * @typechecks */ 'use strict'; /** * @class EventEmitterWithHolding * @description * An EventEmitterWithHolding decorates an event emitter and enables one to * "hold" or cache events and then have a handler register later to actually * handle them. * * This is separated into its own decorator so that only those who want to use * the holding functionality have to and others can just use an emitter. Since * it implements the emitter interface it can also be combined with anything * that uses an emitter. */ class EventEmitterWithHolding { /** * @constructor * @param {object} emitter - The object responsible for emitting the actual * events. * @param {object} holder - The event holder that is responsible for holding * and then emitting held events. */ constructor(emitter, holder) { this._emitter = emitter; this._eventHolder = holder; this._currentEventToken = null; this._emittingHeldEvents = false; } /** * @see EventEmitter#addListener */ addListener(eventType: String, listener, context: ?Object) { return this._emitter.addListener(eventType, listener, context); } /** * @see EventEmitter#once */ once(eventType: String, listener, context: ?Object) { return this._emitter.once(eventType, listener, context); } /** * Adds a listener to be invoked when events of the specified type are * emitted. An optional calling context may be provided. The data arguments * emitted will be passed to the listener function. In addition to subscribing * to all subsequent events, this method will also handle any events that have * already been emitted, held, and not released. * * @param {string} eventType - Name of the event to listen to * @param {function} listener - Function to invoke when the specified event is * emitted * @param {*} context - Optional context object to use when invoking the * listener * * @example * emitter.emitAndHold('someEvent', 'abc'); * * emitter.addRetroactiveListener('someEvent', function(message) { * console.log(message); * }); // logs 'abc' */ addRetroactiveListener( eventType: String, listener, context: ?Object): EmitterSubscription { var subscription = this._emitter.addListener(eventType, listener, context); this._emittingHeldEvents = true; this._eventHolder.emitToListener(eventType, listener, context); this._emittingHeldEvents = false; return subscription; } /** * @see EventEmitter#removeAllListeners */ removeAllListeners(eventType: String) { this._emitter.removeAllListeners(eventType); } /** * @see EventEmitter#removeCurrentListener */ removeCurrentListener() { this._emitter.removeCurrentListener(); } /** * @see EventEmitter#listeners */ listeners(eventType: String) /* TODO: Annotate return type here */ { return this._emitter.listeners(eventType); } /** * @see EventEmitter#emit */ emit(eventType: String, a, b, c, d, e, _) { this._emitter.emit(eventType, a, b, c, d, e, _); } /** * Emits an event of the given type with the given data, and holds that event * in order to be able to dispatch it to a later subscriber when they say they * want to handle held events. * * @param {string} eventType - Name of the event to emit * @param {...*} Arbitrary arguments to be passed to each registered listener * * @example * emitter.emitAndHold('someEvent', 'abc'); * * emitter.addRetroactiveListener('someEvent', function(message) { * console.log(message); * }); // logs 'abc' */ emitAndHold(eventType: String, a, b, c, d, e, _) { this._currentEventToken = this._eventHolder.holdEvent( eventType, a, b, c, d, e, _ ); this._emitter.emit(eventType, a, b, c, d, e, _); this._currentEventToken = null; } /** * @see EventHolder#releaseCurrentEvent */ releaseCurrentEvent() { if (this._currentEventToken !== null) { this._eventHolder.releaseEvent(this._currentEventToken); } else if (this._emittingHeldEvents) { this._eventHolder.releaseCurrentEvent(); } } /** * @see EventHolder#releaseEventType * @param {string} eventType */ releaseHeldEventType(eventType: String) { this._eventHolder.releaseEventType(eventType); } } module.exports = EventEmitterWithHolding;