mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 00:57:45 +00:00
Render unsupported Markdown drafts in preview mode (#33733)
- Preserve source syntax while allowing preview and PDF export - Keep Source available for editing and reserve fallback styling for neutral guidance
This commit is contained in:
@@ -286,10 +286,12 @@ describe('inline Markdown render classification', () => {
|
||||
expect(classifiers.exceedsSizeLimit).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('preserves unsupported and oversized rich-mode fallbacks', () => {
|
||||
it('renders unsupported rich drafts in preview while keeping oversized drafts in source', () => {
|
||||
const unsupported = renderEditPath({ content: '[reference]: https://example.com' })
|
||||
|
||||
expect(unsupported.model.canExportMarkdownToPdf).toBe(false)
|
||||
expect(unsupported.view.container.innerHTML).toContain('data-editor-view="preview"')
|
||||
expect(unsupported.view.container.innerHTML).not.toContain('data-editor-view="source"')
|
||||
expect(unsupported.model.canExportMarkdownToPdf).toBe(true)
|
||||
expect(unsupported.view.getByText('Reference links require source mode.')).toBeTruthy()
|
||||
expect(unsupported.view.queryByText('Open anyway')).toBeNull()
|
||||
unsupported.view.unmount()
|
||||
@@ -300,4 +302,15 @@ describe('inline Markdown render classification', () => {
|
||||
expect(oversized.view.getByText(/File is larger than the .* rich editing limit/)).toBeTruthy()
|
||||
expect(oversized.view.getByText('Open anyway')).toBeTruthy()
|
||||
})
|
||||
|
||||
it('keeps unsupported drafts editable when Source is selected', () => {
|
||||
const source = renderEditPath({
|
||||
content: '[reference]: https://example.com',
|
||||
viewMode: 'source'
|
||||
})
|
||||
|
||||
expect(source.view.container.innerHTML).toContain('data-editor-view="source"')
|
||||
expect(source.view.container.innerHTML).not.toContain('data-editor-view="preview"')
|
||||
expect(classifiers.getUnsupportedMessage).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -142,7 +142,7 @@ export function EditorMarkdownFileSurface({
|
||||
return (
|
||||
<div className="flex h-full min-h-0 flex-col">
|
||||
{shouldExplainRichFallback ? (
|
||||
<div className="border-b border-border/60 bg-amber-500/10 px-3 py-2 text-xs text-amber-950 dark:text-amber-100">
|
||||
<div className="border-b border-border/60 bg-muted/40 px-3 py-2 text-xs text-muted-foreground">
|
||||
{richModeUnsupportedMessage}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
@@ -55,6 +55,35 @@ function parseCjkFriendlyMarkdown(markdown: string) {
|
||||
}
|
||||
|
||||
describe('MarkdownPreviewBody', () => {
|
||||
it('renders forward reference links in research prose and tables without exposing definitions', () => {
|
||||
const url = 'https://github.com/example/app/blob/revision/src/app/(mobile)/language.tsx#L95'
|
||||
const markdown = [
|
||||
'# Language picker research',
|
||||
'',
|
||||
'Sources: [Picker][picker], [Automatic][], and [Settings].',
|
||||
'',
|
||||
'| App | Evidence |',
|
||||
'| --- | --- |',
|
||||
'| Example | [Picker][picker] |',
|
||||
'',
|
||||
`[picker]: ${url} "Mobile picker"`,
|
||||
'[automatic]: https://example.com/automatic',
|
||||
'[settings]: ./settings.md'
|
||||
].join('\n')
|
||||
|
||||
const html = renderToStaticMarkup(<MarkdownPreviewBody content={markdown} components={{}} />)
|
||||
|
||||
expect(html).toContain('<h1 id="language-picker-research">Language picker research</h1>')
|
||||
expect(html.split(`href="${url}"`)).toHaveLength(3)
|
||||
expect(html).toContain('title="Mobile picker"')
|
||||
expect(html).toContain('<a href="https://example.com/automatic">Automatic</a>')
|
||||
expect(html).toContain('<a href="./settings.md">Settings</a>')
|
||||
expect(html).toContain('<table>')
|
||||
expect(html).not.toContain('[picker]')
|
||||
expect(html).not.toContain('[automatic]')
|
||||
expect(html).not.toContain('[settings]')
|
||||
})
|
||||
|
||||
it.each(cjkEmphasisExamples)('renders emphasis for $name', ({ markdown, expectedHtml }) => {
|
||||
const html = renderToStaticMarkup(<MarkdownPreviewBody content={markdown} components={{}} />)
|
||||
|
||||
|
||||
@@ -163,7 +163,8 @@ describe('getEditorPanelRenderModel markdown export affordance', () => {
|
||||
editorDrafts: { '/repo/README.md': '[example]: https://example.com' }
|
||||
})
|
||||
|
||||
expect(model.canExportMarkdownToPdf).toBe(false)
|
||||
expect(model.inlineMarkdownRenderState?.renderMode).toBe('preview')
|
||||
expect(model.canExportMarkdownToPdf).toBe(true)
|
||||
})
|
||||
|
||||
it('disables rich export when a multibyte character crosses the byte limit', () => {
|
||||
|
||||
@@ -32,13 +32,23 @@ describe('getMarkdownRenderMode', () => {
|
||||
).toBe('preview')
|
||||
})
|
||||
|
||||
it('falls back to source mode when rich editing is unsupported', () => {
|
||||
it('renders a preview when rich editing cannot preserve the source', () => {
|
||||
expect(
|
||||
getMarkdownRenderMode({
|
||||
exceedsRichModeSizeLimit: false,
|
||||
hasRichModeUnsupportedContent: true,
|
||||
viewMode: 'rich'
|
||||
})
|
||||
).toBe('preview')
|
||||
})
|
||||
|
||||
it('keeps oversized unsupported documents in source mode', () => {
|
||||
expect(
|
||||
getMarkdownRenderMode({
|
||||
exceedsRichModeSizeLimit: true,
|
||||
hasRichModeUnsupportedContent: true,
|
||||
viewMode: 'rich'
|
||||
})
|
||||
).toBe('source')
|
||||
})
|
||||
|
||||
|
||||
@@ -30,6 +30,6 @@ export function getMarkdownRenderMode({
|
||||
return 'source'
|
||||
}
|
||||
|
||||
// Unsafe rich documents need an editable source fallback; read-only preview has its own explicit mode.
|
||||
return hasRichModeUnsupportedContent ? 'source' : 'rich-editor'
|
||||
// Preview preserves unsupported syntax; Source remains available for editing.
|
||||
return hasRichModeUnsupportedContent ? 'preview' : 'rich-editor'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user