From b3a479533c19b231bf940bb3ac115e2e1cfd6a7b Mon Sep 17 00:00:00 2001 From: irof Date: Sun, 8 Feb 2026 20:10:21 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20Mermaid=E3=81=AE=E9=81=85=E5=BB=B6?= =?UTF-8?q?=E6=8F=8F=E7=94=BB=E3=81=AE=E4=B8=8D=E5=85=B7=E5=90=88=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 複数のダイアグラムがある場合に図が混ざることがあった --- .../main/resources/templates/assets/jig.js | 67 +++++++++++++++++-- 1 file changed, 61 insertions(+), 6 deletions(-) diff --git a/jig-core/src/main/resources/templates/assets/jig.js b/jig-core/src/main/resources/templates/assets/jig.js index 7e0a06cf1..ee7a3bb74 100644 --- a/jig-core/src/main/resources/templates/assets/jig.js +++ b/jig-core/src/main/resources/templates/assets/jig.js @@ -1,5 +1,9 @@ Array.from(document.getElementsByClassName("markdown")).forEach(x => x.innerHTML = marked.parse(x.innerHTML)) +if (window.mermaid) { + mermaid.initialize({startOnLoad: false, securityLevel: "loose"}); +} + function sortTable(event) { const headerColumn = event.target; const columnIndex = Array.from(headerColumn.parentNode.children).indexOf(headerColumn); @@ -84,22 +88,73 @@ function setupLazyMermaidRender() { const diagrams = Array.from(document.querySelectorAll(".mermaid")); if (diagrams.length === 0) return; - mermaid.initialize({startOnLoad: false, securityLevel: "loose"}); + const sourceMap = new WeakMap(); + const rendered = new WeakSet(); + const queued = new WeakSet(); + const renderQueue = []; + let isRendering = false; + + const processRenderQueue = () => { + if (isRendering) return; + const diagram = renderQueue.shift(); + if (!diagram) return; + isRendering = true; + + if (rendered.has(diagram)) { + isRendering = false; + processRenderQueue(); + return; + } - const renderDiagram = (diagram) => { - if (!diagram || diagram.getAttribute("data-processed") === "true") return; - mermaid.run({nodes: [diagram]}); + const source = sourceMap.get(diagram) || diagram.textContent; + if (!source) { + isRendering = false; + processRenderQueue(); + return; + } + + sourceMap.set(diagram, source); + diagram.innerHTML = source; + + const renderResult = mermaid.run({nodes: [diagram]}); + const handleFinish = () => { + rendered.add(diagram); + queued.delete(diagram); + isRendering = false; + processRenderQueue(); + }; + if (renderResult && typeof renderResult.then === "function") { + renderResult.then(handleFinish).catch(handleFinish); + } else { + handleFinish(); + } + }; + + const enqueueRender = (diagram) => { + if (!diagram) return; + if (diagram.getAttribute("data-processed") === "true") { + rendered.add(diagram); + return; + } + if (rendered.has(diagram)) return; + if (queued.has(diagram)) return; + const source = sourceMap.get(diagram) || diagram.textContent; + if (!source) return; + sourceMap.set(diagram, source); + queued.add(diagram); + renderQueue.push(diagram); + processRenderQueue(); }; if (!("IntersectionObserver" in window)) { - diagrams.forEach(renderDiagram); + diagrams.forEach(enqueueRender); return; } const observer = new IntersectionObserver((entries, currentObserver) => { entries.forEach(entry => { if (!entry.isIntersecting) return; - renderDiagram(entry.target); + enqueueRender(entry.target); currentObserver.unobserve(entry.target); }); }, {rootMargin: "200px 0px"});