diff --git a/packages/tiptap-commands/src/commands/markInputRule.js b/packages/tiptap-commands/src/commands/markInputRule.js index f9ad91c2..b8c59b29 100644 --- a/packages/tiptap-commands/src/commands/markInputRule.js +++ b/packages/tiptap-commands/src/commands/markInputRule.js @@ -1,5 +1,19 @@ import { InputRule } from 'prosemirror-inputrules' +function getMarksBetween(start, end, state) { + let marks = [] + + state.doc.nodesBetween(start, end, (node, pos) => { + marks = [...marks, ...node.marks.map(mark => ({ + start: pos, + end: pos + node.nodeSize, + mark, + }))] + }) + + return marks +} + export default function (regexp, markType, getAttrs) { return new InputRule(regexp, (state, match, start, end) => { const attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs @@ -11,11 +25,22 @@ export default function (regexp, markType, getAttrs) { if (match[m]) { const matchStart = start + match[0].indexOf(match[m - 1]) // matchEnd index is -1 because the last matching char is not yet member of transaction - // and actually never will be because it triggered the inputrule and vanishes ;) + // and actually never will be because it triggered the inputrule and vanishes ;) const matchEnd = matchStart + match[m - 1].length - 1 const textStart = matchStart + match[m - 1].lastIndexOf(match[m]) const textEnd = textStart + match[m].length + const excludedMarks = getMarksBetween(start, end, state) + .filter(item => { + const { excluded } = item.mark.type + return excluded.find(type => type.name === markType.name) + }) + .filter(item => item.end > matchStart) + + if (excludedMarks.length) { + return false + } + if (textEnd < matchEnd) { tr.delete(textEnd, matchEnd) }