From 74bced2d35c4763024389ea76712332821f80312 Mon Sep 17 00:00:00 2001 From: binary-husky Date: Mon, 15 Jan 2024 13:41:21 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=84=91=E5=9B=BE=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- themes/mermaid_editor.js | 55 ++++++++++++++++++++++++++++++++++++++++ themes/mermaid_loader.js | 38 +++++++++++++++++++++++++-- 2 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 themes/mermaid_editor.js diff --git a/themes/mermaid_editor.js b/themes/mermaid_editor.js new file mode 100644 index 0000000..18e02a6 --- /dev/null +++ b/themes/mermaid_editor.js @@ -0,0 +1,55 @@ +import { deflate, inflate } from 'https://fastly.jsdelivr.net/gh/nodeca/pako@master/dist/pako.esm.mjs'; +import { toUint8Array, fromUint8Array, toBase64, fromBase64 } from 'https://cdn.jsdelivr.net/npm/js-base64@3.7.2/base64.mjs'; + +const base64Serde = { + serialize: (state) => { + return toBase64(state, true); + }, + deserialize: (state) => { + return fromBase64(state); + } +}; + +const pakoSerde = { + serialize: (state) => { + const data = new TextEncoder().encode(state); + const compressed = deflate(data, { level: 9 }); + return fromUint8Array(compressed, true); + }, + deserialize: (state) => { + const data = toUint8Array(state); + return inflate(data, { to: 'string' }); + } +}; + +const serdes = { + base64: base64Serde, + pako: pakoSerde +}; + +export const serializeState = (state, serde = 'pako') => { + if (!(serde in serdes)) { + throw new Error(`Unknown serde type: ${serde}`); + } + const json = JSON.stringify(state); + const serialized = serdes[serde].serialize(json); + return `${serde}:${serialized}`; +}; + +const deserializeState = (state) => { + let type, serialized; + if (state.includes(':')) { + let tempType; + [tempType, serialized] = state.split(':'); + if (tempType in serdes) { + type = tempType; + } else { + throw new Error(`Unknown serde type: ${tempType}`); + } + } else { + type = 'base64'; + serialized = state; + } + const json = serdes[type].deserialize(serialized); + return JSON.parse(json); +}; \ No newline at end of file diff --git a/themes/mermaid_loader.js b/themes/mermaid_loader.js index 2b53cce..d719f98 100644 --- a/themes/mermaid_loader.js +++ b/themes/mermaid_loader.js @@ -51,6 +51,31 @@ const uml = async className => { return text } + function createOrUpdateHyperlink(parentElement, linkText, linkHref) { + // Search for an existing anchor element within the parentElement + let existingAnchor = parentElement.querySelector("a"); + + // Check if an anchor element already exists + if (existingAnchor) { + // Update the hyperlink reference if it's different from the current one + if (existingAnchor.href !== linkHref) { + existingAnchor.href = linkHref; + } + // Update the target attribute to ensure it opens in a new tab + existingAnchor.target = '_blank'; + + // If the text must be dynamic, uncomment and use the following line: + // existingAnchor.textContent = linkText; + } else { + // If no anchor exists, create one and append it to the parentElement + let anchorElement = document.createElement("a"); + anchorElement.href = linkHref; // Set hyperlink reference + anchorElement.textContent = linkText; // Set text displayed + anchorElement.target = '_blank'; // Ensure it opens in a new tab + parentElement.appendChild(anchorElement); // Append the new anchor element to the parent + } + } + // 给出配置 Provide a default config in case one is not specified const defaultConfig = { startOnLoad: false, @@ -78,7 +103,7 @@ const uml = async className => { const blocks = document.querySelectorAll(`pre.${className}, diagram-div`); for (let i = 0; i < blocks.length; i++) { var block = blocks[i] - // const res = await mermaid.render(`_diagram_${i}`, getFromCode(parentEl)) + ///////////////////////////////////////////////////////////////// var code = getFromCode(block); let code2Element = document.createElement("code2"); // 创建一个新的code2元素 let existingCode2Element = block.querySelector("code2"); // 如果block下已存在code2元素,则获取它 @@ -96,7 +121,6 @@ const uml = async className => { code2Element.textContent = codeContent; block.appendChild(code2Element); // 将新创建的code2元素添加到block中 } - ///////////////////////////////////////////////////////////////// //尝试获取已存在的
let mermaidRender = block.querySelector(".mermaid_render"); @@ -105,6 +129,16 @@ const uml = async className => { mermaidRender.classList.add("mermaid_render"); block.appendChild(mermaidRender); // 将新创建的元素附加到block } + let pako_encode = 'pako:eNpVjzFPw0AMhf-K5QmkZmHMgEQT6FIJJLolHUziq6_k7qKLo6hK-t-50A7gyXrve37yjE1oGXM0XZgaoahwKGsPaV6qQqId1NFwhCx7Xnas4ILnywLbh12AQULfW396vPHbFYJi3q8Yg4r139ebVfzm3z0vUFZ76jX0x7_OYQoLvFb2Q9L5_45ETqm3ylBuKGsoQkHxjvBkzMRf4s6iEqPc1SfcoOPoyLbpsXlVa1RhxzXmaW3Z0NhpjbW_JpRGDZ8X32CuceQNjn1LyqWlUySHqbUb-PoDqCFfzA' + var x = { + "code": codeContent, + "mermaid": "{\n \"theme\": \"default\"\n}", + "autoSync": true, + "updateDiagram": false + }; + const Module = await import('./file=themes/mermaid_editor.js') + pako_encode = Module.serializeState(x) + createOrUpdateHyperlink(block, "点击这里编辑脑图", "https://mermaid.live/edit#"+pako_encode) ///////////////////////////////////////////////////////////////// const content = await mermaid.render(`_diagram_${i}`, code) mermaidRender.innerHTML = content