From f8788798b44f50444f57c43d1a1b07f4af17459e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnau=20G=C3=B3mez=20Farell?= Date: Thu, 5 Jun 2025 12:32:01 +0200 Subject: [PATCH] Merge pull request #6411 from ueberdosis/feature/emit-content-error-when-content-check-is-disabled feat: add config option to emit content error when content check is disabled --- .changeset/fresh-ads-nail.md | 5 +++ packages/core/src/Editor.ts | 1 + packages/core/src/commands/insertContentAt.ts | 39 ++++++++++++++----- packages/core/src/types.ts | 9 +++++ 4 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 .changeset/fresh-ads-nail.md diff --git a/.changeset/fresh-ads-nail.md b/.changeset/fresh-ads-nail.md new file mode 100644 index 000000000..ead724dcc --- /dev/null +++ b/.changeset/fresh-ads-nail.md @@ -0,0 +1,5 @@ +--- +"@tiptap/core": minor +--- + +Add config option to emit content error when content check is disabled diff --git a/packages/core/src/Editor.ts b/packages/core/src/Editor.ts index 7a5572146..beee261e5 100644 --- a/packages/core/src/Editor.ts +++ b/packages/core/src/Editor.ts @@ -81,6 +81,7 @@ export class Editor extends EventEmitter { enablePasteRules: true, enableCoreExtensions: true, enableContentCheck: false, + emitContentError: false, onBeforeCreate: () => null, onCreate: () => null, onUpdate: () => null, diff --git a/packages/core/src/commands/insertContentAt.ts b/packages/core/src/commands/insertContentAt.ts index 33c84524d..c5aa7186f 100644 --- a/packages/core/src/commands/insertContentAt.ts +++ b/packages/core/src/commands/insertContentAt.ts @@ -72,24 +72,43 @@ export const insertContentAt: RawCommands['insertContentAt'] = (position, value, let content: Fragment | ProseMirrorNode - try { - content = createNodeFromContent(value, editor.schema, { - parseOptions: { - preserveWhitespace: 'full', - ...options.parseOptions, - }, - errorOnInvalidContent: options.errorOnInvalidContent ?? editor.options.enableContentCheck, - }) - } catch (e) { + const emitContentError = (error: Error) => { editor.emit('contentError', { editor, - error: e as Error, + error, disableCollaboration: () => { if (editor.storage.collaboration) { editor.storage.collaboration.isDisabled = true } }, }) + } + + const parseOptions: ParseOptions = { + preserveWhitespace: 'full', + ...options.parseOptions, + } + + // If `emitContentError` is enabled, we want to check the content for errors + // but ignore them (do not remove the invalid content from the document) + if (!options.errorOnInvalidContent && !editor.options.enableContentCheck && editor.options.emitContentError) { + try { + createNodeFromContent(value, editor.schema, { + parseOptions, + errorOnInvalidContent: true, + }) + } catch (e) { + emitContentError(e as Error) + } + } + + try { + content = createNodeFromContent(value, editor.schema, { + parseOptions, + errorOnInvalidContent: options.errorOnInvalidContent ?? editor.options.enableContentCheck, + }) + } catch (e) { + emitContentError(e as Error) return false } diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 0f231190b..f01018502 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -127,6 +127,15 @@ export interface EditorOptions { * @default false */ enableContentCheck: boolean; + /** + * If `true`, the editor will emit the `contentError` event if invalid content is + * encountered but `enableContentCheck` is `false`. This lets you preserve the + * invalid editor content while still showing a warning or error message to + * the user. + * + * @default false + */ + emitContentError: boolean; onBeforeCreate: (props: EditorEvents['beforeCreate']) => void; onCreate: (props: EditorEvents['create']) => void; /**