diff --git a/packages/core/src/commands/clearNodes.ts b/packages/core/src/commands/clearNodes.ts index 5f90083f..e3e54e69 100644 --- a/packages/core/src/commands/clearNodes.ts +++ b/packages/core/src/commands/clearNodes.ts @@ -16,15 +16,20 @@ export const clearNodes: RawCommands['clearNodes'] = () => ({ state, tr, dispatc const { selection } = tr const { ranges } = selection - ranges.forEach(range => { - state.doc.nodesBetween(range.$from.pos, range.$to.pos, (node, pos) => { + if (!dispatch) { + return true + } + + ranges.forEach(({ $from, $to }) => { + state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => { if (node.type.isText) { return } - const $fromPos = tr.doc.resolve(tr.mapping.map(pos)) - const $toPos = tr.doc.resolve(tr.mapping.map(pos + node.nodeSize)) - const nodeRange = $fromPos.blockRange($toPos) + const { doc, mapping } = tr + const $mappedFrom = doc.resolve(mapping.map(pos)) + const $mappedTo = doc.resolve(mapping.map(pos + node.nodeSize)) + const nodeRange = $mappedFrom.blockRange($mappedTo) if (!nodeRange) { return @@ -32,13 +37,13 @@ export const clearNodes: RawCommands['clearNodes'] = () => ({ state, tr, dispatc const targetLiftDepth = liftTarget(nodeRange) - if (node.type.isTextblock && dispatch) { - const { defaultType } = $fromPos.parent.contentMatchAt($fromPos.index()) + if (node.type.isTextblock) { + const { defaultType } = $mappedFrom.parent.contentMatchAt($mappedFrom.index()) tr.setNodeMarkup(nodeRange.start, defaultType) } - if ((targetLiftDepth || targetLiftDepth === 0) && dispatch) { + if (targetLiftDepth || targetLiftDepth === 0) { tr.lift(nodeRange, targetLiftDepth) } }) diff --git a/packages/core/src/commands/setNode.ts b/packages/core/src/commands/setNode.ts index faa569a5..19a003b1 100644 --- a/packages/core/src/commands/setNode.ts +++ b/packages/core/src/commands/setNode.ts @@ -24,14 +24,17 @@ export const setNode: RawCommands['setNode'] = (typeOrName, attributes = {}) => return false } - const canSetBlock = setBlockType(type, attributes)(state) - - if (canSetBlock) { - return setBlockType(type, attributes)(state, dispatch) - } - return chain() - .clearNodes() + // try to convert node to default node if needed + .command(({ commands }) => { + const canSetBlock = setBlockType(type, attributes)(state) + + if (canSetBlock) { + return true + } + + return commands.clearNodes() + }) .command(({ state: updatedState }) => { return setBlockType(type, attributes)(updatedState, dispatch) })