2020-08-17 17:23:15 +02:00
|
|
|
import {UIEventSource} from "../Logic/UIEventSource";
|
2021-06-10 01:36:20 +02:00
|
|
|
import BaseUIElement from "./BaseUIElement";
|
2020-06-24 00:35:19 +02:00
|
|
|
|
2021-06-10 01:36:20 +02:00
|
|
|
export abstract class UIElement extends BaseUIElement{
|
2020-09-02 11:37:34 +02:00
|
|
|
|
2020-06-24 00:35:19 +02:00
|
|
|
private static nextId: number = 0;
|
|
|
|
public readonly id: string;
|
|
|
|
public readonly _source: UIEventSource<any>;
|
2021-06-10 01:36:20 +02:00
|
|
|
|
2020-09-09 18:42:13 +02:00
|
|
|
private lastInnerRender: string;
|
2020-06-24 00:35:19 +02:00
|
|
|
|
2020-08-31 02:59:47 +02:00
|
|
|
protected constructor(source: UIEventSource<any> = undefined) {
|
2021-06-10 01:36:20 +02:00
|
|
|
super()
|
|
|
|
this.id = `ui-${this.constructor.name}-${UIElement.nextId}`;
|
2020-06-24 00:35:19 +02:00
|
|
|
this._source = source;
|
|
|
|
UIElement.nextId++;
|
|
|
|
this.ListenTo(source);
|
|
|
|
}
|
|
|
|
|
2020-07-08 13:12:23 +02:00
|
|
|
public ListenTo(source: UIEventSource<any>) {
|
2020-07-01 02:12:33 +02:00
|
|
|
if (source === undefined) {
|
2020-07-21 01:37:48 +02:00
|
|
|
return this;
|
2020-06-24 00:35:19 +02:00
|
|
|
}
|
2021-06-12 02:58:32 +02:00
|
|
|
console.trace("Got a listenTo in ", this.constructor.name)
|
2020-06-24 00:35:19 +02:00
|
|
|
const self = this;
|
|
|
|
source.addCallback(() => {
|
2020-09-09 18:42:13 +02:00
|
|
|
self.lastInnerRender = undefined;
|
2021-06-10 01:36:20 +02:00
|
|
|
if(self._constructedHtmlElement !== undefined){
|
|
|
|
self.UpdateElement(self._constructedHtmlElement);
|
|
|
|
}
|
|
|
|
|
2020-06-24 00:35:19 +02:00
|
|
|
})
|
2020-07-21 01:37:48 +02:00
|
|
|
return this;
|
2020-06-24 00:35:19 +02:00
|
|
|
}
|
|
|
|
|
2020-09-02 11:37:34 +02:00
|
|
|
|
|
|
|
|
2020-06-24 00:35:19 +02:00
|
|
|
Update(): void {
|
2020-07-20 09:57:19 +02:00
|
|
|
|
2020-09-12 23:15:17 +02:00
|
|
|
}
|
|
|
|
|
2021-06-10 01:36:20 +02:00
|
|
|
Render(): string {
|
2021-06-12 02:58:32 +02:00
|
|
|
return this.InnerRenderAsString()
|
2020-06-27 03:06:51 +02:00
|
|
|
}
|
2020-09-12 23:15:17 +02:00
|
|
|
|
|
|
|
|
2021-06-10 01:36:20 +02:00
|
|
|
public InnerRenderAsString(): string {
|
|
|
|
let rendered = this.InnerRender();
|
|
|
|
if (typeof rendered !== "string") {
|
|
|
|
let html = rendered.ConstructElement()
|
|
|
|
return html.innerHTML
|
2020-09-12 23:15:17 +02:00
|
|
|
}
|
2021-06-10 01:36:20 +02:00
|
|
|
return rendered
|
2020-06-24 00:35:19 +02:00
|
|
|
}
|
|
|
|
|
2020-08-22 18:57:27 +02:00
|
|
|
|
2021-01-18 02:51:42 +01:00
|
|
|
/**
|
2021-06-10 01:36:20 +02:00
|
|
|
* Should be overridden for specific HTML functionality
|
2021-01-18 02:51:42 +01:00
|
|
|
*/
|
2021-06-10 01:36:20 +02:00
|
|
|
protected InnerConstructElement(): HTMLElement {
|
|
|
|
// Uses the old fashioned way to construct an element using 'InnerRender'
|
|
|
|
const innerRender = this.InnerRender();
|
|
|
|
if (innerRender === undefined || innerRender === "") {
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
const el = document.createElement("span")
|
|
|
|
if (typeof innerRender === "string") {
|
|
|
|
el.innerHTML = innerRender
|
|
|
|
} else {
|
|
|
|
const subElement = innerRender.ConstructElement();
|
|
|
|
if (subElement === undefined) {
|
|
|
|
return undefined;
|
2021-01-18 02:51:42 +01:00
|
|
|
}
|
2021-06-10 01:36:20 +02:00
|
|
|
el.appendChild(subElement)
|
2020-10-01 01:23:45 +02:00
|
|
|
}
|
2021-06-10 01:36:20 +02:00
|
|
|
return el;
|
2020-10-01 01:23:45 +02:00
|
|
|
}
|
2020-08-31 02:59:47 +02:00
|
|
|
|
2021-06-10 01:36:20 +02:00
|
|
|
protected UpdateElement(el: HTMLElement) : void{
|
|
|
|
const innerRender = this.InnerRender();
|
2021-01-06 02:21:50 +01:00
|
|
|
|
2021-06-10 01:36:20 +02:00
|
|
|
if (typeof innerRender === "string") {
|
|
|
|
if(el.innerHTML !== innerRender){
|
|
|
|
el.innerHTML = innerRender
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
const subElement = innerRender.ConstructElement();
|
|
|
|
if(el.children.length === 1 && el.children[0] === subElement){
|
|
|
|
return; // Nothing changed
|
|
|
|
}
|
2021-01-06 02:21:50 +01:00
|
|
|
|
2021-06-10 01:36:20 +02:00
|
|
|
while (el.firstChild) {
|
|
|
|
el.removeChild(el.firstChild);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (subElement === undefined) {
|
|
|
|
return;
|
2021-01-06 02:21:50 +01:00
|
|
|
}
|
2021-06-10 01:36:20 +02:00
|
|
|
el.appendChild(subElement)
|
2021-01-06 02:21:50 +01:00
|
|
|
}
|
2021-06-10 01:36:20 +02:00
|
|
|
|
2021-01-06 02:21:50 +01:00
|
|
|
}
|
2021-06-10 01:36:20 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated The method should not be used
|
|
|
|
*/
|
|
|
|
protected abstract InnerRender(): string | BaseUIElement;
|
|
|
|
|
2020-07-20 15:54:50 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 00:35:19 +02:00
|
|
|
|
2020-07-29 15:05:19 +02:00
|
|
|
|