diff --git a/docs/src/data/posts/commands.md b/docs/src/data/posts/commands.md index 38b48276..118d5ceb 100644 --- a/docs/src/data/posts/commands.md +++ b/docs/src/data/posts/commands.md @@ -24,6 +24,10 @@ Remove a mark in the current selection. Remove all marks in the current selection. +## .replaceWithNode() + +Replace a given range with a node. + ## .selectAll() Select the whole document. diff --git a/packages/core/src/Editor.ts b/packages/core/src/Editor.ts index 79b0373e..66b0364a 100644 --- a/packages/core/src/Editor.ts +++ b/packages/core/src/Editor.ts @@ -71,6 +71,7 @@ export class Editor extends EventEmitter { this.registerCommand('insertText', require('./commands/insertText').default) this.registerCommand('removeMark', require('./commands/removeMark').default) this.registerCommand('removeMarks', require('./commands/removeMarks').default) + this.registerCommand('replaceWithNode', require('./commands/replaceWithNode').default) this.registerCommand('selectAll', require('./commands/selectAll').default) this.registerCommand('selectParentNode', require('./commands/selectParentNode').default) this.registerCommand('setContent', require('./commands/setContent').default) diff --git a/packages/core/src/commands/replaceWithNode.ts b/packages/core/src/commands/replaceWithNode.ts new file mode 100644 index 00000000..b29d3882 --- /dev/null +++ b/packages/core/src/commands/replaceWithNode.ts @@ -0,0 +1,35 @@ +import { Editor } from '../Editor' +import { NodeType } from 'prosemirror-model' +import getNodeType from '../utils/getNodeType' + +interface Range { + from: number, + to: number, +} + +type ReplaceWithNode = ( + range: Range, + type: NodeType, + attrs: {}, +) => any + +declare module '../Editor' { + interface Editor { + replaceText: ReplaceWithNode, + } +} + +export default (next: Function, editor: Editor): ReplaceWithNode => (range, typeOrName, attrs) => { + const { view, state, schema } = editor + const { $from, $to } = state.selection + const type = getNodeType(typeOrName, schema) + const index = $from.index() + const from = range ? range.from : $from.pos + const to = range ? range.to : $to.pos + + if ($from.parent.canReplaceWith(index, index, type)) { + view.dispatch(state.tr.replaceWith(from, to, type.create(attrs))) + } + + next() +}