dom-observe
Version:
  • 3.91 kB
text/typescript
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;
}
}