Files
cleveragents-core/docs/javascripts/diagram-lightbox.js
T

123 lines
3.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Diagram Lightbox — fullscreen viewer for Kroki-rendered diagrams.
*
* Behaviour:
* - Clicking any Kroki diagram (<img alt="Kroki">) opens a fullscreen
* overlay showing the diagram at maximum viewport size.
* - The overlay has an X close button in the top-right corner.
* - Pressing Escape or clicking the backdrop closes the overlay.
* - Works with mkdocs-material instant-loading / SPA navigation.
*/
(function () {
"use strict";
/** The overlay element (created once, reused). */
var overlay = null;
/** The <img> inside the overlay. */
var overlayImg = null;
/** The close button. */
var closeBtn = null;
/**
* Build the lightbox DOM elements and append to <body>.
* Called once on first use.
*/
function ensureOverlay() {
if (overlay) return;
overlay = document.createElement("div");
overlay.className = "diagram-lightbox";
overlay.setAttribute("role", "dialog");
overlay.setAttribute("aria-modal", "true");
overlay.setAttribute("aria-label", "Diagram fullscreen view");
overlayImg = document.createElement("img");
overlayImg.alt = "Diagram fullscreen";
closeBtn = document.createElement("button");
closeBtn.className = "diagram-lightbox-close";
closeBtn.setAttribute("aria-label", "Close fullscreen diagram");
closeBtn.innerHTML = "&#215;"; // × character
closeBtn.type = "button";
overlay.appendChild(overlayImg);
overlay.appendChild(closeBtn);
document.body.appendChild(overlay);
// Close on button click
closeBtn.addEventListener("click", function (e) {
e.stopPropagation();
closeLightbox();
});
// Close on backdrop click (but not on the image itself)
overlay.addEventListener("click", function (e) {
if (e.target === overlay) {
closeLightbox();
}
});
// Close on Escape key
document.addEventListener("keydown", function (e) {
if (e.key === "Escape" && overlay.classList.contains("active")) {
closeLightbox();
}
});
}
/**
* Open the lightbox with the given image source.
*/
function openLightbox(src) {
ensureOverlay();
overlayImg.src = src;
overlay.classList.add("active");
// Prevent background scrolling
document.body.style.overflow = "hidden";
// Move focus to close button for accessibility
closeBtn.focus();
}
/**
* Close the lightbox.
*/
function closeLightbox() {
if (!overlay) return;
overlay.classList.remove("active");
document.body.style.overflow = "";
}
/**
* Attach click handlers to all Kroki diagram images on the page.
* Safe to call multiple times (skips already-bound images).
*/
function bindDiagrams() {
var imgs = document.querySelectorAll('img[alt="Kroki"]');
imgs.forEach(function (img) {
if (img.dataset.lightboxBound) return;
img.dataset.lightboxBound = "1";
img.addEventListener("click", function () {
openLightbox(img.src);
});
});
}
// ── Bootstrap ─────────────────────────────────────────────────────────
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", bindDiagrams);
} else {
bindDiagrams();
}
// Re-bind after instant navigation (mkdocs-material SPA mode)
if (typeof document$ !== "undefined") {
document$.subscribe(function () {
bindDiagrams();
});
}
})();