All files / src/custom-element/mixins/core ReactiveElementMixin.ts

89.29% Statements 25/28
83.33% Branches 5/6
100% Functions 10/10
88.89% Lines 24/27

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102          17x   17x         85x         85x       191x   160x           14x   14x           81x   72x               246x   148x     98x         98x   98x   98x             98x   98x   98x   98x   98x                           98x   98x         33x        
/**
 * Mixin to trigger updates when the properties or the state change
 * @param Base 
 * @returns 
 */
export default function ReactiveElementMixin(Base): any {
 
    return class ReactiveElement extends Base {
 
        /**
         * Flag that tests if there is an update in progress so no other updates are requested
         */
        private _hasPendingUpdate: boolean = false;
 
        /**
         * Promise to schedule the updates
         */
        private _updatePromise: Promise<void> = new Promise<void>((resolve, reject) => resolve()); // Finished updating by default
 
        protected setProperty(name: string, value: any): void {
 
            if (super.setProperty?.(name, value) === true) {
 
                this.update();
            }
        }
 
        protected setState(key: string, value: any): void {
 
            Eif (super.setState?.(key, value) === true) {
 
                this.update();
            }
        }
 
        connectedCallback() {
 
            super.connectedCallback?.();
 
            this.update(); // First update
        }
 
        /**
         * Requests the custom element to be updated
         */
        protected update(): void {
 
            if (this._hasPendingUpdate) {
 
                return;
            }
 
            this._updatePromise = this._enqueueUpdate();
        }
 
        private async _enqueueUpdate(): Promise<void> {
 
            this._hasPendingUpdate = true;
 
            try {
 
                await this._updatePromise; // Wait for the previous update to finish
            }
            catch (error) {
 
                Promise.reject(error);
            }
 
            return new Promise<void>((resolve, reject) => {
 
                try {
 
                    this.updateDom();
 
                    this._markUpdated();
 
                    resolve();
                }
                catch (error) {
 
                    this._markUpdated();
 
                    reject(error);
                }
 
            });
        }
 
        private _markUpdated() {
 
            this._hasPendingUpdate = false;
 
            this.clearChangedProperties();
        }
 
        get updateComplete(): Promise<void> {
 
            return this._updatePromise;
        }
 
    }
}