fix: Improve behavior when using insertContent (#2147)
* check if we can replace the wrapping node by the newly inserted content
/
* we dont need this anymore
* set selection to inserted content instead of below
* improve hr cursor behavior
This commit is contained in:
@@ -45,15 +45,40 @@ export const insertContentAt: RawCommands['insertContentAt'] = (position, value,
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
const { from, to } = typeof position === 'number'
|
let { from, to } = typeof position === 'number'
|
||||||
? { from: position, to: position }
|
? { from: position, to: position }
|
||||||
: 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)
|
tr.replaceWith(from, to, content)
|
||||||
|
|
||||||
// set cursor at end of inserted content
|
// set cursor at end of inserted content
|
||||||
if (options.updateSelection) {
|
if (options.updateSelection) {
|
||||||
selectionToInsertionEnd(tr, tr.steps.length - 1, 1)
|
selectionToInsertionEnd(tr, tr.steps.length - 1, -1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,35 +45,18 @@ export const HorizontalRule = Node.create<HorizontalRuleOptions>({
|
|||||||
return {
|
return {
|
||||||
setHorizontalRule: () => ({ chain }) => {
|
setHorizontalRule: () => ({ chain }) => {
|
||||||
return 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 })
|
.insertContent({ type: this.name })
|
||||||
// add node after hr if it’s the end of the document
|
// set cursor after horizontal rule
|
||||||
.command(({ tr, dispatch }) => {
|
.command(({ tr, dispatch }) => {
|
||||||
if (dispatch) {
|
if (dispatch) {
|
||||||
const { parent, pos } = tr.selection.$from
|
const { parent, pos } = tr.selection.$from
|
||||||
const posAfter = pos + 1
|
const posAfter = pos + 1
|
||||||
const nodeAfter = tr.doc.nodeAt(posAfter)
|
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()
|
const node = parent.type.contentMatch.defaultType?.create()
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
|
|||||||
Reference in New Issue
Block a user