This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
Перемикання тем для Сирена (AktualізованаM SK1
Thursday, 29 August 2024
Введение
Я використовую Mermaid.js, щоб створити діаграми наркотиків, які ви бачите в кількох постах Але мене дратувало те, що це не реагувало на перемикання тем. (dark/lightM SK3 і здавалося, що там є дуже погана інформація про те, як досягти цього.
Це результат кількох годин викопування та спроби зрозуміти, як це зробити.
Ви можете знайти джерело для mdeswitcher тут: mdeswitcher.js.
NOTA: Я докорінно обновлювала цеM SK1
Діаграма
graph LR
A[Start] --> B[Initialize Mermaid with Theme]
B --> C{Are there any elements matching 'div.mermaid'?}
C --> |No| D[Exit]
C --> |Yes| E[Save Original Data]
E --> F{Did saving data succeed?}
F --> |No| D[Exit]
F --> |Yes| G[Set up Theme Event Listeners]
G --> H[Check Local Storage for Dark Mode]
H --> I{Is Dark Mode enabled?}
I --> |Yes| J[Load Mermaid with Dark Theme]
I --> |No| K[Load Mermaid with Default Theme]
J --> L[Wait for Events]
K --> L[Wait for Events]
L --> M{Event Triggered?}
M --> |Dark Theme Set| N[Reset Processed Data]
N --> O[Load Mermaid with Dark Theme]
M --> |Light Theme Set| P[Reset Processed Data]
P --> Q[Load Mermaid with Default Theme]
O --> L
Q --> L
L --> D[Exit]
Проблема
Проблема в тому, що вам потрібно inicialізувати Mermaid для того, щоб надати тему, і ви можете ' не змінювати її після цього МSK2 В будь-якому разі, якщо ви хочете відновити її на створеному діаграмі
Рішення
Тож після того, як я розкопав і намагався зрозуміти, як це зробити, я знайшов рішення в цей пост про выпуски GitHub
Тим не менше, у нього були декілька проблем, тому мені довелося трохи змінити його, щоб він почав працюватиM SK1
Теми
Ця веб-страна базується на Tailwind тема, яка прийшла з досить жахливою тему перемикач.
Ви побачите, що це робить різні речі, перемикаючи тему, встановляючи тему для того, що зберігається у локальному накопичуванні M SK2 змінюючи декілька таблиць стилю для Simplemde
export function globalSetup() {
const lightStylesheet = document.getElementById('light-mode');
const darkStylesheet = document.getElementById('dark-mode');
const simpleMdeDarkStylesheet = document.getElementById('simplemde-dark');
const simpleMdeLightStylesheet = document.getElementById('simplemde-light');
return {
isMobileMenuOpen: false,
isDarkMode: false,
// Function to initialize the theme based on localStorage or system preference
themeInit() {
if (
localStorage.theme === "dark" ||
(!("theme" in localStorage) &&
window.matchMedia("(prefers-color-scheme: dark)").matches)
) {
localStorage.theme = "dark";
document.documentElement.classList.add("dark");
document.documentElement.classList.remove("light");
this.isDarkMode = true;
this.applyTheme(); // Apply dark theme stylesheets
} else {
localStorage.theme = "base";
document.documentElement.classList.remove("dark");
document.documentElement.classList.add("light");
this.isDarkMode = false;
this.applyTheme(); // Apply light theme stylesheets
}
},
// Function to switch the theme and update the stylesheets accordingly
themeSwitch() {
if (localStorage.theme === "dark") {
localStorage.theme = "light";
document.body.dispatchEvent(new CustomEvent('light-theme-set'));
document.documentElement.classList.remove("dark");
document.documentElement.classList.add("light");
this.isDarkMode = false;
} else {
localStorage.theme = "dark";
document.body.dispatchEvent(new CustomEvent('dark-theme-set'));
document.documentElement.classList.add("dark");
document.documentElement.classList.remove("light");
this.isDarkMode = true;
}
this.applyTheme(); // Apply the theme stylesheets after switching
},
// Function to apply the appropriate stylesheets based on isDarkMode
applyTheme() {
if (this.isDarkMode) {
// Enable dark mode stylesheets
lightStylesheet.disabled = true;
darkStylesheet.disabled = false;
simpleMdeLightStylesheet.disabled = true;
simpleMdeDarkStylesheet.disabled = false;
} else {
// Enable light mode stylesheets
lightStylesheet.disabled = false;
darkStylesheet.disabled = true;
simpleMdeLightStylesheet.disabled = false;
simpleMdeDarkStylesheet.disabled = true;
}
}
};
}
Налагодження
Головні додатки для theme switcher Mermaid:
document.body.dispatchEvent(new CustomEvent('dark-theme-set'));
document.body.dispatchEvent(new CustomEvent('light-theme-set'));
Ці дві події входять у наш компонент ThemeSwitcher, щоб відновити діаграми Сирена.
Загрузити / htmxM SK1 після відкидання
У моєму main.js я встановлюю тему перемикач. я також импортую mdeswitch файл, який містить код для переключення тем.
//Important: Memraid will ALWAYS intialize on window.onload, so we need to make sure we disable this behaviour:
import mermaid from "mermaid";
window.mermaid=mermaid;
mermaid.initialize({startOnLoad:false});
window.mermaidinit = function() {
mermaid.initialize({ startOnLoad: false });
try {
window.initMermaid().then(r => console.log('Mermaid initialized'));
} catch (e) {
console.error('Failed to initialize Mermaid:', e);
}
}
document.body.addEventListener('htmx:afterSwap', function(evt) {
mermaidinit();
//This should be called after the mermaid diagrams have been rendered.
hljs.highlightAll();
});
window.onload = function(ev) {
if(document.readyState === 'complete') {
mermaidinit();
hljs.highlightAll();
}
};
MDESwtich
Це файл, який містить код для зміни тем для Сирена. ( Жахливе діаграма зверху показує послідовність подій, які відбуваються, коли тема змінюється)
(function(window) {
'use strict';
const elementCode = 'div.mermaid';
const loadMermaid = async (theme) => {
mermaid.initialize({startOnLoad: false, theme: theme });
console.log("Loading mermaid with theme:", theme);
await mermaid.run({
querySelector: elementCode,
});
};
const saveOriginalData = async () => {
try {
console.log("Saving original data");
const elements = document.querySelectorAll(elementCode);
const count = elements.length;
if (count === 0) return;
const promises = Array.from(elements).map((element) => {
if (element.getAttribute('data-processed') != null) {
console.log("Element already processed");
return;
}
element.setAttribute('data-original-code', element.innerHTML);
});
await Promise.all(promises);
} catch (error) {
console.error(error);
throw error;
}
};
const resetProcessed = async () => {
try {
console.log("Resetting processed data");
const elements = document.querySelectorAll(elementCode);
const count = elements.length;
if (count === 0) return;
const promises = Array.from(elements).map((element) => {
if (element.getAttribute('data-original-code') != null) {
element.removeAttribute('data-processed');
element.innerHTML = element.getAttribute('data-original-code');
}
else {
console.log("Element already reset");
}
});
await Promise.all(promises);
} catch (error) {
console.error(error);
throw error;
}
};
window.initMermaid = async () => {
const mermaidElements = document.querySelectorAll(elementCode);
if (mermaidElements.length === 0) return;
try {
await saveOriginalData();
} catch (error) {
console.error("Error saving original data:", error);
return; // Early exit if saveOriginalData fails
}
const handleDarkThemeSet = async () => {
try {
await resetProcessed();
await loadMermaid('dark');
console.log("Dark theme set");
} catch (error) {
console.error("Error during dark theme set:", error);
}
};
const handleLightThemeSet = async () => {
try {
await resetProcessed();
await loadMermaid('default');
console.log("Light theme set");
} catch (error) {
console.error("Error during light theme set:", error);
}
};
document.body.removeEventListener('dark-theme-set', handleDarkThemeSet);
document.body.removeEventListener('light-theme-set', handleLightThemeSet);
document.body.addEventListener('dark-theme-set', handleDarkThemeSet);
document.body.addEventListener('light-theme-set', handleLightThemeSet);
const isDarkMode = localStorage.theme === 'dark';
await loadMermaid(isDarkMode ? 'dark' : 'default').then(r => console.log('Initial load complete'));
};
})(window);
Ми йдемо знизу вгору ось тут.
init- - це головна функція, яка викликана при завантаження сторінки
Спочатку зберігається оригінальний зміст діаграми Сиренки. ; це була проблема в версії, яку я копіював з МSK1 вони використовували МSK2innerHTML ' що не спрацювало для мене.
Потім додаємо два слухачі подій для dark-theme-set і light-theme-set події. Коли ці події активуються, вона відобновує оброблені дані і тоді реніціалізує діаграми Сирена з новою темоюM SK1
Тоді він перевіряє локальне зберігання для теми і запускає діаграми Сирена з відповідною темою.
let isDarkMode = localStorage.theme === 'dark';
if(isDarkMode) {
loadMermaid('dark');
}
else{
loadMermaid('default')
}
Заspeicherти оригінальні дані
Ключ до всього цього - зберігати, а потім відновлювати зміст, що міститься в відтворенні <div class="mermaid"><div> які містять маркупу дівчини з наших постів.
Ви побачите, що це просто створює Обіцянку, яка проходить через всі елементи і зберігає оригінальний контент в data-original-code атрибут.
const saveOriginalData = async () => {
try {
console.log("Saving original data");
const elements = document.querySelectorAll(elementCode);
const count = elements.length;
if (count === 0) return;
const promises = Array.from(elements).map((element) => {
if (element.getAttribute('data-processed') != null) {
console.log("Element already processed");
return;
}
element.setAttribute('data-original-code', element.innerHTML);
});
await Promise.all(promises);
} catch (error) {
console.error(error);
throw error;
}
};
resetProcessed є однаковим, за винятком зворотнього, де він бере значок з data-original-code атрибут і повертає його до елементу.
Ініт
Тепер у нас є всі ці дані, ми можемо відновити Сирена, щоб застосувати нашу нову тему і перенести діаграму SVG в наш HTML вихідні код.
const elementCode = 'div.mermaid';
const loadMermaid = async (theme) => {
mermaid.initialize({startOnLoad: false, theme: theme });
console.log("Loading mermaid with theme:", theme);
await mermaid.run({
querySelector: elementCode,
});
};
На завершення
Це було трохи важко зрозуміти, але я рада, що зробила це. Сподіваюсь, це допоможе комусь іншому, хто намагається зробити те ж саме.