summaryrefslogtreecommitdiff
path: root/static
diff options
context:
space:
mode:
Diffstat (limited to 'static')
-rw-r--r--static/favicon.svg6
-rw-r--r--static/js/theme.js75
2 files changed, 81 insertions, 0 deletions
diff --git a/static/favicon.svg b/static/favicon.svg
new file mode 100644
index 0000000..39493b6
--- /dev/null
+++ b/static/favicon.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-labelledby="title">
+ <title id="title">たかしの記録</title>
+ <rect width="64" height="64" rx="6" fill="#202124"/>
+ <path d="M15 15h34v34H15z" fill="none" stroke="#86b6d8" stroke-width="3"/>
+ <path d="M24 23h16M24 31h16M24 39h11" stroke="#f6f5f1" stroke-width="3"/>
+</svg>
diff --git a/static/js/theme.js b/static/js/theme.js
new file mode 100644
index 0000000..3d2b25c
--- /dev/null
+++ b/static/js/theme.js
@@ -0,0 +1,75 @@
+(function () {
+ "use strict";
+
+ var root = document.documentElement;
+ root.classList.add("theme-ready");
+ var toggle = document.querySelector("[data-theme-toggle]");
+ var syntaxLight = document.getElementById("syntax-light");
+ var syntaxDark = document.getElementById("syntax-dark");
+ var media = window.matchMedia("(prefers-color-scheme: dark)");
+ var storedTheme = null;
+
+ try {
+ storedTheme = window.localStorage.getItem("theme");
+ } catch (error) {
+ storedTheme = null;
+ }
+
+ function activeTheme() {
+ if (root.dataset.theme === "light" || root.dataset.theme === "dark") {
+ return root.dataset.theme;
+ }
+ return media.matches ? "dark" : "light";
+ }
+
+ function syncSyntax(theme) {
+ if (!syntaxLight || !syntaxDark) {
+ return;
+ }
+ syntaxLight.media = theme === "light" ? "all" : "not all";
+ syntaxDark.media = theme === "dark" ? "all" : "not all";
+ }
+
+ function updateToggle() {
+ if (!toggle) {
+ return;
+ }
+ var dark = activeTheme() === "dark";
+ toggle.setAttribute("aria-pressed", String(dark));
+ toggle.setAttribute("aria-label", dark ? "ライトテーマに切り替える" : "ダークテーマに切り替える");
+ toggle.textContent = dark ? "Light" : "Dark";
+ }
+
+ function applyTheme(theme, persist) {
+ root.dataset.theme = theme;
+ syncSyntax(theme);
+ updateToggle();
+ if (persist) {
+ try {
+ window.localStorage.setItem("theme", theme);
+ } catch (error) {
+ // Storageが利用できなくても、現在のpageではthemeを維持する。
+ }
+ }
+ }
+
+ if (storedTheme === "light" || storedTheme === "dark") {
+ applyTheme(storedTheme, false);
+ } else {
+ syncSyntax(activeTheme());
+ updateToggle();
+ }
+
+ if (toggle) {
+ toggle.addEventListener("click", function () {
+ applyTheme(activeTheme() === "dark" ? "light" : "dark", true);
+ });
+ }
+
+ media.addEventListener("change", function () {
+ if (!root.dataset.theme) {
+ syncSyntax(activeTheme());
+ updateToggle();
+ }
+ });
+})();