diff --git a/packages/core/src/ExtensionManager.ts b/packages/core/src/ExtensionManager.ts index c1c6631d..7284d75c 100644 --- a/packages/core/src/ExtensionManager.ts +++ b/packages/core/src/ExtensionManager.ts @@ -11,6 +11,7 @@ import getNodeType from './helpers/getNodeType' import splitExtensions from './helpers/splitExtensions' import getAttributesFromExtensions from './helpers/getAttributesFromExtensions' import getRenderedAttributes from './helpers/getRenderedAttributes' +import callOrReturn from './utilities/callOrReturn' export default class ExtensionManager { @@ -20,6 +21,8 @@ export default class ExtensionManager { extensions: Extensions + splittableMarks: string[] = [] + constructor(extensions: Extensions, editor: Editor) { this.editor = editor this.extensions = extensions @@ -32,6 +35,14 @@ export default class ExtensionManager { type: getSchemaTypeByName(extension.config.name, this.schema), } + if (extension.type === 'mark') { + const keepOnSplit = callOrReturn(extension.config.keepOnSplit, context) ?? true + + if (keepOnSplit) { + this.splittableMarks.push(extension.config.name) + } + } + if (typeof extension.config.onCreate === 'function') { this.editor.on('create', extension.config.onCreate.bind(context)) } diff --git a/packages/core/src/Mark.ts b/packages/core/src/Mark.ts index 46f89072..7986b5df 100644 --- a/packages/core/src/Mark.ts +++ b/packages/core/src/Mark.ts @@ -191,6 +191,11 @@ declare module '@tiptap/core' { type: MarkType, }) => void) | null, + /** + * Keep mark after split node + */ + keepOnSplit?: boolean | (() => boolean), + /** * Inclusive */ diff --git a/packages/core/src/commands/splitBlock.ts b/packages/core/src/commands/splitBlock.ts index edff1e02..af66133d 100644 --- a/packages/core/src/commands/splitBlock.ts +++ b/packages/core/src/commands/splitBlock.ts @@ -15,12 +15,14 @@ function defaultBlockAt(match: ContentMatch) { return null } -function ensureMarks(state: EditorState) { +function ensureMarks(state: EditorState, splittableMarks?: string[]) { const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()) if (marks) { - state.tr.ensureMarks(marks) + const filteredMarks = marks.filter(mark => splittableMarks?.includes(mark.type.name)) + + state.tr.ensureMarks(filteredMarks) } } @@ -57,7 +59,7 @@ export const splitBlock: RawCommands['splitBlock'] = ({ keepMarks = true } = {}) if (dispatch) { if (keepMarks) { - ensureMarks(state) + ensureMarks(state, editor.extensionManager.splittableMarks) } tr.split($from.pos).scrollIntoView() @@ -118,7 +120,7 @@ export const splitBlock: RawCommands['splitBlock'] = ({ keepMarks = true } = {}) } if (keepMarks) { - ensureMarks(state) + ensureMarks(state, editor.extensionManager.splittableMarks) } tr.scrollIntoView()