diff --git a/packages/core/src/commands/insertContent.ts b/packages/core/src/commands/insertContent.ts index 47ad19be..ac28af3c 100644 --- a/packages/core/src/commands/insertContent.ts +++ b/packages/core/src/commands/insertContent.ts @@ -1,5 +1,3 @@ -import createNodeFromContent from '../helpers/createNodeFromContent' -import selectionToInsertionEnd from '../helpers/selectionToInsertionEnd' import { Command, RawCommands, Content } from '../types' declare module '@tiptap/core' { @@ -13,25 +11,6 @@ declare module '@tiptap/core' { } } -export const insertContent: RawCommands['insertContent'] = value => ({ tr, dispatch, editor }) => { - if (dispatch) { - const content = createNodeFromContent(value, editor.schema) - - if (typeof content === 'string') { - tr.insertText(content) - tr.scrollIntoView() - - return true - } - - if (!tr.selection.empty) { - tr.deleteSelection() - } - - tr.insert(tr.selection.anchor, content) - selectionToInsertionEnd(tr, tr.steps.length - 1, -1) - tr.scrollIntoView() - } - - return true +export const insertContent: RawCommands['insertContent'] = value => ({ tr, commands }) => { + return commands.insertContentAt({ from: tr.selection.from, to: tr.selection.to }, value) } diff --git a/packages/core/src/commands/insertContentAt.ts b/packages/core/src/commands/insertContentAt.ts new file mode 100644 index 00000000..14b2ab26 --- /dev/null +++ b/packages/core/src/commands/insertContentAt.ts @@ -0,0 +1,39 @@ +import createNodeFromContent from '../helpers/createNodeFromContent' +import selectionToInsertionEnd from '../helpers/selectionToInsertionEnd' +import { + Command, RawCommands, Content, Range, +} from '../types' + +declare module '@tiptap/core' { + interface Commands { + insertContentAt: { + /** + * Insert a node or string of HTML at the current position. + */ + insertContentAt: (range: Range, value: Content) => Command, + } + } +} + +export const insertContentAt: RawCommands['insertContentAt'] = (range, value) => ({ tr, dispatch, editor }) => { + if (dispatch) { + const content = createNodeFromContent(value, editor.schema) + + if (typeof content === 'string') { + tr.insertText(content) + tr.scrollIntoView() + + return true + } + + if (!tr.selection.empty) { + tr.deleteRange(range.from, range.to) + } + + tr.insert(range.from, content) + selectionToInsertionEnd(tr, tr.steps.length - 1, -1) + tr.scrollIntoView() + } + + return true +} diff --git a/packages/core/src/extensions/commands.ts b/packages/core/src/extensions/commands.ts index be1c57db..ea8dfb29 100644 --- a/packages/core/src/extensions/commands.ts +++ b/packages/core/src/extensions/commands.ts @@ -12,6 +12,7 @@ import * as extendMarkRange from '../commands/extendMarkRange' import * as first from '../commands/first' import * as focus from '../commands/focus' import * as insertContent from '../commands/insertContent' +import * as insertContentAt from '../commands/insertContentAt' import * as insertHTML from '../commands/insertHTML' import * as insertNode from '../commands/insertNode' import * as insertText from '../commands/insertText' @@ -64,6 +65,7 @@ export { extendMarkRange } export { first } export { focus } export { insertContent } +export { insertContentAt } export { insertHTML } export { insertNode } export { insertText } @@ -121,6 +123,7 @@ export const Commands = Extension.create({ ...first, ...focus, ...insertContent, + ...insertContentAt, ...insertHTML, ...insertNode, ...insertText,