class OutfitLayer extends HTMLElement { #internals; constructor() { super(); this.#internals = this.attachInternals(); // An starts in the loading state, and then might very // quickly decide it's not after `#connectToChildren`. This is to prevent a // flash of *non*-loading state, when a new layer loads in. (e.g. In the // time between our parent loading, which shows the loading // spinner; and us being marked `:state(loading)`, which shows the loading // spinner; we don't want the loading spinner to do its usual *immediate* // total fade-out; then have to fade back in again, on the usual delay.) this.#setStatus("loading"); } connectedCallback() { setTimeout(() => this.#connectToChildren(), 0); } disconnectedCallback() { window.removeEventListener("message", this.#onMessage); } #connectToChildren() { const image = this.querySelector("img"); const iframe = this.querySelector("iframe"); if (image) { image.addEventListener("load", () => this.#setStatus("loaded")); image.addEventListener("error", () => this.#setStatus("error")); this.#setStatus(image.complete ? "loaded" : "loading"); } else if (iframe) { this.iframe = iframe; window.addEventListener("message", (m) => this.#onMessage(m)); this.iframe.addEventListener("error", () => this.#setStatus("error")); this.#setStatus("loading"); } else { throw new Error(` must contain an or