UNPKG

dom-observe

Version:

![npm](https://img.shields.io/npm/v/dom-observe?style=for-the-badge)![npm](https://img.shields.io/npm/dw/dom-observe?style=for-the-badge)![npm](https://img.shields.io/npm/dt/dom-observe?style=for-the-badge) ![node](https://img.shields.io/node/v/dom-observ

128 lines (102 loc) 3.91 kB
import {SelectorCallback} from "./callbacks"; import {DeferredPromise} from "../DeferredPromise"; import {IDOMDeferredSelectorParameters} from "./parameters/IDOMDeferredSelectorParameters"; import {setImmediate} from "delay-me"; export class DOMDeferredSelector<T extends Element = Element>{ protected readonly selector: SelectorCallback<T>; protected readonly parameters: IDOMDeferredSelectorParameters; private _deferred: DeferredPromise<T, never>; private _is_activated: boolean = false; public get isActivated(): boolean{ return this._is_activated; } private _is_cancelled: boolean = false; public get isCancelled(): boolean{ return this._is_cancelled; } protected _repeats_left: number = null; protected _interval_ref: number = null; /** * @param {SelectorCallback<T>} selector * @param {IDOMDeferredSelectorParameters} parameters * @returns {DOMDeferredSelector<T>} */ public static use<T extends Element = Element>(selector: SelectorCallback<T>, parameters: IDOMDeferredSelectorParameters): DOMDeferredSelector<T>{ const deferred_selector = new this(selector, parameters); deferred_selector.activate(); return deferred_selector; } /** * @param {SelectorCallback<T>} selector * @param {IDOMDeferredSelectorParameters} parameters */ public constructor(selector: SelectorCallback<T>, parameters: IDOMDeferredSelectorParameters) { this.selector = selector; this.parameters = parameters; this._deferred = new DeferredPromise<T, never>(); this._repeats_left = this.parameters.repeats; this.awaitElementProcess = this.awaitElementProcess.bind(this); } /** * @protected */ public activate(): void{ if(this._is_activated || this._is_cancelled) return; this._is_activated = true; this._is_cancelled = false; setImmediate(this.awaitElementProcess); } /** * Reactivates DOMDeferredSelector so it can be activated once again */ public reactivate(): void{ if(this._is_activated || !this._is_cancelled) return; this._is_activated = false; this._is_cancelled = false; if(this._interval_ref !== null){ clearInterval(this._interval_ref); this._interval_ref = null; } this._deferred = new DeferredPromise<T, never>(); this._repeats_left = this.parameters.repeats; } /** * @returns {Promise<T | null>} */ public promise(): Promise<T|null>{ return this._deferred.promise; } /** * Cancels deferred selection and resolves promise with null result */ public cancel(): void{ if(!this._is_activated || this._is_cancelled) return; clearInterval(this._interval_ref); this._interval_ref = null; this._is_activated = false; this._is_cancelled = true; } /** * @protected */ protected awaitElementProcess(): void{ if(this._is_cancelled){ clearInterval(this._interval_ref); this._interval_ref = null; return this._deferred.resolve(null); } this._repeats_left--; const $element = this.selector.apply(null, []); if($element !== null){ clearInterval(this._interval_ref); this._interval_ref = null; return this._deferred.resolve($element); } if(this._repeats_left === 0 || this._is_cancelled){ clearInterval(this._interval_ref); this._interval_ref = null; return this._deferred.resolve(null); } if(this._interval_ref === null && !this._is_cancelled) this._interval_ref = setInterval(this.awaitElementProcess, this.parameters.interval) as unknown as number; } }