@@ -206,6 +206,7 @@ class Theme {
206206
207207 theme ;
208208 ctrl ;
209+ onChangeCallbacks = [ ] ;
209210
210211 get current ( ) {
211212 if ( this . theme == "system" ) {
@@ -245,6 +246,10 @@ class Theme {
245246 return isDark ? "dark" : "light" ;
246247 }
247248
249+ onChange ( callback ) {
250+ this . onChangeCallbacks . push ( callback ) ;
251+ }
252+
248253 change ( theme ) {
249254 localStorage . setItem ( "theme" , theme ) ;
250255 this . apply ( theme ) ;
@@ -266,6 +271,84 @@ class Theme {
266271
267272 this . ctrl . classList . remove ( "icon-theme-dark" , "icon-theme-light" , "icon-theme-system" ) ;
268273 this . ctrl . classList . add ( "icon-theme-" + this . theme ) ;
274+
275+ this . onChangeCallbacks . forEach ( callback => {
276+ try {
277+ callback ( this . current ) ;
278+ } catch ( _ ) { }
279+ } ) ;
269280 }
270281}
271- new Theme ( ) ;
282+ const theme = new Theme ( ) ;
283+
284+ // Mermaid manager
285+ class MermaidManager {
286+
287+ constructor ( theme ) {
288+ this . theme = theme ;
289+
290+ document . addEventListener ( "DOMContentLoaded" , ( ) => {
291+ this . renderAll ( { firstRun : true } ) ;
292+ this . theme . onChange ( ( ) => {
293+ this . renderAll ( { firstRun : false } ) ;
294+ } ) ;
295+ } ) ;
296+ }
297+
298+ initMermaid ( ) {
299+ mermaid . initialize ( {
300+ startOnLoad : false ,
301+ theme : this . theme . isDark ? "dark" : "default" ,
302+ securityLevel : "loose"
303+ } ) ;
304+ }
305+
306+ initialTransform ( ) {
307+ const blocks = document . querySelectorAll (
308+ "pre code.language-mermaid, pre.language-mermaid code"
309+ ) ;
310+
311+ blocks . forEach ( block => {
312+ const pre = block . closest ( "pre" ) ;
313+ if ( ! pre ) return ;
314+
315+ const code = block . textContent ;
316+ const div = document . createElement ( "div" ) ;
317+ div . className = "mermaid" ;
318+ div . textContent = code ;
319+ div . setAttribute ( "data-original-code" , code ) ;
320+ pre . replaceWith ( div ) ;
321+ } ) ;
322+ }
323+
324+ resetDiagrams ( ) {
325+ document . querySelectorAll ( ".mermaid" ) . forEach ( diagram => {
326+ const original = diagram . getAttribute ( "data-original-code" ) ;
327+ if ( ! original ) return ;
328+ diagram . removeAttribute ( "data-processed" ) ;
329+ diagram . textContent = original ;
330+ } ) ;
331+ }
332+
333+ runMermaid ( ) {
334+ if ( typeof mermaid . run === "function" ) {
335+ mermaid . run ( ) ;
336+ } else if ( typeof mermaid . init === "function" ) {
337+ mermaid . init ( undefined , ".mermaid" ) ;
338+ }
339+ }
340+
341+ renderAll ( { firstRun } = { firstRun : false } ) {
342+ if ( firstRun ) {
343+ this . initialTransform ( ) ;
344+ } else {
345+ this . resetDiagrams ( ) ;
346+ }
347+
348+ this . initMermaid ( ) ;
349+ this . runMermaid ( ) ;
350+ }
351+ }
352+
353+ if ( typeof mermaid !== "undefined" )
354+ new MermaidManager ( theme ) ;
0 commit comments