diff --git a/src/renderer/plugins/markdown-mermaid.ts b/src/renderer/plugins/markdown-mermaid.ts index d6d924be..dc28d8fc 100644 --- a/src/renderer/plugins/markdown-mermaid.ts +++ b/src/renderer/plugins/markdown-mermaid.ts @@ -22,25 +22,36 @@ const Mermaid = defineComponent({ setup (props) { const container = ref() const result = ref('') + const img = ref('') + + function getImageUrl (code?: string) { + const svg = code || container.value?.innerHTML + if (!svg) { + return '' + } + + return 'data:image/svg+xml;base64,' + strToBase64(svg) + } function render () { logger.debug('render', props.code) try { mermaid.render(`mermaid-${mid++}`, props.code, (svgCode: string) => { result.value = svgCode + img.value = getImageUrl(svgCode) }, container.value) } catch (error) { logger.error('render', error) } } - const exportData = async () => { - const svg = container.value?.innerHTML - if (!svg) { + function exportData () { + const url = getImageUrl() + if (!url) { return } - downloadDataURL(`mermaid-${Date.now()}.svg`, 'data:image/svg+xml;base64,' + strToBase64(svg)) + downloadDataURL(`mermaid-${Date.now()}.svg`, url) } const renderDebounce = debounce(render, 100) @@ -57,13 +68,17 @@ const Mermaid = defineComponent({ return () => { return h('div', { ...props.attrs, class: 'mermaid-wrapper' }, [ h('div', { class: 'mermaid-action no-print' }, [ - h('button', { class: 'small', onClick: () => exportData() }, 'SVG'), + h('button', { class: 'small', onClick: exportData }, 'SVG'), ]), h('div', { ref: container, key: props.code, - class: 'mermaid', + class: 'mermaid-container', innerHTML: result.value, + }), + h('img', { + src: img.value, + class: 'mermaid-image', }) ]) } @@ -109,13 +124,30 @@ export default { .markdown-view .markdown-body .mermaid-wrapper:hover .mermaid-action { opacity: 1; } + + .markdown-view .markdown-body .mermaid-wrapper .mermaid-container { + visibility: hidden; + } + + .markdown-view .markdown-body .mermaid-wrapper .mermaid-container > svg { + display: block; + } + + .markdown-view .markdown-body .mermaid-wrapper .mermaid-image { + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + display: block; + } `) ctx.markdown.registerPlugin(MermaidPlugin) function setTheme () { mermaid.mermaidAPI.initialize({ - theme: ctx.theme.getColorScheme() === 'dark' ? 'dark' : 'forest' + theme: ctx.theme.getColorScheme() === 'dark' ? 'dark' : 'default' }) }