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 3dc1d43
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 7 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ No changes to highlight.

## Bug Fixes:

No changes to highlight.
- Gradio will no longer hang forever when waiting for external CSS to load by [@akx](https://github.com/akx) in [PR 4335](https://github.com/gradio-app/gradio/pull/4335)


## Other Changes:

Expand Down
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
27 changes: 21 additions & 6 deletions js/app/src/css.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
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 +16,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 3dc1d43

Please sign in to comment.