补充主题静态资源与归档模板
This commit is contained in:
1 parent
1268a55dd0
commit
3247db7ed1
265 files changed
+59174
No files matched your search
@@ -0,0 +1,269 @@
|
||||
/**
|
||||
* AKSRT Theme Toggle — dark/light mode switching with transitions
|
||||
*/
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var THEME_KEY = "aksrt-theme";
|
||||
var THEME_COOKIE_KEY = "theme_mode";
|
||||
|
||||
function normalizeStoredTheme(value) {
|
||||
if (value === "dark" || value === "dark-theme") return "dark";
|
||||
if (value === "light" || value === "white-theme") return "light";
|
||||
return null;
|
||||
}
|
||||
|
||||
function toCookieTheme(value) {
|
||||
return value === "dark" ? "dark-theme" : "white-theme";
|
||||
}
|
||||
|
||||
function getCookie(name) {
|
||||
var parts = document.cookie ? document.cookie.split("; ") : [];
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
var pair = parts[i].split("=");
|
||||
if (decodeURIComponent(pair[0]) === name) {
|
||||
return decodeURIComponent(pair.slice(1).join("="));
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function setCookie(name, value, days) {
|
||||
var maxAge = days ? "; max-age=" + (days * 24 * 60 * 60) : "";
|
||||
var secure = window.location && window.location.protocol === "https:" ? "; Secure" : "";
|
||||
document.cookie = encodeURIComponent(name) + "=" + encodeURIComponent(value) + maxAge + "; path=/; SameSite=Lax" + secure;
|
||||
}
|
||||
|
||||
function getStoredTheme() {
|
||||
var localTheme = null;
|
||||
try {
|
||||
localTheme = normalizeStoredTheme(localStorage.getItem(THEME_KEY));
|
||||
} catch (e) {
|
||||
localTheme = null;
|
||||
}
|
||||
|
||||
var theme = normalizeStoredTheme(getCookie(THEME_COOKIE_KEY)) || localTheme;
|
||||
if (theme) {
|
||||
setStoredTheme(theme);
|
||||
}
|
||||
return theme;
|
||||
}
|
||||
|
||||
function setStoredTheme(value) {
|
||||
var theme = normalizeStoredTheme(value);
|
||||
if (!theme) return;
|
||||
try {
|
||||
localStorage.setItem(THEME_KEY, theme);
|
||||
} catch (e) {}
|
||||
setCookie(THEME_COOKIE_KEY, toCookieTheme(theme), 365);
|
||||
}
|
||||
|
||||
function getTimeAutoTheme() {
|
||||
var hour = (new Date()).getHours();
|
||||
return hour >= 20 || hour < 8 ? "dark" : "light";
|
||||
}
|
||||
|
||||
function resolveConfiguredTheme(mode) {
|
||||
var normalized = normalizeStoredTheme(mode);
|
||||
if (normalized) return normalized;
|
||||
if (mode === "time-auto" || mode === "auto") {
|
||||
return getTimeAutoTheme();
|
||||
}
|
||||
return "light";
|
||||
}
|
||||
|
||||
function syncBrandLogos(isDark) {
|
||||
document.querySelectorAll("[data-logo-light]").forEach(function (img) {
|
||||
var lightSrc = img.getAttribute("data-logo-light") || "";
|
||||
var darkSrc = img.getAttribute("data-logo-dark") || "";
|
||||
if (!lightSrc) return;
|
||||
img.setAttribute("src", isDark && darkSrc ? darkSrc : lightSrc);
|
||||
});
|
||||
}
|
||||
|
||||
function syncThemeColorMeta(isDark) {
|
||||
var meta = document.querySelector('meta[name="theme-color"]');
|
||||
if (!meta) {
|
||||
meta = document.createElement("meta");
|
||||
meta.setAttribute("name", "theme-color");
|
||||
document.head.appendChild(meta);
|
||||
}
|
||||
meta.setAttribute("content", isDark ? "#2F3135" : "#FDFCFE");
|
||||
}
|
||||
|
||||
function getThemeImageAttr(img, name) {
|
||||
return img.getAttribute(name) || img.getAttribute("data-" + name) || "";
|
||||
}
|
||||
|
||||
function setThemeImageSource(img, src) {
|
||||
if (!src || img.getAttribute("src") === src) return;
|
||||
img.setAttribute("src", src);
|
||||
}
|
||||
|
||||
function syncThemeImages(isDark) {
|
||||
document.querySelectorAll("img[switch-src], img[data-switch-src]").forEach(function (img) {
|
||||
var darkSrc = getThemeImageAttr(img, "switch-src");
|
||||
if (!img.dataset.aksrtThemeLightSrc) {
|
||||
img.dataset.aksrtThemeLightSrc = img.getAttribute("src") || "";
|
||||
}
|
||||
setThemeImageSource(img, isDark && darkSrc ? darkSrc : img.dataset.aksrtThemeLightSrc);
|
||||
});
|
||||
|
||||
document.querySelectorAll("img[white-src], img[dark-src], img[data-white-src], img[data-dark-src]").forEach(function (img) {
|
||||
var lightSrc = getThemeImageAttr(img, "white-src") || img.dataset.aksrtThemeLightSrc || img.getAttribute("src") || "";
|
||||
var darkSrc = getThemeImageAttr(img, "dark-src");
|
||||
if (!img.dataset.aksrtThemeLightSrc && lightSrc) {
|
||||
img.dataset.aksrtThemeLightSrc = lightSrc;
|
||||
}
|
||||
setThemeImageSource(img, isDark && darkSrc ? darkSrc : lightSrc);
|
||||
});
|
||||
}
|
||||
|
||||
function syncCodeHighlightTheme(isDark) {
|
||||
if (typeof window.AksrtPrecodeApplyTheme === "function") {
|
||||
window.AksrtPrecodeApplyTheme(isDark);
|
||||
return;
|
||||
}
|
||||
|
||||
var settings = (window.aksrtData && window.aksrtData.codeHighlight) || {};
|
||||
var theme = isDark ? (settings.darkTheme || "monokai") : (settings.lightTheme || "enlighter");
|
||||
document.querySelectorAll(".enlighter-default").forEach(function (el) {
|
||||
el.className = el.className.replace(/\benlighter-t-[\w-]+\b/g, "").replace(/\s+/g, " ").trim();
|
||||
el.classList.add("enlighter-t-" + theme);
|
||||
});
|
||||
}
|
||||
|
||||
function dispatchThemeChange(isDark) {
|
||||
try {
|
||||
document.dispatchEvent(new CustomEvent("aksrt:theme-change", {
|
||||
detail: {
|
||||
theme: isDark ? "dark" : "light",
|
||||
isDark: isDark
|
||||
}
|
||||
}));
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
function applyTheme(mode) {
|
||||
var isDark = mode === "dark";
|
||||
document.documentElement.classList.toggle("dark", isDark);
|
||||
document.documentElement.setAttribute("data-theme", isDark ? "dark" : "light");
|
||||
document.body.classList.toggle("theme-dark", isDark);
|
||||
document.body.classList.toggle("dark-theme", isDark);
|
||||
document.body.classList.toggle("white-theme", !isDark);
|
||||
document.body.setAttribute("data-theme", isDark ? "dark" : "light");
|
||||
syncBrandLogos(isDark);
|
||||
syncThemeColorMeta(isDark);
|
||||
syncThemeImages(isDark);
|
||||
syncCodeHighlightTheme(isDark);
|
||||
dispatchThemeChange(isDark);
|
||||
var btn = document.getElementById("theme-toggle");
|
||||
if (btn) {
|
||||
btn.setAttribute("aria-pressed", isDark ? "true" : "false");
|
||||
btn.classList.toggle("is-dark", isDark);
|
||||
var moon = btn.querySelector(".theme-icon-moon");
|
||||
var sun = btn.querySelector(".theme-icon-sun");
|
||||
if (moon && sun) {
|
||||
moon.style.display = isDark ? "none" : "";
|
||||
sun.style.display = isDark ? "" : "none";
|
||||
}
|
||||
}
|
||||
var floatBtn = document.getElementById("float-theme-toggle");
|
||||
if (floatBtn) {
|
||||
floatBtn.setAttribute("aria-pressed", isDark ? "true" : "false");
|
||||
var moonIcon = floatBtn.querySelector(".float-btn__icon-moon");
|
||||
var sunIcon = floatBtn.querySelector(".float-btn__icon-sun");
|
||||
if (moonIcon && sunIcon) {
|
||||
moonIcon.style.display = isDark ? "" : "none";
|
||||
sunIcon.style.display = isDark ? "none" : "";
|
||||
}
|
||||
}
|
||||
var ddBtn = document.getElementById("dropdown-theme-toggle");
|
||||
if (ddBtn) ddBtn.setAttribute("aria-pressed", isDark ? "true" : "false");
|
||||
}
|
||||
|
||||
function initTheme() {
|
||||
var stored = getStoredTheme();
|
||||
var configuredMode = (window.aksrtData && aksrtData.themeMode) || "light";
|
||||
if (stored === "dark" || stored === "light") {
|
||||
applyTheme(stored);
|
||||
} else {
|
||||
applyTheme(resolveConfiguredTheme(configuredMode));
|
||||
}
|
||||
|
||||
function prefersReducedMotion() {
|
||||
return window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
||||
}
|
||||
|
||||
function getThemeTransitionPoint(event) {
|
||||
if (event && typeof event.clientX === "number" && typeof event.clientY === "number") {
|
||||
return { x: event.clientX, y: event.clientY };
|
||||
}
|
||||
return { x: window.innerWidth / 2, y: window.innerHeight / 2 };
|
||||
}
|
||||
|
||||
function runThemeTransition(next, event) {
|
||||
if (!document.startViewTransition || prefersReducedMotion()) {
|
||||
applyTheme(next);
|
||||
return;
|
||||
}
|
||||
|
||||
var point = getThemeTransitionPoint(event);
|
||||
var endRadius = Math.hypot(
|
||||
Math.max(point.x, window.innerWidth - point.x),
|
||||
Math.max(point.y, window.innerHeight - point.y)
|
||||
);
|
||||
var clipPath = [
|
||||
"circle(0px at " + point.x + "px " + point.y + "px)",
|
||||
"circle(" + endRadius + "px at " + point.x + "px " + point.y + "px)"
|
||||
];
|
||||
var enteringDark = next === "dark";
|
||||
|
||||
try {
|
||||
var transition = document.startViewTransition(function () {
|
||||
applyTheme(next);
|
||||
});
|
||||
|
||||
transition.ready.then(function () {
|
||||
try {
|
||||
document.documentElement.animate(
|
||||
{ clipPath: enteringDark ? clipPath : clipPath.slice().reverse() },
|
||||
{
|
||||
duration: 500,
|
||||
easing: enteringDark ? "ease-in" : "ease-out",
|
||||
fill: "both",
|
||||
pseudoElement: enteringDark ? "::view-transition-new(root)" : "::view-transition-old(root)"
|
||||
}
|
||||
);
|
||||
} catch (e) {}
|
||||
}).catch(function () {});
|
||||
} catch (e) {
|
||||
applyTheme(next);
|
||||
}
|
||||
}
|
||||
|
||||
function bindToggle(id) {
|
||||
var el = document.getElementById(id);
|
||||
if (!el) return;
|
||||
el.addEventListener("click", function (event) {
|
||||
var next = document.body.classList.contains("theme-dark") ? "light" : "dark";
|
||||
setStoredTheme(next);
|
||||
runThemeTransition(next, event);
|
||||
});
|
||||
}
|
||||
|
||||
bindToggle("theme-toggle");
|
||||
bindToggle("theme-toggle-desktop");
|
||||
bindToggle("dropdown-theme-toggle");
|
||||
bindToggle("float-theme-toggle");
|
||||
bindToggle("theme-toggle-mobile");
|
||||
|
||||
aksrt.toggleTheme = function (event) {
|
||||
var next = document.body.classList.contains("theme-dark") ? "light" : "dark";
|
||||
setStoredTheme(next);
|
||||
runThemeTransition(next, event);
|
||||
};
|
||||
}
|
||||
|
||||
window.AksrtFrontend.register("aksrt-theme", function () { initTheme(); });
|
||||
})();
|
||||
Reference in new issue
Block a user