mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 08:02:28 +00:00
fix(editor): keep rich mode for documents with details blocks
The markdown serializer always injected class="orca-details" into saved <details> tags. The rich-mode round-trip check compares the serialized output against the source's literal opening tag, so any user-authored <details> without that class failed the comparison and fell back to Source mode, making the details extension unreachable from a file. The class is already applied to the rendered DOM node independently, so the serializer no longer needs to write it into the markdown source.
This commit is contained in:
committed by
Neil
parent
be766569bd
commit
68cf9ea08a
@@ -78,8 +78,11 @@ export function detailsBodyHtmlToMarkdown(body: string): string {
|
||||
.trim()
|
||||
}
|
||||
|
||||
// Why: the styling class is applied to the rendered DOM node independently
|
||||
// (OrcaDetails' HTMLAttributes config), so writing it into the markdown
|
||||
// source would rewrite a user's plain `<details>` on every save.
|
||||
export function renderDetailsAttributes(attrs: Record<string, unknown> | undefined): string {
|
||||
const attributes = ['class="orca-details"']
|
||||
const attributes: string[] = []
|
||||
|
||||
const variant = parseToggleHeadingVariant(attrs?.variant)
|
||||
if (variant) {
|
||||
|
||||
@@ -168,6 +168,58 @@ describe('getMarkdownRichModeUnsupportedMessage', () => {
|
||||
expect(usedGlobalHtmlFragmentMatch).toBe(false)
|
||||
})
|
||||
|
||||
it('allows a minimal bare details block with no pre-existing styling class', () => {
|
||||
expect(
|
||||
getMarkdownRichModeUnsupportedMessage('<details><summary>x</summary>\n\nbody\n\n</details>\n')
|
||||
).toBeNull()
|
||||
})
|
||||
|
||||
it('allows a minimal bare details block with the open attribute', () => {
|
||||
expect(
|
||||
getMarkdownRichModeUnsupportedMessage(
|
||||
'<details open><summary>x</summary>\n\nbody\n\n</details>\n'
|
||||
)
|
||||
).toBeNull()
|
||||
})
|
||||
|
||||
it('allows a document with front matter, prose, and two details blocks', () => {
|
||||
const content = [
|
||||
'---',
|
||||
'title: Details Disclosure Test',
|
||||
'---',
|
||||
'',
|
||||
'# Heading',
|
||||
'',
|
||||
'Some prose before the first toggle.',
|
||||
'',
|
||||
'<details>',
|
||||
'<summary>First toggle</summary>',
|
||||
'',
|
||||
'**Bold text** and a [link](./target%20file.md).',
|
||||
'',
|
||||
'- one',
|
||||
'- two',
|
||||
'',
|
||||
'```ts',
|
||||
'const answer = 42',
|
||||
'```',
|
||||
'',
|
||||
'</details>',
|
||||
'',
|
||||
'A paragraph between the two toggles.',
|
||||
'',
|
||||
'<details open>',
|
||||
'<summary>Second toggle</summary>',
|
||||
'',
|
||||
'Short body.',
|
||||
'',
|
||||
'</details>',
|
||||
''
|
||||
].join('\n')
|
||||
|
||||
expect(getMarkdownRichModeUnsupportedMessage(content)).toBeNull()
|
||||
})
|
||||
|
||||
it('keeps unsupported content blocked when it also exceeds the size limit', () => {
|
||||
const content = `${'a'.repeat(RICH_MARKDOWN_MAX_SIZE_BYTES + 1)}<Widget />`
|
||||
|
||||
|
||||
@@ -282,8 +282,9 @@ const OrcaDetails = Details.extend({
|
||||
)
|
||||
const body = helpers.renderChildren(content?.content ?? [], '\n\n').trim()
|
||||
const attrs = renderDetailsAttributes(node.attrs)
|
||||
const openingTag = attrs ? `<details ${attrs}>` : '<details>'
|
||||
|
||||
return `<details ${attrs}>\n<summary>${summaryText}</summary>\n\n${body}\n\n</details>`
|
||||
return `${openingTag}\n<summary>${summaryText}</summary>\n\n${body}\n\n</details>`
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -90,12 +90,12 @@ describe('rich markdown details keyboard behavior', () => {
|
||||
[
|
||||
'text toggle',
|
||||
'<details><summary>Toggle</summary><p></p></details>',
|
||||
'<details class="orca-details">\n<summary>Toggle</summary>\n\n\n\n</details>'
|
||||
'<details>\n<summary>Toggle</summary>\n\n\n\n</details>'
|
||||
],
|
||||
[
|
||||
'heading toggle',
|
||||
'<details data-orca-toggle="heading-1"><summary>Toggle</summary><p></p></details>',
|
||||
'<details class="orca-details" data-orca-toggle="heading-1">\n<summary>Toggle</summary>\n\n\n\n</details>'
|
||||
'<details data-orca-toggle="heading-1">\n<summary>Toggle</summary>\n\n\n\n</details>'
|
||||
]
|
||||
])('moves backspace from an empty %s body to the summary', (_name, content, expected) => {
|
||||
const editor = createEditor(content)
|
||||
|
||||
Reference in New Issue
Block a user