Diffstat (limited to 'src/doc_mermaid_injector.js')
| -rw-r--r-- | src/doc_mermaid_injector.js | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/src/doc_mermaid_injector.js b/src/doc_mermaid_injector.js new file mode 100644 index 0000000..5436120 --- /dev/null +++ b/src/doc_mermaid_injector.js @@ -0,0 +1,146 @@ +if(!window.__injector_global_mermaid) { + const mermaid_module = await import("https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs") + + if(!window.__injector_global_mermaid) { + window.__injector_global_mermaid = mermaid_module.default; + + const mermaid = window.__injector_global_mermaid; + + var doc_theme = localStorage.getItem("rustdoc-theme"); + + if (doc_theme === "dark" || doc_theme === "ayu") { + mermaid.initialize({theme: "dark", startOneLoad: false}); + } else { + mermaid.initialize({startOneLoad: false}); + } + + let scripts = Array + .from(document.querySelectorAll('script')) + .map(scr => scr.src); + + if (!scripts.includes('svg-pan-zoom.min.js')) { + var tag = document.createElement('script'); + tag.src = 'https://cdn.jsdelivr.net/npm/[email protected]/dist/svg-pan-zoom.min.js'; + document.getElementsByTagName('body')[0].appendChild(tag); + } + + var tag = document.createElement('style'); + tag.innerHTML = ` + svg { + border: 3px solid #85858500; + } + svg.active { + border: 3px solid #85858560; + } + svg.hovered { + border: 3px solid #85858530; + } + svg.hovered.active { + border: 3px solid #85858590; + } + ` + document.getElementsByTagName('body')[0].appendChild(tag); + + window.addEventListener('load', run_mermaid()) + } +} + +async function run_mermaid() { + const mermaid = window.__injector_global_mermaid; + + const diagrams = document.getElementsByClassName("mermaid"); + for (let i = 0; i < diagrams.length; i++) { + const diagram = diagrams.item(i); + + const text = diagram.textContent.replaceAll("\\n", "<br>"); + + diagram.innerHTML = "<svg id=\"diagram" + i + "\"></svg>" + + try { + var result = await mermaid.render("diagram" + i, text, diagram) + } catch (error) { + const error_div = diagram.children[0] + + error_div.style.height = "100%" + + const error_svg = error_div.children[0] + + error_svg.style.height = "100%" + error_svg.style.display = "block" + error_svg.style.margin = "auto" + + continue + } + console.log(result) + var { svg } = result + + diagram.innerHTML = svg; + + svg = document.getElementById("diagram" + i) + + svg.style.maxWidth = "" + svg.style.height = "100%" + svg.style.width = "100%" + svg.style.display = "block" + svg.style.cursor = "default" + + var svg_active = false; + var mouse_moved = false; + var svg_hovered = false; + + var pan_zoom; + pan_zoom = svgPanZoom("#diagram" + i, { + zoomEnabled: false, + panEnabled: false, + zoomScaleSensitivity: 0.3, + controlIconsEnabled: false, + customEventsHandler: { + init: function(options) { + function update_svg_class(){ + options.svgElement.setAttribute('class', '' + (svg_active ? 'active':'') + (svg_hovered ? ' hovered':'')) + } + + this.listeners = { + mousedown: function() { + mouse_moved = false + }, + mousemove: function() { + mouse_moved = true + }, + mouseup: function() { + if (!mouse_moved) { + if (svg_active) { + options.instance.disableZoom() + options.instance.disablePan() + svg_active = false + } else { + options.instance.enableZoom() + options.instance.enablePan() + svg_active = true + } + update_svg_class() + } + }, + mouseenter: function() { + svg_hovered = true + update_svg_class() + }, + mouseleave: function() { + svg_hovered = false + update_svg_class() + }, + } + + for (var eventName in this.listeners){ + options.svgElement.addEventListener(eventName, this.listeners[eventName]) + } + }, + destroy: function(options){ + for (var eventName in this.listeners){ + options.svgElement.removeEventListener(eventName, this.listeners[eventName]) + } + } + } + }) + } +} |