Diffstat (limited to 'src/doc_mermaid_injector.js')
-rw-r--r--src/doc_mermaid_injector.js146
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])
+ }
+ }
+ }
+ })
+ }
+}