import {UIEventSource} from "./UIEventSource"; export abstract class UIElement { private static nextId: number = 0; public readonly id: string; public readonly _source: UIEventSource; private _hideIfEmpty = false; protected constructor(source: UIEventSource) { this.id = "ui-element-" + UIElement.nextId; this._source = source; UIElement.nextId++; this.ListenTo(source); } protected ListenTo(source: UIEventSource) { if(source === undefined){ return; } const self = this; source.addCallback(() => { self.Update(); }) } Update(): void { let element = document.getElementById(this.id); if (element === null || element === undefined) { // The element is not painted return; } element.innerHTML = this.InnerRender(); if(this._hideIfEmpty){ if(element.innerHTML === ""){ element.parentElement.style.display = "none"; }else{ element.parentElement.style.display = undefined; } } this.InnerUpdate(element); } HideOnEmpty(hide : boolean){ this._hideIfEmpty = hide; this.Update(); return this; } // Called after the HTML has been replaced. Can be used for css tricks InnerUpdate(htmlElement : HTMLElement){} Render(): string { return "" + this.InnerRender() + "" } AttachTo(divId: string) { let element = document.getElementById(divId); if(element === null){ console.log("SEVERE: could not attach UIElement to ", divId); return; } element.innerHTML = this.Render(); this.Update(); return this; } protected abstract InnerRender(): string; public Activate(): void {}; public IsEmpty(): boolean { return this.InnerRender() === ""; } }