Keep an empty doc content in editor-normal ADF, as the schema requires

This commit is contained in:
2026-10-03 16:22:54 +02:00
parent 00c89dd63b
commit 7bab478729
4 changed files with 8 additions and 5 deletions
+2 -2
View File
@@ -42,8 +42,8 @@ adjacent text nodes, an empty `attrs`, `content` or `marks`, and `-0`. Neither s
CommonMark's spelling stays wherever a document holds none of those shapes. The plain reader builds
what is written, as `markdownToAdf` does. Only the plain writer is lossy: its reduction reads and
writes editor-normal ADF — adjacent text nodes of identical marks and no attributes merged, `-0` as
`0`, and an empty `attrs`, `content` or `marks` the absent key — so two documents the editor holds
equal write the same plain markdown.
`0`, and an empty `attrs`, `content` or `marks` the absent key, but the doc's `content` — so two
documents the editor holds equal write the same plain markdown.
## `!adf:textBreak{}` parts text CommonMark would join
+1 -1
View File
@@ -58,7 +58,7 @@ export function reduceToPlain(document: AdfDocument): Result<AdfDocument> {
const raw = reduceBlocks(nodeContent(document), { depth: 0, memo: new Map(), path: [] })
return !raw.ok && raw.error.code === blocks.error.code ? raw : blocks
}
return success({ content: nodeContent(toEditorNormal({ content: blocks.value, type: 'doc', version: 1 })).slice(), type: 'doc', version: 1 })
return success(toEditorNormal({ content: blocks.value, type: 'doc', version: 1 }))
}
function reduceBlocks(nodes: readonly AdfNode[], reduction: Reduction): Result<AdfNode[]> {
+3 -2
View File
@@ -50,14 +50,15 @@ test('reads negative zero as zero, as JSON does', () => {
)
})
test('reads an empty attrs object, marks array or content array as the absent key', () => {
test('reads an empty attrs object, marks array or content array as the absent key, but on doc', () => {
const paragraph: AdfNode = { attrs: {}, content: [{ attrs: {}, marks: [], text: 'a', type: 'text' }, { marks: [{ attrs: {}, type: 'em' }], text: 'b', type: 'text' }], marks: [], type: 'paragraph' }
assert.deepEqual(toEditorNormal({ content: [paragraph, { content: [], type: 'rule' }], type: 'doc', version: 1 }), {
content: [{ content: [{ text: 'a', type: 'text' }, { marks: [{ type: 'em' }], text: 'b', type: 'text' }], type: 'paragraph' }, { type: 'rule' }],
type: 'doc',
version: 1,
})
assert.deepEqual(toEditorNormal({ content: [], type: 'doc', version: 1 }), { type: 'doc', version: 1 })
assert.deepEqual(toEditorNormal({ content: [], type: 'doc', version: 1 }), { content: [], type: 'doc', version: 1 })
assert.deepEqual(toEditorNormal({ type: 'doc', version: 1 }), { type: 'doc', version: 1 })
})
test('normalizes blocks and mark attributes nesting far past the levels a recursive walk survives', () => {
+2
View File
@@ -28,6 +28,8 @@ export function toEditorNormal(document: AdfDocument): AdfDocument {
return holder
})
}
// ADF's schema requires content on doc, so an empty one stays.
if (document.content !== undefined && normal.content === undefined) normal.content = []
return normal
}