From 7b5880ab9eab63bf7381f21d160ec4ac81902b0d Mon Sep 17 00:00:00 2001 From: Shirasawa <764798966@qq.com> Date: Fri, 17 Apr 2026 10:44:10 +0800 Subject: [PATCH] fix: clean up Mermaid temporary DOM nodes after render failures (#23727) * fix: clean up Mermaid temporary DOM nodes after render failures * fix: prevent Mermaid temp DOM artifacts from accumulating --- src/app.css | 6 ++++++ src/lib/utils/index.ts | 28 ++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/app.css b/src/app.css index 93417b680..ac02afcb1 100644 --- a/src/app.css +++ b/src/app.css @@ -260,6 +260,12 @@ select { display: none; } +/* Hide leaked Mermaid temp containers if render cleanup misses */ +body > div[id^='dmermaid-'], +body > iframe[id^='imermaid-'] { + display: none !important; +} + .scrollbar-hidden:active::-webkit-scrollbar-thumb, .scrollbar-hidden:focus::-webkit-scrollbar-thumb, .scrollbar-hidden:hover::-webkit-scrollbar-thumb { diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts index ecaeefab0..f0feb807e 100644 --- a/src/lib/utils/index.ts +++ b/src/lib/utils/index.ts @@ -1713,13 +1713,29 @@ export const initMermaid = async () => { return mermaid; }; -export const renderMermaidDiagram = async (mermaid, code: string) => { - const parseResult = await mermaid.parse(code, { suppressErrors: false }); - if (parseResult) { - const { svg } = await mermaid.render(`mermaid-${uuidv4()}`, code); - return svg; +const cleanupMermaidTempElements = (id: string) => { + if (typeof document === 'undefined') { + return; + } + + document.getElementById(id)?.remove(); + document.getElementById(`d${id}`)?.remove(); + document.getElementById(`i${id}`)?.remove(); +}; + +export const renderMermaidDiagram = async (mermaid: typeof import('mermaid').default, code: string, renderId?: string) => { + const id = renderId ?? `mermaid-${uuidv4()}`; + try { + const parseResult = await mermaid.parse(code, { suppressErrors: false }); + if (parseResult) { + const { svg } = await mermaid.render(id, code); + return svg; + } + return ''; + } finally { + // Mermaid can leave temporary d*/i* wrappers on error paths. + cleanupMermaidTempElements(id); } - return ''; }; export const renderVegaVisualization = async (spec: string, i18n?: any) => {