Merge pull request #473 from koic/fix_docs_theme_stylesheet_fouc
Fix flash of unstyled content when loading the docs site
This commit is contained in:
commit
ba88d9fbfd
2 changed files with 86 additions and 3 deletions
|
|
@ -40,6 +40,81 @@
|
|||
return mediaQuery.matches ? "dark" : "light";
|
||||
}
|
||||
|
||||
const colorSchemePattern = /just-the-docs-(default|light|dark)\.css(\?.*)?$/;
|
||||
let pendingColorLink = null;
|
||||
|
||||
function findColorStylesheet() {
|
||||
const links = document.querySelectorAll('link[rel="stylesheet"]');
|
||||
for (let index = 0; index < links.length; index += 1) {
|
||||
if (colorSchemePattern.test(links[index].getAttribute("href") || "")) {
|
||||
return links[index];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function stylesheetTheme(link) {
|
||||
const match = colorSchemePattern.exec(link.getAttribute("href") || "");
|
||||
const scheme = match ? match[1] : "default";
|
||||
return scheme === "default" ? "light" : scheme;
|
||||
}
|
||||
|
||||
/*
|
||||
* Swap the color stylesheet without going through jtd.setTheme, which
|
||||
* rewrites the href of the render-blocking link and lets the page paint
|
||||
* unstyled until the replacement CSS arrives. The site has no color_scheme,
|
||||
* so the default stylesheet equals the light one and needs no swap at all;
|
||||
* for dark, keep the old sheet applied until the new one has loaded.
|
||||
*/
|
||||
function setColorStylesheet(theme) {
|
||||
const currentLink = findColorStylesheet();
|
||||
if (!currentLink) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pendingColorLink) {
|
||||
if (pendingColorLink.parentNode) {
|
||||
pendingColorLink.parentNode.removeChild(pendingColorLink);
|
||||
}
|
||||
pendingColorLink = null;
|
||||
}
|
||||
|
||||
if (stylesheetTheme(currentLink) === theme) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newLink = document.createElement("link");
|
||||
newLink.setAttribute("rel", "stylesheet");
|
||||
newLink.setAttribute("blocking", "render");
|
||||
newLink.setAttribute(
|
||||
"href",
|
||||
currentLink.getAttribute("href").replace(colorSchemePattern, "just-the-docs-" + theme + ".css")
|
||||
);
|
||||
|
||||
newLink.addEventListener("load", function() {
|
||||
if (pendingColorLink !== newLink) {
|
||||
return;
|
||||
}
|
||||
pendingColorLink = null;
|
||||
if (currentLink.parentNode) {
|
||||
currentLink.parentNode.removeChild(currentLink);
|
||||
}
|
||||
});
|
||||
|
||||
newLink.addEventListener("error", function() {
|
||||
if (pendingColorLink === newLink) {
|
||||
pendingColorLink = null;
|
||||
}
|
||||
if (newLink.parentNode) {
|
||||
newLink.parentNode.removeChild(newLink);
|
||||
}
|
||||
});
|
||||
|
||||
currentLink.parentNode.insertBefore(newLink, currentLink.nextSibling);
|
||||
pendingColorLink = newLink;
|
||||
}
|
||||
|
||||
function nextPreference(preference) {
|
||||
const index = validPreferences.indexOf(preference);
|
||||
if (index === -1 || index === validPreferences.length - 1) {
|
||||
|
|
@ -62,9 +137,7 @@
|
|||
const safePreference = isValidPreference(preference) ? preference : "system";
|
||||
const theme = resolvedTheme(safePreference);
|
||||
|
||||
if (window.jtd && typeof window.jtd.setTheme === "function") {
|
||||
window.jtd.setTheme(theme);
|
||||
}
|
||||
setColorStylesheet(theme);
|
||||
document.documentElement.setAttribute("data-theme-preference", safePreference);
|
||||
document.documentElement.setAttribute("data-theme", theme);
|
||||
setThemeToggleLabel(safePreference);
|
||||
|
|
|
|||
|
|
@ -62,6 +62,16 @@
|
|||
color-scheme: dark;
|
||||
}
|
||||
|
||||
/*
|
||||
* Applied before the dark stylesheet finishes loading, so browsers that
|
||||
* do not support blocking="render" avoid a light-colored first paint.
|
||||
* Values match $grey-dk-300 and $grey-lt-300 from the dark color scheme.
|
||||
*/
|
||||
:root[data-theme="dark"] body {
|
||||
background-color: #27262b;
|
||||
color: #e6e1e8;
|
||||
}
|
||||
|
||||
:root[data-theme="light"] {
|
||||
color-scheme: light;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue