11/**
22 * Mermaid Diagram Fullscreen Viewer
33 *
4- * Uses the native Fullscreen API on the .mermaid container.
5- * Works regardless of how Mermaid renders (SVG, canvas, shadow DOM).
6- * The browser fullscreens whatever is visually rendered in the element.
4+ * Wraps the .mermaid element in a temporary fullscreen container
5+ * with a close button. On exit, the element is moved back.
76 *
8- * Zoom: use browser native zoom (Ctrl+/Ctrl - or pinch on mobile).
9- * Exit: Esc key or swipe down on mobile .
7+ * Zoom: browser native (Ctrl+/- or pinch on mobile).
8+ * Exit: Close button, Esc key, or browser fullscreen controls .
109 */
1110
1211function openMermaidFullscreen ( btnEl ) {
@@ -16,13 +15,16 @@ function openMermaidFullscreen(btnEl) {
1615 while ( el && ! ( el . classList && el . classList . contains ( "mermaid" ) ) ) {
1716 el = el . previousElementSibling ;
1817 }
18+ if ( ! el ) return ;
1919
20- if ( ! el ) {
21- console . warn ( "[diagram-fullscreen] No .mermaid element found" ) ;
22- return ;
23- }
20+ // Remember position for restoring later
21+ var originalParent = el . parentNode ;
22+ var originalNext = el . nextSibling ;
23+
24+ // Build fullscreen wrapper
25+ var wrapper = document . createElement ( "div" ) ;
26+ wrapper . className = "mermaid-fs-wrapper" ;
2427
25- // Add close button inside the element
2628 var closeBtn = document . createElement ( "button" ) ;
2729 closeBtn . className = "mermaid-close-btn" ;
2830 closeBtn . setAttribute ( "aria-label" , "Exit fullscreen" ) ;
@@ -31,30 +33,28 @@ function openMermaidFullscreen(btnEl) {
3133 if ( document . exitFullscreen ) document . exitFullscreen ( ) ;
3234 else if ( document . webkitExitFullscreen ) document . webkitExitFullscreen ( ) ;
3335 } ) ;
34- el . appendChild ( closeBtn ) ;
3536
36- // Enter fullscreen
37- el . classList . add ( "mermaid--fullscreen" ) ;
37+ // Move .mermaid into wrapper, add close button
38+ wrapper . appendChild ( closeBtn ) ;
39+ originalParent . insertBefore ( wrapper , originalNext ) ;
40+ wrapper . appendChild ( el ) ;
3841
39- var fsMethod = el . requestFullscreen || el . webkitRequestFullscreen || el . msRequestFullscreen ;
42+ // Enter fullscreen on the wrapper
43+ var fsMethod = wrapper . requestFullscreen || wrapper . webkitRequestFullscreen ;
4044 if ( fsMethod ) {
41- fsMethod . call ( el ) . catch ( function ( err ) {
42- console . warn ( "[diagram-fullscreen] Fullscreen request failed:" , err ) ;
43- el . classList . remove ( "mermaid--fullscreen" ) ;
44- el . removeChild ( closeBtn ) ;
45+ fsMethod . call ( wrapper ) . catch ( function ( ) {
46+ // Fullscreen failed — restore DOM
47+ originalParent . insertBefore ( el , wrapper ) ;
48+ originalParent . removeChild ( wrapper ) ;
4549 } ) ;
46- } else {
47- console . warn ( "[diagram-fullscreen] Fullscreen API not supported" ) ;
48- el . classList . remove ( "mermaid--fullscreen" ) ;
49- el . removeChild ( closeBtn ) ;
5050 }
5151
52- // Clean up when exiting fullscreen
52+ // Restore DOM when exiting fullscreen
5353 function onFsChange ( ) {
5454 var fsEl = document . fullscreenElement || document . webkitFullscreenElement ;
5555 if ( ! fsEl ) {
56- el . classList . remove ( "mermaid--fullscreen" ) ;
57- if ( closeBtn . parentNode ) closeBtn . parentNode . removeChild ( closeBtn ) ;
56+ originalParent . insertBefore ( el , wrapper ) ;
57+ if ( wrapper . parentNode ) wrapper . parentNode . removeChild ( wrapper ) ;
5858 document . removeEventListener ( "fullscreenchange" , onFsChange ) ;
5959 document . removeEventListener ( "webkitfullscreenchange" , onFsChange ) ;
6060 }
0 commit comments