blob: 7c8055562ff2271b5c9ce7a4d74ba370b5105fa6 [file] [edit]
// Copyright (c) 2009 Giampaolo Rodola. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flips data-theme on <html> between "light" and "dark" and persists
// the choice in localStorage. Initial application happens inline in
// layout.html (extrahead) so there is no flash on page load. Keep the
// "psutil-sphinx-theme" key in sync with the inline script.
//
// Shortcuts:
// click on #theme-toggle button (in the topbar)
// Shift+D anywhere outside an input/textarea
(function () {
const html = document.documentElement;
const KEY = "psutil-sphinx-theme";
function applyTheme(dark) {
html.setAttribute("data-theme", dark ? "dark" : "light");
const btn = document.getElementById("theme-toggle");
if (btn) {
const icon = btn.querySelector("i");
if (icon) {
icon.className = dark
? "fa-solid fa-sun"
: "fa-regular fa-moon";
}
}
}
function setTheme(dark) {
applyTheme(dark);
try {
localStorage.setItem(KEY, dark ? "dark" : "light");
} catch (e) {
// private mode / storage disabled: skip persisting
}
}
// Sync the icon with whatever the inline script in <head> set.
applyTheme(html.getAttribute("data-theme") === "dark");
const btn = document.getElementById("theme-toggle");
if (btn) {
btn.addEventListener("click", () => {
setTheme(html.getAttribute("data-theme") !== "dark");
});
}
// Shift+D: toggle dark mode (skip when typing in a form field).
document.addEventListener("keydown", (e) => {
const tag = document.activeElement && document.activeElement.tagName;
if (tag === "INPUT" || tag === "TEXTAREA") {
return;
}
if (e.shiftKey && e.key === "D") {
setTheme(html.getAttribute("data-theme") !== "dark");
}
});
// Keep tabs in sync: another tab toggled, mirror it here without
// re-writing localStorage (would loop the storage event).
window.addEventListener("storage", (e) => {
if (e.key === KEY && e.newValue) {
applyTheme(e.newValue === "dark");
}
});
})();