b4b06bfa42
Signed-off-by: Tobias Erbshäußer <tobias@tesoft.dev>
86 lines
2.3 KiB
TypeScript
86 lines
2.3 KiB
TypeScript
export abstract class TesoftComponent extends HTMLElement {
|
|
private ready: boolean;
|
|
|
|
protected constructor() {
|
|
super();
|
|
|
|
this.ready = false;
|
|
}
|
|
|
|
// noinspection JSUnusedGlobalSymbols
|
|
async connectedCallback() {
|
|
const promises = [];
|
|
|
|
for (const child of findComponents(this.shadowRoot)) {
|
|
promises.push(new Promise(resolve =>
|
|
window.customElements.whenDefined(child.tagName.toLowerCase()).then(() => {
|
|
if (child.isConnected) {
|
|
resolve(void {});
|
|
} else {
|
|
child.addEventListener("ready", (e: any) => {
|
|
e.preventDefault();
|
|
resolve(void {});
|
|
}, {once: true});
|
|
}
|
|
})
|
|
));
|
|
}
|
|
|
|
await Promise.all(promises);
|
|
await this.populate();
|
|
|
|
this.ready = true;
|
|
this.dispatchEvent(new CustomEvent("ready", {
|
|
bubbles: true,
|
|
cancelable: true,
|
|
}));
|
|
}
|
|
|
|
async populate() {
|
|
// Overwrite if necessary in components
|
|
}
|
|
|
|
get isReady(): boolean {
|
|
return this.ready;
|
|
}
|
|
}
|
|
|
|
function findComponents(root: any | null): TesoftComponent[] {
|
|
const components = [];
|
|
|
|
for (const child of root?.querySelectorAll("*") ?? []) {
|
|
if (child.tagName.toLowerCase().startsWith("snz-")) {
|
|
components.push(child);
|
|
}
|
|
}
|
|
|
|
return components;
|
|
}
|
|
|
|
export function onReady(callback: () => void, ...components: TesoftComponent[]) {
|
|
async function domLoaded() {
|
|
if (components.length === 0) {
|
|
components = findComponents(document);
|
|
}
|
|
|
|
const promises = [];
|
|
for (const component of components) {
|
|
if (!component.isReady) {
|
|
promises.push(new Promise(resolve => {
|
|
component.addEventListener("ready", resolve, {once: true});
|
|
}));
|
|
}
|
|
}
|
|
|
|
await Promise.all(promises);
|
|
callback();
|
|
}
|
|
|
|
if (document.readyState === "loading") {
|
|
document.addEventListener("DOMContentLoaded", domLoaded, {once: true});
|
|
} else {
|
|
// noinspection JSIgnoredPromiseFromCall
|
|
domLoaded();
|
|
}
|
|
}
|