/**
* @author Wolfgang Kowarschick <kowa@hs-augsburg.de>
* @copyright 2017 - 2018
* @license CC-BY-NC-SA-4.0
*/
import Event from './Event.js';
/**
* Partly implements the interface EventTarget.
* @class
* @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget
* @cmp https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.cloneInto
*/
class EventDispatcher
{ constructor()
{ this.v_listeners = {}; }
/**
* Adds a callback function for a specific type. One and the same
* function can only be added once for each type. If it is tried to
* add a function again for a specific type, the method returns
* without any modification or reaction.
*
* @param {string} p_type
* @param {Function} p_callback
*
* @fires this.v_initial_events[p_type]
*/
addEventListener(p_type, p_callback)
{ let
l_listeners = this.v_listeners[p_type];
if (l_listeners === undefined)
{ l_listeners = this.v_listeners[p_type] = []; }
if (l_listeners.findIndex(v => v === p_callback) > 0)
{ return; }
l_listeners.push(p_callback);
}
/**
* Removes a callback function for a specific type, if it exists.
*
* @param {string} p_type
* @param {Function} p_callback
*/
removeEventListener(p_type, p_callback)
{ if (!(p_type in this.v_listeners))
{ return; }
const
l_callbacks = this.v_listeners[p_type];
l_callbacks.splice(l_callbacks.findIndex(v => v === p_callback), 1);
}
/**
* Handles events of type String or {@link Event} by invoking
* all callback functions that have been registered for that
* type.
*
* @param {string|Event} p_type
* @param {?Object} p_detail
* Detail information passed to the listener
*/
dispatchEvent(p_type, p_detail=null)
{ let l_event;
if (p_type instanceof Event)
{ if (!(p_type.type in this.v_listeners))
{ return; }
if (p_detail === null)
{ l_event = p_type; }
else
{ l_event = new Event({type: p_type.type, detail: p_detail}); }
}
else
{ if (!(p_type in this.v_listeners))
{ return; }
else
{ l_event = new Event({type: p_type, detail: p_detail}); }
}
const
l_callbacks = this.v_listeners[l_event.type];
for (let l_callback of l_callbacks)
{ l_callback.call(this, l_event); }
}
}
export {EventDispatcher};
export default EventDispatcher;