feat(changes): render mermaid fences in the reading mode via the shared lazy chunk

Documents containing mermaid fences now route through the editor preview chunk-resident renderer (splitMermaidBlocks detection + LazyMermaidMarkdown), so diagrams draw with zoom/pan instead of code blocks, while plain documents keep the byte-for-byte single MarkdownText pass. The lazy stub moves to a light mermaid-lazy.tsx module (re-exported from MarkdownHtml.tsx) so the core client bundle imports it without statically pulling DOMPurify/HTML analysis along. Typecheck, 4 affected suites (22 tests), and the full build pass.
This commit is contained in:
lhh010
2026-09-02 09:14:59 +08:00
parent 0142ac550b
commit 2eb9f66ce8
5 changed files with 35 additions and 8 deletions
+5 -5
View File
@@ -31,11 +31,11 @@ import type { SessionScope } from './api.ts'
import css from './sidebar.module.css'
/** The chunk-resident markdown renderer (mermaid lazy chunk), shared with the
* legacy no-HTML preview path in TextEditor. */
export const LazyMermaidMarkdown = lazyChunkComponent<MermaidMarkdownProps>(
'mermaid',
(mod) => mod.MermaidMarkdown as ComponentType<MermaidMarkdownProps> | undefined,
)
* legacy no-HTML preview path in TextEditor. Defined in mermaid-lazy.tsx (a
* light module) so core-bundle consumers can import the stub without
* dragging DOMPurify along. */
export { LazyMermaidMarkdown } from './mermaid-lazy.tsx'
import { LazyMermaidMarkdown } from './mermaid-lazy.tsx'
/** Everything the sanitizers need to resolve local media + scope the route. */
export interface MarkdownHtmlMedia {
+12 -1
View File
@@ -23,6 +23,8 @@ import { buildDiffSegments, diffLines, diffStats, parseUnifiedDiff, unifiedSegme
import { parseReadContent, parseReadLines, type FileOp } from './ops.ts'
import { rewriteLocalImageUrls } from '../markdown-images.ts'
import { markdownTextProps } from '../markdown-labels.tsx'
import { splitMermaidBlocks } from '../mermaid-blocks.ts'
import { LazyMermaidMarkdown } from '../mermaid-lazy.tsx'
import css from './changes.module.css'
import diffCss from '../diff/diff.module.css'
@@ -183,6 +185,13 @@ export function DiffPane({ target, scope, height, onHeightCommit, onClose, onExp
: ''),
[mdOp, reading, readingSrc, scope, target],
)
// Mermaid fences render through the same chunk-resident renderer the editor
// preview uses (one MarkdownText pass with the mermaid fences lifted out);
// the plain single-pass path stays byte-for-byte for documents without any.
const readingHasMermaid = useMemo(
() => (readingText !== '' ? splitMermaidBlocks(readingText).some((block) => block.kind === 'mermaid') : false),
[readingText],
)
const codeLabels = { copyLabel: t('copy'), copiedLabel: t('copied') }
// Header stats for git targets come off the parsed patch text.
@@ -310,7 +319,9 @@ export function DiffPane({ target, scope, height, onHeightCommit, onClose, onExp
? (
<div className={css.paneBody}>
<div className={css.mdBody}>
<MarkdownText {...markdownTextProps(readingText, codeLabels)} />
{readingHasMermaid
? <LazyMermaidMarkdown text={readingText} codeLabels={codeLabels} />
: <MarkdownText {...markdownTextProps(readingText, codeLabels)} />}
</div>
</div>
)
+16
View File
@@ -0,0 +1,16 @@
/**
* The chunk-resident markdown renderer (mermaid lazy chunk): a light stub
* module so core-bundle consumers (the changes tab's reading mode) can mount
* the mermaid-aware renderer without statically pulling MarkdownHtml's
* DOMPurify/HTML-analysis machinery into the core bundle. The chunk itself
* (src/client/chunks/mermaid) loads on first render via /sidebar/bundle.
*/
import type { ComponentType } from 'react'
import { lazyChunkComponent } from './lazy-chunk.tsx'
import type { MermaidMarkdownProps } from './mermaid-blocks.ts'
/** Shared with the legacy no-HTML preview path in TextEditor (re-exported). */
export const LazyMermaidMarkdown = lazyChunkComponent<MermaidMarkdownProps>(
'mermaid',
(mod) => mod.MermaidMarkdown as ComponentType<MermaidMarkdownProps> | undefined,
)