| 
									
										
										
										
											2020-08-17 17:23:15 +02:00
										 |  |  | import {UIEventSource} from "../Logic/UIEventSource"; | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-27 01:19:38 +02:00
										 |  |  | export abstract class UIElement extends UIEventSource<string>{ | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  |     private static nextId: number = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public readonly id: string; | 
					
						
							|  |  |  |     public readonly _source: UIEventSource<any>; | 
					
						
							| 
									
										
										
										
											2020-07-29 18:35:46 +02:00
										 |  |  |     public clss : string = "" | 
					
						
							| 
									
										
										
										
											2020-06-27 03:06:51 +02:00
										 |  |  |      | 
					
						
							|  |  |  |     private _hideIfEmpty = false; | 
					
						
							| 
									
										
										
										
											2020-07-26 02:01:34 +02:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2020-08-17 17:23:15 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * In the 'deploy'-step, some code needs to be run by ts-node. | 
					
						
							|  |  |  |      * However, ts-node crashes when it sees 'document'. When running from console, we flag this and disable all code where document is needed. | 
					
						
							|  |  |  |      * This is a workaround and yet another hack | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-07-26 02:01:34 +02:00
										 |  |  |     public static runningFromConsole = false; | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     protected constructor(source: UIEventSource<any>) { | 
					
						
							| 
									
										
										
										
											2020-07-27 01:19:38 +02:00
										 |  |  |         super(""); | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  |         this.id = "ui-element-" + UIElement.nextId; | 
					
						
							|  |  |  |         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
										 |  |  |         } | 
					
						
							|  |  |  |         const self = this; | 
					
						
							|  |  |  |         source.addCallback(() => { | 
					
						
							|  |  |  |             self.Update(); | 
					
						
							|  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2020-07-21 01:37:48 +02:00
										 |  |  |         return this; | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-01 02:12:33 +02:00
										 |  |  |     private _onClick: () => void; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public onClick(f: (() => void)) { | 
					
						
							|  |  |  |         this._onClick = f; | 
					
						
							|  |  |  |         this.Update(); | 
					
						
							| 
									
										
										
										
											2020-07-01 17:38:48 +02:00
										 |  |  |         return this; | 
					
						
							| 
									
										
										
										
											2020-07-01 02:12:33 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  |     Update(): void { | 
					
						
							| 
									
										
										
										
											2020-07-26 02:01:34 +02:00
										 |  |  |         if(UIElement.runningFromConsole){ | 
					
						
							|  |  |  |             return; | 
					
						
							| 
									
										
										
										
											2020-07-25 18:00:08 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-07-26 02:01:34 +02:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2020-07-01 02:12:33 +02:00
										 |  |  |         let element = document.getElementById(this.id); | 
					
						
							| 
									
										
										
										
											2020-07-21 00:07:04 +02:00
										 |  |  |         if (element === undefined || element === null) { | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  |             // The element is not painted
 | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-07-27 01:19:38 +02:00
										 |  |  |         this.setData(this.InnerRender()); | 
					
						
							|  |  |  |         element.innerHTML = this.data; | 
					
						
							| 
									
										
										
										
											2020-07-01 02:12:33 +02:00
										 |  |  |         if (this._hideIfEmpty) { | 
					
						
							|  |  |  |             if (element.innerHTML === "") { | 
					
						
							| 
									
										
										
										
											2020-06-27 03:06:51 +02:00
										 |  |  |                 element.parentElement.style.display = "none"; | 
					
						
							| 
									
										
										
										
											2020-07-01 02:12:33 +02:00
										 |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2020-06-27 03:06:51 +02:00
										 |  |  |                 element.parentElement.style.display = undefined; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-07-01 02:12:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (this._onClick !== undefined) { | 
					
						
							|  |  |  |             const self = this; | 
					
						
							| 
									
										
										
										
											2020-07-22 12:17:06 +02:00
										 |  |  |             element.onclick = (e) => { | 
					
						
							| 
									
										
										
										
											2020-07-24 15:22:28 +02:00
										 |  |  |                 // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2020-07-22 12:17:06 +02:00
										 |  |  |                 if(e.consumed){ | 
					
						
							|  |  |  |                     return; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2020-07-01 02:12:33 +02:00
										 |  |  |                 self._onClick(); | 
					
						
							| 
									
										
										
										
											2020-07-24 15:22:28 +02:00
										 |  |  |                 // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2020-07-22 12:17:06 +02:00
										 |  |  |                 e.consumed = true; | 
					
						
							| 
									
										
										
										
											2020-07-01 02:12:33 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-07-01 21:21:29 +02:00
										 |  |  |             element.style.pointerEvents = "all"; | 
					
						
							| 
									
										
										
										
											2020-07-01 02:12:33 +02:00
										 |  |  |             element.style.cursor = "pointer"; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  |         this.InnerUpdate(element); | 
					
						
							| 
									
										
										
										
											2020-07-20 09:57:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for (const i in this) { | 
					
						
							|  |  |  |             const child = this[i]; | 
					
						
							|  |  |  |             if (child instanceof UIElement) { | 
					
						
							|  |  |  |                 child.Update(); | 
					
						
							|  |  |  |             } else if (child instanceof Array) { | 
					
						
							|  |  |  |                 for (const ch of child) { | 
					
						
							|  |  |  |                     if (ch instanceof UIElement) { | 
					
						
							|  |  |  |                         ch.Update(); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2020-06-27 03:06:51 +02:00
										 |  |  |     HideOnEmpty(hide : boolean){ | 
					
						
							|  |  |  |         this._hideIfEmpty = hide; | 
					
						
							|  |  |  |         this.Update(); | 
					
						
							|  |  |  |         return this; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  |     // Called after the HTML has been replaced. Can be used for css tricks
 | 
					
						
							| 
									
										
										
										
											2020-07-20 21:39:07 +02:00
										 |  |  |    protected InnerUpdate(htmlElement: HTMLElement) { | 
					
						
							|  |  |  |    } | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Render(): string { | 
					
						
							| 
									
										
										
										
											2020-07-29 18:35:46 +02:00
										 |  |  |         return `<span class='uielement ${this.clss}' id='${this.id}'>${this.InnerRender()}</span>` | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     AttachTo(divId: string) { | 
					
						
							|  |  |  |         let element = document.getElementById(divId); | 
					
						
							| 
									
										
										
										
											2020-07-20 09:57:19 +02:00
										 |  |  |         if (element === null) { | 
					
						
							| 
									
										
										
										
											2020-07-21 02:55:28 +02:00
										 |  |  |             throw "SEVERE: could not attach UIElement to " + divId; | 
					
						
							| 
									
										
										
										
											2020-06-27 03:06:51 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  |         element.innerHTML = this.Render(); | 
					
						
							|  |  |  |         this.Update(); | 
					
						
							| 
									
										
										
										
											2020-06-25 03:39:31 +02:00
										 |  |  |         return this; | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 18:24:00 +02:00
										 |  |  |     public abstract InnerRender(): string; | 
					
						
							| 
									
										
										
										
											2020-07-20 09:57:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     public Activate(): void { | 
					
						
							|  |  |  |         for (const i in this) { | 
					
						
							|  |  |  |             const child = this[i]; | 
					
						
							|  |  |  |             if (child instanceof UIElement) { | 
					
						
							|  |  |  |                 child.Activate(); | 
					
						
							|  |  |  |             } else if (child instanceof Array) { | 
					
						
							|  |  |  |                 for (const ch of child) { | 
					
						
							|  |  |  |                     if (ch instanceof UIElement) { | 
					
						
							|  |  |  |                         ch.Activate(); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     public IsEmpty(): boolean { | 
					
						
							|  |  |  |         return this.InnerRender() === ""; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-22 18:57:27 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     public SetClass(clss: string): UIElement { | 
					
						
							|  |  |  |         this.clss = clss; | 
					
						
							|  |  |  |         return this; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 15:54:50 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-24 00:35:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-29 15:05:19 +02:00
										 |  |  | 
 |