@tiptap/core 2.3.2 → 2.5.0-beta.0

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 (186) hide show
  1. package/dist/index.cjs +277 -67
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +277 -67
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.umd.js +277 -67
  6. package/dist/index.umd.js.map +1 -1
  7. package/dist/packages/core/src/EventEmitter.d.ts +2 -2
  8. package/dist/packages/core/src/Extension.d.ts +129 -14
  9. package/dist/packages/core/src/ExtensionManager.d.ts +37 -0
  10. package/dist/packages/core/src/Mark.d.ts +129 -14
  11. package/dist/packages/core/src/Node.d.ts +226 -30
  12. package/dist/packages/core/src/NodeView.d.ts +4 -0
  13. package/dist/packages/core/src/PasteRule.d.ts +4 -0
  14. package/dist/packages/core/src/commands/blur.d.ts +1 -0
  15. package/dist/packages/core/src/commands/clearContent.d.ts +2 -0
  16. package/dist/packages/core/src/commands/clearNodes.d.ts +1 -0
  17. package/dist/packages/core/src/commands/command.d.ts +6 -0
  18. package/dist/packages/core/src/commands/createParagraphNear.d.ts +1 -0
  19. package/dist/packages/core/src/commands/cut.d.ts +5 -0
  20. package/dist/packages/core/src/commands/deleteCurrentNode.d.ts +1 -0
  21. package/dist/packages/core/src/commands/deleteNode.d.ts +3 -1
  22. package/dist/packages/core/src/commands/deleteRange.d.ts +2 -0
  23. package/dist/packages/core/src/commands/deleteSelection.d.ts +1 -0
  24. package/dist/packages/core/src/commands/enter.d.ts +1 -0
  25. package/dist/packages/core/src/commands/exitCode.d.ts +1 -0
  26. package/dist/packages/core/src/commands/extendMarkRange.d.ts +14 -2
  27. package/dist/packages/core/src/commands/first.d.ts +2 -0
  28. package/dist/packages/core/src/commands/focus.d.ts +14 -1
  29. package/dist/packages/core/src/commands/insertContent.d.ts +17 -1
  30. package/dist/packages/core/src/commands/insertContentAt.d.ts +20 -1
  31. package/dist/packages/core/src/commands/join.d.ts +12 -4
  32. package/dist/packages/core/src/commands/joinItemBackward.d.ts +2 -1
  33. package/dist/packages/core/src/commands/joinItemForward.d.ts +2 -1
  34. package/dist/packages/core/src/commands/keyboardShortcut.d.ts +2 -0
  35. package/dist/packages/core/src/commands/lift.d.ts +5 -1
  36. package/dist/packages/core/src/commands/liftEmptyBlock.d.ts +2 -1
  37. package/dist/packages/core/src/commands/liftListItem.d.ts +3 -1
  38. package/dist/packages/core/src/commands/newlineInCode.d.ts +1 -0
  39. package/dist/packages/core/src/commands/resetAttributes.d.ts +3 -0
  40. package/dist/packages/core/src/commands/scrollIntoView.d.ts +1 -0
  41. package/dist/packages/core/src/commands/selectAll.d.ts +1 -0
  42. package/dist/packages/core/src/commands/selectNodeBackward.d.ts +1 -0
  43. package/dist/packages/core/src/commands/selectNodeForward.d.ts +1 -0
  44. package/dist/packages/core/src/commands/selectParentNode.d.ts +1 -0
  45. package/dist/packages/core/src/commands/selectTextblockEnd.d.ts +1 -0
  46. package/dist/packages/core/src/commands/selectTextblockStart.d.ts +1 -0
  47. package/dist/packages/core/src/commands/setContent.d.ts +19 -1
  48. package/dist/packages/core/src/commands/setMark.d.ts +2 -0
  49. package/dist/packages/core/src/commands/setMeta.d.ts +3 -0
  50. package/dist/packages/core/src/commands/setNode.d.ts +3 -0
  51. package/dist/packages/core/src/commands/setNodeSelection.d.ts +2 -0
  52. package/dist/packages/core/src/commands/setTextSelection.d.ts +2 -0
  53. package/dist/packages/core/src/commands/sinkListItem.d.ts +2 -0
  54. package/dist/packages/core/src/commands/splitBlock.d.ts +3 -0
  55. package/dist/packages/core/src/commands/splitListItem.d.ts +2 -0
  56. package/dist/packages/core/src/commands/toggleList.d.ts +5 -0
  57. package/dist/packages/core/src/commands/toggleMark.d.ts +13 -1
  58. package/dist/packages/core/src/commands/toggleNode.d.ts +4 -0
  59. package/dist/packages/core/src/commands/toggleWrap.d.ts +3 -0
  60. package/dist/packages/core/src/commands/undoInputRule.d.ts +1 -0
  61. package/dist/packages/core/src/commands/unsetAllMarks.d.ts +1 -0
  62. package/dist/packages/core/src/commands/unsetMark.d.ts +8 -1
  63. package/dist/packages/core/src/commands/updateAttributes.d.ts +12 -1
  64. package/dist/packages/core/src/commands/wrapIn.d.ts +3 -0
  65. package/dist/packages/core/src/commands/wrapInList.d.ts +3 -0
  66. package/dist/packages/core/src/helpers/combineTransactionSteps.d.ts +3 -0
  67. package/dist/packages/core/src/helpers/createChainableState.d.ts +5 -0
  68. package/dist/packages/core/src/helpers/createDocument.d.ts +7 -0
  69. package/dist/packages/core/src/helpers/createNodeFromContent.d.ts +7 -0
  70. package/dist/packages/core/src/helpers/defaultBlockAt.d.ts +5 -0
  71. package/dist/packages/core/src/helpers/findChildren.d.ts +6 -0
  72. package/dist/packages/core/src/helpers/findChildrenInRange.d.ts +4 -0
  73. package/dist/packages/core/src/helpers/findParentNode.d.ts +8 -0
  74. package/dist/packages/core/src/helpers/findParentNodeClosestToPos.d.ts +9 -0
  75. package/dist/packages/core/src/helpers/generateHTML.d.ts +6 -0
  76. package/dist/packages/core/src/helpers/generateJSON.d.ts +6 -0
  77. package/dist/packages/core/src/helpers/generateText.d.ts +7 -0
  78. package/dist/packages/core/src/helpers/getAttributes.d.ts +6 -0
  79. package/dist/packages/core/src/helpers/getExtensionField.d.ts +7 -0
  80. package/dist/packages/core/src/helpers/getSchemaByResolvedExtensions.d.ts +6 -0
  81. package/dist/packages/core/src/helpers/getSchemaTypeByName.d.ts +6 -0
  82. package/dist/packages/core/src/helpers/getSchemaTypeNameByName.d.ts +6 -0
  83. package/dist/packages/core/src/helpers/getSplittedAttributes.d.ts +7 -0
  84. package/dist/packages/core/src/helpers/getText.d.ts +9 -0
  85. package/dist/packages/core/src/helpers/getTextBetween.d.ts +8 -0
  86. package/dist/packages/core/src/helpers/getTextContentFromNodes.d.ts +6 -0
  87. package/dist/packages/core/src/helpers/getTextSerializersFromSchema.d.ts +5 -0
  88. package/dist/packages/core/src/inputRules/markInputRule.d.ts +1 -0
  89. package/dist/packages/core/src/inputRules/nodeInputRule.d.ts +1 -0
  90. package/dist/packages/core/src/inputRules/textInputRule.d.ts +1 -0
  91. package/dist/packages/core/src/inputRules/textblockTypeInputRule.d.ts +1 -0
  92. package/dist/packages/core/src/inputRules/wrappingInputRule.d.ts +1 -0
  93. package/dist/packages/core/src/pasteRules/markPasteRule.d.ts +1 -0
  94. package/dist/packages/core/src/pasteRules/nodePasteRule.d.ts +1 -0
  95. package/dist/packages/core/src/pasteRules/textPasteRule.d.ts +1 -0
  96. package/package.json +2 -2
  97. package/src/EventEmitter.ts +2 -2
  98. package/src/Extension.ts +130 -14
  99. package/src/ExtensionManager.ts +117 -85
  100. package/src/Mark.ts +129 -14
  101. package/src/Node.ts +226 -30
  102. package/src/NodeView.ts +4 -0
  103. package/src/PasteRule.ts +4 -0
  104. package/src/commands/blur.ts +1 -0
  105. package/src/commands/clearContent.ts +2 -0
  106. package/src/commands/clearNodes.ts +1 -0
  107. package/src/commands/command.ts +6 -0
  108. package/src/commands/createParagraphNear.ts +1 -0
  109. package/src/commands/cut.ts +5 -0
  110. package/src/commands/deleteCurrentNode.ts +1 -0
  111. package/src/commands/deleteNode.ts +3 -1
  112. package/src/commands/deleteRange.ts +2 -0
  113. package/src/commands/deleteSelection.ts +1 -0
  114. package/src/commands/enter.ts +1 -0
  115. package/src/commands/exitCode.ts +1 -0
  116. package/src/commands/extendMarkRange.ts +12 -1
  117. package/src/commands/first.ts +2 -0
  118. package/src/commands/focus.ts +12 -0
  119. package/src/commands/insertContent.ts +16 -0
  120. package/src/commands/insertContentAt.ts +19 -0
  121. package/src/commands/join.ts +12 -4
  122. package/src/commands/joinItemBackward.ts +6 -3
  123. package/src/commands/joinItemForward.ts +2 -1
  124. package/src/commands/keyboardShortcut.ts +2 -0
  125. package/src/commands/lift.ts +5 -1
  126. package/src/commands/liftEmptyBlock.ts +2 -1
  127. package/src/commands/liftListItem.ts +3 -1
  128. package/src/commands/newlineInCode.ts +1 -0
  129. package/src/commands/resetAttributes.ts +3 -0
  130. package/src/commands/scrollIntoView.ts +1 -0
  131. package/src/commands/selectAll.ts +1 -0
  132. package/src/commands/selectNodeBackward.ts +1 -0
  133. package/src/commands/selectNodeForward.ts +1 -0
  134. package/src/commands/selectParentNode.ts +1 -0
  135. package/src/commands/selectTextblockEnd.ts +1 -0
  136. package/src/commands/selectTextblockStart.ts +1 -0
  137. package/src/commands/setContent.ts +17 -0
  138. package/src/commands/setMark.ts +2 -0
  139. package/src/commands/setMeta.ts +3 -0
  140. package/src/commands/setNode.ts +3 -0
  141. package/src/commands/setNodeSelection.ts +2 -0
  142. package/src/commands/setTextSelection.ts +2 -0
  143. package/src/commands/sinkListItem.ts +2 -0
  144. package/src/commands/splitBlock.ts +3 -0
  145. package/src/commands/splitListItem.ts +2 -0
  146. package/src/commands/toggleList.ts +5 -0
  147. package/src/commands/toggleMark.ts +12 -0
  148. package/src/commands/toggleNode.ts +4 -0
  149. package/src/commands/toggleWrap.ts +3 -0
  150. package/src/commands/undoInputRule.ts +1 -0
  151. package/src/commands/unsetAllMarks.ts +1 -0
  152. package/src/commands/unsetMark.ts +7 -0
  153. package/src/commands/updateAttributes.ts +10 -0
  154. package/src/commands/wrapIn.ts +3 -0
  155. package/src/commands/wrapInList.ts +3 -0
  156. package/src/extensions/keymap.ts +7 -1
  157. package/src/helpers/combineTransactionSteps.ts +3 -0
  158. package/src/helpers/createChainableState.ts +5 -0
  159. package/src/helpers/createDocument.ts +7 -0
  160. package/src/helpers/createNodeFromContent.ts +16 -3
  161. package/src/helpers/defaultBlockAt.ts +5 -0
  162. package/src/helpers/findChildren.ts +6 -0
  163. package/src/helpers/findChildrenInRange.ts +4 -0
  164. package/src/helpers/findParentNode.ts +8 -0
  165. package/src/helpers/findParentNodeClosestToPos.ts +9 -0
  166. package/src/helpers/generateHTML.ts +6 -0
  167. package/src/helpers/generateJSON.ts +6 -0
  168. package/src/helpers/generateText.ts +7 -0
  169. package/src/helpers/getAttributes.ts +6 -0
  170. package/src/helpers/getExtensionField.ts +7 -0
  171. package/src/helpers/getSchemaByResolvedExtensions.ts +6 -0
  172. package/src/helpers/getSchemaTypeByName.ts +6 -0
  173. package/src/helpers/getSchemaTypeNameByName.ts +6 -0
  174. package/src/helpers/getSplittedAttributes.ts +7 -0
  175. package/src/helpers/getText.ts +9 -0
  176. package/src/helpers/getTextBetween.ts +12 -10
  177. package/src/helpers/getTextContentFromNodes.ts +6 -0
  178. package/src/helpers/getTextSerializersFromSchema.ts +5 -0
  179. package/src/inputRules/markInputRule.ts +1 -0
  180. package/src/inputRules/nodeInputRule.ts +4 -1
  181. package/src/inputRules/textInputRule.ts +1 -0
  182. package/src/inputRules/textblockTypeInputRule.ts +1 -0
  183. package/src/inputRules/wrappingInputRule.ts +1 -0
  184. package/src/pasteRules/markPasteRule.ts +1 -0
  185. package/src/pasteRules/nodePasteRule.ts +1 -0
  186. package/src/pasteRules/textPasteRule.ts +1 -0
package/dist/index.umd.js CHANGED
@@ -4,6 +4,11 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["@tiptap/core"] = {}, global.state, global.view, global.keymap, global.model, global.transform, global.commands$1, global.schemaList));
5
5
  })(this, (function (exports, state, view, keymap, model, transform, commands$1, schemaList) { 'use strict';
6
6
 
7
+ /**
8
+ * Takes a Transaction & Editor State and turns it into a chainable state object
9
+ * @param config The transaction and state to create the chainable state from
10
+ * @returns A chainable Editor state object
11
+ */
7
12
  function createChainableState(config) {
8
13
  const { state, transaction } = config;
9
14
  let { selection } = transaction;
@@ -170,6 +175,13 @@
170
175
  }
171
176
  }
172
177
 
178
+ /**
179
+ * Returns a field from an extension
180
+ * @param extension The Tiptap extension
181
+ * @param field The field, for example `renderHTML` or `priority`
182
+ * @param context The context object that should be passed as `this` into the function
183
+ * @returns The field value
184
+ */
173
185
  function getExtensionField(extension, field, context) {
174
186
  if (extension.config[field] === undefined && extension.parent) {
175
187
  return getExtensionField(extension.parent, field, context);
@@ -414,6 +426,12 @@
414
426
  return value !== null && value !== undefined;
415
427
  }));
416
428
  }
429
+ /**
430
+ * Creates a new Prosemirror schema based on the given extensions.
431
+ * @param extensions An array of Tiptap extensions
432
+ * @param editor The editor instance
433
+ * @returns A Prosemirror schema
434
+ */
417
435
  function getSchemaByResolvedExtensions(extensions, editor) {
418
436
  var _a;
419
437
  const allAttributes = getAttributesFromExtensions(extensions);
@@ -515,6 +533,12 @@
515
533
  });
516
534
  }
517
535
 
536
+ /**
537
+ * Tries to get a node or mark type by its name.
538
+ * @param name The name of the node or mark type
539
+ * @param schema The Prosemiror schema to search in
540
+ * @returns The node or mark type, or null if it doesn't exist
541
+ */
518
542
  function getSchemaTypeByName(name, schema) {
519
543
  return schema.nodes[name] || schema.marks[name] || null;
520
544
  }
@@ -531,6 +555,12 @@
531
555
  return enabled;
532
556
  }
533
557
 
558
+ /**
559
+ * Returns the text content of a resolved prosemirror position
560
+ * @param $from The resolved position to get the text content from
561
+ * @param maxMatch The maximum number of characters to match
562
+ * @returns The text content
563
+ */
534
564
  const getTextContentFromNodes = ($from, maxMatch = 500) => {
535
565
  let textBefore = '';
536
566
  const sliceEndPos = $from.parentOffset;
@@ -738,6 +768,10 @@
738
768
  return typeof value === 'number';
739
769
  }
740
770
 
771
+ /**
772
+ * Paste rules are used to react to pasted content.
773
+ * @see https://tiptap.dev/guide/custom-extensions/#paste-rules
774
+ */
741
775
  class PasteRule {
742
776
  constructor(config) {
743
777
  this.find = config.find;
@@ -936,57 +970,14 @@
936
970
  this.editor = editor;
937
971
  this.extensions = ExtensionManager.resolve(extensions);
938
972
  this.schema = getSchemaByResolvedExtensions(this.extensions, editor);
939
- this.extensions.forEach(extension => {
940
- var _a;
941
- // store extension storage in editor
942
- this.editor.extensionStorage[extension.name] = extension.storage;
943
- const context = {
944
- name: extension.name,
945
- options: extension.options,
946
- storage: extension.storage,
947
- editor: this.editor,
948
- type: getSchemaTypeByName(extension.name, this.schema),
949
- };
950
- if (extension.type === 'mark') {
951
- const keepOnSplit = (_a = callOrReturn(getExtensionField(extension, 'keepOnSplit', context))) !== null && _a !== void 0 ? _a : true;
952
- if (keepOnSplit) {
953
- this.splittableMarks.push(extension.name);
954
- }
955
- }
956
- const onBeforeCreate = getExtensionField(extension, 'onBeforeCreate', context);
957
- if (onBeforeCreate) {
958
- this.editor.on('beforeCreate', onBeforeCreate);
959
- }
960
- const onCreate = getExtensionField(extension, 'onCreate', context);
961
- if (onCreate) {
962
- this.editor.on('create', onCreate);
963
- }
964
- const onUpdate = getExtensionField(extension, 'onUpdate', context);
965
- if (onUpdate) {
966
- this.editor.on('update', onUpdate);
967
- }
968
- const onSelectionUpdate = getExtensionField(extension, 'onSelectionUpdate', context);
969
- if (onSelectionUpdate) {
970
- this.editor.on('selectionUpdate', onSelectionUpdate);
971
- }
972
- const onTransaction = getExtensionField(extension, 'onTransaction', context);
973
- if (onTransaction) {
974
- this.editor.on('transaction', onTransaction);
975
- }
976
- const onFocus = getExtensionField(extension, 'onFocus', context);
977
- if (onFocus) {
978
- this.editor.on('focus', onFocus);
979
- }
980
- const onBlur = getExtensionField(extension, 'onBlur', context);
981
- if (onBlur) {
982
- this.editor.on('blur', onBlur);
983
- }
984
- const onDestroy = getExtensionField(extension, 'onDestroy', context);
985
- if (onDestroy) {
986
- this.editor.on('destroy', onDestroy);
987
- }
988
- });
973
+ this.setupExtensions();
989
974
  }
975
+ /**
976
+ * Returns a flattened and sorted extension list while
977
+ * also checking for duplicated extensions and warns the user.
978
+ * @param extensions An array of Tiptap extensions
979
+ * @returns An flattened and sorted array of Tiptap extensions
980
+ */
990
981
  static resolve(extensions) {
991
982
  const resolvedExtensions = ExtensionManager.sort(ExtensionManager.flatten(extensions));
992
983
  const duplicatedNames = findDuplicates(resolvedExtensions.map(extension => extension.name));
@@ -997,6 +988,11 @@
997
988
  }
998
989
  return resolvedExtensions;
999
990
  }
991
+ /**
992
+ * Create a flattened array of extensions by traversing the `addExtensions` field.
993
+ * @param extensions An array of Tiptap extensions
994
+ * @returns A flattened array of Tiptap extensions
995
+ */
1000
996
  static flatten(extensions) {
1001
997
  return (extensions
1002
998
  .map(extension => {
@@ -1014,6 +1010,11 @@
1014
1010
  // `Infinity` will break TypeScript so we set a number that is probably high enough
1015
1011
  .flat(10));
1016
1012
  }
1013
+ /**
1014
+ * Sort extensions by priority.
1015
+ * @param extensions An array of Tiptap extensions
1016
+ * @returns A sorted array of Tiptap extensions by priority
1017
+ */
1017
1018
  static sort(extensions) {
1018
1019
  const defaultPriority = 100;
1019
1020
  return extensions.sort((a, b) => {
@@ -1028,6 +1029,10 @@
1028
1029
  return 0;
1029
1030
  });
1030
1031
  }
1032
+ /**
1033
+ * Get all commands from the extensions.
1034
+ * @returns An object with all commands where the key is the command name and the value is the command function
1035
+ */
1031
1036
  get commands() {
1032
1037
  return this.extensions.reduce((commands, extension) => {
1033
1038
  const context = {
@@ -1047,6 +1052,10 @@
1047
1052
  };
1048
1053
  }, {});
1049
1054
  }
1055
+ /**
1056
+ * Get all registered Prosemirror plugins from the extensions.
1057
+ * @returns An array of Prosemirror plugins
1058
+ */
1050
1059
  get plugins() {
1051
1060
  const { editor } = this;
1052
1061
  // With ProseMirror, first plugins within an array are executed first.
@@ -1109,9 +1118,17 @@
1109
1118
  ...allPlugins,
1110
1119
  ];
1111
1120
  }
1121
+ /**
1122
+ * Get all attributes from the extensions.
1123
+ * @returns An array of attributes
1124
+ */
1112
1125
  get attributes() {
1113
1126
  return getAttributesFromExtensions(this.extensions);
1114
1127
  }
1128
+ /**
1129
+ * Get all node views from the extensions.
1130
+ * @returns An object with all node views where the key is the node name and the value is the node view function
1131
+ */
1115
1132
  get nodeViews() {
1116
1133
  const { editor } = this;
1117
1134
  const { nodeExtensions } = splitExtensions(this.extensions);
@@ -1144,6 +1161,62 @@
1144
1161
  return [extension.name, nodeview];
1145
1162
  }));
1146
1163
  }
1164
+ /**
1165
+ * Go through all extensions, create extension storages & setup marks
1166
+ * & bind editor event listener.
1167
+ */
1168
+ setupExtensions() {
1169
+ this.extensions.forEach(extension => {
1170
+ var _a;
1171
+ // store extension storage in editor
1172
+ this.editor.extensionStorage[extension.name] = extension.storage;
1173
+ const context = {
1174
+ name: extension.name,
1175
+ options: extension.options,
1176
+ storage: extension.storage,
1177
+ editor: this.editor,
1178
+ type: getSchemaTypeByName(extension.name, this.schema),
1179
+ };
1180
+ if (extension.type === 'mark') {
1181
+ const keepOnSplit = (_a = callOrReturn(getExtensionField(extension, 'keepOnSplit', context))) !== null && _a !== void 0 ? _a : true;
1182
+ if (keepOnSplit) {
1183
+ this.splittableMarks.push(extension.name);
1184
+ }
1185
+ }
1186
+ const onBeforeCreate = getExtensionField(extension, 'onBeforeCreate', context);
1187
+ const onCreate = getExtensionField(extension, 'onCreate', context);
1188
+ const onUpdate = getExtensionField(extension, 'onUpdate', context);
1189
+ const onSelectionUpdate = getExtensionField(extension, 'onSelectionUpdate', context);
1190
+ const onTransaction = getExtensionField(extension, 'onTransaction', context);
1191
+ const onFocus = getExtensionField(extension, 'onFocus', context);
1192
+ const onBlur = getExtensionField(extension, 'onBlur', context);
1193
+ const onDestroy = getExtensionField(extension, 'onDestroy', context);
1194
+ if (onBeforeCreate) {
1195
+ this.editor.on('beforeCreate', onBeforeCreate);
1196
+ }
1197
+ if (onCreate) {
1198
+ this.editor.on('create', onCreate);
1199
+ }
1200
+ if (onUpdate) {
1201
+ this.editor.on('update', onUpdate);
1202
+ }
1203
+ if (onSelectionUpdate) {
1204
+ this.editor.on('selectionUpdate', onSelectionUpdate);
1205
+ }
1206
+ if (onTransaction) {
1207
+ this.editor.on('transaction', onTransaction);
1208
+ }
1209
+ if (onFocus) {
1210
+ this.editor.on('focus', onFocus);
1211
+ }
1212
+ if (onBlur) {
1213
+ this.editor.on('blur', onBlur);
1214
+ }
1215
+ if (onDestroy) {
1216
+ this.editor.on('destroy', onDestroy);
1217
+ }
1218
+ });
1219
+ }
1147
1220
  }
1148
1221
 
1149
1222
  // see: https://github.com/mesqueeb/is-what/blob/88d6e4ca92fb2baab6003c54e02eedf4e729e5ab/src/index.ts
@@ -1177,6 +1250,10 @@
1177
1250
  return output;
1178
1251
  }
1179
1252
 
1253
+ /**
1254
+ * The Extension class is the base class for all extensions.
1255
+ * @see https://tiptap.dev/api/extensions#create-a-new-extension
1256
+ */
1180
1257
  class Extension {
1181
1258
  constructor(config = {}) {
1182
1259
  this.type = 'extension';
@@ -1214,6 +1291,7 @@
1214
1291
  // return a new instance so we can use the same extension
1215
1292
  // with different calls of `configure`
1216
1293
  const extension = this.extend();
1294
+ extension.parent = this.parent;
1217
1295
  extension.options = mergeDeep(this.options, options);
1218
1296
  extension.storage = callOrReturn(getExtensionField(extension, 'addStorage', {
1219
1297
  name: extension.name,
@@ -1240,19 +1318,25 @@
1240
1318
  }
1241
1319
  }
1242
1320
 
1321
+ /**
1322
+ * Gets the text between two positions in a Prosemirror node
1323
+ * and serializes it using the given text serializers and block separator (see getText)
1324
+ * @param startNode The Prosemirror node to start from
1325
+ * @param range The range of the text to get
1326
+ * @param options Options for the text serializer & block separator
1327
+ * @returns The text between the two positions
1328
+ */
1243
1329
  function getTextBetween(startNode, range, options) {
1244
1330
  const { from, to } = range;
1245
1331
  const { blockSeparator = '\n\n', textSerializers = {} } = options || {};
1246
1332
  let text = '';
1247
- let separated = true;
1248
1333
  startNode.nodesBetween(from, to, (node, pos, parent, index) => {
1249
1334
  var _a;
1335
+ if (node.isBlock && pos > from) {
1336
+ text += blockSeparator;
1337
+ }
1250
1338
  const textSerializer = textSerializers === null || textSerializers === void 0 ? void 0 : textSerializers[node.type.name];
1251
1339
  if (textSerializer) {
1252
- if (node.isBlock && !separated) {
1253
- text += blockSeparator;
1254
- separated = true;
1255
- }
1256
1340
  if (parent) {
1257
1341
  text += textSerializer({
1258
1342
  node,
@@ -1267,16 +1351,16 @@
1267
1351
  }
1268
1352
  if (node.isText) {
1269
1353
  text += (_a = node === null || node === void 0 ? void 0 : node.text) === null || _a === void 0 ? void 0 : _a.slice(Math.max(from, pos) - pos, to - pos); // eslint-disable-line
1270
- separated = false;
1271
- }
1272
- else if (node.isBlock && !separated) {
1273
- text += blockSeparator;
1274
- separated = true;
1275
1354
  }
1276
1355
  });
1277
1356
  return text;
1278
1357
  }
1279
1358
 
1359
+ /**
1360
+ * Find text serializers `toText` in a Prosemirror schema
1361
+ * @param schema The Prosemirror schema to search in
1362
+ * @returns A record of text serializers by node name
1363
+ */
1280
1364
  function getTextSerializersFromSchema(schema) {
1281
1365
  return Object.fromEntries(Object.entries(schema.nodes)
1282
1366
  .filter(([, node]) => node.spec.toText)
@@ -1659,15 +1743,26 @@
1659
1743
  return removeWhitespaces(html);
1660
1744
  }
1661
1745
 
1746
+ /**
1747
+ * Takes a JSON or HTML content and creates a Prosemirror node or fragment from it.
1748
+ * @param content The JSON or HTML content to create the node from
1749
+ * @param schema The Prosemirror schema to use for the node
1750
+ * @param options Options for the parser
1751
+ * @returns The created Prosemirror node or fragment
1752
+ */
1662
1753
  function createNodeFromContent(content, schema, options) {
1663
1754
  options = {
1664
1755
  slice: true,
1665
1756
  parseOptions: {},
1666
1757
  ...options,
1667
1758
  };
1668
- if (typeof content === 'object' && content !== null) {
1759
+ const isJSONContent = typeof content === 'object' && content !== null;
1760
+ const isTextContent = typeof content === 'string';
1761
+ if (isJSONContent) {
1669
1762
  try {
1670
- if (Array.isArray(content) && content.length > 0) {
1763
+ const isArrayContent = Array.isArray(content) && content.length > 0;
1764
+ // if the JSON Content is an array of nodes, create a fragment for each node
1765
+ if (isArrayContent) {
1671
1766
  return model.Fragment.fromArray(content.map(item => schema.nodeFromJSON(item)));
1672
1767
  }
1673
1768
  return schema.nodeFromJSON(content);
@@ -1677,7 +1772,7 @@
1677
1772
  return createNodeFromContent('', schema, options);
1678
1773
  }
1679
1774
  }
1680
- if (typeof content === 'string') {
1775
+ if (isTextContent) {
1681
1776
  const parser = model.DOMParser.fromSchema(schema);
1682
1777
  return options.slice
1683
1778
  ? parser.parseSlice(elementFromString(content), options.parseOptions).content
@@ -1799,7 +1894,7 @@
1799
1894
  return commands$1.joinForward(state, dispatch);
1800
1895
  };
1801
1896
 
1802
- const joinItemBackward = () => ({ tr, state, dispatch, }) => {
1897
+ const joinItemBackward = () => ({ state, dispatch, tr, }) => {
1803
1898
  try {
1804
1899
  const point = transform.joinPoint(state.doc, state.selection.$from.pos, -1);
1805
1900
  if (point === null || point === undefined) {
@@ -1811,7 +1906,7 @@
1811
1906
  }
1812
1907
  return true;
1813
1908
  }
1814
- catch {
1909
+ catch (e) {
1815
1910
  return false;
1816
1911
  }
1817
1912
  };
@@ -1977,6 +2072,12 @@
1977
2072
  return commands$1.newlineInCode(state, dispatch);
1978
2073
  };
1979
2074
 
2075
+ /**
2076
+ * Get the type of a schema item by its name.
2077
+ * @param name The name of the schema item
2078
+ * @param schema The Prosemiror schema to search in
2079
+ * @returns The type of the schema item (`node` or `mark`), or null if it doesn't exist
2080
+ */
1980
2081
  function getSchemaTypeNameByName(name, schema) {
1981
2082
  if (schema.nodes[name]) {
1982
2083
  return 'node';
@@ -2074,6 +2175,13 @@
2074
2175
  return commands$1.selectTextblockStart(state, dispatch);
2075
2176
  };
2076
2177
 
2178
+ /**
2179
+ * Create a new Prosemirror document node from content.
2180
+ * @param content The JSON or HTML content to create the document from
2181
+ * @param schema The Prosemirror schema to use for the document
2182
+ * @param parseOptions Options for the parser
2183
+ * @returns The created Prosemirror document node
2184
+ */
2077
2185
  function createDocument(content, schema, parseOptions = {}) {
2078
2186
  return createNodeFromContent(content, schema, { slice: false, parseOptions });
2079
2187
  }
@@ -2111,6 +2219,9 @@
2111
2219
 
2112
2220
  /**
2113
2221
  * Returns a new `Transform` based on all steps of the passed transactions.
2222
+ * @param oldDoc The Prosemirror node to start from
2223
+ * @param transactions The transactions to combine
2224
+ * @returns A new `Transform` with all steps of the passed transactions
2114
2225
  */
2115
2226
  function combineTransactionSteps(oldDoc, transactions) {
2116
2227
  const transform$1 = new transform.Transform(oldDoc);
@@ -2122,6 +2233,11 @@
2122
2233
  return transform$1;
2123
2234
  }
2124
2235
 
2236
+ /**
2237
+ * Gets the default block type at a given match
2238
+ * @param match The content match to get the default block type from
2239
+ * @returns The default block type or null
2240
+ */
2125
2241
  function defaultBlockAt(match) {
2126
2242
  for (let i = 0; i < match.edgeCount; i += 1) {
2127
2243
  const { type } = match.edge(i);
@@ -2132,6 +2248,12 @@
2132
2248
  return null;
2133
2249
  }
2134
2250
 
2251
+ /**
2252
+ * Find children inside a Prosemirror node that match a predicate.
2253
+ * @param node The Prosemirror node to search in
2254
+ * @param predicate The predicate to match
2255
+ * @returns An array of nodes with their positions
2256
+ */
2135
2257
  function findChildren(node, predicate) {
2136
2258
  const nodesWithPos = [];
2137
2259
  node.descendants((child, pos) => {
@@ -2147,6 +2269,10 @@
2147
2269
 
2148
2270
  /**
2149
2271
  * Same as `findChildren` but searches only within a `range`.
2272
+ * @param node The Prosemirror node to search in
2273
+ * @param range The range to search in
2274
+ * @param predicate The predicate to match
2275
+ * @returns An array of nodes with their positions
2150
2276
  */
2151
2277
  function findChildrenInRange(node, range, predicate) {
2152
2278
  const nodesWithPos = [];
@@ -2170,6 +2296,15 @@
2170
2296
  return nodesWithPos;
2171
2297
  }
2172
2298
 
2299
+ /**
2300
+ * Finds the closest parent node to a resolved position that matches a predicate.
2301
+ * @param $pos The resolved position to search from
2302
+ * @param predicate The predicate to match
2303
+ * @returns The closest parent node to the resolved position that matches the predicate
2304
+ * @example ```js
2305
+ * findParentNodeClosestToPos($from, node => node.type.name === 'paragraph')
2306
+ * ```
2307
+ */
2173
2308
  function findParentNodeClosestToPos($pos, predicate) {
2174
2309
  for (let i = $pos.depth; i > 0; i -= 1) {
2175
2310
  const node = $pos.node(i);
@@ -2184,6 +2319,14 @@
2184
2319
  }
2185
2320
  }
2186
2321
 
2322
+ /**
2323
+ * Finds the closest parent node to the current selection that matches a predicate.
2324
+ * @param predicate The predicate to match
2325
+ * @returns A command that finds the closest parent node to the current selection that matches the predicate
2326
+ * @example ```js
2327
+ * findParentNode(node => node.type.name === 'paragraph')
2328
+ * ```
2329
+ */
2187
2330
  function findParentNode(predicate) {
2188
2331
  return (selection) => findParentNodeClosestToPos(selection.$from, predicate);
2189
2332
  }
@@ -2201,18 +2344,39 @@
2201
2344
  return getSchemaByResolvedExtensions(resolvedExtensions, editor);
2202
2345
  }
2203
2346
 
2347
+ /**
2348
+ * Generate HTML from a JSONContent
2349
+ * @param doc The JSONContent to generate HTML from
2350
+ * @param extensions The extensions to use for the schema
2351
+ * @returns The generated HTML
2352
+ */
2204
2353
  function generateHTML(doc, extensions) {
2205
2354
  const schema = getSchema(extensions);
2206
2355
  const contentNode = model.Node.fromJSON(schema, doc);
2207
2356
  return getHTMLFromFragment(contentNode.content, schema);
2208
2357
  }
2209
2358
 
2359
+ /**
2360
+ * Generate JSONContent from HTML
2361
+ * @param html The HTML to generate JSONContent from
2362
+ * @param extensions The extensions to use for the schema
2363
+ * @returns The generated JSONContent
2364
+ */
2210
2365
  function generateJSON(html, extensions) {
2211
2366
  const schema = getSchema(extensions);
2212
2367
  const dom = elementFromString(html);
2213
2368
  return model.DOMParser.fromSchema(schema).parse(dom).toJSON();
2214
2369
  }
2215
2370
 
2371
+ /**
2372
+ * Gets the text of a Prosemirror node
2373
+ * @param node The Prosemirror node
2374
+ * @param options Options for the text serializer & block separator
2375
+ * @returns The text of the node
2376
+ * @example ```js
2377
+ * const text = getText(node, { blockSeparator: '\n' })
2378
+ * ```
2379
+ */
2216
2380
  function getText(node, options) {
2217
2381
  const range = {
2218
2382
  from: 0,
@@ -2221,6 +2385,13 @@
2221
2385
  return getTextBetween(node, range, options);
2222
2386
  }
2223
2387
 
2388
+ /**
2389
+ * Generate raw text from a JSONContent
2390
+ * @param doc The JSONContent to generate text from
2391
+ * @param extensions The extensions to use for the schema
2392
+ * @param options Options for the text generation f.e. blockSeparator or textSerializers
2393
+ * @returns The generated text
2394
+ */
2224
2395
  function generateText(doc, extensions, options) {
2225
2396
  const { blockSeparator = '\n\n', textSerializers = {} } = options || {};
2226
2397
  const schema = getSchema(extensions);
@@ -2248,6 +2419,12 @@
2248
2419
  return { ...node.attrs };
2249
2420
  }
2250
2421
 
2422
+ /**
2423
+ * Get node or mark attributes by type or name on the current editor state
2424
+ * @param state The current editor state
2425
+ * @param typeOrName The node or mark type or name
2426
+ * @returns The attributes of the node or mark or an empty object
2427
+ */
2251
2428
  function getAttributes(state, typeOrName) {
2252
2429
  const schemaType = getSchemaTypeNameByName(typeof typeOrName === 'string' ? typeOrName : typeOrName.name, state.schema);
2253
2430
  if (schemaType === 'node') {
@@ -2432,6 +2609,13 @@
2432
2609
  return [node, currentDepth];
2433
2610
  };
2434
2611
 
2612
+ /**
2613
+ * Return attributes of an extension that should be splitted by keepOnSplit flag
2614
+ * @param extensionAttributes Array of extension attributes
2615
+ * @param typeName The type of the extension
2616
+ * @param attributes The attributes of the extension
2617
+ * @returns The splitted attributes
2618
+ */
2435
2619
  function getSplittedAttributes(extensionAttributes, typeName, attributes) {
2436
2620
  return Object.fromEntries(Object
2437
2621
  .entries(attributes)
@@ -3282,7 +3466,12 @@
3282
3466
  const isAtStart = (parentIsIsolating && $parentPos.parent.childCount === 1)
3283
3467
  ? parentPos === $anchor.pos
3284
3468
  : state.Selection.atStart(doc).from === pos;
3285
- if (!empty || !isAtStart || !parent.type.isTextblock || parent.textContent.length) {
3469
+ if (!empty
3470
+ || !parent.type.isTextblock
3471
+ || parent.textContent.length
3472
+ || !isAtStart
3473
+ || (isAtStart && $anchor.parent.type.name === 'paragraph') // prevent clearNodes when no nodes to clear, otherwise history stack is appended
3474
+ ) {
3286
3475
  return false;
3287
3476
  }
3288
3477
  return commands.clearNodes();
@@ -4054,6 +4243,7 @@ img.ProseMirror-separator {
4054
4243
  /**
4055
4244
  * Build an input rule that adds a mark when the
4056
4245
  * matched text is typed into it.
4246
+ * @see https://tiptap.dev/guide/custom-extensions/#input-rules
4057
4247
  */
4058
4248
  function markInputRule(config) {
4059
4249
  return new InputRule({
@@ -4097,6 +4287,7 @@ img.ProseMirror-separator {
4097
4287
  /**
4098
4288
  * Build an input rule that adds a node when the
4099
4289
  * matched text is typed into it.
4290
+ * @see https://tiptap.dev/guide/custom-extensions/#input-rules
4100
4291
  */
4101
4292
  function nodeInputRule(config) {
4102
4293
  return new InputRule({
@@ -4123,7 +4314,8 @@ img.ProseMirror-separator {
4123
4314
  tr.replaceWith(matchStart, end, newNode);
4124
4315
  }
4125
4316
  else if (match[0]) {
4126
- tr.insert(start - 1, config.type.create(attributes)).delete(tr.mapping.map(start), tr.mapping.map(end));
4317
+ const insertionStart = config.type.isInline ? start : start - 1;
4318
+ tr.insert(insertionStart, config.type.create(attributes)).delete(tr.mapping.map(start), tr.mapping.map(end));
4127
4319
  }
4128
4320
  tr.scrollIntoView();
4129
4321
  },
@@ -4135,6 +4327,7 @@ img.ProseMirror-separator {
4135
4327
  * matched text is typed into it. When using a regular expresion you’ll
4136
4328
  * probably want the regexp to start with `^`, so that the pattern can
4137
4329
  * only occur at the start of a textblock.
4330
+ * @see https://tiptap.dev/guide/custom-extensions/#input-rules
4138
4331
  */
4139
4332
  function textblockTypeInputRule(config) {
4140
4333
  return new InputRule({
@@ -4155,6 +4348,7 @@ img.ProseMirror-separator {
4155
4348
  /**
4156
4349
  * Build an input rule that replaces text when the
4157
4350
  * matched text is typed into it.
4351
+ * @see https://tiptap.dev/guide/custom-extensions/#input-rules
4158
4352
  */
4159
4353
  function textInputRule(config) {
4160
4354
  return new InputRule({
@@ -4191,6 +4385,7 @@ img.ProseMirror-separator {
4191
4385
  * two nodes. You can pass a join predicate, which takes a regular
4192
4386
  * expression match and the node before the wrapped node, and can
4193
4387
  * return a boolean to indicate whether a join should happen.
4388
+ * @see https://tiptap.dev/guide/custom-extensions/#input-rules
4194
4389
  */
4195
4390
  function wrappingInputRule(config) {
4196
4391
  return new InputRule({
@@ -4230,6 +4425,10 @@ img.ProseMirror-separator {
4230
4425
  });
4231
4426
  }
4232
4427
 
4428
+ /**
4429
+ * The Mark class is used to create custom mark extensions.
4430
+ * @see https://tiptap.dev/api/extensions#create-a-new-extension
4431
+ */
4233
4432
  class Mark {
4234
4433
  constructor(config = {}) {
4235
4434
  this.type = 'mark';
@@ -4313,6 +4512,10 @@ img.ProseMirror-separator {
4313
4512
  }
4314
4513
  }
4315
4514
 
4515
+ /**
4516
+ * The Node class is used to create custom node extensions.
4517
+ * @see https://tiptap.dev/api/extensions#create-a-new-extension
4518
+ */
4316
4519
  class Node {
4317
4520
  constructor(config = {}) {
4318
4521
  this.type = 'node';
@@ -4380,6 +4583,10 @@ img.ProseMirror-separator {
4380
4583
  return navigator.platform === 'Android' || /android/i.test(navigator.userAgent);
4381
4584
  }
4382
4585
 
4586
+ /**
4587
+ * Node views are used to customize the rendered DOM structure of a node.
4588
+ * @see https://tiptap.dev/guide/node-views
4589
+ */
4383
4590
  class NodeView {
4384
4591
  constructor(component, props, options) {
4385
4592
  this.isDragging = false;
@@ -4570,6 +4777,7 @@ img.ProseMirror-separator {
4570
4777
  /**
4571
4778
  * Build an paste rule that adds a mark when the
4572
4779
  * matched text is pasted into it.
4780
+ * @see https://tiptap.dev/guide/custom-extensions/#paste-rules
4573
4781
  */
4574
4782
  function markPasteRule(config) {
4575
4783
  return new PasteRule({
@@ -4623,6 +4831,7 @@ img.ProseMirror-separator {
4623
4831
  /**
4624
4832
  * Build an paste rule that adds a node when the
4625
4833
  * matched text is pasted into it.
4834
+ * @see https://tiptap.dev/guide/custom-extensions/#paste-rules
4626
4835
  */
4627
4836
  function nodePasteRule(config) {
4628
4837
  return new PasteRule({
@@ -4645,6 +4854,7 @@ img.ProseMirror-separator {
4645
4854
  /**
4646
4855
  * Build an paste rule that replaces text when the
4647
4856
  * matched text is pasted into it.
4857
+ * @see https://tiptap.dev/guide/custom-extensions/#paste-rules
4648
4858
  */
4649
4859
  function textPasteRule(config) {
4650
4860
  return new PasteRule({