40 lines
1.8 KiB
TypeScript
40 lines
1.8 KiB
TypeScript
import { nextTick } from 'vue'
|
|
import { renderMermaid } from '@/services/mermaidService'
|
|
import { t } from '@/i18n'
|
|
|
|
let previewId = 0
|
|
export function createMermaidPreview(source: string, dark: boolean, applyPreview: (value: HTMLElement) => void): HTMLElement {
|
|
// Each revision owns its element, so a slow render cannot replace newer content.
|
|
const container = document.createElement('div')
|
|
container.className = 'editor-mermaid-preview'
|
|
container.id = `editor-mermaid-preview-${++previewId}`
|
|
container.setAttribute('aria-live', 'polite')
|
|
container.textContent = t('正在渲染图表…', 'Rendering diagram…')
|
|
const publish = async () => {
|
|
await nextTick()
|
|
// Milkdown sanitizes and copies this element. Publish only if its revision
|
|
// still exists; edits, language changes and unmounts remove the old marker.
|
|
const visible = document.getElementById(container.id)
|
|
if (visible) {
|
|
// PreviewPanel copies HTML instead of retaining the supplied element.
|
|
// Update the current copy through Milkdown's reactive callback.
|
|
applyPreview(container.cloneNode(true) as HTMLElement)
|
|
}
|
|
}
|
|
void renderMermaid(source, { theme: dark ? 'dark' : 'light' }).then(result => {
|
|
if (result.warnings.length) {
|
|
container.classList.add('has-error')
|
|
container.textContent = `${t('图表语法有误,可点击编辑修改:', 'Diagram syntax error. Choose Edit to fix:')} ${result.warnings.join('\n')}`
|
|
void publish()
|
|
return
|
|
}
|
|
// Mermaid runs in strict mode; Milkdown sanitizes the preview before insertion.
|
|
container.innerHTML = result.svg
|
|
void publish()
|
|
}).catch(() => {
|
|
container.textContent = t('图表渲染失败,请点击编辑检查源码。', 'Unable to render diagram. Choose Edit to inspect the source.')
|
|
void publish()
|
|
})
|
|
return container
|
|
}
|