@playkit-js/playkit-js
Version:
[](https://github.com/kaltura/playkit-js/actions/workflows/run_canary.yaml) [ • 3.97 kB
text/typescript
import { FakeEvent } from './fake-event';
import {MultiMap} from '../utils';
import { getLogger } from '../utils/logger';
/**
* A work-alike for EventTarget. Only DOM elements may be true EventTargets,
* but this can be used as a base class to provide event dispatch to non-DOM
* classes. Only FakeEvents should be dispatched.
*
* @struct
* @constructor
* @export
*/
export class FakeEventTarget {
private _listeners: MultiMap<string, (event: FakeEvent) => boolean | void>;
private readonly dispatchTarget: FakeEventTarget;
private __logger: any;
constructor() {
/**
* @private {!MultiMap.<FakeEventTarget.EventListener>}
*/
this._listeners = new MultiMap();
/**
* The target of all dispatched events. Defaults to |this|.
* @type {FakeEventTarget}
*/
this.dispatchTarget = this;
this.__logger = getLogger('FakeEventTarget');
}
/**
* Add an event listener to this object.
*
* @param {string} type The event type to listen for.
* @param {FakeEventTarget.EventListener} listener The callback or
* listener object to invoke.
* @param {boolean=} opt_capturing Ignored. FakeEventTargets do not have
* parents, so events neither capture nor bubble.
* @override
* @export
*/
public addEventListener(type: string, listener: typeof EventListener): void {
this._listeners.push(type, listener);
}
/**
* Remove an event listener from this object.
*
* @param {string} type The event type for which you wish to remove a listener.
* @param {FakeEventTarget.EventListener} listener The callback or
* listener object to remove.
* @param {boolean=} opt_capturing Ignored. FakeEventTargets do not have
* parents, so events neither capture nor bubble.
* @override
* @export
*/
public removeEventListener(type: string, listener: typeof EventListener): void {
this._listeners.remove(type, listener);
}
/**
* Dispatch an event from this object.
*
* @param {!Event} event The event to be dispatched from this object.
* @return {boolean} True if the default action was prevented.
* @override
* @export
*/
public dispatchEvent(event: FakeEvent): boolean {
// In many browsers, it is complex to overwrite properties of actual Events.
// Here we expect only to dispatch FakeEvents, which are simpler.
//goog.asserts.assert(event instanceof FakeEvent,
// 'FakeEventTarget can only dispatch FakeEvents!');
const list = this._listeners.get(event.type) || [];
for (let i = 0; i < list.length; ++i) {
// Do this every time, since events can be re-dispatched from handlers.
//$FlowFixMe - need to cast to event target but can't yet make EventTarget inherited
event.target = this.dispatchTarget;
//$FlowFixMe - need to cast to event target but can't yet make EventTarget inherited
event.currentTarget = this.dispatchTarget;
const listener = list[i];
try {
// native DOM event handler
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
if (listener.handleEvent) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
listener.handleEvent(event);
} else {
listener.call(this, event);
}
} catch (exception) {
// Exceptions during event handlers should not affect the caller,
// but should appear on the console as uncaught, according to MDN:
// http://goo.gl/N6Ff27
this.__logger.error(`Error occurred when handling event: ${event.type}.`, exception);
}
if (event.stopped) {
break;
}
}
return event.defaultPrevented;
}
}
/**
* These are the listener types defined in the closure extern for EventTarget.
* @typedef {EventListener|function(!Event):(boolean|undefined)}
*/
declare function EventListener(event: FakeEvent): boolean | void;