mirror of
https://github.com/iflytek/skillhub.git
synced 2026-10-14 04:08:16 +00:00
fix(frontend): clean up failed mermaid renders
Signed-off-by: dongmucat <1127093059@qq.com>
This commit is contained in:
parent
804991fe89
commit
5e5fedf22c
3 changed files with 22 additions and 6 deletions
|
|
@ -55,9 +55,11 @@ test.describe('Markdown Mermaid rendering (Real API)', () => {
|
|||
|
||||
await page.goto(`/space/${encodeURIComponent(namespace.slug)}/${encodeURIComponent(skill.slug)}`)
|
||||
|
||||
await expect(page.locator('[data-mermaid-error]')).toBeVisible()
|
||||
const source = page.locator('pre code.language-mermaid')
|
||||
await expect(source).toContainText('this is not a Mermaid diagram')
|
||||
await expect(page.locator('[data-mermaid-diagram]')).toHaveCount(0)
|
||||
await expect(page.locator('body > div[id^="dmermaid-"]')).toHaveCount(0)
|
||||
} finally {
|
||||
await builder.cleanup()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,7 +92,11 @@ describe('MarkdownRenderer Mermaid blocks', () => {
|
|||
|
||||
await waitFor(() => expect(container.querySelector('[data-testid="mermaid-svg"]')).toBeTruthy())
|
||||
|
||||
expect(mermaidInitialize).toHaveBeenCalledWith({ startOnLoad: false, securityLevel: 'strict' })
|
||||
expect(mermaidInitialize).toHaveBeenCalledWith({
|
||||
startOnLoad: false,
|
||||
securityLevel: 'strict',
|
||||
suppressErrorRendering: true,
|
||||
})
|
||||
expect(container.querySelector('[data-testid="mermaid-svg"]')?.closest('pre')).toBeNull()
|
||||
})
|
||||
|
||||
|
|
@ -103,7 +107,7 @@ describe('MarkdownRenderer Mermaid blocks', () => {
|
|||
<MarkdownRenderer content={'```mermaid\nnot a valid diagram\n```'} />,
|
||||
)
|
||||
|
||||
await waitFor(() => expect(mermaidRender).toHaveBeenCalled())
|
||||
await waitFor(() => expect(container.querySelector('[data-mermaid-error]')).toBeTruthy())
|
||||
|
||||
expect(container.querySelector('pre code')?.textContent).toContain('not a valid diagram')
|
||||
})
|
||||
|
|
|
|||
|
|
@ -28,7 +28,11 @@ let mermaidBlockSequence = 0
|
|||
|
||||
function loadMermaid(): Promise<MermaidApi> {
|
||||
mermaidPromise ??= import('mermaid').then(({ default: mermaid }) => {
|
||||
mermaid.initialize({ startOnLoad: false, securityLevel: 'strict' })
|
||||
mermaid.initialize({
|
||||
startOnLoad: false,
|
||||
securityLevel: 'strict',
|
||||
suppressErrorRendering: true,
|
||||
})
|
||||
return mermaid
|
||||
})
|
||||
|
||||
|
|
@ -60,9 +64,12 @@ function getTextContent(node: ReactNode): string {
|
|||
.join('')
|
||||
}
|
||||
|
||||
function CodeBlock({ children }: { children: ReactNode }) {
|
||||
function CodeBlock({ children, mermaidError }: { children: ReactNode; mermaidError?: boolean }) {
|
||||
return (
|
||||
<div className="my-4 rounded-lg border border-border/60 bg-secondary/30">
|
||||
<div
|
||||
className="my-4 rounded-lg border border-border/60 bg-secondary/30"
|
||||
data-mermaid-error={mermaidError || undefined}
|
||||
>
|
||||
<div className="max-w-full overflow-x-auto rounded-lg bg-background px-4 py-3">
|
||||
<pre className="m-0 min-w-max bg-transparent p-0 text-[13px] leading-6">{children}</pre>
|
||||
</div>
|
||||
|
|
@ -79,10 +86,12 @@ const MermaidBlock = memo(function MermaidBlock({ children }: MermaidBlockProps)
|
|||
const renderId = useRef(`mermaid-${++mermaidBlockSequence}`).current
|
||||
const diagramRef = useRef<HTMLDivElement>(null)
|
||||
const [svg, setSvg] = useState<string | null>(null)
|
||||
const [failed, setFailed] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
let mounted = true
|
||||
setSvg(null)
|
||||
setFailed(false)
|
||||
|
||||
enqueueMermaidRender(async () => {
|
||||
const mermaid = await loadMermaid()
|
||||
|
|
@ -96,6 +105,7 @@ const MermaidBlock = memo(function MermaidBlock({ children }: MermaidBlockProps)
|
|||
.catch(() => {
|
||||
if (mounted) {
|
||||
setSvg(null)
|
||||
setFailed(true)
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -111,7 +121,7 @@ const MermaidBlock = memo(function MermaidBlock({ children }: MermaidBlockProps)
|
|||
}, [svg])
|
||||
|
||||
if (!svg) {
|
||||
return <CodeBlock>{children}</CodeBlock>
|
||||
return <CodeBlock mermaidError={failed}>{children}</CodeBlock>
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue