import { App } from "../../App"; import { INameValuePairs, INotifyPropertyChanging } from "../../core/types"; import { AtomStyle } from "./AtomStyle"; export class AtomStyleSheet extends AtomStyle implements INotifyPropertyChanging { public styleElement: HTMLElement; private lastUpdateId: any = 0; private isAttaching: boolean = false; [key: string]: any; constructor(public readonly app: App, prefix: string) { super(null, null, prefix); this.styleSheet = this; this.pushUpdate(0); } public onPropertyChanging(name: string, newValue: any, oldValue: any): void { this.pushUpdate(); } public pushUpdate(delay: number = 1): void { if (this.isAttaching) { return; } if (this.lastUpdateId) { clearTimeout(this.lastUpdateId); } this.lastUpdateId = setTimeout(() => { this.attach(); }, delay); } public dispose(): void { if (this.styleElement) { this.styleElement.remove(); } } public attach(): void { this.isAttaching = true; const pairs = this.toStyle({}); const textContent = this.flatten(pairs); if (this.styleElement) { if (this.styleElement.textContent === textContent) { this.isAttaching = false; return; } } const ss = document.createElement("style"); ss.textContent = textContent; if (this.styleElement) { this.styleElement.remove(); } document.head.appendChild(ss); this.styleElement = ss; this.isAttaching = false; } protected build(): void { // do nothing.. } private flatten(pairs: INameValuePairs): string { const sl: string[] = []; for (const key in pairs) { if (pairs.hasOwnProperty(key)) { const element = pairs[key]; sl.push(`.${key} ${element} `); } } return sl.join("\r\n"); } }