diff --git a/packages/core/src/commands/updateAttributes.ts b/packages/core/src/commands/updateAttributes.ts index d6993b6d65..d894c9a0cf 100644 --- a/packages/core/src/commands/updateAttributes.ts +++ b/packages/core/src/commands/updateAttributes.ts @@ -1,4 +1,7 @@ -import { MarkType, NodeType } from '@tiptap/pm/model' +import { + Mark, MarkType, Node, NodeType, +} from '@tiptap/pm/model' +import { SelectionRange } from '@tiptap/pm/state' import { getMarkType } from '../helpers/getMarkType.js' import { getNodeType } from '../helpers/getNodeType.js' @@ -51,37 +54,49 @@ export const updateAttributes: RawCommands['updateAttributes'] = (typeOrName, at } if (dispatch) { - tr.selection.ranges.forEach(range => { + let lastPos: number | undefined + let lastNode: Node | undefined + let trimmedFrom: number + let trimmedTo: number + + tr.selection.ranges.forEach((range: SelectionRange) => { const from = range.$from.pos const to = range.$to.pos - state.doc.nodesBetween(from, to, (node, pos) => { + state.doc.nodesBetween(from, to, (node: Node, pos: number) => { if (nodeType && nodeType === node.type) { - tr.setNodeMarkup(pos, undefined, { - ...node.attrs, - ...attributes, - }) - } - - if (markType && node.marks.length) { - node.marks.forEach(mark => { - if (markType === mark.type) { - const trimmedFrom = Math.max(pos, from) - const trimmedTo = Math.min(pos + node.nodeSize, to) - - tr.addMark( - trimmedFrom, - trimmedTo, - markType.create({ - ...mark.attrs, - ...attributes, - }), - ) - } - }) + trimmedFrom = Math.max(pos, from) + trimmedTo = Math.min(pos + node.nodeSize, to) + lastPos = pos + lastNode = node } }) }) + + if (lastNode) { + + if (lastPos !== undefined) { + tr.setNodeMarkup(lastPos, undefined, { + ...lastNode.attrs, + ...attributes, + }) + } + + if (markType && lastNode.marks.length) { + lastNode.marks.forEach((mark: Mark) => { + if (markType === mark.type) { + tr.addMark( + trimmedFrom, + trimmedTo, + markType.create({ + ...mark.attrs, + ...attributes, + }), + ) + } + }) + } + } } return true