NOTE: Apart from
(and even then it's questionable, I'm Scottish). These are machine translated in languages I don't read. If they're terrible please contact me.
You can see how this translation was done in this article.
Thursday, 29 August 2024
//Less than a minute
Χρησιμοποιώ το Mermaid.js για να δημιουργήσω τα διαγράμματα ναρκωτικών που βλέπετε σε μερικές θέσεις. Σαν αυτό από κάτω. Ωστόσο, κάτι που με ενόχλησε είναι ότι δεν ήταν αντιδραστικό στην αλλαγή θεμάτων (σκοτεινό / φως) και φαινόταν να υπάρχουν πολύ ανεπαρκείς πληροφορίες εκεί έξω για την επίτευξη αυτού.
Αυτό είναι το αποτέλεσμα μερικών ωρών σκάψιμο και προσπαθεί να καταλάβει πώς να το κάνει αυτό.
Μπορείτε να βρείτε την πηγή για mdeswitcher εδώ: mdeswitcher.js.
ΣΗΜΕΙΩΣΗ: Το έχω ενημερώσει αυτό ουσιαστικά.
Το θέμα είναι ότι πρέπει να αρχικοποιήσεις την Γοργόνα για να βάλεις το θέμα, και δεν μπορείς να το αλλάξεις μετά από αυτό. ΠΩΣ αν θέλετε να το επανεκκινήσετε σε ένα ήδη δημιουργημένο διάγραμμα; δεν μπορεί να ξανακάνει το διάγραμμα καθώς τα δεδομένα δεν αποθηκεύονται στο DOM.
Έτσι, μετά το σκάψιμο πολλών και προσπαθώντας να βρω πώς να το κάνω αυτό, βρήκα μια λύση σε αυτό το άρθρο έκδοσης GitHub
Ωστόσο, είχε ακόμη μερικά ζητήματα, έτσι έπρεπε να το τροποποιήσω λίγο για να το κάνω να λειτουργήσει.
Αυτή η ιστοσελίδα βασίζεται σε ένα θέμα Tailwind που ήρθε με ένα αρκετά τρομερό διακόπτη θέμα.
Θα δείτε ότι αυτό είναι κάνει διάφορα πράγματα γύρω από την αλλαγή του θέματος, που το θέμα για ό, τι είναι αποθηκευμένο στην τοπική αποθήκευση, αλλάζοντας ένα ζευγάρι stylesheers για simplemde & highlight.js και στη συνέχεια την εφαρμογή του θέματος.
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;
}
}
};
}
Οι κύριες προσθήκες για τον διακόπτη θέματος της Γοργόνας είναι οι εξής:
document.body.dispatchEvent(new CustomEvent('dark-theme-set'));
document.body.dispatchEvent(new CustomEvent('light-theme-set'));
Αυτά τα δύο γεγονότα χρησιμοποιούνται στο εξάρτημα μας ThemeSwitcher για να επανεκκινήσουν τα διαγράμματα Γοργόνας.
Στο............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................. 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();
}
};
Αυτό είναι το αρχείο που περιέχει τον κωδικό για την αλλαγή των θεμάτων για την Γοργόνα. (Το φρικτό διάγραμμα ανωτέρω δείχνει την ακολουθία των γεγονότων που συμβαίνουν όταν το θέμα αλλάζει)
(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
- λειτουργία είναι η κύρια λειτουργία που ονομάζεται όταν η σελίδα είναι φορτωμένη.Αρχικά σώζει το αρχικό περιεχόμενο των διαγραμμάτων της Γοργόνας· αυτό ήταν ένα θέμα στην έκδοση που το αντιγράφω, χρησιμοποίησαν το "innerHTML" που δεν λειτούργησε για μένα, καθώς ορισμένα διαγράμματα βασίζονται σε νέες γραμμές από τις οποίες ταινία.
Στη συνέχεια προσθέτει δύο ακροατές εκδηλώσεων για την dark-theme-set
και light-theme-set
Γεγονότα. Όταν αυτά τα γεγονότα απολύονται επαναφέρει τα επεξεργασμένα δεδομένα και στη συνέχεια επανακινεί τα διαγράμματα Γοργόνας με το νέο θέμα.
Στη συνέχεια ελέγχει την τοπική αποθήκευση για το θέμα και αρχικοποιεί τα διαγράμματα Γοργόνας με το κατάλληλο θέμα.
let isDarkMode = localStorage.theme === 'dark';
if(isDarkMode) {
loadMermaid('dark');
}
else{
loadMermaid('default')
}
Το κλειδί για όλο αυτό το πράγμα είναι η αποθήκευση στη συνέχεια την αποκατάσταση του περιεχομένου που περιέχεται στην απόδοση <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,
});
};
Αυτό ήταν ένα κομμάτι του πόνου για να καταλάβω, αλλά είμαι ευτυχής που το έκανα. Ελπίζω αυτό να βοηθήσει κάποιον άλλο εκεί έξω που προσπαθεί να κάνει το ίδιο πράγμα.