From 3ae4b0a8b0b13fed969e73c4a839782279fc0c23 Mon Sep 17 00:00:00 2001 From: Junyi Hou Date: Tue, 9 Apr 2024 16:42:47 +0800 Subject: [PATCH] feat: mermaid theme auto switch --- assets/js/load-mermaid.js | 69 ++++++++++++++++++++++++++++ layouts/_default/single.html | 24 +++++++++- layouts/partials/theme-switcher.html | 18 ++++---- 3 files changed, 102 insertions(+), 9 deletions(-) create mode 100644 assets/js/load-mermaid.js diff --git a/assets/js/load-mermaid.js b/assets/js/load-mermaid.js new file mode 100644 index 0000000..75b1df5 --- /dev/null +++ b/assets/js/load-mermaid.js @@ -0,0 +1,69 @@ + +/*! + * Simple-Jekyll-Search + * Copyright 2015-2020, Christian Fei + * Licensed under the MIT License. + */ + +(function(window){ + 'use strict' + + const elementCode = '.mermaid' + const loadMermaid = function(theme) { + window.mermaid.initialize({theme}) + window.mermaid.init({theme}, document.querySelectorAll(elementCode)) + } + const saveOriginalData = function(){ + return new Promise((resolve, reject) => { + try { + var els = document.querySelectorAll(elementCode), + count = els.length; + els.forEach(element => { + element.setAttribute('data-original-code', element.innerHTML) + count-- + if(count == 0){ + resolve() + } + }); + } catch (error) { + reject(error) + } + }) + } + const resetProcessed = function(){ + return new Promise((resolve, reject) => { + try { + var els = document.querySelectorAll(elementCode), + count = els.length; + els.forEach(element => { + if(element.getAttribute('data-original-code') != null){ + element.removeAttribute('data-processed') + element.innerHTML = element.getAttribute('data-original-code') + } + count-- + if(count == 0){ + resolve() + } + }); + } catch (error) { + reject(error) + } + }) + } + + const init = ()=>{ + saveOriginalData() + .catch( console.error ) + document.body.addEventListener('dark-theme-set', ()=>{ + resetProcessed() + .then(loadMermaid('dark')) + .catch(console.error) + }) + document.body.addEventListener('light-theme-set', ()=>{ + resetProcessed() + .then(loadMermaid('default')) + .catch(console.error) + }) + } + window.initMermaid = init + })(window); \ No newline at end of file diff --git a/layouts/_default/single.html b/layouts/_default/single.html index ddda08d..c701504 100644 --- a/layouts/_default/single.html +++ b/layouts/_default/single.html @@ -46,10 +46,32 @@ `.Store.Set "hasMermaid"` is executed. `.Store.Get "hasMermaid"` will return true and mermaid.js will be loaded. */}} + {{ if .Store.Get "hasMermaid" }} + {{ partial "resource.html" (dict "context" . "type" "js" "filename" "js/load-mermaid.js") }} + + {{ $colorTheme := "light" }} + {{ if and (isset site.Params "colortheme") (ne site.Params.colortheme "") }} + {{ $colorTheme = site.Params.colortheme | lower }} + {{ end }} + {{ end }} {{ end }} + diff --git a/layouts/partials/theme-switcher.html b/layouts/partials/theme-switcher.html index 8ad76de..4614a57 100644 --- a/layouts/partials/theme-switcher.html +++ b/layouts/partials/theme-switcher.html @@ -23,11 +23,20 @@ let currentTheme let switchButton let autoDefinedScheme = window.matchMedia('(prefers-color-scheme: dark)') - + + function switchTheme(e) { + currentTheme = (currentTheme === 'dark') ? 'light' : 'dark'; + if (localStorage) localStorage.setItem(STORAGE_KEY, currentTheme); + document.documentElement.setAttribute('data-theme', currentTheme); + changeGiscusTheme(currentTheme); + document.body.dispatchEvent(new CustomEvent(currentTheme + "-theme-set")); + } + const autoChangeScheme = e => { currentTheme = e.matches ? 'dark' : 'light' document.documentElement.setAttribute('data-theme', currentTheme); changeGiscusTheme(currentTheme); + document.body.dispatchEvent(new CustomEvent(currentTheme + "-theme-set")); } document.addEventListener('DOMContentLoaded', function () { @@ -58,13 +67,6 @@ return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; } - function switchTheme(e) { - currentTheme = (currentTheme === 'dark') ? 'light' : 'dark'; - if (localStorage) localStorage.setItem(STORAGE_KEY, currentTheme); - document.documentElement.setAttribute('data-theme', currentTheme); - changeGiscusTheme(currentTheme); - } - function showContent() { document.body.style.visibility = 'visible'; document.body.style.opacity = 1;