mirror of
https://github.com/wu736139669/hapi.git
synced 2026-11-07 01:21:37 +00:00
* feat(web): markdown Source | Preview toggle in session file pane Add Source | Preview toggle for .md/.mdx files in the session file route, defaulting to preview with localStorage persistence. Reuse chat markdown pipeline via MarkdownRenderer standalone mode (no assistant-ui thread). Includes unit tests, Playwright smoke, and e2e fixture. Closes tiann/hapi#954 Co-authored-by: Cursor <cursoragent@cursor.com> * fix(web): cast standalone MarkdownRenderer components for react-markdown Soup verify gate: defaultComponents merge type is wider than react-markdown Components; standalone file-pane path needs explicit cast. * fix(web): route file-pane markdown fences through SyntaxHighlighter Standalone file preview now mirrors chat code-block rendering: fenced blocks use SyntaxHighlighter and MARKDOWN_COMPONENTS_BY_LANGUAGE (mermaid included) without requiring ThreadPrimitive context. Addresses HAPI Bot Major on tiann/hapi#957. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(web): detect fenced vs inline code in standalone markdown preview Move block detection to the pre override (react-markdown v10 does not pass inline to custom code components). Add inline-code regression test. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
37 lines
1.4 KiB
TypeScript
37 lines
1.4 KiB
TypeScript
import { beforeEach, describe, expect, it } from 'vitest'
|
|
import {
|
|
DEFAULT_MARKDOWN_PREVIEW_MODE,
|
|
MARKDOWN_PREVIEW_MODE_STORAGE_KEY,
|
|
getInitialMarkdownPreviewMode,
|
|
isMarkdownFile,
|
|
persistMarkdownPreviewMode,
|
|
} from './file-markdown-preview'
|
|
|
|
describe('file-markdown-preview helpers', () => {
|
|
beforeEach(() => {
|
|
window.localStorage.clear()
|
|
})
|
|
|
|
it('detects markdown file extensions', () => {
|
|
expect(isMarkdownFile('README.md')).toBe(true)
|
|
expect(isMarkdownFile('docs/guide/page.mdx')).toBe(true)
|
|
expect(isMarkdownFile('src/file.ts')).toBe(false)
|
|
expect(isMarkdownFile('noext')).toBe(false)
|
|
})
|
|
|
|
it('defaults to preview when storage is missing or invalid', () => {
|
|
expect(getInitialMarkdownPreviewMode()).toBe(DEFAULT_MARKDOWN_PREVIEW_MODE)
|
|
window.localStorage.setItem(MARKDOWN_PREVIEW_MODE_STORAGE_KEY, 'nope')
|
|
expect(getInitialMarkdownPreviewMode()).toBe(DEFAULT_MARKDOWN_PREVIEW_MODE)
|
|
})
|
|
|
|
it('reads and persists a valid preview mode', () => {
|
|
persistMarkdownPreviewMode('source')
|
|
expect(getInitialMarkdownPreviewMode()).toBe('source')
|
|
|
|
persistMarkdownPreviewMode('preview')
|
|
expect(window.localStorage.getItem(MARKDOWN_PREVIEW_MODE_STORAGE_KEY)).toBeNull()
|
|
expect(getInitialMarkdownPreviewMode()).toBe(DEFAULT_MARKDOWN_PREVIEW_MODE)
|
|
})
|
|
})
|