diff --git a/packages/core/src/commands/insertContentAt.ts b/packages/core/src/commands/insertContentAt.ts index ea875a89..10f1f69f 100644 --- a/packages/core/src/commands/insertContentAt.ts +++ b/packages/core/src/commands/insertContentAt.ts @@ -45,15 +45,40 @@ export const insertContentAt: RawCommands['insertContentAt'] = (position, value, return true } - const { from, to } = typeof position === 'number' + let { from, to } = typeof position === 'number' ? { from: position, to: position } : position + let isOnlyBlockContent = true + + content.forEach(node => { + isOnlyBlockContent = isOnlyBlockContent + ? node.isBlock + : false + }) + + // check if we can replace the wrapping node by + // the newly inserted content + // example: + // replace an empty paragraph by an inserted image + // instead of inserting the image below the paragraph + if (from === to && isOnlyBlockContent) { + const $from = tr.doc.resolve(from) + const isEmptyTextBlock = $from.parent.isTextblock + && !$from.parent.type.spec.code + && !$from.parent.textContent + + if (isEmptyTextBlock) { + from -= 1 + to += 1 + } + } + tr.replaceWith(from, to, content) // set cursor at end of inserted content if (options.updateSelection) { - selectionToInsertionEnd(tr, tr.steps.length - 1, 1) + selectionToInsertionEnd(tr, tr.steps.length - 1, -1) } } diff --git a/packages/extension-horizontal-rule/src/horizontal-rule.ts b/packages/extension-horizontal-rule/src/horizontal-rule.ts index c82ab053..6f583e1f 100644 --- a/packages/extension-horizontal-rule/src/horizontal-rule.ts +++ b/packages/extension-horizontal-rule/src/horizontal-rule.ts @@ -45,35 +45,18 @@ export const HorizontalRule = Node.create({ return { setHorizontalRule: () => ({ chain }) => { return chain() - // remove node before hr if it’s an empty text block - .command(({ tr, dispatch }) => { - const { selection } = tr - const { empty, $anchor } = selection - const isEmptyTextBlock = $anchor.parent.isTextblock - && !$anchor.parent.type.spec.code - && !$anchor.parent.textContent - - if (!empty || !isEmptyTextBlock || !dispatch) { - return true - } - - const from = $anchor.before() - const to = $anchor.start() - - tr.deleteRange(from, to) - tr.setSelection(TextSelection.create(tr.doc, from)) - - return true - }) .insertContent({ type: this.name }) - // add node after hr if it’s the end of the document + // set cursor after horizontal rule .command(({ tr, dispatch }) => { if (dispatch) { const { parent, pos } = tr.selection.$from const posAfter = pos + 1 const nodeAfter = tr.doc.nodeAt(posAfter) - if (!nodeAfter) { + if (nodeAfter) { + tr.setSelection(TextSelection.create(tr.doc, posAfter)) + } else { + // add node after horizontal rule if it’s the end of the document const node = parent.type.contentMatch.defaultType?.create() if (node) {