From d44919c3dde72d0cd5ecf79a12d4970d3dd55b45 Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Sun, 20 Oct 2024 01:39:45 +0200 Subject: [PATCH] Update extra.js for auto theme (#18) --- docs/overrides/javascript/extra.js | 89 ++++++++++-------------------- 1 file changed, 30 insertions(+), 59 deletions(-) diff --git a/docs/overrides/javascript/extra.js b/docs/overrides/javascript/extra.js index 045d9bc..f33fc68 100644 --- a/docs/overrides/javascript/extra.js +++ b/docs/overrides/javascript/extra.js @@ -1,71 +1,42 @@ -// Function that applies light/dark theme based on the user's preference -const applyAutoTheme = () => { - // Determine the user's preferred color scheme - const prefersLight = window.matchMedia("(prefers-color-scheme: light)").matches; - const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches; +// Apply theme based on user preference +const applyTheme = (isDark) => { + document.body.setAttribute("data-md-color-scheme", isDark ? "slate" : "default"); + document.body.setAttribute("data-md-color-primary", isDark ? "black" : "indigo"); +}; + +// Check and apply auto theme +const checkAutoTheme = () => { + const supportedLangCodes = ["en", "zh", "ko", "ja", "ru", "de", "fr", "es", "pt", "it", "tr", "vi", "ar"]; + const langCode = window.location.pathname.split("/")[1]; + const localStorageKey = `${supportedLangCodes.includes(langCode) ? `/${langCode}` : ""}/.__palette`; + const palette = JSON.parse(localStorage.getItem(localStorageKey) || "{}"); - // Apply the appropriate attributes based on the user's preference - if (prefersLight) { - document.body.setAttribute("data-md-color-scheme", "default"); - document.body.setAttribute("data-md-color-primary", "indigo"); - } else if (prefersDark) { - document.body.setAttribute("data-md-color-scheme", "slate"); - document.body.setAttribute("data-md-color-primary", "black"); + if (palette.index === 0) { + applyTheme(window.matchMedia("(prefers-color-scheme: dark)").matches); } }; -// Function that checks and applies light/dark theme based on the user's preference (if auto theme is enabled) -function checkAutoTheme() { - // Array of supported language codes -> each language has its own palette (stored in local storage) - const supportedLangCodes = ["en", "zh", "ko", "ja", "ru", "de", "fr", "es", "pt", "it", "tr", "vi", "nl"]; - // Get the URL path - const path = window.location.pathname; - // Extract the language code from the URL (assuming it's in the format /xx/...) - const langCode = path.split("/")[1]; - // Check if the extracted language code is in the supported languages - const isValidLangCode = supportedLangCodes.includes(langCode); - // Construct the local storage key based on the language code if valid, otherwise default to the root key - const localStorageKey = isValidLangCode ? `/${langCode}/.__palette` : "/.__palette"; - // Retrieve the palette from local storage using the constructed key - const palette = localStorage.getItem(localStorageKey); - if (palette) { - // Check if the palette's index is 0 (auto theme) - const paletteObj = JSON.parse(palette); - if (paletteObj && paletteObj.index === 0) { - applyAutoTheme(); - } - } -} +// Event listeners for theme changes +const mediaQueryList = window.matchMedia("(prefers-color-scheme: dark)"); +mediaQueryList.addListener(checkAutoTheme); -// Run function when the script loads +// Initial theme check checkAutoTheme(); -// Re-run the function when the user's preference changes (when the user changes their system theme) -window.matchMedia("(prefers-color-scheme: light)").addEventListener("change", checkAutoTheme); -window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", checkAutoTheme); - -// Re-run the function when the palette changes (e.g. user switched from dark theme to auto theme) -// ! We can't use window.addEventListener("storage", checkAutoTheme) because it will NOT be triggered on the current tab -// ! So we have to use the following workaround: -// Get the palette input for auto theme -var autoThemeInput = document.getElementById("__palette_1"); -if (autoThemeInput) { - // Add a click event listener to the input - autoThemeInput.addEventListener("click", function () { - // Check if the auto theme is selected - if (autoThemeInput.checked) { - // Re-run the function after a short delay (to ensure that the palette has been updated) - setTimeout(applyAutoTheme); - } +// Auto theme input listener +document.addEventListener("DOMContentLoaded", () => { + const autoThemeInput = document.getElementById("__palette_1"); + autoThemeInput?.addEventListener("click", () => { + if (autoThemeInput.checked) setTimeout(checkAutoTheme); }); -} +}); -// Add iframe navigation -window.onhashchange = function() { - window.parent.postMessage({ - type: 'navigation', - hash: window.location.pathname + window.location.search + window.location.hash - }, '*'); +// Iframe navigation +window.onhashchange = () => { + window.parent.postMessage({ + type: 'navigation', + hash: window.location.pathname + window.location.search + window.location.hash + }, '*'); }; // Add Inkeep button