Mermaidin teemat vaihtaminen (UpdatedM SK1 (Suomi (Finnish))

Mermaidin teemat vaihtaminen (UpdatedM SK1

Thursday, 29 August 2024

//

7 minute read

Esitys

Käytän Mermaidia.js luodakseni ne huumausainediagrammat, joita näette muutamassa julkaisussaM SK1 Kuten jäljempänä olevassa Minua kuitenkin häiritsee se, että se ei reagoi aiheiden vaihtamiseen: (, "dark" ja "light". Näyttää siltä, että tämän tavoitteen saavuttamisesta on olemassa hyvin huonoja tietoja.

Tämä on tulosta muutaman tunnin kaivauksesta ja siitä, että yritetään selvittää, miten tämä tehdään.

Mdeswitcherin lähde löytyy täältä: mdeswitcher.js.

PANEE MERKILLE: Olen ajantasaistanut tätä merkittävästi

Diagrammi

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]


Ongelma

Ongelmana on se, että Mermaid-aihetta on initialisoitava ja sen jälkeen sitä ei voida muuttaa.

Ratkaisu

Näin ollen sen jälkeen, kun tutkiin paljon ja yritin selvittää, miten tämä tehdään, löysin ratkaisun tämä GitHubin issue post

Siinä oli kuitenkin vielä joitakin ongelmia, joten minun oli muutettava sitä hieman, jotta se toimisi.

Aiheet

Tämä sivusto perustuu Tailwind teema, joka tuli melko hirvittävän teeman vaihtaja.

Huomaatte, että tämä tekee erilaisia asioita vaihtaessa aihetta, ottamalla käyttöön aihetta siitä, mikä on tallennettu paikalliseen varastoon M SK2 muuttamalla paria stylesheeriä simplemde-järjestelmälle & korostamaan.js ja sitten soveltamalla aihetta

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;
            }
        }
    };
}

Järjestelmä

Tärkeimmät lisäykset Mermaid theme switcher ovat seuraavat:

  document.body.dispatchEvent(new CustomEvent('dark-theme-set'));
    document.body.dispatchEvent(new CustomEvent('light-theme-set'));

Näitä kahta tapahtumaa käytetään ThemeSwitcher-komponenttina Mermaid -diagrammien elvyttämiseksi.

OnLoad / htmx:afterSwap

Minun main.js asiakirjan laatiminen theme switcher. myös maahantuo mdeswitch asiakirja, joka sisältää koodin aiheiden vaihtamiseksi.

//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

Tämä on tiedosto, joka sisältää koodin Mermaidin teemajen vaihtamiseksi. (Huottava taulukko edellä osoittaa sellaisten tapahtumien ketjun, jotka tapahtuvat, kun teemaa muutetaan)

(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);

Siihen pääsemme hieman alaspäin..

  1. init - on päätehtävä, joka kutsutaan, kun sivua laaditaan

Ensinnäkin se säilyttää mermaid-diagrammien alkuperäisen sisällön; tämä oli kysymys versiossani, joka kopioin.

Sen jälkeen siihen lisätään kaksi tapahtuman kuuntelijaa dark-theme-set ja light-theme-set events. Kun nämä tapahtumat käynnistetään, se palauttaa uudelleen käsiteltyjä tietoja ja käynnistää uudelleen Mermaid-diagrammat uudella teemalla.

Sen jälkeen se tarkistaa teeman paikallisen varastoinnin ja käynnistää Mermaid-diagrammat asianmukaisella teemalla.

let isDarkMode = localStorage.theme === 'dark';
        if(isDarkMode) {
            loadMermaid('dark');
         }
         else{
             loadMermaid('default')
         }

Säädä alkuperäiset tiedot

Avain tähän koko asiaan on varastointi ja sen jälkeen sisällön palauttaminen, joka sisältyy esitettyyn <div class="mermaid"><div> jotka sisältävät mermaid markup-merkintöjä postistamme.

Huomaatte, että tämä vain perustaa lupauksen, joka kiertää kaikkia osatekijöitä ja tallentaa alkuperäisen sisällön data-original-code ominaisuuksia.

    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 on sama lukuun ottamatta käännekohtaa, jossa se ottaa merkintä data-original-code ja palauttaa sen elementtiin.

Init

Nyt meillä on kaikki nämä tiedot voimme käynnistää mermaid soveltaa uutta teemaamme ja rerender SVG-diagrammaa HTML -tulokseen

    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,
    });
};

Päätelmissä

Tämä oli hieman hankalaa ymmärtää, mutta olen iloinen siitä. Toivon, että tämä auttaa muita, jotka yrittävät tehdä samoin.

Finding related posts...
logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.