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

96.55% Statements 28/29
77.78% Branches 14/18
100% Functions 11/11
96.43% Lines 27/28

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 103          15x   15x         81x         81x       142x   137x           6x   6x           77x   69x               212x   111x     101x         101x   101x   101x             101x   101x   101x   95x   95x       6x   6x               101x   101x         29x         15x
/**
 * Mixin to trigger updates when the properties or the state change
 * @param Base 
 * @returns 
 */
const ReactiveElementMixin = Base =>
 
    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;
        }
 
    }
 
export default ReactiveElementMixin;