From 55d767d94cb069c445b6a3b26274bf49d15f6b29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Wed, 20 Jan 2021 20:37:53 +0100 Subject: [PATCH] add replaceRange command --- docs/src/docPages/api/commands.md | 3 ++- packages/core/src/commands/replace.ts | 24 ++++++---------------- packages/core/src/commands/replaceRange.ts | 23 +++++++++++++++++++++ packages/core/src/extensions/commands.ts | 2 ++ packages/extension-mention/src/mention.ts | 2 +- 5 files changed, 34 insertions(+), 20 deletions(-) create mode 100644 packages/core/src/commands/replaceRange.ts diff --git a/docs/src/docPages/api/commands.md b/docs/src/docPages/api/commands.md index 4762e50a..7b9e68db 100644 --- a/docs/src/docPages/api/commands.md +++ b/docs/src/docPages/api/commands.md @@ -147,7 +147,8 @@ Have a look at all of the core commands listed below. They should give you a goo | .lift() | Removes an existing wrap. | | .liftEmptyBlock() | Lift block if empty. | | .newlineInCode() | Add a newline character in code. | -| .replace() | Replaces text with a node within a range. | +| .replace() | Replaces text with a node. | +| .replaceRange() | Replaces text with a node within a range. | | .resetNodeAttributes() | Resets all node attributes to the default value. | | .selectParentNode() | Select the parent node. | | .setMark() | Add a mark with new attributes. | diff --git a/packages/core/src/commands/replace.ts b/packages/core/src/commands/replace.ts index ae29981a..1535b09e 100644 --- a/packages/core/src/commands/replace.ts +++ b/packages/core/src/commands/replace.ts @@ -1,24 +1,12 @@ import { NodeType } from 'prosemirror-model' -import getNodeType from '../helpers/getNodeType' -import { Command, Range, AnyObject } from '../types' +import { Command, AnyObject } from '../types' /** - * Replaces text with a node within a range. + * Replaces text with a node. */ -export const replace = (range: Range | null = null, typeOrName: string | NodeType, attrs: AnyObject = {}): Command => ({ tr, state, dispatch }) => { - const type = getNodeType(typeOrName, state.schema) - const { $from, $to } = state.selection - const index = $from.index() - const from = range ? range.from : $from.pos - const to = range ? range.to : $to.pos +export const replace = (typeOrName: string | NodeType, attributes: AnyObject = {}): Command => ({ state, commands }) => { + const { from, to } = state.selection + const range = { from, to } - if (!$from.parent.canReplaceWith(index, index, type)) { - return false - } - - if (dispatch) { - tr.replaceWith(from, to, type.create(attrs)) - } - - return true + return commands.replaceRange(range, typeOrName, attributes) } diff --git a/packages/core/src/commands/replaceRange.ts b/packages/core/src/commands/replaceRange.ts new file mode 100644 index 00000000..bb87a774 --- /dev/null +++ b/packages/core/src/commands/replaceRange.ts @@ -0,0 +1,23 @@ +import { NodeType } from 'prosemirror-model' +import getNodeType from '../helpers/getNodeType' +import { Command, Range, AnyObject } from '../types' + +/** + * Replaces text with a node within a range. + */ +export const replaceRange = (range: Range, typeOrName: string | NodeType, attributes: AnyObject = {}): Command => ({ tr, state, dispatch }) => { + const type = getNodeType(typeOrName, state.schema) + const { from, to } = range + const $from = tr.doc.resolve(from) + const index = $from.index() + + if (!$from.parent.canReplaceWith(index, index, type)) { + return false + } + + if (dispatch) { + tr.replaceWith(from, to, type.create(attributes)) + } + + return true +} diff --git a/packages/core/src/extensions/commands.ts b/packages/core/src/extensions/commands.ts index c52f3da1..117b5708 100644 --- a/packages/core/src/extensions/commands.ts +++ b/packages/core/src/extensions/commands.ts @@ -18,6 +18,7 @@ import * as liftEmptyBlock from '../commands/liftEmptyBlock' import * as liftListItem from '../commands/liftListItem' import * as newlineInCode from '../commands/newlineInCode' import * as replace from '../commands/replace' +import * as replaceRange from '../commands/replaceRange' import * as resetNodeAttributes from '../commands/resetNodeAttributes' import * as scrollIntoView from '../commands/scrollIntoView' import * as selectAll from '../commands/selectAll' @@ -65,6 +66,7 @@ export const Commands = Extension.create({ ...liftListItem, ...newlineInCode, ...replace, + ...replaceRange, ...resetNodeAttributes, ...scrollIntoView, ...selectAll, diff --git a/packages/extension-mention/src/mention.ts b/packages/extension-mention/src/mention.ts index d4f884ff..b5db04f4 100644 --- a/packages/extension-mention/src/mention.ts +++ b/packages/extension-mention/src/mention.ts @@ -19,7 +19,7 @@ export const Mention = Node.create({ editor .chain() .focus() - .replace(range, 'mention', attributes) + .replaceRange(range, 'mention', attributes) .insertText(' ') .run() },