fix: repair rich editor invalid list content

This commit is contained in:
lucaronin
2026-05-17 03:06:49 +02:00
parent 28e2072f9b
commit 247c3eefb9
2 changed files with 93 additions and 8 deletions

View File

@@ -82,10 +82,12 @@ describe('installRichEditorTransformErrorRecovery', () => {
'Invalid content for node blockContainer: <paragraph("Procedures are long-running"), blockGroup(blockContainer(bulletListItem("Step")))>',
)
const { currentDoc, view } = createView(schemaError)
const recoverDocument = vi.fn()
installRichEditorTransformErrorRecovery(view)
installRichEditorTransformErrorRecovery(view, { recoverDocument })
expect(() => view.dispatch({ before: currentDoc })).not.toThrow()
expect(recoverDocument).toHaveBeenCalledTimes(1)
expect(trackEvent).toHaveBeenCalledWith('rich_editor_transform_error_recovered', {
reason: 'transform_error',
})
@@ -138,4 +140,48 @@ describe('createRichEditorTransformErrorRecoveryExtension', () => {
expect(view.dispatch).toBe(dispatch)
})
it('repairs malformed list-heavy editor documents when invalid-content dispatch fails', () => {
const schemaError = new RangeError(
'Invalid content for node blockContainer: <paragraph("Procedures are long-running"), blockGroup(blockContainer(bulletListItem("Step")))>',
)
const { currentDoc, view } = createView(schemaError)
const childListItem = {
id: 'list-child',
type: 'bulletListItem',
content: [{ type: 'text', text: 'Step', styles: {} }],
children: [],
}
const paragraph = {
id: 'paragraph-parent',
type: 'paragraph',
content: [{ type: 'text', text: 'Procedures are long-running', styles: {} }],
children: [childListItem],
}
const editor = {
document: [paragraph],
replaceBlocks: vi.fn(),
_tiptapEditor: { view },
prosemirrorView: view,
}
const extension = createRichEditorTransformErrorRecoveryExtension()({ editor: editor as never })
const controller = new AbortController()
extension.mount?.({
dom: document.createElement('div'),
root: document,
signal: controller.signal,
})
expect(() => view.dispatch({ before: currentDoc })).not.toThrow()
expect(editor.replaceBlocks).toHaveBeenCalledWith(
[paragraph],
[
{ ...paragraph, children: [] },
childListItem,
],
)
controller.abort()
})
})