Skip to content

Commit

Permalink
Simplify CSS hot reloading in Firefox
Browse files Browse the repository at this point in the history
Firefox has solved the bug with “restricted” errors being thrown a year
ago. However, Firefox still caches style sheets over eagerly, so hot
reloading `@import` still doesn’t work. But at least we don’t need a
separate code path anymore. We still print a warning on Firefox.
  • Loading branch information
lydell committed Jan 10, 2025
1 parent f2158f6 commit 11ff215
Showing 1 changed file with 11 additions and 23 deletions.
34 changes: 11 additions & 23 deletions client/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,34 +30,22 @@ async function reloadCssIfNeeded(
}

const newCss = await response.text();
let newStyleSheet: CSSStyleSheet | undefined;

const isFirefox = "MozAppearance" in document.documentElement.style;
if (isFirefox) {
// We cannot support `@import` due to the below “restricted” bug,
// and it’s difficult to bust Firefox’s cache (`fetch(url, {cache:
// "reload"})`} does not help).
if (/@import\b/i.test(newCss)) {
// eslint-disable-next-line no-console
console.warn(
"elm-watch: Reloading CSS with @import is not possible in Firefox (not even in a comment or string). Style sheet:",
url.href,
);
return false;
}
// We can’t use `parseCssWithImports`, because Firefox has a bug where
// things in the style sheet become “restricted” if devtools are open.
// https://bugzilla.mozilla.org/show_bug.cgi?id=1873290
newStyleSheet = new CSSStyleSheet();
await newStyleSheet.replace(newCss);
} else {
const importUrls = getAllCssImports(url, styleSheet);
await Promise.allSettled(
importUrls.map((importUrl) => fetch(importUrl, { cache: "reload" })),
if (isFirefox && /@import\b/i.test(newCss)) {
// eslint-disable-next-line no-console
console.warn(
"elm-watch: In Firefox, @import:ed CSS files are not hot reloaded due to over eager caching by Firefox. Style sheet:",
url.href,
);
newStyleSheet = await parseCssWithImports(newCss);
}

const importUrls = getAllCssImports(url, styleSheet);
await Promise.allSettled(
importUrls.map((importUrl) => fetch(importUrl, { cache: "reload" })),
);
const newStyleSheet = await parseCssWithImports(newCss);

return newStyleSheet === undefined
? false
: updateStyleSheetIfNeeded(originalStyles, styleSheet, newStyleSheet);
Expand Down

0 comments on commit 11ff215

Please sign in to comment.