@tiptap/core 2.9.1 → 2.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/Editor.d.ts.map +1 -1
  2. package/dist/EventEmitter.d.ts +1 -0
  3. package/dist/EventEmitter.d.ts.map +1 -1
  4. package/dist/Extension.d.ts +3 -3
  5. package/dist/Extension.d.ts.map +1 -1
  6. package/dist/InputRule.d.ts.map +1 -1
  7. package/dist/Mark.d.ts +3 -3
  8. package/dist/Mark.d.ts.map +1 -1
  9. package/dist/Node.d.ts +19 -3
  10. package/dist/Node.d.ts.map +1 -1
  11. package/dist/PasteRule.d.ts +1 -1
  12. package/dist/PasteRule.d.ts.map +1 -1
  13. package/dist/commands/insertContent.d.ts +2 -2
  14. package/dist/commands/insertContent.d.ts.map +1 -1
  15. package/dist/commands/insertContentAt.d.ts +2 -2
  16. package/dist/commands/insertContentAt.d.ts.map +1 -1
  17. package/dist/commands/setContent.d.ts +2 -2
  18. package/dist/commands/setContent.d.ts.map +1 -1
  19. package/dist/commands/setNode.d.ts.map +1 -1
  20. package/dist/commands/updateAttributes.d.ts.map +1 -1
  21. package/dist/helpers/createDocument.d.ts +2 -2
  22. package/dist/helpers/createDocument.d.ts.map +1 -1
  23. package/dist/helpers/createNodeFromContent.d.ts +1 -1
  24. package/dist/helpers/createNodeFromContent.d.ts.map +1 -1
  25. package/dist/helpers/getMarkRange.d.ts +17 -1
  26. package/dist/helpers/getMarkRange.d.ts.map +1 -1
  27. package/dist/helpers/getSchemaByResolvedExtensions.d.ts.map +1 -1
  28. package/dist/index.cjs +158 -44
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.js +159 -45
  31. package/dist/index.js.map +1 -1
  32. package/dist/index.umd.js +158 -44
  33. package/dist/index.umd.js.map +1 -1
  34. package/dist/inputRules/markInputRule.d.ts +1 -1
  35. package/dist/inputRules/nodeInputRule.d.ts +1 -1
  36. package/dist/inputRules/textInputRule.d.ts +1 -1
  37. package/dist/inputRules/textblockTypeInputRule.d.ts +1 -1
  38. package/dist/inputRules/wrappingInputRule.d.ts +1 -1
  39. package/dist/pasteRules/markPasteRule.d.ts +1 -1
  40. package/dist/pasteRules/nodePasteRule.d.ts +1 -1
  41. package/dist/pasteRules/textPasteRule.d.ts +1 -1
  42. package/package.json +2 -2
  43. package/src/Editor.ts +5 -8
  44. package/src/EventEmitter.ts +9 -0
  45. package/src/Extension.ts +4 -4
  46. package/src/InputRule.ts +45 -30
  47. package/src/Mark.ts +4 -4
  48. package/src/Node.ts +23 -4
  49. package/src/PasteRule.ts +67 -42
  50. package/src/commands/insertContent.ts +9 -9
  51. package/src/commands/insertContentAt.ts +11 -1
  52. package/src/commands/setContent.ts +10 -14
  53. package/src/commands/setNode.ts +9 -2
  54. package/src/commands/updateAttributes.ts +72 -12
  55. package/src/helpers/createDocument.ts +4 -2
  56. package/src/helpers/createNodeFromContent.ts +4 -1
  57. package/src/helpers/getMarkRange.ts +29 -5
  58. package/src/helpers/getSchemaByResolvedExtensions.ts +1 -0
  59. package/src/inputRules/markInputRule.ts +1 -1
  60. package/src/inputRules/nodeInputRule.ts +1 -1
  61. package/src/inputRules/textInputRule.ts +1 -1
  62. package/src/inputRules/textblockTypeInputRule.ts +1 -1
  63. package/src/inputRules/wrappingInputRule.ts +1 -1
  64. package/src/pasteRules/markPasteRule.ts +1 -1
  65. package/src/pasteRules/nodePasteRule.ts +1 -1
  66. package/src/pasteRules/textPasteRule.ts +1 -1
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Plugin, PluginKey, TextSelection, Selection, NodeSelection, EditorState } from '@tiptap/pm/state';
2
2
  import { EditorView } from '@tiptap/pm/view';
3
3
  import { keymap } from '@tiptap/pm/keymap';
4
- import { Schema, Fragment, DOMParser, DOMSerializer, Node as Node$1, Slice } from '@tiptap/pm/model';
4
+ import { Schema, DOMSerializer, Fragment, Node as Node$1, DOMParser, Slice } from '@tiptap/pm/model';
5
5
  import { liftTarget, ReplaceStep, ReplaceAroundStep, joinPoint, Transform, canSplit, canJoin, findWrapping } from '@tiptap/pm/transform';
6
6
  import { createParagraphNear as createParagraphNear$1, deleteSelection as deleteSelection$1, exitCode as exitCode$1, joinUp as joinUp$1, joinDown as joinDown$1, joinBackward as joinBackward$1, joinForward as joinForward$1, joinTextblockBackward as joinTextblockBackward$1, joinTextblockForward as joinTextblockForward$1, lift as lift$1, liftEmptyBlock as liftEmptyBlock$1, newlineInCode as newlineInCode$1, selectNodeBackward as selectNodeBackward$1, selectNodeForward as selectNodeForward$1, selectParentNode as selectParentNode$1, selectTextblockEnd as selectTextblockEnd$1, selectTextblockStart as selectTextblockStart$1, setBlockType, wrapIn as wrapIn$1 } from '@tiptap/pm/commands';
7
7
  import { liftListItem as liftListItem$1, sinkListItem as sinkListItem$1, wrapInList as wrapInList$1 } from '@tiptap/pm/schema-list';
@@ -172,6 +172,13 @@ class EventEmitter {
172
172
  }
173
173
  return this;
174
174
  }
175
+ once(event, fn) {
176
+ const onceFn = (...args) => {
177
+ this.off(event, onceFn);
178
+ fn.apply(this, args);
179
+ };
180
+ return this.on(event, onceFn);
181
+ }
175
182
  removeAllListeners() {
176
183
  this.callbacks = {};
177
184
  }
@@ -477,6 +484,7 @@ function getSchemaByResolvedExtensions(extensions, editor) {
477
484
  draggable: callOrReturn(getExtensionField(extension, 'draggable', context)),
478
485
  code: callOrReturn(getExtensionField(extension, 'code', context)),
479
486
  whitespace: callOrReturn(getExtensionField(extension, 'whitespace', context)),
487
+ linebreakReplacement: callOrReturn(getExtensionField(extension, 'linebreakReplacement', context)),
480
488
  defining: callOrReturn(getExtensionField(extension, 'defining', context)),
481
489
  isolating: callOrReturn(getExtensionField(extension, 'isolating', context)),
482
490
  attrs: Object.fromEntries(extensionAttributes.map(extensionAttribute => {
@@ -570,6 +578,14 @@ function isExtensionRulesEnabled(extension, enabled) {
570
578
  return enabled;
571
579
  }
572
580
 
581
+ function getHTMLFromFragment(fragment, schema) {
582
+ const documentFragment = DOMSerializer.fromSchema(schema).serializeFragment(fragment);
583
+ const temporaryDocument = document.implementation.createHTMLDocument();
584
+ const container = temporaryDocument.createElement('div');
585
+ container.appendChild(documentFragment);
586
+ return container.innerHTML;
587
+ }
588
+
573
589
  /**
574
590
  * Returns the text content of a resolved prosemirror position
575
591
  * @param $from The resolved position to get the text content from
@@ -699,7 +715,7 @@ function inputRulesPlugin(props) {
699
715
  init() {
700
716
  return null;
701
717
  },
702
- apply(tr, prev) {
718
+ apply(tr, prev, state) {
703
719
  const stored = tr.getMeta(plugin);
704
720
  if (stored) {
705
721
  return stored;
@@ -709,7 +725,14 @@ function inputRulesPlugin(props) {
709
725
  const isSimulatedInput = !!simulatedInputMeta;
710
726
  if (isSimulatedInput) {
711
727
  setTimeout(() => {
712
- const { from, text } = simulatedInputMeta;
728
+ let { text } = simulatedInputMeta;
729
+ if (typeof text === 'string') {
730
+ text = text;
731
+ }
732
+ else {
733
+ text = getHTMLFromFragment(Fragment.from(text), state.schema);
734
+ }
735
+ const { from } = simulatedInputMeta;
713
736
  const to = from + text.length;
714
737
  run$1({
715
738
  editor,
@@ -902,7 +925,7 @@ function isNumber(value) {
902
925
 
903
926
  /**
904
927
  * Paste rules are used to react to pasted content.
905
- * @see https://tiptap.dev/guide/custom-extensions/#paste-rules
928
+ * @see https://tiptap.dev/docs/editor/extensions/custom-extensions/extend-existing#paste-rules
906
929
  */
907
930
  class PasteRule {
908
931
  constructor(config) {
@@ -992,7 +1015,13 @@ function pasteRulesPlugin(props) {
992
1015
  let isPastedFromProseMirror = false;
993
1016
  let isDroppedFromProseMirror = false;
994
1017
  let pasteEvent = typeof ClipboardEvent !== 'undefined' ? new ClipboardEvent('paste') : null;
995
- let dropEvent = typeof DragEvent !== 'undefined' ? new DragEvent('drop') : null;
1018
+ let dropEvent;
1019
+ try {
1020
+ dropEvent = typeof DragEvent !== 'undefined' ? new DragEvent('drop') : null;
1021
+ }
1022
+ catch (e) {
1023
+ dropEvent = null;
1024
+ }
996
1025
  const processEvent = ({ state, from, to, rule, pasteEvt, }) => {
997
1026
  const tr = state.tr;
998
1027
  const chainableState = createChainableState({
@@ -1011,7 +1040,12 @@ function pasteRulesPlugin(props) {
1011
1040
  if (!handler || !tr.steps.length) {
1012
1041
  return;
1013
1042
  }
1014
- dropEvent = typeof DragEvent !== 'undefined' ? new DragEvent('drop') : null;
1043
+ try {
1044
+ dropEvent = typeof DragEvent !== 'undefined' ? new DragEvent('drop') : null;
1045
+ }
1046
+ catch (e) {
1047
+ dropEvent = null;
1048
+ }
1015
1049
  pasteEvent = typeof ClipboardEvent !== 'undefined' ? new ClipboardEvent('paste') : null;
1016
1050
  return tr;
1017
1051
  };
@@ -1060,7 +1094,14 @@ function pasteRulesPlugin(props) {
1060
1094
  }
1061
1095
  // Handle simulated paste
1062
1096
  if (isSimulatedPaste) {
1063
- const { from, text } = simulatedPasteMeta;
1097
+ let { text } = simulatedPasteMeta;
1098
+ if (typeof text === 'string') {
1099
+ text = text;
1100
+ }
1101
+ else {
1102
+ text = getHTMLFromFragment(Fragment.from(text), state.schema);
1103
+ }
1104
+ const { from } = simulatedPasteMeta;
1064
1105
  const to = from + text.length;
1065
1106
  const pasteEvt = createClipboardPasteEvent(text);
1066
1107
  return processEvent({
@@ -1657,13 +1698,33 @@ function objectIncludes(object1, object2, options = { strict: true }) {
1657
1698
 
1658
1699
  function findMarkInSet(marks, type, attributes = {}) {
1659
1700
  return marks.find(item => {
1660
- return item.type === type && objectIncludes(item.attrs, attributes);
1701
+ return (item.type === type
1702
+ && objectIncludes(
1703
+ // Only check equality for the attributes that are provided
1704
+ Object.fromEntries(Object.keys(attributes).map(k => [k, item.attrs[k]])), attributes));
1661
1705
  });
1662
1706
  }
1663
1707
  function isMarkInSet(marks, type, attributes = {}) {
1664
1708
  return !!findMarkInSet(marks, type, attributes);
1665
1709
  }
1666
- function getMarkRange($pos, type, attributes = {}) {
1710
+ /**
1711
+ * Get the range of a mark at a resolved position.
1712
+ */
1713
+ function getMarkRange(
1714
+ /**
1715
+ * The position to get the mark range for.
1716
+ */
1717
+ $pos,
1718
+ /**
1719
+ * The mark type to get the range for.
1720
+ */
1721
+ type,
1722
+ /**
1723
+ * The attributes to match against.
1724
+ * If not provided, only the first mark at the position will be matched.
1725
+ */
1726
+ attributes) {
1727
+ var _a;
1667
1728
  if (!$pos || !type) {
1668
1729
  return;
1669
1730
  }
@@ -1676,6 +1737,8 @@ function getMarkRange($pos, type, attributes = {}) {
1676
1737
  if (!start.node || !start.node.marks.some(mark => mark.type === type)) {
1677
1738
  return;
1678
1739
  }
1740
+ // Default to only matching against the first mark's attributes
1741
+ attributes = attributes || ((_a = start.node.marks[0]) === null || _a === void 0 ? void 0 : _a.attrs);
1679
1742
  // We now know that the cursor is either at the start, middle or end of a text node with the specified mark
1680
1743
  // so we can look it up on the targeted mark
1681
1744
  const mark = findMarkInSet([...start.node.marks], type, attributes);
@@ -1686,8 +1749,8 @@ function getMarkRange($pos, type, attributes = {}) {
1686
1749
  let startPos = $pos.start() + start.offset;
1687
1750
  let endIndex = startIndex + 1;
1688
1751
  let endPos = startPos + start.node.nodeSize;
1689
- findMarkInSet([...start.node.marks], type, attributes);
1690
- while (startIndex > 0 && mark.isInSet($pos.parent.child(startIndex - 1).marks)) {
1752
+ while (startIndex > 0
1753
+ && isMarkInSet([...$pos.parent.child(startIndex - 1).marks], type, attributes)) {
1691
1754
  startIndex -= 1;
1692
1755
  startPos -= $pos.parent.child(startIndex).nodeSize;
1693
1756
  }
@@ -1863,6 +1926,9 @@ function elementFromString(value) {
1863
1926
  * @returns The created Prosemirror node or fragment
1864
1927
  */
1865
1928
  function createNodeFromContent(content, schema, options) {
1929
+ if (content instanceof Node$1 || content instanceof Fragment) {
1930
+ return content;
1931
+ }
1866
1932
  options = {
1867
1933
  slice: true,
1868
1934
  parseOptions: {},
@@ -2027,6 +2093,15 @@ const insertContentAt = (position, value, options) => ({ tr, dispatch, editor })
2027
2093
  if (Array.isArray(value)) {
2028
2094
  newContent = value.map(v => v.text || '').join('');
2029
2095
  }
2096
+ else if (value instanceof Fragment) {
2097
+ let text = '';
2098
+ value.forEach(node => {
2099
+ if (node.text) {
2100
+ text += node.text;
2101
+ }
2102
+ });
2103
+ newContent = text;
2104
+ }
2030
2105
  else if (typeof value === 'object' && !!value && !!value.text) {
2031
2106
  newContent = value.text;
2032
2107
  }
@@ -2523,14 +2598,6 @@ function findParentNode(predicate) {
2523
2598
  return (selection) => findParentNodeClosestToPos(selection.$from, predicate);
2524
2599
  }
2525
2600
 
2526
- function getHTMLFromFragment(fragment, schema) {
2527
- const documentFragment = DOMSerializer.fromSchema(schema).serializeFragment(fragment);
2528
- const temporaryDocument = document.implementation.createHTMLDocument();
2529
- const container = temporaryDocument.createElement('div');
2530
- container.appendChild(documentFragment);
2531
- return container.innerHTML;
2532
- }
2533
-
2534
2601
  function getSchema(extensions, editor) {
2535
2602
  const resolvedExtensions = ExtensionManager.resolve(extensions);
2536
2603
  return getSchemaByResolvedExtensions(resolvedExtensions, editor);
@@ -3101,6 +3168,11 @@ const setMeta = (key, value) => ({ tr }) => {
3101
3168
 
3102
3169
  const setNode = (typeOrName, attributes = {}) => ({ state, dispatch, chain }) => {
3103
3170
  const type = getNodeType(typeOrName, state.schema);
3171
+ let attributesToCopy;
3172
+ if (state.selection.$anchor.sameParent(state.selection.$head)) {
3173
+ // only copy attributes if the selection is pointing to a node of the same type
3174
+ attributesToCopy = state.selection.$anchor.parent.attrs;
3175
+ }
3104
3176
  // TODO: use a fallback like insertContent?
3105
3177
  if (!type.isTextblock) {
3106
3178
  console.warn('[tiptap warn]: Currently "setNode()" only supports text block nodes.');
@@ -3109,14 +3181,14 @@ const setNode = (typeOrName, attributes = {}) => ({ state, dispatch, chain }) =>
3109
3181
  return (chain()
3110
3182
  // try to convert node to default node if needed
3111
3183
  .command(({ commands }) => {
3112
- const canSetBlock = setBlockType(type, attributes)(state);
3184
+ const canSetBlock = setBlockType(type, { ...attributesToCopy, ...attributes })(state);
3113
3185
  if (canSetBlock) {
3114
3186
  return true;
3115
3187
  }
3116
3188
  return commands.clearNodes();
3117
3189
  })
3118
3190
  .command(({ state: updatedState }) => {
3119
- return setBlockType(type, attributes)(updatedState, dispatch);
3191
+ return setBlockType(type, { ...attributesToCopy, ...attributes })(updatedState, dispatch);
3120
3192
  })
3121
3193
  .run());
3122
3194
  };
@@ -3535,21 +3607,63 @@ const updateAttributes = (typeOrName, attributes = {}) => ({ tr, state, dispatch
3535
3607
  markType = getMarkType(typeOrName, state.schema);
3536
3608
  }
3537
3609
  if (dispatch) {
3538
- tr.selection.ranges.forEach(range => {
3610
+ tr.selection.ranges.forEach((range) => {
3539
3611
  const from = range.$from.pos;
3540
3612
  const to = range.$to.pos;
3541
- state.doc.nodesBetween(from, to, (node, pos) => {
3542
- if (nodeType && nodeType === node.type) {
3543
- tr.setNodeMarkup(pos, undefined, {
3544
- ...node.attrs,
3613
+ let lastPos;
3614
+ let lastNode;
3615
+ let trimmedFrom;
3616
+ let trimmedTo;
3617
+ if (tr.selection.empty) {
3618
+ state.doc.nodesBetween(from, to, (node, pos) => {
3619
+ if (nodeType && nodeType === node.type) {
3620
+ trimmedFrom = Math.max(pos, from);
3621
+ trimmedTo = Math.min(pos + node.nodeSize, to);
3622
+ lastPos = pos;
3623
+ lastNode = node;
3624
+ }
3625
+ });
3626
+ }
3627
+ else {
3628
+ state.doc.nodesBetween(from, to, (node, pos) => {
3629
+ if (pos < from && nodeType && nodeType === node.type) {
3630
+ trimmedFrom = Math.max(pos, from);
3631
+ trimmedTo = Math.min(pos + node.nodeSize, to);
3632
+ lastPos = pos;
3633
+ lastNode = node;
3634
+ }
3635
+ if (pos >= from && pos <= to) {
3636
+ if (nodeType && nodeType === node.type) {
3637
+ tr.setNodeMarkup(pos, undefined, {
3638
+ ...node.attrs,
3639
+ ...attributes,
3640
+ });
3641
+ }
3642
+ if (markType && node.marks.length) {
3643
+ node.marks.forEach((mark) => {
3644
+ if (markType === mark.type) {
3645
+ const trimmedFrom2 = Math.max(pos, from);
3646
+ const trimmedTo2 = Math.min(pos + node.nodeSize, to);
3647
+ tr.addMark(trimmedFrom2, trimmedTo2, markType.create({
3648
+ ...mark.attrs,
3649
+ ...attributes,
3650
+ }));
3651
+ }
3652
+ });
3653
+ }
3654
+ }
3655
+ });
3656
+ }
3657
+ if (lastNode) {
3658
+ if (lastPos !== undefined) {
3659
+ tr.setNodeMarkup(lastPos, undefined, {
3660
+ ...lastNode.attrs,
3545
3661
  ...attributes,
3546
3662
  });
3547
3663
  }
3548
- if (markType && node.marks.length) {
3549
- node.marks.forEach(mark => {
3664
+ if (markType && lastNode.marks.length) {
3665
+ lastNode.marks.forEach((mark) => {
3550
3666
  if (markType === mark.type) {
3551
- const trimmedFrom = Math.max(pos, from);
3552
- const trimmedTo = Math.min(pos + node.nodeSize, to);
3553
3667
  tr.addMark(trimmedFrom, trimmedTo, markType.create({
3554
3668
  ...mark.attrs,
3555
3669
  ...attributes,
@@ -3557,7 +3671,7 @@ const updateAttributes = (typeOrName, attributes = {}) => ({ tr, state, dispatch
3557
3671
  }
3558
3672
  });
3559
3673
  }
3560
- });
3674
+ }
3561
3675
  });
3562
3676
  }
3563
3677
  return true;
@@ -4373,6 +4487,7 @@ class Editor extends EventEmitter {
4373
4487
  * Creates a ProseMirror view.
4374
4488
  */
4375
4489
  createView() {
4490
+ var _a;
4376
4491
  let doc;
4377
4492
  try {
4378
4493
  doc = createDocument(this.options.content, this.schema, this.options.parseOptions, { errorOnInvalidContent: this.options.enableContentCheck });
@@ -4401,18 +4516,17 @@ class Editor extends EventEmitter {
4401
4516
  const selection = resolveFocusPosition(doc, this.options.autofocus);
4402
4517
  this.view = new EditorView(this.options.element, {
4403
4518
  ...this.options.editorProps,
4519
+ attributes: {
4520
+ // add `role="textbox"` to the editor element
4521
+ role: 'textbox',
4522
+ ...(_a = this.options.editorProps) === null || _a === void 0 ? void 0 : _a.attributes,
4523
+ },
4404
4524
  dispatchTransaction: this.dispatchTransaction.bind(this),
4405
4525
  state: EditorState.create({
4406
4526
  doc,
4407
4527
  selection: selection || undefined,
4408
4528
  }),
4409
4529
  });
4410
- // add `role="textbox"` to the editor element
4411
- this.view.dom.setAttribute('role', 'textbox');
4412
- // add aria-label to the editor element
4413
- if (!this.view.dom.getAttribute('aria-label')) {
4414
- this.view.dom.setAttribute('aria-label', 'Rich-Text Editor');
4415
- }
4416
4530
  // `editor.view` is not yet available at this time.
4417
4531
  // Therefore we will add all plugins and node views directly afterwards.
4418
4532
  const newState = this.state.reconfigure({
@@ -4608,7 +4722,7 @@ class Editor extends EventEmitter {
4608
4722
  /**
4609
4723
  * Build an input rule that adds a mark when the
4610
4724
  * matched text is typed into it.
4611
- * @see https://tiptap.dev/guide/custom-extensions/#input-rules
4725
+ * @see https://tiptap.dev/docs/editor/extensions/custom-extensions/extend-existing#input-rules
4612
4726
  */
4613
4727
  function markInputRule(config) {
4614
4728
  return new InputRule({
@@ -4652,7 +4766,7 @@ function markInputRule(config) {
4652
4766
  /**
4653
4767
  * Build an input rule that adds a node when the
4654
4768
  * matched text is typed into it.
4655
- * @see https://tiptap.dev/guide/custom-extensions/#input-rules
4769
+ * @see https://tiptap.dev/docs/editor/extensions/custom-extensions/extend-existing#input-rules
4656
4770
  */
4657
4771
  function nodeInputRule(config) {
4658
4772
  return new InputRule({
@@ -4692,7 +4806,7 @@ function nodeInputRule(config) {
4692
4806
  * matched text is typed into it. When using a regular expresion you’ll
4693
4807
  * probably want the regexp to start with `^`, so that the pattern can
4694
4808
  * only occur at the start of a textblock.
4695
- * @see https://tiptap.dev/guide/custom-extensions/#input-rules
4809
+ * @see https://tiptap.dev/docs/editor/extensions/custom-extensions/extend-existing#input-rules
4696
4810
  */
4697
4811
  function textblockTypeInputRule(config) {
4698
4812
  return new InputRule({
@@ -4713,7 +4827,7 @@ function textblockTypeInputRule(config) {
4713
4827
  /**
4714
4828
  * Build an input rule that replaces text when the
4715
4829
  * matched text is typed into it.
4716
- * @see https://tiptap.dev/guide/custom-extensions/#input-rules
4830
+ * @see https://tiptap.dev/docs/editor/extensions/custom-extensions/extend-existing#input-rules
4717
4831
  */
4718
4832
  function textInputRule(config) {
4719
4833
  return new InputRule({
@@ -4750,7 +4864,7 @@ function textInputRule(config) {
4750
4864
  * two nodes. You can pass a join predicate, which takes a regular
4751
4865
  * expression match and the node before the wrapped node, and can
4752
4866
  * return a boolean to indicate whether a join should happen.
4753
- * @see https://tiptap.dev/guide/custom-extensions/#input-rules
4867
+ * @see https://tiptap.dev/docs/editor/extensions/custom-extensions/extend-existing#input-rules
4754
4868
  */
4755
4869
  function wrappingInputRule(config) {
4756
4870
  return new InputRule({
@@ -5083,7 +5197,7 @@ class NodeView {
5083
5197
  /**
5084
5198
  * Build an paste rule that adds a mark when the
5085
5199
  * matched text is pasted into it.
5086
- * @see https://tiptap.dev/guide/custom-extensions/#paste-rules
5200
+ * @see https://tiptap.dev/docs/editor/extensions/custom-extensions/extend-existing#paste-rules
5087
5201
  */
5088
5202
  function markPasteRule(config) {
5089
5203
  return new PasteRule({
@@ -5137,7 +5251,7 @@ function isString(value) {
5137
5251
  /**
5138
5252
  * Build an paste rule that adds a node when the
5139
5253
  * matched text is pasted into it.
5140
- * @see https://tiptap.dev/guide/custom-extensions/#paste-rules
5254
+ * @see https://tiptap.dev/docs/editor/extensions/custom-extensions/extend-existing#paste-rules
5141
5255
  */
5142
5256
  function nodePasteRule(config) {
5143
5257
  return new PasteRule({
@@ -5162,7 +5276,7 @@ function nodePasteRule(config) {
5162
5276
  /**
5163
5277
  * Build an paste rule that replaces text when the
5164
5278
  * matched text is pasted into it.
5165
- * @see https://tiptap.dev/guide/custom-extensions/#paste-rules
5279
+ * @see https://tiptap.dev/docs/editor/extensions/custom-extensions/extend-existing#paste-rules
5166
5280
  */
5167
5281
  function textPasteRule(config) {
5168
5282
  return new PasteRule({