diff options
| author | tanaka takashi <isazaka@gmail.com> | 2026-08-22 00:18:56 +0900 |
|---|---|---|
| committer | tanaka takashi <isazaka@gmail.com> | 2026-08-22 00:19:26 +0900 |
| commit | 9f2fb3bda733c32995c008bd0f40365e43c348da (patch) | |
| tree | 663a6b48ec83b2b6ba2c998dcfed89e0bb29f172 /static/js | |
| parent | 31b19ee74469c23633bbea4e021d91ddd8c34e3a (diff) | |
feat: Zolaで「たかしの記録」を構築
Specifications.mdとDesign.mdを実装の基準として、個人アーカイブサイトをZola 0.23.3向けに構築する。
- Home、Notes、Software、About、Tagsの情報設計と専用URLを追加
- Notesの年別アーカイブ、タグ分類、目次、脚注、参考文献、更新日表示を実装
- Softwareの一覧・詳細、cgit/GitHub情報、Notesとの明示的な相互参照を実装
- Tera 2 componentによる再帰TOCと共通partialsを追加
- Minimal Editorial ArchiveのSCSS、レスポンシブ表示、アクセシビリティ対応を追加
- OS設定とlocalStorageに対応するLight/Darkテーマ切替を外部JavaScriptで実装
- Atom/RSS、sitemap、robots.txt、404、favicon、syntax highlightingを設定
- メールアドレスをzola.tomlへ一元化し、AboutとFooterから参照
- 表示名・内部ディレクトリ・変数・URLをSoftware/softwareへ統一
- public/をGit管理対象外とし、外部CDNやNode.js依存を導入しない
- zola checkおよびzola buildの成功を確認
Diffstat (limited to 'static/js')
| -rw-r--r-- | static/js/theme.js | 75 |
1 files changed, 75 insertions, 0 deletions
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(); + } + }); +})(); |
