new_site/assets/js/theme.js

170 lines
5.1 KiB
JavaScript

// Has to be in the head tag, otherwise a flicker effect will occur.
let toggleTheme = (theme) => {
if (theme == "dark") {
setTheme("light");
} else {
setTheme("dark");
}
};
let setTheme = (theme) => {
transTheme();
setHighlight(theme);
setGiscusTheme(theme);
// if mermaid is not defined, do nothing
if (typeof mermaid !== "undefined") {
setMermaidTheme(theme);
}
// if echarts is not defined, do nothing
if (typeof echarts !== "undefined") {
setEchartsTheme(theme);
}
if (theme) {
document.documentElement.setAttribute("data-theme", theme);
// Add class to tables.
let tables = document.getElementsByTagName("table");
for (let i = 0; i < tables.length; i++) {
if (theme == "dark") {
tables[i].classList.add("table-dark");
} else {
tables[i].classList.remove("table-dark");
}
}
// Set jupyter notebooks themes.
let jupyterNotebooks = document.getElementsByClassName("jupyter-notebook-iframe-container");
for (let i = 0; i < jupyterNotebooks.length; i++) {
let bodyElement = jupyterNotebooks[i].getElementsByTagName("iframe")[0].contentWindow.document.body;
if (theme == "dark") {
bodyElement.setAttribute("data-jp-theme-light", "false");
bodyElement.setAttribute("data-jp-theme-name", "JupyterLab Dark");
} else {
bodyElement.setAttribute("data-jp-theme-light", "true");
bodyElement.setAttribute("data-jp-theme-name", "JupyterLab Light");
}
}
} else {
document.documentElement.removeAttribute("data-theme");
}
localStorage.setItem("theme", theme);
// Updates the background of medium-zoom overlay.
if (typeof medium_zoom !== "undefined") {
medium_zoom.update({
background: getComputedStyle(document.documentElement).getPropertyValue("--global-bg-color") + "ee", // + 'ee' for trasparency.
});
}
};
let setHighlight = (theme) => {
if (theme == "dark") {
document.getElementById("highlight_theme_light").media = "none";
document.getElementById("highlight_theme_dark").media = "";
} else {
document.getElementById("highlight_theme_dark").media = "none";
document.getElementById("highlight_theme_light").media = "";
}
};
let setGiscusTheme = (theme) => {
function sendMessage(message) {
const iframe = document.querySelector("iframe.giscus-frame");
if (!iframe) return;
iframe.contentWindow.postMessage({ giscus: message }, "https://giscus.app");
}
sendMessage({
setConfig: {
theme: theme,
},
});
};
let addMermaidZoom = (records, observer) => {
var svgs = d3.selectAll(".mermaid svg");
svgs.each(function () {
var svg = d3.select(this);
svg.html("<g>" + svg.html() + "</g>");
var inner = svg.select("g");
var zoom = d3.zoom().on("zoom", function (event) {
inner.attr("transform", event.transform);
});
svg.call(zoom);
});
observer.disconnect();
};
let setMermaidTheme = (theme) => {
if (theme == "light") {
// light theme name in mermaid is 'default'
// https://mermaid.js.org/config/theming.html#available-themes
theme = "default";
}
/* Re-render the SVG, based on https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/_includes/mermaid.html */
document.querySelectorAll(".mermaid").forEach((elem) => {
// Get the code block content from previous element, since it is the mermaid code itself as defined in Markdown, but it is hidden
let svgCode = elem.previousSibling.childNodes[0].innerHTML;
elem.removeAttribute("data-processed");
elem.innerHTML = svgCode;
});
mermaid.initialize({ theme: theme });
window.mermaid.init(undefined, document.querySelectorAll(".mermaid"));
const observable = document.querySelector(".mermaid svg");
if (observable !== null) {
var observer = new MutationObserver(addMermaidZoom);
const observerOptions = { childList: true };
observer.observe(observable, observerOptions);
}
};
let setEchartsTheme = (theme) => {
document.querySelectorAll(".echarts").forEach((elem) => {
// Get the code block content from previous element, since it is the echarts code itself as defined in Markdown, but it is hidden
let jsonData = elem.previousSibling.childNodes[0].innerHTML;
echarts.dispose(elem);
if (theme === "dark") {
var chart = echarts.init(elem, "dark-fresh-cut");
} else {
var chart = echarts.init(elem);
}
chart.setOption(JSON.parse(jsonData));
});
};
let transTheme = () => {
document.documentElement.classList.add("transition");
window.setTimeout(() => {
document.documentElement.classList.remove("transition");
}, 500);
};
let initTheme = (theme) => {
if (theme == null || theme == "null") {
const userPref = window.matchMedia;
if (userPref && userPref("(prefers-color-scheme: dark)").matches) {
theme = "dark";
}
}
setTheme(theme);
};
initTheme(localStorage.getItem("theme"));
document.addEventListener("DOMContentLoaded", function () {
const mode_toggle = document.getElementById("light-toggle");
mode_toggle.addEventListener("click", function () {
toggleTheme(localStorage.getItem("theme"));
});
});