import { App } from "../app" export class TestResourceMaintainer { public script: HTMLScriptElement public style: HTMLStyleElement constructor() { let meta = document.querySelector("meta[name='style']") if (meta) { this.styleSrc = meta.getAttribute("content") } meta = document.querySelector("meta[name='script']") if (meta) { this.scriptSrc = meta.getAttribute("content") } this.load() App.fileChangeNotificationService.events.listenBy(this, "change", () => { this.load() }) } public scriptSrc = "/composer/R.js" public styleSrc = "/composer/style/R.css" public events = new Leaf.EventEmitter<{ reloading reloaded }>() isLoading: boolean = false keepLoading: boolean = false load() { if (this.isLoading) { this.keepLoading = true return } this.isLoading = true if (this.script) { this.script.parentElement.removeChild(this.script) } this.script = document.createElement("script") this.script.src = this.scriptSrc this.events.emit("reloading") document.body.appendChild(this.script) this.script.addEventListener("load", () => { if (this.style) { this.style.parentElement.removeChild(this.style) } let link = this.style = document.createElement("link") link.setAttribute("rel", "stylesheet") link.setAttribute("href", this.styleSrc) link.setAttribute("type", "text/css") document.body.appendChild(link) link.addEventListener("load", () => { this.isLoading = false if (this.keepLoading) { this.keepLoading = false this.load() return } this.events.emit("reloaded") }) link.addEventListener("error", () => { console.error("fail to load style, retry after", this.retryInterval, "ms") setTimeout(() => { this.isLoading = false this.load() }, this.retryInterval) }) }) this.script.addEventListener("error", () => { console.error("fail to load script, retry after", this.retryInterval, "ms") setTimeout(() => { this.isLoading = false this.load() }, this.retryInterval) }) } public retryInterval: number = 1000 }