-
Notifications
You must be signed in to change notification settings - Fork 11.5k
/
Copy paththeme.js
252 lines (215 loc) · 7.83 KB
/
theme.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
// Has to be in the head tag, otherwise a flicker effect will occur.
// Toggle through light, dark, and system theme settings.
let toggleThemeSetting = () => {
let themeSetting = determineThemeSetting();
if (themeSetting == "system") {
setThemeSetting("light");
} else if (themeSetting == "light") {
setThemeSetting("dark");
} else {
setThemeSetting("system");
}
};
// Change the theme setting and apply the theme.
let setThemeSetting = (themeSetting) => {
localStorage.setItem("theme", themeSetting);
document.documentElement.setAttribute("data-theme-setting", themeSetting);
applyTheme();
};
// Apply the computed dark or light theme to the website.
let applyTheme = () => {
let theme = determineComputedTheme();
transTheme();
setHighlight(theme);
setGiscusTheme(theme);
setSearchTheme(theme);
// if mermaid is not defined, do nothing
if (typeof mermaid !== "undefined") {
setMermaidTheme(theme);
}
// if diff2html is not defined, do nothing
if (typeof Diff2HtmlUI !== "undefined") {
setDiff2htmlTheme(theme);
}
// if echarts is not defined, do nothing
if (typeof echarts !== "undefined") {
setEchartsTheme(theme);
}
// if vegaEmbed is not defined, do nothing
if (typeof vegaEmbed !== "undefined") {
setVegaLiteTheme(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");
}
}
// 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 setDiff2htmlTheme = (theme) => {
document.querySelectorAll(".diff2html").forEach((elem) => {
// Get the code block content from previous element, since it is the diff code itself as defined in Markdown, but it is hidden
let textData = elem.previousSibling.childNodes[0].innerHTML;
elem.innerHTML = "";
const configuration = { colorScheme: theme, drawFileList: true, highlight: true, matching: "lines" };
const diff2htmlUi = new Diff2HtmlUI(elem, textData, configuration);
diff2htmlUi.draw();
});
};
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 setVegaLiteTheme = (theme) => {
document.querySelectorAll(".vega-lite").forEach((elem) => {
// Get the code block content from previous element, since it is the vega lite code itself as defined in Markdown, but it is hidden
let jsonData = elem.previousSibling.childNodes[0].innerHTML;
elem.innerHTML = "";
if (theme === "dark") {
vegaEmbed(elem, JSON.parse(jsonData), { theme: "dark" });
} else {
vegaEmbed(elem, JSON.parse(jsonData));
}
});
};
let setSearchTheme = (theme) => {
const ninjaKeys = document.querySelector("ninja-keys");
if (!ninjaKeys) return;
if (theme === "dark") {
ninjaKeys.classList.add("dark");
} else {
ninjaKeys.classList.remove("dark");
}
};
let transTheme = () => {
document.documentElement.classList.add("transition");
window.setTimeout(() => {
document.documentElement.classList.remove("transition");
}, 500);
};
// Determine the expected state of the theme toggle, which can be "dark", "light", or
// "system". Default is "system".
let determineThemeSetting = () => {
let themeSetting = localStorage.getItem("theme");
if (themeSetting != "dark" && themeSetting != "light" && themeSetting != "system") {
themeSetting = "system";
}
return themeSetting;
};
// Determine the computed theme, which can be "dark" or "light". If the theme setting is
// "system", the computed theme is determined based on the user's system preference.
let determineComputedTheme = () => {
let themeSetting = determineThemeSetting();
if (themeSetting == "system") {
const userPref = window.matchMedia;
if (userPref && userPref("(prefers-color-scheme: dark)").matches) {
return "dark";
} else {
return "light";
}
} else {
return themeSetting;
}
};
let initTheme = () => {
let themeSetting = determineThemeSetting();
setThemeSetting(themeSetting);
// Add event listener to the theme toggle button.
document.addEventListener("DOMContentLoaded", function () {
const mode_toggle = document.getElementById("light-toggle");
mode_toggle.addEventListener("click", function () {
toggleThemeSetting();
});
});
// Add event listener to the system theme preference change.
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", ({ matches }) => {
applyTheme();
});
};