mirror of
https://github.com/ueberdosis/tiptap.git
synced 2025-06-07 09:25:29 +08:00
feat: add config option to emit content error when content check is disabled
This commit is contained in:
parent
f750c521a7
commit
1a5c5f866e
@ -81,6 +81,7 @@ export class Editor extends EventEmitter<EditorEvents> {
|
||||
enablePasteRules: true,
|
||||
enableCoreExtensions: true,
|
||||
enableContentCheck: false,
|
||||
emitContentError: false,
|
||||
onBeforeCreate: () => null,
|
||||
onCreate: () => null,
|
||||
onUpdate: () => null,
|
||||
|
@ -72,6 +72,18 @@ export const insertContentAt: RawCommands['insertContentAt'] = (position, value,
|
||||
|
||||
let content: Fragment | ProseMirrorNode
|
||||
|
||||
const emitContentError = (error: Error) => {
|
||||
editor.emit('contentError', {
|
||||
editor,
|
||||
error,
|
||||
disableCollaboration: () => {
|
||||
if (editor.storage.collaboration) {
|
||||
editor.storage.collaboration.isDisabled = true
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
try {
|
||||
content = createNodeFromContent(value, editor.schema, {
|
||||
parseOptions: {
|
||||
@ -79,17 +91,10 @@ export const insertContentAt: RawCommands['insertContentAt'] = (position, value,
|
||||
...options.parseOptions,
|
||||
},
|
||||
errorOnInvalidContent: options.errorOnInvalidContent ?? editor.options.enableContentCheck,
|
||||
onIgnoredError: editor.options.emitContentError ? emitContentError : undefined,
|
||||
})
|
||||
} catch (e) {
|
||||
editor.emit('contentError', {
|
||||
editor,
|
||||
error: e as Error,
|
||||
disableCollaboration: () => {
|
||||
if (editor.storage.collaboration) {
|
||||
editor.storage.collaboration.isDisabled = true
|
||||
}
|
||||
},
|
||||
})
|
||||
emitContentError(e as Error)
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,13 @@ export type CreateNodeFromContentOptions = {
|
||||
slice?: boolean
|
||||
parseOptions?: ParseOptions
|
||||
errorOnInvalidContent?: boolean
|
||||
/**
|
||||
* Runs if a content is invalid and an error would have been thrown, but
|
||||
* `errorOnInvalidContent` is `false` so the invalid content is ignored.
|
||||
*
|
||||
* @param error The error that was not thrown
|
||||
*/
|
||||
onIgnoredError?: (error: Error) => void
|
||||
}
|
||||
|
||||
/**
|
||||
@ -56,11 +63,16 @@ export function createNodeFromContent(
|
||||
|
||||
return node
|
||||
} catch (error) {
|
||||
if (options.errorOnInvalidContent) {
|
||||
throw new Error('[tiptap error]: Invalid JSON content', { cause: error as Error })
|
||||
}
|
||||
const thrownError = new Error('[tiptap error]: Invalid JSON content', { cause: error as Error })
|
||||
|
||||
console.warn('[tiptap warn]: Invalid content.', 'Passed value:', content, 'Error:', error)
|
||||
if (options.errorOnInvalidContent) {
|
||||
throw thrownError
|
||||
}
|
||||
if (options.onIgnoredError) {
|
||||
options.onIgnoredError(thrownError)
|
||||
} else {
|
||||
console.warn('[tiptap warn]: Invalid content.', 'Passed value:', content, 'Error:', error)
|
||||
}
|
||||
|
||||
return createNodeFromContent('', schema, options)
|
||||
}
|
||||
@ -105,8 +117,15 @@ export function createNodeFromContent(
|
||||
DOMParser.fromSchema(contentCheckSchema).parse(elementFromString(content), options.parseOptions)
|
||||
}
|
||||
|
||||
if (options.errorOnInvalidContent && hasInvalidContent) {
|
||||
throw new Error('[tiptap error]: Invalid HTML content', { cause: new Error(`Invalid element found: ${invalidContent}`) })
|
||||
if (hasInvalidContent) {
|
||||
const thrownError = new Error('[tiptap error]: Invalid HTML content', { cause: new Error(`Invalid element found: ${invalidContent}`) })
|
||||
|
||||
if (options.errorOnInvalidContent) {
|
||||
throw thrownError
|
||||
} else if (options.onIgnoredError) {
|
||||
options.onIgnoredError(thrownError)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,6 +127,15 @@ export interface EditorOptions {
|
||||
* @default false
|
||||
*/
|
||||
enableContentCheck: boolean;
|
||||
/**
|
||||
* If `true`, the editor will emit the `contentError` event 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;
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user