Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 76 additions & 3 deletions docs/_includes/head_custom.html
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
Expand Down
10 changes: 10 additions & 0 deletions docs/_sass/custom/custom.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}