Skip to content

Commit

Permalink
mount_css: add timeout; use it for external CSS
Browse files Browse the repository at this point in the history
Refs #4332 (part of it anyway)
  • Loading branch information
akx committed May 25, 2023
1 parent 5be5327 commit 74dd6cb
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 6 deletions.
2 changes: 2 additions & 0 deletions js/app/src/Index.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@
stylesheet.startsWith("http:") || stylesheet.startsWith("https:");
return mount_css(
absolute_link ? stylesheet : config.root + "/" + stylesheet,
// Wait up to 1.5 seconds for external stylesheets to load before continuing anyway.
absolute_link ? 1500 : undefined,
);
})
);
Expand Down
30 changes: 24 additions & 6 deletions js/app/src/css.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
export function mount_css(url: string): Promise<void> {
/**
* Loads a CSS file and appends it to the document head.
* The optional timeout parameter will resolve the promise without error
* if the CSS file has not loaded after the specified time.
*
* @param url URL to load.
* @param timeout Optional timeout, in milliseconds.
*/
export function mount_css(
url: string,
timeout?: number,
): Promise<unknown> {
const existing_link = document.querySelector(`link[href='${url}']`);

if (existing_link) return Promise.resolve();
Expand All @@ -8,10 +19,17 @@ export function mount_css(url: string): Promise<void> {
link.href = url;
document.head.appendChild(link);

return new Promise((res, rej) => {
link.addEventListener("load", () => res());
link.addEventListener("error", () =>
rej(new Error(`Unable to preload CSS for ${url}`))
);
const loadPromise = new Promise((res, rej) => {
link.addEventListener("load", res);
link.addEventListener("error", (err) => {
console.error(`load_css: failed to load CSS`, url, err);
rej(err);
});
});

if (timeout) {
const timeoutPromise = new Promise(res => setTimeout(res, timeout));
return Promise.race([loadPromise, timeoutPromise]);
}
return loadPromise;
}

0 comments on commit 74dd6cb

Please sign in to comment.