BabylonJS/Spector.js

View on GitHub
src/embeddedFrontend/mvx/componentInstance.ts

Summary

Maintainability
C
1 day
Test Coverage
import { BaseNoneGenericComponent } from "./baseComponent";
import { LastOperation } from "./stateStore";

export class ComponentInstance {
    private static idGenerator: number = 0;

    private readonly component: BaseNoneGenericComponent;

    private cachedCurrentChildrenContainer: Element;
    private cachedCurrentDomNode: Element;

    private domNode: Element;

    constructor(component: BaseNoneGenericComponent) {
        this.component = component;
    }

    public render(state: {}, stateId: number, lastOperation: LastOperation): void {
        if (lastOperation === LastOperation.Processed) {
            return;
        }
        if (lastOperation === LastOperation.Delete) {
            this.removeNode();
            return;
        }
        this.domNode = this.component.render(state, stateId);
    }

    public composeInContainer(parentContainer: Element, indexInContainer: number, lastOperation: LastOperation): Element {
        if (lastOperation === LastOperation.Delete) {
            this.removeNode();
            return null;
        }

        const currentChildrenContainer = this.cachedCurrentChildrenContainer;
        if (lastOperation === LastOperation.Processed) {
            return currentChildrenContainer;
        }

        const element = this.domNode;
        const newChildrenContainer = element.getAttribute("childrencontainer") ? element : element.querySelector("[childrenContainer]");
        if (newChildrenContainer && currentChildrenContainer) {
            const children = currentChildrenContainer.children;
            while (children.length > 0) {
                newChildrenContainer.appendChild(children[0]);
            }
        }
        this.cachedCurrentChildrenContainer = newChildrenContainer;

        if (indexInContainer >= parentContainer.children.length) {
            parentContainer.appendChild(element);
            if (this.cachedCurrentDomNode && lastOperation === LastOperation.Update) {
                if (this.cachedCurrentDomNode.remove) {
                    this.cachedCurrentDomNode.remove();
                }
                else if (this.cachedCurrentDomNode.parentNode) {
                    this.cachedCurrentDomNode.parentNode.removeChild(this.cachedCurrentDomNode);
                }
            }
        }
        else {
            const currentElement = parentContainer.children[indexInContainer];
            parentContainer.insertBefore(element, currentElement);
            if (lastOperation === LastOperation.Update) {
                parentContainer.removeChild(currentElement);
            }
        }

        this.cachedCurrentDomNode = this.domNode;
        return newChildrenContainer;
    }

    private removeNode() {
        if (this.domNode && this.domNode.parentElement) {
            if (this.domNode.remove) {
                this.domNode.remove();
            }
            else if (this.domNode.parentNode) {
                this.domNode.parentNode.removeChild(this.domNode);
            }
        }
        if (this.cachedCurrentDomNode && this.cachedCurrentDomNode.parentElement) {
            if (this.cachedCurrentDomNode.remove) {
                this.cachedCurrentDomNode.remove();
            }
            else if (this.cachedCurrentDomNode.parentNode) {
                this.cachedCurrentDomNode.parentNode.removeChild(this.cachedCurrentDomNode);
            }
        }
    }
}