@tiptap/core 2.0.0-beta.2 → 2.0.0-beta.200

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 (331) hide show
  1. package/README.md +2 -2
  2. package/dist/packages/core/src/CommandManager.d.ts +13 -6
  3. package/dist/packages/core/src/Editor.d.ts +27 -25
  4. package/dist/packages/core/src/EventEmitter.d.ts +8 -4
  5. package/dist/packages/core/src/Extension.d.ts +103 -26
  6. package/dist/packages/core/src/ExtensionManager.d.ts +8 -12
  7. package/dist/packages/core/src/InputRule.d.ts +42 -0
  8. package/dist/packages/core/src/Mark.d.ts +148 -31
  9. package/dist/packages/core/src/Node.d.ts +162 -33
  10. package/dist/packages/core/src/NodeView.d.ts +27 -0
  11. package/dist/packages/core/src/PasteRule.d.ts +42 -0
  12. package/dist/packages/core/src/Tracker.d.ts +11 -0
  13. package/dist/packages/core/src/commands/blur.d.ts +3 -3
  14. package/dist/packages/core/src/commands/clearContent.d.ts +3 -3
  15. package/dist/packages/core/src/commands/clearNodes.d.ts +3 -3
  16. package/dist/packages/core/src/commands/command.d.ts +2 -2
  17. package/dist/packages/core/src/commands/createParagraphNear.d.ts +3 -3
  18. package/dist/packages/core/src/commands/deleteNode.d.ts +13 -0
  19. package/dist/packages/core/src/commands/deleteRange.d.ts +3 -3
  20. package/dist/packages/core/src/commands/deleteSelection.d.ts +3 -3
  21. package/dist/packages/core/src/commands/enter.d.ts +3 -3
  22. package/dist/packages/core/src/commands/exitCode.d.ts +3 -3
  23. package/dist/packages/core/src/commands/extendMarkRange.d.ts +3 -3
  24. package/dist/packages/core/src/commands/first.d.ts +3 -3
  25. package/dist/packages/core/src/commands/focus.d.ts +5 -3
  26. package/dist/packages/core/src/commands/forEach.d.ts +14 -0
  27. package/dist/packages/core/src/commands/index.d.ts +50 -0
  28. package/dist/packages/core/src/commands/insertContent.d.ts +16 -0
  29. package/dist/packages/core/src/commands/insertContentAt.d.ts +16 -0
  30. package/dist/packages/core/src/commands/joinBackward.d.ts +3 -3
  31. package/dist/packages/core/src/commands/joinForward.d.ts +3 -3
  32. package/dist/packages/core/src/commands/keyboardShortcut.d.ts +3 -3
  33. package/dist/packages/core/src/commands/lift.d.ts +3 -3
  34. package/dist/packages/core/src/commands/liftEmptyBlock.d.ts +3 -3
  35. package/dist/packages/core/src/commands/liftListItem.d.ts +3 -3
  36. package/dist/packages/core/src/commands/newlineInCode.d.ts +3 -3
  37. package/dist/packages/core/src/commands/resetAttributes.d.ts +13 -0
  38. package/dist/packages/core/src/commands/scrollIntoView.d.ts +3 -3
  39. package/dist/packages/core/src/commands/selectAll.d.ts +3 -3
  40. package/dist/packages/core/src/commands/selectNodeBackward.d.ts +3 -3
  41. package/dist/packages/core/src/commands/selectNodeForward.d.ts +3 -3
  42. package/dist/packages/core/src/commands/selectParentNode.d.ts +3 -3
  43. package/dist/packages/core/src/commands/selectTextblockEnd.d.ts +12 -0
  44. package/dist/packages/core/src/commands/selectTextblockStart.d.ts +12 -0
  45. package/dist/packages/core/src/commands/setContent.d.ts +4 -3
  46. package/dist/packages/core/src/commands/setMark.d.ts +3 -3
  47. package/dist/packages/core/src/commands/setMeta.d.ts +12 -0
  48. package/dist/packages/core/src/commands/setNode.d.ts +3 -3
  49. package/dist/packages/core/src/commands/setNodeSelection.d.ts +12 -0
  50. package/dist/packages/core/src/commands/setTextSelection.d.ts +12 -0
  51. package/dist/packages/core/src/commands/sinkListItem.d.ts +3 -3
  52. package/dist/packages/core/src/commands/splitBlock.d.ts +3 -3
  53. package/dist/packages/core/src/commands/splitListItem.d.ts +3 -3
  54. package/dist/packages/core/src/commands/toggleList.d.ts +3 -3
  55. package/dist/packages/core/src/commands/toggleMark.d.ts +8 -3
  56. package/dist/packages/core/src/commands/toggleNode.d.ts +3 -3
  57. package/dist/packages/core/src/commands/toggleWrap.d.ts +3 -3
  58. package/dist/packages/core/src/commands/undoInputRule.d.ts +3 -3
  59. package/dist/packages/core/src/commands/unsetAllMarks.d.ts +3 -3
  60. package/dist/packages/core/src/commands/unsetMark.d.ts +8 -3
  61. package/dist/packages/core/src/commands/updateAttributes.d.ts +13 -0
  62. package/dist/packages/core/src/commands/wrapIn.d.ts +3 -3
  63. package/dist/packages/core/src/commands/wrapInList.d.ts +3 -3
  64. package/dist/packages/core/src/extensions/clipboardTextSerializer.d.ts +1 -1
  65. package/dist/packages/core/src/extensions/commands.d.ts +2 -91
  66. package/dist/packages/core/src/extensions/editable.d.ts +1 -1
  67. package/dist/packages/core/src/extensions/focusEvents.d.ts +1 -1
  68. package/dist/packages/core/src/extensions/index.d.ts +1 -0
  69. package/dist/packages/core/src/extensions/keymap.d.ts +1 -1
  70. package/dist/packages/core/src/extensions/tabindex.d.ts +2 -0
  71. package/dist/packages/core/src/helpers/combineTransactionSteps.d.ts +7 -0
  72. package/dist/packages/core/src/helpers/createChainableState.d.ts +5 -0
  73. package/dist/packages/core/src/helpers/createDocument.d.ts +3 -0
  74. package/dist/packages/core/src/helpers/createNodeFromContent.d.ts +7 -0
  75. package/dist/packages/core/src/helpers/defaultBlockAt.d.ts +2 -0
  76. package/dist/packages/core/src/helpers/findChildren.d.ts +3 -0
  77. package/dist/packages/core/src/helpers/findChildrenInRange.d.ts +6 -0
  78. package/dist/packages/core/src/helpers/findParentNode.d.ts +2 -3
  79. package/dist/packages/core/src/helpers/findParentNodeClosestToPos.d.ts +2 -2
  80. package/dist/packages/core/src/helpers/generateHTML.d.ts +2 -2
  81. package/dist/packages/core/src/helpers/generateJSON.d.ts +2 -0
  82. package/dist/packages/core/src/helpers/generateText.d.ts +5 -0
  83. package/dist/packages/core/src/helpers/getAttributes.d.ts +3 -0
  84. package/dist/packages/core/src/helpers/getAttributesFromExtensions.d.ts +2 -2
  85. package/dist/packages/core/src/helpers/getChangedRanges.d.ts +11 -0
  86. package/dist/packages/core/src/helpers/getDebugJSON.d.ts +8 -0
  87. package/dist/packages/core/src/helpers/getExtensionField.d.ts +2 -0
  88. package/dist/packages/core/src/helpers/getHTMLFromFragment.d.ts +2 -2
  89. package/dist/packages/core/src/helpers/getMarkAttributes.d.ts +2 -3
  90. package/dist/packages/core/src/helpers/getMarkRange.d.ts +1 -1
  91. package/dist/packages/core/src/helpers/getMarkType.d.ts +1 -1
  92. package/dist/packages/core/src/helpers/getMarksBetween.d.ts +2 -2
  93. package/dist/packages/core/src/helpers/getNodeAttributes.d.ts +2 -3
  94. package/dist/packages/core/src/helpers/getNodeType.d.ts +1 -1
  95. package/dist/packages/core/src/helpers/getRenderedAttributes.d.ts +3 -3
  96. package/dist/packages/core/src/helpers/getSchema.d.ts +1 -1
  97. package/dist/packages/core/src/helpers/getSchemaByResolvedExtensions.d.ts +3 -0
  98. package/dist/packages/core/src/helpers/getSchemaTypeByName.d.ts +1 -1
  99. package/dist/packages/core/src/helpers/getSchemaTypeNameByName.d.ts +1 -1
  100. package/dist/packages/core/src/helpers/getSplittedAttributes.d.ts +2 -2
  101. package/dist/packages/core/src/helpers/getText.d.ts +6 -0
  102. package/dist/packages/core/src/helpers/getTextBetween.d.ts +6 -0
  103. package/dist/packages/core/src/helpers/getTextContentFromNodes.d.ts +2 -0
  104. package/dist/packages/core/src/helpers/getTextSerializersFromSchema.d.ts +3 -0
  105. package/dist/packages/core/src/helpers/index.d.ts +33 -0
  106. package/dist/packages/core/src/helpers/injectExtensionAttributesToParseRule.d.ts +1 -1
  107. package/dist/packages/core/src/helpers/isActive.d.ts +1 -2
  108. package/dist/packages/core/src/helpers/isExtensionRulesEnabled.d.ts +2 -0
  109. package/dist/packages/core/src/helpers/isList.d.ts +1 -1
  110. package/dist/packages/core/src/helpers/isMarkActive.d.ts +2 -3
  111. package/dist/packages/core/src/helpers/isNodeActive.d.ts +2 -3
  112. package/dist/packages/core/src/helpers/isNodeEmpty.d.ts +2 -0
  113. package/dist/packages/core/src/helpers/isNodeSelection.d.ts +1 -1
  114. package/dist/packages/core/src/helpers/isTextSelection.d.ts +1 -1
  115. package/dist/packages/core/src/helpers/posToDOMRect.d.ts +2 -0
  116. package/dist/packages/core/src/helpers/resolveFocusPosition.d.ts +4 -0
  117. package/dist/packages/core/src/helpers/selectionToInsertionEnd.d.ts +1 -1
  118. package/dist/packages/core/src/helpers/splitExtensions.d.ts +6 -6
  119. package/dist/packages/core/src/index.d.ts +15 -20
  120. package/dist/packages/core/src/inputRules/index.d.ts +5 -0
  121. package/dist/packages/core/src/inputRules/markInputRule.d.ts +11 -2
  122. package/dist/packages/core/src/inputRules/nodeInputRule.d.ts +11 -2
  123. package/dist/packages/core/src/inputRules/textInputRule.d.ts +9 -0
  124. package/dist/packages/core/src/inputRules/textblockTypeInputRule.d.ts +14 -0
  125. package/dist/packages/core/src/inputRules/wrappingInputRule.d.ts +23 -0
  126. package/dist/packages/core/src/pasteRules/index.d.ts +3 -0
  127. package/dist/packages/core/src/pasteRules/markPasteRule.d.ts +11 -2
  128. package/dist/packages/core/src/pasteRules/nodePasteRule.d.ts +12 -0
  129. package/dist/packages/core/src/pasteRules/textPasteRule.d.ts +9 -0
  130. package/dist/packages/core/src/style.d.ts +1 -2
  131. package/dist/packages/core/src/types.d.ts +120 -53
  132. package/dist/packages/core/src/utilities/callOrReturn.d.ts +2 -1
  133. package/dist/packages/core/src/utilities/createStyleTag.d.ts +1 -1
  134. package/dist/packages/core/src/utilities/deleteProps.d.ts +1 -2
  135. package/dist/packages/core/src/utilities/elementFromString.d.ts +1 -1
  136. package/dist/packages/core/src/utilities/escapeForRegEx.d.ts +1 -0
  137. package/dist/packages/core/src/utilities/findDuplicates.d.ts +1 -0
  138. package/dist/packages/core/src/utilities/fromString.d.ts +1 -1
  139. package/dist/packages/core/src/utilities/index.d.ts +3 -0
  140. package/dist/packages/core/src/utilities/isEmptyObject.d.ts +1 -1
  141. package/dist/packages/core/src/utilities/isFunction.d.ts +1 -0
  142. package/dist/packages/core/src/utilities/isMacOS.d.ts +1 -0
  143. package/dist/packages/core/src/utilities/isNumber.d.ts +1 -0
  144. package/dist/packages/core/src/utilities/isPlainObject.d.ts +1 -1
  145. package/dist/packages/core/src/utilities/isRegExp.d.ts +1 -0
  146. package/dist/packages/core/src/utilities/isiOS.d.ts +1 -0
  147. package/dist/packages/core/src/utilities/mergeAttributes.d.ts +1 -2
  148. package/dist/packages/core/src/utilities/mergeDeep.d.ts +1 -2
  149. package/dist/packages/core/src/utilities/minMax.d.ts +1 -1
  150. package/dist/packages/core/src/utilities/objectIncludes.d.ts +3 -2
  151. package/dist/packages/core/src/utilities/removeDuplicates.d.ts +8 -0
  152. package/dist/tiptap-core.cjs.js +2896 -1261
  153. package/dist/tiptap-core.cjs.js.map +1 -1
  154. package/dist/tiptap-core.esm.js +2889 -1290
  155. package/dist/tiptap-core.esm.js.map +1 -1
  156. package/dist/tiptap-core.umd.js +2899 -1263
  157. package/dist/tiptap-core.umd.js.map +1 -1
  158. package/package.json +16 -20
  159. package/src/CommandManager.ts +64 -65
  160. package/src/Editor.ts +133 -98
  161. package/src/EventEmitter.ts +14 -4
  162. package/src/Extension.ts +198 -41
  163. package/src/ExtensionManager.ts +263 -78
  164. package/src/InputRule.ts +265 -0
  165. package/src/Mark.ts +285 -49
  166. package/src/Node.ts +284 -56
  167. package/src/NodeView.ts +261 -0
  168. package/src/PasteRule.ts +280 -0
  169. package/src/Tracker.ts +42 -0
  170. package/src/commands/blur.ts +12 -6
  171. package/src/commands/clearContent.ts +3 -3
  172. package/src/commands/clearNodes.ts +32 -18
  173. package/src/commands/command.ts +2 -2
  174. package/src/commands/createParagraphNear.ts +4 -3
  175. package/src/commands/deleteNode.ts +37 -0
  176. package/src/commands/deleteRange.ts +3 -3
  177. package/src/commands/deleteSelection.ts +4 -3
  178. package/src/commands/enter.ts +3 -3
  179. package/src/commands/exitCode.ts +4 -3
  180. package/src/commands/extendMarkRange.ts +12 -11
  181. package/src/commands/first.ts +3 -3
  182. package/src/commands/focus.ts +47 -44
  183. package/src/commands/forEach.ts +24 -0
  184. package/src/commands/index.ts +50 -0
  185. package/src/commands/insertContent.ts +24 -0
  186. package/src/commands/insertContentAt.ts +108 -0
  187. package/src/commands/joinBackward.ts +4 -3
  188. package/src/commands/joinForward.ts +4 -3
  189. package/src/commands/keyboardShortcut.ts +6 -6
  190. package/src/commands/lift.ts +6 -5
  191. package/src/commands/liftEmptyBlock.ts +4 -3
  192. package/src/commands/liftListItem.ts +6 -5
  193. package/src/commands/newlineInCode.ts +4 -3
  194. package/src/commands/resetAttributes.ts +62 -0
  195. package/src/commands/scrollIntoView.ts +3 -3
  196. package/src/commands/selectAll.ts +8 -6
  197. package/src/commands/selectNodeBackward.ts +4 -3
  198. package/src/commands/selectNodeForward.ts +4 -3
  199. package/src/commands/selectParentNode.ts +4 -3
  200. package/src/commands/selectTextblockEnd.ts +20 -0
  201. package/src/commands/selectTextblockStart.ts +20 -0
  202. package/src/commands/setContent.ts +12 -9
  203. package/src/commands/setMark.ts +83 -15
  204. package/src/commands/setMeta.ts +18 -0
  205. package/src/commands/setNode.ts +29 -7
  206. package/src/commands/setNodeSelection.ts +27 -0
  207. package/src/commands/setTextSelection.ts +33 -0
  208. package/src/commands/sinkListItem.ts +6 -5
  209. package/src/commands/splitBlock.ts +20 -23
  210. package/src/commands/splitListItem.ts +45 -18
  211. package/src/commands/toggleList.ts +83 -18
  212. package/src/commands/toggleMark.ts +18 -7
  213. package/src/commands/toggleNode.ts +6 -5
  214. package/src/commands/toggleWrap.ts +9 -9
  215. package/src/commands/undoInputRule.ts +34 -5
  216. package/src/commands/unsetAllMarks.ts +8 -10
  217. package/src/commands/unsetMark.ts +31 -13
  218. package/src/commands/updateAttributes.ts +73 -0
  219. package/src/commands/wrapIn.ts +5 -10
  220. package/src/commands/wrapInList.ts +6 -5
  221. package/src/extensions/clipboardTextSerializer.ts +14 -35
  222. package/src/extensions/commands.ts +3 -135
  223. package/src/extensions/editable.ts +1 -0
  224. package/src/extensions/focusEvents.ts +3 -5
  225. package/src/extensions/index.ts +1 -0
  226. package/src/extensions/keymap.ts +110 -13
  227. package/src/extensions/tabindex.ts +18 -0
  228. package/src/helpers/combineTransactionSteps.ts +18 -0
  229. package/src/helpers/createChainableState.ts +38 -0
  230. package/src/helpers/createDocument.ts +12 -0
  231. package/src/helpers/createNodeFromContent.ts +57 -0
  232. package/src/helpers/defaultBlockAt.ts +13 -0
  233. package/src/helpers/findChildren.ts +18 -0
  234. package/src/helpers/findChildrenInRange.ts +32 -0
  235. package/src/helpers/findParentNode.ts +3 -2
  236. package/src/helpers/findParentNodeClosestToPos.ts +3 -2
  237. package/src/helpers/generateHTML.ts +6 -5
  238. package/src/helpers/generateJSON.ts +14 -0
  239. package/src/helpers/generateText.ts +30 -0
  240. package/src/helpers/getAttributes.ts +28 -0
  241. package/src/helpers/getAttributesFromExtensions.ts +42 -14
  242. package/src/helpers/getChangedRanges.ts +83 -0
  243. package/src/helpers/getDebugJSON.ts +54 -0
  244. package/src/helpers/getExtensionField.ts +25 -0
  245. package/src/helpers/getHTMLFromFragment.ts +6 -5
  246. package/src/helpers/getMarkAttributes.ts +14 -10
  247. package/src/helpers/getMarkRange.ts +41 -8
  248. package/src/helpers/getMarkType.ts +5 -1
  249. package/src/helpers/getMarksBetween.ts +32 -10
  250. package/src/helpers/getNodeAttributes.ts +9 -9
  251. package/src/helpers/getNodeType.ts +5 -1
  252. package/src/helpers/getRenderedAttributes.ts +6 -7
  253. package/src/helpers/getSchema.ts +7 -137
  254. package/src/helpers/getSchemaByResolvedExtensions.ts +148 -0
  255. package/src/helpers/getSchemaTypeByName.ts +2 -10
  256. package/src/helpers/getSchemaTypeNameByName.ts +1 -1
  257. package/src/helpers/getSplittedAttributes.ts +4 -4
  258. package/src/helpers/getText.ts +19 -0
  259. package/src/helpers/getTextBetween.ts +49 -0
  260. package/src/helpers/getTextContentFromNodes.ts +21 -0
  261. package/src/helpers/getTextSerializersFromSchema.ts +10 -0
  262. package/src/helpers/index.ts +33 -0
  263. package/src/helpers/injectExtensionAttributesToParseRule.ts +17 -19
  264. package/src/helpers/isActive.ts +5 -5
  265. package/src/helpers/isExtensionRulesEnabled.ts +15 -0
  266. package/src/helpers/isList.ts +14 -7
  267. package/src/helpers/isMarkActive.ts +45 -20
  268. package/src/helpers/isNodeActive.ts +28 -35
  269. package/src/helpers/isNodeEmpty.ts +8 -0
  270. package/src/helpers/isNodeSelection.ts +2 -3
  271. package/src/helpers/isTextSelection.ts +2 -3
  272. package/src/helpers/posToDOMRect.ts +35 -0
  273. package/src/helpers/resolveFocusPosition.ts +43 -0
  274. package/src/helpers/selectionToInsertionEnd.ts +2 -2
  275. package/src/helpers/splitExtensions.ts +3 -3
  276. package/src/index.ts +16 -22
  277. package/src/inputRules/index.ts +5 -0
  278. package/src/inputRules/markInputRule.ts +59 -39
  279. package/src/inputRules/nodeInputRule.ts +45 -11
  280. package/src/inputRules/textInputRule.ts +35 -0
  281. package/src/inputRules/textblockTypeInputRule.ts +38 -0
  282. package/src/inputRules/wrappingInputRule.ts +60 -0
  283. package/src/pasteRules/index.ts +3 -0
  284. package/src/pasteRules/markPasteRule.ts +62 -53
  285. package/src/pasteRules/nodePasteRule.ts +39 -0
  286. package/src/pasteRules/textPasteRule.ts +35 -0
  287. package/src/style.ts +16 -3
  288. package/src/types.ts +132 -47
  289. package/src/utilities/callOrReturn.ts +6 -3
  290. package/src/utilities/createStyleTag.ts +12 -1
  291. package/src/utilities/deleteProps.ts +2 -4
  292. package/src/utilities/elementFromString.ts +4 -5
  293. package/src/utilities/escapeForRegEx.ts +4 -0
  294. package/src/utilities/findDuplicates.ts +5 -0
  295. package/src/utilities/fromString.ts +2 -2
  296. package/src/utilities/index.ts +3 -0
  297. package/src/utilities/isEmptyObject.ts +2 -2
  298. package/src/utilities/isFunction.ts +3 -0
  299. package/src/utilities/isMacOS.ts +5 -0
  300. package/src/utilities/isNumber.ts +3 -0
  301. package/src/utilities/isPlainObject.ts +8 -5
  302. package/src/utilities/isRegExp.ts +3 -0
  303. package/src/utilities/isString.ts +3 -0
  304. package/src/utilities/isiOS.ts +12 -0
  305. package/src/utilities/mergeAttributes.ts +2 -3
  306. package/src/utilities/mergeDeep.ts +2 -3
  307. package/src/utilities/minMax.ts +1 -1
  308. package/src/utilities/objectIncludes.ts +17 -5
  309. package/src/utilities/removeDuplicates.ts +15 -0
  310. package/CHANGELOG.md +0 -198
  311. package/LICENSE.md +0 -21
  312. package/dist/packages/core/src/commands/insertHTML.d.ts +0 -12
  313. package/dist/packages/core/src/commands/insertText.d.ts +0 -12
  314. package/dist/packages/core/src/commands/replace.d.ts +0 -13
  315. package/dist/packages/core/src/commands/replaceRange.d.ts +0 -13
  316. package/dist/packages/core/src/commands/resetNodeAttributes.d.ts +0 -13
  317. package/dist/packages/core/src/commands/updateNodeAttributes.d.ts +0 -13
  318. package/dist/packages/core/src/utilities/isClass.d.ts +0 -1
  319. package/dist/packages/core/src/utilities/isObject.d.ts +0 -1
  320. package/dist/packages/core/src/utilities/removeElement.d.ts +0 -1
  321. package/dist/tiptap-core.bundle.umd.min.js +0 -17
  322. package/dist/tiptap-core.bundle.umd.min.js.map +0 -1
  323. package/src/commands/insertHTML.ts +0 -28
  324. package/src/commands/insertText.ts +0 -20
  325. package/src/commands/replace.ts +0 -20
  326. package/src/commands/replaceRange.ts +0 -36
  327. package/src/commands/resetNodeAttributes.ts +0 -29
  328. package/src/commands/updateNodeAttributes.ts +0 -31
  329. package/src/utilities/isClass.ts +0 -7
  330. package/src/utilities/isObject.ts +0 -10
  331. package/src/utilities/removeElement.ts +0 -5
@@ -1,18 +1,25 @@
1
1
  import { keymap } from 'prosemirror-keymap'
2
- import { Schema, Node as ProsemirrorNode } from 'prosemirror-model'
3
- import { inputRules as inputRulesPlugin } from 'prosemirror-inputrules'
4
- import { EditorView, Decoration } from 'prosemirror-view'
2
+ import { Node as ProsemirrorNode, Schema } from 'prosemirror-model'
5
3
  import { Plugin } from 'prosemirror-state'
6
- import { Editor } from './Editor'
7
- import { Extensions, NodeViewRenderer, RawCommands } from './types'
8
- import getSchema from './helpers/getSchema'
9
- import getSchemaTypeByName from './helpers/getSchemaTypeByName'
10
- import getNodeType from './helpers/getNodeType'
11
- import splitExtensions from './helpers/splitExtensions'
12
- import getAttributesFromExtensions from './helpers/getAttributesFromExtensions'
13
- import getRenderedAttributes from './helpers/getRenderedAttributes'
4
+ import { Decoration, EditorView } from 'prosemirror-view'
14
5
 
15
- export default class ExtensionManager {
6
+ import { Mark, NodeConfig } from '.'
7
+ import { Editor } from './Editor'
8
+ import { getAttributesFromExtensions } from './helpers/getAttributesFromExtensions'
9
+ import { getExtensionField } from './helpers/getExtensionField'
10
+ import { getNodeType } from './helpers/getNodeType'
11
+ import { getRenderedAttributes } from './helpers/getRenderedAttributes'
12
+ import { getSchemaByResolvedExtensions } from './helpers/getSchemaByResolvedExtensions'
13
+ import { getSchemaTypeByName } from './helpers/getSchemaTypeByName'
14
+ import { isExtensionRulesEnabled } from './helpers/isExtensionRulesEnabled'
15
+ import { splitExtensions } from './helpers/splitExtensions'
16
+ import { inputRulesPlugin } from './InputRule'
17
+ import { pasteRulesPlugin } from './PasteRule'
18
+ import { AnyConfig, Extensions, RawCommands } from './types'
19
+ import { callOrReturn } from './utilities/callOrReturn'
20
+ import { findDuplicates } from './utilities/findDuplicates'
21
+
22
+ export class ExtensionManager {
16
23
 
17
24
  editor: Editor
18
25
 
@@ -20,106 +27,282 @@ export default class ExtensionManager {
20
27
 
21
28
  extensions: Extensions
22
29
 
30
+ splittableMarks: string[] = []
31
+
23
32
  constructor(extensions: Extensions, editor: Editor) {
24
33
  this.editor = editor
25
- this.extensions = extensions
26
- this.schema = getSchema(this.extensions)
34
+ this.extensions = ExtensionManager.resolve(extensions)
35
+ this.schema = getSchemaByResolvedExtensions(this.extensions)
27
36
 
28
37
  this.extensions.forEach(extension => {
38
+ // store extension storage in editor
39
+ this.editor.extensionStorage[extension.name] = extension.storage
40
+
29
41
  const context = {
42
+ name: extension.name,
30
43
  options: extension.options,
44
+ storage: extension.storage,
31
45
  editor: this.editor,
32
- type: getSchemaTypeByName(extension.config.name, this.schema),
46
+ type: getSchemaTypeByName(extension.name, this.schema),
33
47
  }
34
48
 
35
- if (typeof extension.config.onCreate === 'function') {
36
- this.editor.on('create', extension.config.onCreate.bind(context))
49
+ if (extension.type === 'mark') {
50
+ const keepOnSplit = callOrReturn(getExtensionField(extension, 'keepOnSplit', context)) ?? true
51
+
52
+ if (keepOnSplit) {
53
+ this.splittableMarks.push(extension.name)
54
+ }
55
+ }
56
+
57
+ const onBeforeCreate = getExtensionField<AnyConfig['onBeforeCreate']>(
58
+ extension,
59
+ 'onBeforeCreate',
60
+ context,
61
+ )
62
+
63
+ if (onBeforeCreate) {
64
+ this.editor.on('beforeCreate', onBeforeCreate)
37
65
  }
38
66
 
39
- if (typeof extension.config.onUpdate === 'function') {
40
- this.editor.on('update', extension.config.onUpdate.bind(context))
67
+ const onCreate = getExtensionField<AnyConfig['onCreate']>(
68
+ extension,
69
+ 'onCreate',
70
+ context,
71
+ )
72
+
73
+ if (onCreate) {
74
+ this.editor.on('create', onCreate)
41
75
  }
42
76
 
43
- if (typeof extension.config.onSelectionUpdate === 'function') {
44
- this.editor.on('selectionUpdate', extension.config.onSelectionUpdate.bind(context))
77
+ const onUpdate = getExtensionField<AnyConfig['onUpdate']>(
78
+ extension,
79
+ 'onUpdate',
80
+ context,
81
+ )
82
+
83
+ if (onUpdate) {
84
+ this.editor.on('update', onUpdate)
45
85
  }
46
86
 
47
- if (typeof extension.config.onViewUpdate === 'function') {
48
- this.editor.on('viewUpdate', extension.config.onViewUpdate.bind(context))
87
+ const onSelectionUpdate = getExtensionField<AnyConfig['onSelectionUpdate']>(
88
+ extension,
89
+ 'onSelectionUpdate',
90
+ context,
91
+ )
92
+
93
+ if (onSelectionUpdate) {
94
+ this.editor.on('selectionUpdate', onSelectionUpdate)
49
95
  }
50
96
 
51
- if (typeof extension.config.onTransaction === 'function') {
52
- this.editor.on('transaction', extension.config.onTransaction.bind(context))
97
+ const onTransaction = getExtensionField<AnyConfig['onTransaction']>(
98
+ extension,
99
+ 'onTransaction',
100
+ context,
101
+ )
102
+
103
+ if (onTransaction) {
104
+ this.editor.on('transaction', onTransaction)
53
105
  }
54
106
 
55
- if (typeof extension.config.onFocus === 'function') {
56
- this.editor.on('focus', extension.config.onFocus.bind(context))
107
+ const onFocus = getExtensionField<AnyConfig['onFocus']>(
108
+ extension,
109
+ 'onFocus',
110
+ context,
111
+ )
112
+
113
+ if (onFocus) {
114
+ this.editor.on('focus', onFocus)
57
115
  }
58
116
 
59
- if (typeof extension.config.onBlur === 'function') {
60
- this.editor.on('blur', extension.config.onBlur.bind(context))
117
+ const onBlur = getExtensionField<AnyConfig['onBlur']>(
118
+ extension,
119
+ 'onBlur',
120
+ context,
121
+ )
122
+
123
+ if (onBlur) {
124
+ this.editor.on('blur', onBlur)
61
125
  }
62
126
 
63
- if (typeof extension.config.onDestroy === 'function') {
64
- this.editor.on('destroy', extension.config.onDestroy.bind(context))
127
+ const onDestroy = getExtensionField<AnyConfig['onDestroy']>(
128
+ extension,
129
+ 'onDestroy',
130
+ context,
131
+ )
132
+
133
+ if (onDestroy) {
134
+ this.editor.on('destroy', onDestroy)
65
135
  }
66
136
  })
67
137
  }
68
138
 
139
+ static resolve(extensions: Extensions): Extensions {
140
+ const resolvedExtensions = ExtensionManager.sort(ExtensionManager.flatten(extensions))
141
+ const duplicatedNames = findDuplicates(resolvedExtensions.map(extension => extension.name))
142
+
143
+ if (duplicatedNames.length) {
144
+ console.warn(`[tiptap warn]: Duplicate extension names found: [${duplicatedNames.map(item => `'${item}'`).join(', ')}]. This can lead to issues.`)
145
+ }
146
+
147
+ return resolvedExtensions
148
+ }
149
+
150
+ static flatten(extensions: Extensions): Extensions {
151
+ return extensions
152
+ .map(extension => {
153
+ const context = {
154
+ name: extension.name,
155
+ options: extension.options,
156
+ storage: extension.storage,
157
+ }
158
+
159
+ const addExtensions = getExtensionField<AnyConfig['addExtensions']>(
160
+ extension,
161
+ 'addExtensions',
162
+ context,
163
+ )
164
+
165
+ if (addExtensions) {
166
+ return [
167
+ extension,
168
+ ...this.flatten(addExtensions()),
169
+ ]
170
+ }
171
+
172
+ return extension
173
+ })
174
+ // `Infinity` will break TypeScript so we set a number that is probably high enough
175
+ .flat(10)
176
+ }
177
+
178
+ static sort(extensions: Extensions): Extensions {
179
+ const defaultPriority = 100
180
+
181
+ return extensions.sort((a, b) => {
182
+ const priorityA = getExtensionField<AnyConfig['priority']>(a, 'priority') || defaultPriority
183
+ const priorityB = getExtensionField<AnyConfig['priority']>(b, 'priority') || defaultPriority
184
+
185
+ if (priorityA > priorityB) {
186
+ return -1
187
+ }
188
+
189
+ if (priorityA < priorityB) {
190
+ return 1
191
+ }
192
+
193
+ return 0
194
+ })
195
+ }
196
+
69
197
  get commands(): RawCommands {
70
198
  return this.extensions.reduce((commands, extension) => {
71
199
  const context = {
200
+ name: extension.name,
72
201
  options: extension.options,
202
+ storage: extension.storage,
73
203
  editor: this.editor,
74
- type: getSchemaTypeByName(extension.config.name, this.schema),
204
+ type: getSchemaTypeByName(extension.name, this.schema),
75
205
  }
76
206
 
77
- if (!extension.config.addCommands) {
207
+ const addCommands = getExtensionField<AnyConfig['addCommands']>(
208
+ extension,
209
+ 'addCommands',
210
+ context,
211
+ )
212
+
213
+ if (!addCommands) {
78
214
  return commands
79
215
  }
80
216
 
81
217
  return {
82
218
  ...commands,
83
- ...extension.config.addCommands.bind(context)(),
219
+ ...addCommands(),
84
220
  }
85
221
  }, {} as RawCommands)
86
222
  }
87
223
 
88
224
  get plugins(): Plugin[] {
89
- return [...this.extensions]
90
- .reverse()
225
+ const { editor } = this
226
+
227
+ // With ProseMirror, first plugins within an array are executed first.
228
+ // In tiptap, we provide the ability to override plugins,
229
+ // so it feels more natural to run plugins at the end of an array first.
230
+ // That’s why we have to reverse the `extensions` array and sort again
231
+ // based on the `priority` option.
232
+ const extensions = ExtensionManager.sort([...this.extensions].reverse())
233
+
234
+ const inputRules: any[] = []
235
+ const pasteRules: any[] = []
236
+
237
+ const allPlugins = extensions
91
238
  .map(extension => {
92
239
  const context = {
240
+ name: extension.name,
93
241
  options: extension.options,
94
- editor: this.editor,
95
- type: getSchemaTypeByName(extension.config.name, this.schema),
242
+ storage: extension.storage,
243
+ editor,
244
+ type: getSchemaTypeByName(extension.name, this.schema),
96
245
  }
97
246
 
98
247
  const plugins: Plugin[] = []
99
248
 
100
- if (extension.config.addKeyboardShortcuts) {
101
- const keyMapPlugin = keymap(extension.config.addKeyboardShortcuts.bind(context)())
249
+ const addKeyboardShortcuts = getExtensionField<AnyConfig['addKeyboardShortcuts']>(
250
+ extension,
251
+ 'addKeyboardShortcuts',
252
+ context,
253
+ )
254
+
255
+ let defaultBindings: Record<string, () => boolean> = {}
102
256
 
103
- plugins.push(keyMapPlugin)
257
+ // bind exit handling
258
+ if (extension.type === 'mark' && extension.config.exitable) {
259
+ defaultBindings.ArrowRight = () => Mark.handleExit({ editor, mark: (extension as Mark) })
104
260
  }
105
261
 
106
- if (this.editor.options.enableInputRules && extension.config.addInputRules) {
107
- const inputRules = extension.config.addInputRules.bind(context)()
108
- const inputRulePlugins = inputRules.length
109
- ? [inputRulesPlugin({ rules: inputRules })]
110
- : []
262
+ if (addKeyboardShortcuts) {
263
+ const bindings = Object.fromEntries(
264
+ Object
265
+ .entries(addKeyboardShortcuts())
266
+ .map(([shortcut, method]) => {
267
+ return [shortcut, () => method({ editor })]
268
+ }),
269
+ )
111
270
 
112
- plugins.push(...inputRulePlugins)
271
+ defaultBindings = { ...defaultBindings, ...bindings }
113
272
  }
114
273
 
115
- if (this.editor.options.enablePasteRules && extension.config.addPasteRules) {
116
- const pasteRulePlugins = extension.config.addPasteRules.bind(context)()
274
+ const keyMapPlugin = keymap(defaultBindings)
275
+
276
+ plugins.push(keyMapPlugin)
277
+
278
+ const addInputRules = getExtensionField<AnyConfig['addInputRules']>(
279
+ extension,
280
+ 'addInputRules',
281
+ context,
282
+ )
117
283
 
118
- plugins.push(...pasteRulePlugins)
284
+ if (isExtensionRulesEnabled(extension, editor.options.enableInputRules) && addInputRules) {
285
+ inputRules.push(...addInputRules())
119
286
  }
120
287
 
121
- if (extension.config.addProseMirrorPlugins) {
122
- const proseMirrorPlugins = extension.config.addProseMirrorPlugins.bind(context)()
288
+ const addPasteRules = getExtensionField<AnyConfig['addPasteRules']>(
289
+ extension,
290
+ 'addPasteRules',
291
+ context,
292
+ )
293
+
294
+ if (isExtensionRulesEnabled(extension, editor.options.enablePasteRules) && addPasteRules) {
295
+ pasteRules.push(...addPasteRules())
296
+ }
297
+
298
+ const addProseMirrorPlugins = getExtensionField<AnyConfig['addProseMirrorPlugins']>(
299
+ extension,
300
+ 'addProseMirrorPlugins',
301
+ context,
302
+ )
303
+
304
+ if (addProseMirrorPlugins) {
305
+ const proseMirrorPlugins = addProseMirrorPlugins()
123
306
 
124
307
  plugins.push(...proseMirrorPlugins)
125
308
  }
@@ -127,6 +310,18 @@ export default class ExtensionManager {
127
310
  return plugins
128
311
  })
129
312
  .flat()
313
+
314
+ return [
315
+ inputRulesPlugin({
316
+ editor,
317
+ rules: inputRules,
318
+ }),
319
+ ...pasteRulesPlugin({
320
+ editor,
321
+ rules: pasteRules,
322
+ }),
323
+ ...allPlugins,
324
+ ]
130
325
  }
131
326
 
132
327
  get attributes() {
@@ -138,15 +333,25 @@ export default class ExtensionManager {
138
333
  const { nodeExtensions } = splitExtensions(this.extensions)
139
334
 
140
335
  return Object.fromEntries(nodeExtensions
141
- .filter(extension => !!extension.config.addNodeView)
336
+ .filter(extension => !!getExtensionField(extension, 'addNodeView'))
142
337
  .map(extension => {
143
- const extensionAttributes = this.attributes.filter(attribute => attribute.type === extension.config.name)
338
+ const extensionAttributes = this.attributes.filter(attribute => attribute.type === extension.name)
144
339
  const context = {
340
+ name: extension.name,
145
341
  options: extension.options,
342
+ storage: extension.storage,
146
343
  editor,
147
- type: getNodeType(extension.config.name, this.schema),
344
+ type: getNodeType(extension.name, this.schema),
345
+ }
346
+ const addNodeView = getExtensionField<NodeConfig['addNodeView']>(
347
+ extension,
348
+ 'addNodeView',
349
+ context,
350
+ )
351
+
352
+ if (!addNodeView) {
353
+ return []
148
354
  }
149
- const renderer = extension.config.addNodeView?.call(context) as NodeViewRenderer
150
355
 
151
356
  const nodeview = (
152
357
  node: ProsemirrorNode,
@@ -156,7 +361,7 @@ export default class ExtensionManager {
156
361
  ) => {
157
362
  const HTMLAttributes = getRenderedAttributes(node, extensionAttributes)
158
363
 
159
- return renderer({
364
+ return addNodeView()({
160
365
  editor,
161
366
  node,
162
367
  getPos,
@@ -166,27 +371,7 @@ export default class ExtensionManager {
166
371
  })
167
372
  }
168
373
 
169
- return [extension.config.name, nodeview]
374
+ return [extension.name, nodeview]
170
375
  }))
171
376
  }
172
-
173
- get textSerializers() {
174
- const { editor } = this
175
- const { nodeExtensions } = splitExtensions(this.extensions)
176
-
177
- return Object.fromEntries(nodeExtensions
178
- .filter(extension => !!extension.config.renderText)
179
- .map(extension => {
180
- const context = {
181
- options: extension.options,
182
- editor,
183
- type: getNodeType(extension.config.name, this.schema),
184
- }
185
-
186
- const textSerializer = (props: { node: ProsemirrorNode }) => extension.config.renderText?.call(context, props)
187
-
188
- return [extension.config.name, textSerializer]
189
- }))
190
- }
191
-
192
377
  }
@@ -0,0 +1,265 @@
1
+ import { EditorState, Plugin, TextSelection } from 'prosemirror-state'
2
+
3
+ import { CommandManager } from './CommandManager'
4
+ import { Editor } from './Editor'
5
+ import { createChainableState } from './helpers/createChainableState'
6
+ import { getTextContentFromNodes } from './helpers/getTextContentFromNodes'
7
+ import {
8
+ CanCommands,
9
+ ChainedCommands,
10
+ ExtendedRegExpMatchArray,
11
+ Range,
12
+ SingleCommands,
13
+ } from './types'
14
+ import { isRegExp } from './utilities/isRegExp'
15
+
16
+ export type InputRuleMatch = {
17
+ index: number,
18
+ text: string,
19
+ replaceWith?: string,
20
+ match?: RegExpMatchArray,
21
+ data?: Record<string, any>,
22
+ }
23
+
24
+ export type InputRuleFinder =
25
+ | RegExp
26
+ | ((text: string) => InputRuleMatch | null)
27
+
28
+ export class InputRule {
29
+ find: InputRuleFinder
30
+
31
+ handler: (props: {
32
+ state: EditorState,
33
+ range: Range,
34
+ match: ExtendedRegExpMatchArray,
35
+ commands: SingleCommands,
36
+ chain: () => ChainedCommands,
37
+ can: () => CanCommands,
38
+ }) => void | null
39
+
40
+ constructor(config: {
41
+ find: InputRuleFinder,
42
+ handler: (props: {
43
+ state: EditorState,
44
+ range: Range,
45
+ match: ExtendedRegExpMatchArray,
46
+ commands: SingleCommands,
47
+ chain: () => ChainedCommands,
48
+ can: () => CanCommands,
49
+ }) => void | null,
50
+ }) {
51
+ this.find = config.find
52
+ this.handler = config.handler
53
+ }
54
+ }
55
+
56
+ const inputRuleMatcherHandler = (text: string, find: InputRuleFinder): ExtendedRegExpMatchArray | null => {
57
+ if (isRegExp(find)) {
58
+ return find.exec(text)
59
+ }
60
+
61
+ const inputRuleMatch = find(text)
62
+
63
+ if (!inputRuleMatch) {
64
+ return null
65
+ }
66
+
67
+ const result: ExtendedRegExpMatchArray = []
68
+
69
+ result.push(inputRuleMatch.text)
70
+ result.index = inputRuleMatch.index
71
+ result.input = text
72
+ result.data = inputRuleMatch.data
73
+
74
+ if (inputRuleMatch.replaceWith) {
75
+ if (!inputRuleMatch.text.includes(inputRuleMatch.replaceWith)) {
76
+ console.warn('[tiptap warn]: "inputRuleMatch.replaceWith" must be part of "inputRuleMatch.text".')
77
+ }
78
+
79
+ result.push(inputRuleMatch.replaceWith)
80
+ }
81
+
82
+ return result
83
+ }
84
+
85
+ function run(config: {
86
+ editor: Editor,
87
+ from: number,
88
+ to: number,
89
+ text: string,
90
+ rules: InputRule[],
91
+ plugin: Plugin,
92
+ }): boolean {
93
+ const {
94
+ editor,
95
+ from,
96
+ to,
97
+ text,
98
+ rules,
99
+ plugin,
100
+ } = config
101
+ const { view } = editor
102
+
103
+ if (view.composing) {
104
+ return false
105
+ }
106
+
107
+ const $from = view.state.doc.resolve(from)
108
+
109
+ if (
110
+ // check for code node
111
+ $from.parent.type.spec.code
112
+ // check for code mark
113
+ || !!($from.nodeBefore || $from.nodeAfter)?.marks.find(mark => mark.type.spec.code)
114
+ ) {
115
+ return false
116
+ }
117
+
118
+ let matched = false
119
+
120
+ const textBefore = getTextContentFromNodes($from) + text
121
+
122
+ rules.forEach(rule => {
123
+ if (matched) {
124
+ return
125
+ }
126
+
127
+ const match = inputRuleMatcherHandler(textBefore, rule.find)
128
+
129
+ if (!match) {
130
+ return
131
+ }
132
+
133
+ const tr = view.state.tr
134
+ const state = createChainableState({
135
+ state: view.state,
136
+ transaction: tr,
137
+ })
138
+ const range = {
139
+ from: from - (match[0].length - text.length),
140
+ to,
141
+ }
142
+
143
+ const { commands, chain, can } = new CommandManager({
144
+ editor,
145
+ state,
146
+ })
147
+
148
+ const handler = rule.handler({
149
+ state,
150
+ range,
151
+ match,
152
+ commands,
153
+ chain,
154
+ can,
155
+ })
156
+
157
+ // stop if there are no changes
158
+ if (handler === null || !tr.steps.length) {
159
+ return
160
+ }
161
+
162
+ // store transform as meta data
163
+ // so we can undo input rules within the `undoInputRules` command
164
+ tr.setMeta(plugin, {
165
+ transform: tr,
166
+ from,
167
+ to,
168
+ text,
169
+ })
170
+
171
+ view.dispatch(tr)
172
+ matched = true
173
+ })
174
+
175
+ return matched
176
+ }
177
+
178
+ /**
179
+ * Create an input rules plugin. When enabled, it will cause text
180
+ * input that matches any of the given rules to trigger the rule’s
181
+ * action.
182
+ */
183
+ export function inputRulesPlugin(props: { editor: Editor, rules: InputRule[] }): Plugin {
184
+ const { editor, rules } = props
185
+ const plugin = new Plugin({
186
+ state: {
187
+ init() {
188
+ return null
189
+ },
190
+ apply(tr, prev) {
191
+ const stored = tr.getMeta(plugin)
192
+
193
+ if (stored) {
194
+ return stored
195
+ }
196
+
197
+ return tr.selectionSet || tr.docChanged
198
+ ? null
199
+ : prev
200
+ },
201
+ },
202
+
203
+ props: {
204
+ handleTextInput(view, from, to, text) {
205
+ return run({
206
+ editor,
207
+ from,
208
+ to,
209
+ text,
210
+ rules,
211
+ plugin,
212
+ })
213
+ },
214
+
215
+ handleDOMEvents: {
216
+ compositionend: view => {
217
+ setTimeout(() => {
218
+ const { $cursor } = view.state.selection as TextSelection
219
+
220
+ if ($cursor) {
221
+ run({
222
+ editor,
223
+ from: $cursor.pos,
224
+ to: $cursor.pos,
225
+ text: '',
226
+ rules,
227
+ plugin,
228
+ })
229
+ }
230
+ })
231
+
232
+ return false
233
+ },
234
+ },
235
+
236
+ // add support for input rules to trigger on enter
237
+ // this is useful for example for code blocks
238
+ handleKeyDown(view, event) {
239
+ if (event.key !== 'Enter') {
240
+ return false
241
+ }
242
+
243
+ const { $cursor } = view.state.selection as TextSelection
244
+
245
+ if ($cursor) {
246
+ return run({
247
+ editor,
248
+ from: $cursor.pos,
249
+ to: $cursor.pos,
250
+ text: '\n',
251
+ rules,
252
+ plugin,
253
+ })
254
+ }
255
+
256
+ return false
257
+ },
258
+ },
259
+
260
+ // @ts-ignore
261
+ isInputRules: true,
262
+ }) as Plugin
263
+
264
+ return plugin
265
+ }