@tiptap/core 2.0.0-beta.18 → 2.0.0-beta.182

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 (333) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +2 -2
  3. package/dist/packages/core/src/CommandManager.d.ts +13 -6
  4. package/dist/packages/core/src/Editor.d.ts +24 -19
  5. package/dist/packages/core/src/EventEmitter.d.ts +8 -4
  6. package/dist/packages/core/src/Extension.d.ts +99 -27
  7. package/dist/packages/core/src/ExtensionManager.d.ts +7 -13
  8. package/dist/packages/core/src/InputRule.d.ts +42 -0
  9. package/dist/packages/core/src/Mark.d.ts +131 -31
  10. package/dist/packages/core/src/Node.d.ts +157 -33
  11. package/dist/packages/core/src/NodeView.d.ts +8 -12
  12. package/dist/packages/core/src/PasteRule.d.ts +42 -0
  13. package/dist/packages/core/src/Tracker.d.ts +11 -0
  14. package/dist/packages/core/src/commands/blur.d.ts +3 -3
  15. package/dist/packages/core/src/commands/clearContent.d.ts +3 -3
  16. package/dist/packages/core/src/commands/clearNodes.d.ts +3 -3
  17. package/dist/packages/core/src/commands/command.d.ts +2 -2
  18. package/dist/packages/core/src/commands/createParagraphNear.d.ts +3 -3
  19. package/dist/packages/core/src/commands/deleteNode.d.ts +13 -0
  20. package/dist/packages/core/src/commands/deleteRange.d.ts +3 -3
  21. package/dist/packages/core/src/commands/deleteSelection.d.ts +3 -3
  22. package/dist/packages/core/src/commands/enter.d.ts +3 -3
  23. package/dist/packages/core/src/commands/exitCode.d.ts +3 -3
  24. package/dist/packages/core/src/commands/extendMarkRange.d.ts +3 -3
  25. package/dist/packages/core/src/commands/first.d.ts +3 -3
  26. package/dist/packages/core/src/commands/focus.d.ts +5 -3
  27. package/dist/packages/core/src/commands/forEach.d.ts +14 -0
  28. package/dist/packages/core/src/commands/index.d.ts +50 -0
  29. package/dist/packages/core/src/commands/insertContent.d.ts +7 -3
  30. package/dist/packages/core/src/commands/insertContentAt.d.ts +16 -0
  31. package/dist/packages/core/src/commands/joinBackward.d.ts +3 -3
  32. package/dist/packages/core/src/commands/joinForward.d.ts +3 -3
  33. package/dist/packages/core/src/commands/keyboardShortcut.d.ts +3 -3
  34. package/dist/packages/core/src/commands/lift.d.ts +3 -3
  35. package/dist/packages/core/src/commands/liftEmptyBlock.d.ts +3 -3
  36. package/dist/packages/core/src/commands/liftListItem.d.ts +3 -3
  37. package/dist/packages/core/src/commands/newlineInCode.d.ts +3 -3
  38. package/dist/packages/core/src/commands/resetAttributes.d.ts +13 -0
  39. package/dist/packages/core/src/commands/scrollIntoView.d.ts +3 -3
  40. package/dist/packages/core/src/commands/selectAll.d.ts +3 -3
  41. package/dist/packages/core/src/commands/selectNodeBackward.d.ts +3 -3
  42. package/dist/packages/core/src/commands/selectNodeForward.d.ts +3 -3
  43. package/dist/packages/core/src/commands/selectParentNode.d.ts +3 -3
  44. package/dist/packages/core/src/commands/selectTextblockEnd.d.ts +12 -0
  45. package/dist/packages/core/src/commands/selectTextblockStart.d.ts +12 -0
  46. package/dist/packages/core/src/commands/setContent.d.ts +4 -3
  47. package/dist/packages/core/src/commands/setMark.d.ts +3 -3
  48. package/dist/packages/core/src/commands/setMeta.d.ts +12 -0
  49. package/dist/packages/core/src/commands/setNode.d.ts +3 -3
  50. package/dist/packages/core/src/commands/setNodeSelection.d.ts +12 -0
  51. package/dist/packages/core/src/commands/setTextSelection.d.ts +12 -0
  52. package/dist/packages/core/src/commands/sinkListItem.d.ts +3 -3
  53. package/dist/packages/core/src/commands/splitBlock.d.ts +3 -3
  54. package/dist/packages/core/src/commands/splitListItem.d.ts +3 -3
  55. package/dist/packages/core/src/commands/toggleList.d.ts +3 -3
  56. package/dist/packages/core/src/commands/toggleMark.d.ts +8 -3
  57. package/dist/packages/core/src/commands/toggleNode.d.ts +3 -3
  58. package/dist/packages/core/src/commands/toggleWrap.d.ts +3 -3
  59. package/dist/packages/core/src/commands/undoInputRule.d.ts +3 -3
  60. package/dist/packages/core/src/commands/unsetAllMarks.d.ts +3 -3
  61. package/dist/packages/core/src/commands/unsetMark.d.ts +8 -3
  62. package/dist/packages/core/src/commands/updateAttributes.d.ts +13 -0
  63. package/dist/packages/core/src/commands/wrapIn.d.ts +3 -3
  64. package/dist/packages/core/src/commands/wrapInList.d.ts +3 -3
  65. package/dist/packages/core/src/extensions/clipboardTextSerializer.d.ts +1 -1
  66. package/dist/packages/core/src/extensions/commands.d.ts +2 -95
  67. package/dist/packages/core/src/extensions/editable.d.ts +1 -1
  68. package/dist/packages/core/src/extensions/focusEvents.d.ts +1 -1
  69. package/dist/packages/core/src/extensions/index.d.ts +1 -0
  70. package/dist/packages/core/src/extensions/keymap.d.ts +1 -1
  71. package/dist/packages/core/src/extensions/tabindex.d.ts +2 -0
  72. package/dist/packages/core/src/helpers/combineTransactionSteps.d.ts +7 -0
  73. package/dist/packages/core/src/helpers/createChainableState.d.ts +5 -0
  74. package/dist/packages/core/src/helpers/createDocument.d.ts +3 -4
  75. package/dist/packages/core/src/helpers/createNodeFromContent.d.ts +4 -5
  76. package/dist/packages/core/src/helpers/defaultBlockAt.d.ts +2 -0
  77. package/dist/packages/core/src/helpers/findChildren.d.ts +3 -0
  78. package/dist/packages/core/src/helpers/findChildrenInRange.d.ts +6 -0
  79. package/dist/packages/core/src/helpers/findParentNode.d.ts +2 -3
  80. package/dist/packages/core/src/helpers/findParentNodeClosestToPos.d.ts +2 -2
  81. package/dist/packages/core/src/helpers/generateHTML.d.ts +2 -2
  82. package/dist/packages/core/src/helpers/generateJSON.d.ts +2 -0
  83. package/dist/packages/core/src/helpers/generateText.d.ts +5 -0
  84. package/dist/packages/core/src/helpers/getAttributes.d.ts +3 -0
  85. package/dist/packages/core/src/helpers/getAttributesFromExtensions.d.ts +2 -2
  86. package/dist/packages/core/src/helpers/getChangedRanges.d.ts +11 -0
  87. package/dist/packages/core/src/helpers/getDebugJSON.d.ts +8 -0
  88. package/dist/packages/core/src/helpers/getExtensionField.d.ts +2 -0
  89. package/dist/packages/core/src/helpers/getHTMLFromFragment.d.ts +2 -2
  90. package/dist/packages/core/src/helpers/getMarkAttributes.d.ts +2 -3
  91. package/dist/packages/core/src/helpers/getMarkRange.d.ts +1 -1
  92. package/dist/packages/core/src/helpers/getMarkType.d.ts +1 -1
  93. package/dist/packages/core/src/helpers/getMarksBetween.d.ts +2 -2
  94. package/dist/packages/core/src/helpers/getNodeAttributes.d.ts +2 -3
  95. package/dist/packages/core/src/helpers/getNodeType.d.ts +1 -1
  96. package/dist/packages/core/src/helpers/getRenderedAttributes.d.ts +3 -3
  97. package/dist/packages/core/src/helpers/getSchema.d.ts +1 -1
  98. package/dist/packages/core/src/helpers/getSchemaByResolvedExtensions.d.ts +3 -0
  99. package/dist/packages/core/src/helpers/getSchemaTypeByName.d.ts +1 -1
  100. package/dist/packages/core/src/helpers/getSchemaTypeNameByName.d.ts +1 -1
  101. package/dist/packages/core/src/helpers/getSplittedAttributes.d.ts +2 -2
  102. package/dist/packages/core/src/helpers/getText.d.ts +6 -0
  103. package/dist/packages/core/src/helpers/getTextBetween.d.ts +6 -0
  104. package/dist/packages/core/src/helpers/getTextContentFromNodes.d.ts +2 -0
  105. package/dist/packages/core/src/helpers/getTextSerializersFromSchema.d.ts +3 -0
  106. package/dist/packages/core/src/helpers/index.d.ts +33 -0
  107. package/dist/packages/core/src/helpers/injectExtensionAttributesToParseRule.d.ts +1 -1
  108. package/dist/packages/core/src/helpers/isActive.d.ts +1 -2
  109. package/dist/packages/core/src/helpers/isExtensionRulesEnabled.d.ts +2 -0
  110. package/dist/packages/core/src/helpers/isList.d.ts +1 -1
  111. package/dist/packages/core/src/helpers/isMarkActive.d.ts +2 -3
  112. package/dist/packages/core/src/helpers/isNodeActive.d.ts +2 -3
  113. package/dist/packages/core/src/helpers/isNodeEmpty.d.ts +1 -1
  114. package/dist/packages/core/src/helpers/isNodeSelection.d.ts +1 -1
  115. package/dist/packages/core/src/helpers/isTextSelection.d.ts +1 -1
  116. package/dist/packages/core/src/helpers/posToDOMRect.d.ts +2 -0
  117. package/dist/packages/core/src/helpers/resolveFocusPosition.d.ts +4 -0
  118. package/dist/packages/core/src/helpers/selectionToInsertionEnd.d.ts +1 -1
  119. package/dist/packages/core/src/helpers/splitExtensions.d.ts +6 -6
  120. package/dist/packages/core/src/index.d.ts +14 -21
  121. package/dist/packages/core/src/inputRules/index.d.ts +5 -0
  122. package/dist/packages/core/src/inputRules/markInputRule.d.ts +11 -2
  123. package/dist/packages/core/src/inputRules/nodeInputRule.d.ts +11 -2
  124. package/dist/packages/core/src/inputRules/textInputRule.d.ts +9 -0
  125. package/dist/packages/core/src/inputRules/textblockTypeInputRule.d.ts +14 -0
  126. package/dist/packages/core/src/inputRules/wrappingInputRule.d.ts +23 -0
  127. package/dist/packages/core/src/pasteRules/index.d.ts +3 -0
  128. package/dist/packages/core/src/pasteRules/markPasteRule.d.ts +11 -2
  129. package/dist/packages/core/src/pasteRules/nodePasteRule.d.ts +12 -0
  130. package/dist/packages/core/src/pasteRules/textPasteRule.d.ts +9 -0
  131. package/dist/packages/core/src/style.d.ts +1 -2
  132. package/dist/packages/core/src/types.d.ts +112 -56
  133. package/dist/packages/core/src/utilities/callOrReturn.d.ts +2 -1
  134. package/dist/packages/core/src/utilities/createStyleTag.d.ts +1 -1
  135. package/dist/packages/core/src/utilities/deleteProps.d.ts +1 -2
  136. package/dist/packages/core/src/utilities/elementFromString.d.ts +1 -1
  137. package/dist/packages/core/src/utilities/escapeForRegEx.d.ts +1 -0
  138. package/dist/packages/core/src/utilities/findDuplicates.d.ts +1 -0
  139. package/dist/packages/core/src/utilities/fromString.d.ts +1 -1
  140. package/dist/packages/core/src/utilities/index.d.ts +3 -0
  141. package/dist/packages/core/src/utilities/isClass.d.ts +1 -1
  142. package/dist/packages/core/src/utilities/isEmptyObject.d.ts +1 -1
  143. package/dist/packages/core/src/utilities/isFunction.d.ts +1 -0
  144. package/dist/packages/core/src/utilities/isMacOS.d.ts +1 -0
  145. package/dist/packages/core/src/utilities/isNumber.d.ts +1 -0
  146. package/dist/packages/core/src/utilities/isObject.d.ts +1 -1
  147. package/dist/packages/core/src/utilities/isPlainObject.d.ts +1 -1
  148. package/dist/packages/core/src/utilities/isRegExp.d.ts +1 -0
  149. package/dist/packages/core/src/utilities/isiOS.d.ts +1 -0
  150. package/dist/packages/core/src/utilities/mergeAttributes.d.ts +1 -2
  151. package/dist/packages/core/src/utilities/mergeDeep.d.ts +1 -2
  152. package/dist/packages/core/src/utilities/minMax.d.ts +1 -1
  153. package/dist/packages/core/src/utilities/objectIncludes.d.ts +3 -2
  154. package/dist/packages/core/src/utilities/removeDuplicates.d.ts +8 -0
  155. package/dist/tiptap-core.cjs.js +2696 -1374
  156. package/dist/tiptap-core.cjs.js.map +1 -1
  157. package/dist/tiptap-core.esm.js +2630 -1342
  158. package/dist/tiptap-core.esm.js.map +1 -1
  159. package/dist/tiptap-core.umd.js +2648 -1325
  160. package/dist/tiptap-core.umd.js.map +1 -1
  161. package/package.json +17 -20
  162. package/src/CommandManager.ts +63 -64
  163. package/src/Editor.ts +115 -78
  164. package/src/EventEmitter.ts +14 -4
  165. package/src/Extension.ts +193 -43
  166. package/src/ExtensionManager.ts +232 -83
  167. package/src/InputRule.ts +265 -0
  168. package/src/Mark.ts +239 -49
  169. package/src/Node.ts +279 -57
  170. package/src/NodeView.ts +115 -47
  171. package/src/PasteRule.ts +247 -0
  172. package/src/Tracker.ts +42 -0
  173. package/src/commands/blur.ts +12 -6
  174. package/src/commands/clearContent.ts +3 -3
  175. package/src/commands/clearNodes.ts +30 -18
  176. package/src/commands/command.ts +2 -2
  177. package/src/commands/createParagraphNear.ts +4 -3
  178. package/src/commands/deleteNode.ts +37 -0
  179. package/src/commands/deleteRange.ts +3 -3
  180. package/src/commands/deleteSelection.ts +4 -3
  181. package/src/commands/enter.ts +3 -3
  182. package/src/commands/exitCode.ts +4 -3
  183. package/src/commands/extendMarkRange.ts +12 -11
  184. package/src/commands/first.ts +3 -3
  185. package/src/commands/focus.ts +47 -44
  186. package/src/commands/forEach.ts +24 -0
  187. package/src/commands/index.ts +50 -0
  188. package/src/commands/insertContent.ts +13 -24
  189. package/src/commands/insertContentAt.ts +108 -0
  190. package/src/commands/joinBackward.ts +4 -3
  191. package/src/commands/joinForward.ts +4 -3
  192. package/src/commands/keyboardShortcut.ts +6 -6
  193. package/src/commands/lift.ts +6 -5
  194. package/src/commands/liftEmptyBlock.ts +4 -3
  195. package/src/commands/liftListItem.ts +6 -5
  196. package/src/commands/newlineInCode.ts +4 -3
  197. package/src/commands/resetAttributes.ts +62 -0
  198. package/src/commands/scrollIntoView.ts +3 -3
  199. package/src/commands/selectAll.ts +8 -6
  200. package/src/commands/selectNodeBackward.ts +4 -3
  201. package/src/commands/selectNodeForward.ts +4 -3
  202. package/src/commands/selectParentNode.ts +4 -3
  203. package/src/commands/selectTextblockEnd.ts +20 -0
  204. package/src/commands/selectTextblockStart.ts +20 -0
  205. package/src/commands/setContent.ts +9 -15
  206. package/src/commands/setMark.ts +36 -12
  207. package/src/commands/setMeta.ts +18 -0
  208. package/src/commands/setNode.ts +29 -7
  209. package/src/commands/setNodeSelection.ts +29 -0
  210. package/src/commands/setTextSelection.ts +33 -0
  211. package/src/commands/sinkListItem.ts +6 -5
  212. package/src/commands/splitBlock.ts +16 -10
  213. package/src/commands/splitListItem.ts +45 -18
  214. package/src/commands/toggleList.ts +83 -18
  215. package/src/commands/toggleMark.ts +18 -7
  216. package/src/commands/toggleNode.ts +6 -5
  217. package/src/commands/toggleWrap.ts +9 -9
  218. package/src/commands/undoInputRule.ts +34 -5
  219. package/src/commands/unsetAllMarks.ts +7 -11
  220. package/src/commands/unsetMark.ts +35 -22
  221. package/src/commands/updateAttributes.ts +73 -0
  222. package/src/commands/wrapIn.ts +5 -10
  223. package/src/commands/wrapInList.ts +6 -5
  224. package/src/extensions/clipboardTextSerializer.ts +14 -35
  225. package/src/extensions/commands.ts +3 -141
  226. package/src/extensions/editable.ts +1 -0
  227. package/src/extensions/focusEvents.ts +3 -5
  228. package/src/extensions/index.ts +1 -0
  229. package/src/extensions/keymap.ts +110 -13
  230. package/src/extensions/tabindex.ts +18 -0
  231. package/src/helpers/combineTransactionSteps.ts +18 -0
  232. package/src/helpers/createChainableState.ts +38 -0
  233. package/src/helpers/createDocument.ts +5 -6
  234. package/src/helpers/createNodeFromContent.ts +17 -19
  235. package/src/helpers/defaultBlockAt.ts +13 -0
  236. package/src/helpers/findChildren.ts +18 -0
  237. package/src/helpers/findChildrenInRange.ts +32 -0
  238. package/src/helpers/findParentNode.ts +3 -2
  239. package/src/helpers/findParentNodeClosestToPos.ts +3 -2
  240. package/src/helpers/generateHTML.ts +6 -5
  241. package/src/helpers/generateJSON.ts +14 -0
  242. package/src/helpers/generateText.ts +30 -0
  243. package/src/helpers/getAttributes.ts +28 -0
  244. package/src/helpers/getAttributesFromExtensions.ts +42 -14
  245. package/src/helpers/getChangedRanges.ts +83 -0
  246. package/src/helpers/getDebugJSON.ts +54 -0
  247. package/src/helpers/getExtensionField.ts +25 -0
  248. package/src/helpers/getHTMLFromFragment.ts +6 -5
  249. package/src/helpers/getMarkAttributes.ts +14 -10
  250. package/src/helpers/getMarkRange.ts +41 -8
  251. package/src/helpers/getMarkType.ts +5 -1
  252. package/src/helpers/getMarksBetween.ts +32 -10
  253. package/src/helpers/getNodeAttributes.ts +9 -9
  254. package/src/helpers/getNodeType.ts +5 -1
  255. package/src/helpers/getRenderedAttributes.ts +6 -7
  256. package/src/helpers/getSchema.ts +7 -133
  257. package/src/helpers/getSchemaByResolvedExtensions.ts +148 -0
  258. package/src/helpers/getSchemaTypeByName.ts +2 -10
  259. package/src/helpers/getSchemaTypeNameByName.ts +1 -1
  260. package/src/helpers/getSplittedAttributes.ts +4 -4
  261. package/src/helpers/getText.ts +19 -0
  262. package/src/helpers/getTextBetween.ts +49 -0
  263. package/src/helpers/getTextContentFromNodes.ts +17 -0
  264. package/src/helpers/getTextSerializersFromSchema.ts +10 -0
  265. package/src/helpers/index.ts +33 -0
  266. package/src/helpers/injectExtensionAttributesToParseRule.ts +17 -19
  267. package/src/helpers/isActive.ts +5 -5
  268. package/src/helpers/isExtensionRulesEnabled.ts +15 -0
  269. package/src/helpers/isList.ts +14 -7
  270. package/src/helpers/isMarkActive.ts +45 -20
  271. package/src/helpers/isNodeActive.ts +28 -35
  272. package/src/helpers/isNodeEmpty.ts +1 -1
  273. package/src/helpers/isNodeSelection.ts +3 -2
  274. package/src/helpers/isTextSelection.ts +3 -2
  275. package/src/helpers/posToDOMRect.ts +35 -0
  276. package/src/helpers/resolveFocusPosition.ts +43 -0
  277. package/src/helpers/selectionToInsertionEnd.ts +2 -2
  278. package/src/helpers/splitExtensions.ts +3 -3
  279. package/src/index.ts +15 -24
  280. package/src/inputRules/index.ts +5 -0
  281. package/src/inputRules/markInputRule.ts +59 -39
  282. package/src/inputRules/nodeInputRule.ts +45 -11
  283. package/src/inputRules/textInputRule.ts +35 -0
  284. package/src/inputRules/textblockTypeInputRule.ts +38 -0
  285. package/src/inputRules/wrappingInputRule.ts +60 -0
  286. package/src/pasteRules/index.ts +3 -0
  287. package/src/pasteRules/markPasteRule.ts +62 -53
  288. package/src/pasteRules/nodePasteRule.ts +39 -0
  289. package/src/pasteRules/textPasteRule.ts +35 -0
  290. package/src/style.ts +16 -3
  291. package/src/types.ts +129 -43
  292. package/src/utilities/callOrReturn.ts +6 -3
  293. package/src/utilities/createStyleTag.ts +12 -1
  294. package/src/utilities/deleteProps.ts +2 -4
  295. package/src/utilities/elementFromString.ts +4 -5
  296. package/src/utilities/escapeForRegEx.ts +4 -0
  297. package/src/utilities/findDuplicates.ts +5 -0
  298. package/src/utilities/fromString.ts +2 -2
  299. package/src/utilities/index.ts +3 -0
  300. package/src/utilities/isClass.ts +2 -2
  301. package/src/utilities/isEmptyObject.ts +2 -2
  302. package/src/utilities/isFunction.ts +3 -0
  303. package/src/utilities/isMacOS.ts +5 -0
  304. package/src/utilities/isNumber.ts +3 -0
  305. package/src/utilities/isObject.ts +6 -6
  306. package/src/utilities/isPlainObject.ts +8 -5
  307. package/src/utilities/isRegExp.ts +3 -0
  308. package/src/utilities/isString.ts +3 -0
  309. package/src/utilities/isiOS.ts +12 -0
  310. package/src/utilities/mergeAttributes.ts +2 -3
  311. package/src/utilities/mergeDeep.ts +2 -3
  312. package/src/utilities/minMax.ts +1 -1
  313. package/src/utilities/objectIncludes.ts +17 -5
  314. package/src/utilities/removeDuplicates.ts +15 -0
  315. package/CHANGELOG.md +0 -335
  316. package/dist/packages/core/src/commands/insertHTML.d.ts +0 -12
  317. package/dist/packages/core/src/commands/insertNode.d.ts +0 -13
  318. package/dist/packages/core/src/commands/insertText.d.ts +0 -12
  319. package/dist/packages/core/src/commands/replace.d.ts +0 -13
  320. package/dist/packages/core/src/commands/replaceRange.d.ts +0 -13
  321. package/dist/packages/core/src/commands/resetNodeAttributes.d.ts +0 -13
  322. package/dist/packages/core/src/commands/updateNodeAttributes.d.ts +0 -13
  323. package/dist/packages/core/src/utilities/removeElement.d.ts +0 -1
  324. package/dist/tiptap-core.bundle.umd.min.js +0 -17
  325. package/dist/tiptap-core.bundle.umd.min.js.map +0 -1
  326. package/src/commands/insertHTML.ts +0 -30
  327. package/src/commands/insertNode.ts +0 -33
  328. package/src/commands/insertText.ts +0 -22
  329. package/src/commands/replace.ts +0 -20
  330. package/src/commands/replaceRange.ts +0 -36
  331. package/src/commands/resetNodeAttributes.ts +0 -31
  332. package/src/commands/updateNodeAttributes.ts +0 -33
  333. package/src/utilities/removeElement.ts +0 -5
@@ -1,19 +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'
14
- import callOrReturn from './utilities/callOrReturn'
4
+ import { Decoration, EditorView } from 'prosemirror-view'
15
5
 
16
- export default class ExtensionManager {
6
+ import { 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 {
17
23
 
18
24
  editor: Editor
19
25
 
@@ -25,67 +31,162 @@ export default class ExtensionManager {
25
31
 
26
32
  constructor(extensions: Extensions, editor: Editor) {
27
33
  this.editor = editor
28
- this.extensions = this.sort(extensions)
29
- this.schema = getSchema(this.extensions)
34
+ this.extensions = ExtensionManager.resolve(extensions)
35
+ this.schema = getSchemaByResolvedExtensions(this.extensions)
30
36
 
31
37
  this.extensions.forEach(extension => {
38
+ // store extension storage in editor
39
+ this.editor.extensionStorage[extension.name] = extension.storage
40
+
32
41
  const context = {
42
+ name: extension.name,
33
43
  options: extension.options,
44
+ storage: extension.storage,
34
45
  editor: this.editor,
35
- type: getSchemaTypeByName(extension.config.name, this.schema),
46
+ type: getSchemaTypeByName(extension.name, this.schema),
36
47
  }
37
48
 
38
49
  if (extension.type === 'mark') {
39
- const keepOnSplit = callOrReturn(extension.config.keepOnSplit, context) ?? true
50
+ const keepOnSplit = callOrReturn(getExtensionField(extension, 'keepOnSplit', context)) ?? true
40
51
 
41
52
  if (keepOnSplit) {
42
- this.splittableMarks.push(extension.config.name)
53
+ this.splittableMarks.push(extension.name)
43
54
  }
44
55
  }
45
56
 
46
- if (typeof extension.config.onCreate === 'function') {
47
- this.editor.on('create', extension.config.onCreate.bind(context))
57
+ const onBeforeCreate = getExtensionField<AnyConfig['onBeforeCreate']>(
58
+ extension,
59
+ 'onBeforeCreate',
60
+ context,
61
+ )
62
+
63
+ if (onBeforeCreate) {
64
+ this.editor.on('beforeCreate', onBeforeCreate)
48
65
  }
49
66
 
50
- if (typeof extension.config.onUpdate === 'function') {
51
- 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)
52
75
  }
53
76
 
54
- if (typeof extension.config.onSelectionUpdate === 'function') {
55
- 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)
56
85
  }
57
86
 
58
- if (typeof extension.config.onViewUpdate === 'function') {
59
- 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)
60
95
  }
61
96
 
62
- if (typeof extension.config.onTransaction === 'function') {
63
- 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)
64
105
  }
65
106
 
66
- if (typeof extension.config.onFocus === 'function') {
67
- 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)
68
115
  }
69
116
 
70
- if (typeof extension.config.onBlur === 'function') {
71
- 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)
72
125
  }
73
126
 
74
- if (typeof extension.config.onDestroy === 'function') {
75
- 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)
76
135
  }
77
136
  })
78
137
  }
79
138
 
80
- private sort(extensions: Extensions) {
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 {
81
179
  const defaultPriority = 100
82
180
 
83
181
  return extensions.sort((a, b) => {
84
- if ((a.config.priority || defaultPriority) > (b.config.priority || defaultPriority)) {
182
+ const priorityA = getExtensionField<AnyConfig['priority']>(a, 'priority') || defaultPriority
183
+ const priorityB = getExtensionField<AnyConfig['priority']>(b, 'priority') || defaultPriority
184
+
185
+ if (priorityA > priorityB) {
85
186
  return -1
86
187
  }
87
188
 
88
- if ((a.config.priority || defaultPriority) < (b.config.priority || defaultPriority)) {
189
+ if (priorityA < priorityB) {
89
190
  return 1
90
191
  }
91
192
 
@@ -96,57 +197,103 @@ export default class ExtensionManager {
96
197
  get commands(): RawCommands {
97
198
  return this.extensions.reduce((commands, extension) => {
98
199
  const context = {
200
+ name: extension.name,
99
201
  options: extension.options,
202
+ storage: extension.storage,
100
203
  editor: this.editor,
101
- type: getSchemaTypeByName(extension.config.name, this.schema),
204
+ type: getSchemaTypeByName(extension.name, this.schema),
102
205
  }
103
206
 
104
- if (!extension.config.addCommands) {
207
+ const addCommands = getExtensionField<AnyConfig['addCommands']>(
208
+ extension,
209
+ 'addCommands',
210
+ context,
211
+ )
212
+
213
+ if (!addCommands) {
105
214
  return commands
106
215
  }
107
216
 
108
217
  return {
109
218
  ...commands,
110
- ...extension.config.addCommands.bind(context)(),
219
+ ...addCommands(),
111
220
  }
112
221
  }, {} as RawCommands)
113
222
  }
114
223
 
115
224
  get plugins(): Plugin[] {
116
- return [...this.extensions]
117
- .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
118
238
  .map(extension => {
119
239
  const context = {
240
+ name: extension.name,
120
241
  options: extension.options,
121
- editor: this.editor,
122
- type: getSchemaTypeByName(extension.config.name, this.schema),
242
+ storage: extension.storage,
243
+ editor,
244
+ type: getSchemaTypeByName(extension.name, this.schema),
123
245
  }
124
246
 
125
247
  const plugins: Plugin[] = []
126
248
 
127
- if (extension.config.addKeyboardShortcuts) {
128
- const keyMapPlugin = keymap(extension.config.addKeyboardShortcuts.bind(context)())
249
+ const addKeyboardShortcuts = getExtensionField<AnyConfig['addKeyboardShortcuts']>(
250
+ extension,
251
+ 'addKeyboardShortcuts',
252
+ context,
253
+ )
254
+
255
+ if (addKeyboardShortcuts) {
256
+ const bindings = Object.fromEntries(
257
+ Object
258
+ .entries(addKeyboardShortcuts())
259
+ .map(([shortcut, method]) => {
260
+ return [shortcut, () => method({ editor })]
261
+ }),
262
+ )
263
+
264
+ const keyMapPlugin = keymap(bindings)
129
265
 
130
266
  plugins.push(keyMapPlugin)
131
267
  }
132
268
 
133
- if (this.editor.options.enableInputRules && extension.config.addInputRules) {
134
- const inputRules = extension.config.addInputRules.bind(context)()
135
- const inputRulePlugins = inputRules.length
136
- ? [inputRulesPlugin({ rules: inputRules })]
137
- : []
269
+ const addInputRules = getExtensionField<AnyConfig['addInputRules']>(
270
+ extension,
271
+ 'addInputRules',
272
+ context,
273
+ )
138
274
 
139
- plugins.push(...inputRulePlugins)
275
+ if (isExtensionRulesEnabled(extension, editor.options.enableInputRules) && addInputRules) {
276
+ inputRules.push(...addInputRules())
140
277
  }
141
278
 
142
- if (this.editor.options.enablePasteRules && extension.config.addPasteRules) {
143
- const pasteRulePlugins = extension.config.addPasteRules.bind(context)()
279
+ const addPasteRules = getExtensionField<AnyConfig['addPasteRules']>(
280
+ extension,
281
+ 'addPasteRules',
282
+ context,
283
+ )
144
284
 
145
- plugins.push(...pasteRulePlugins)
285
+ if (isExtensionRulesEnabled(extension, editor.options.enablePasteRules) && addPasteRules) {
286
+ pasteRules.push(...addPasteRules())
146
287
  }
147
288
 
148
- if (extension.config.addProseMirrorPlugins) {
149
- const proseMirrorPlugins = extension.config.addProseMirrorPlugins.bind(context)()
289
+ const addProseMirrorPlugins = getExtensionField<AnyConfig['addProseMirrorPlugins']>(
290
+ extension,
291
+ 'addProseMirrorPlugins',
292
+ context,
293
+ )
294
+
295
+ if (addProseMirrorPlugins) {
296
+ const proseMirrorPlugins = addProseMirrorPlugins()
150
297
 
151
298
  plugins.push(...proseMirrorPlugins)
152
299
  }
@@ -154,6 +301,18 @@ export default class ExtensionManager {
154
301
  return plugins
155
302
  })
156
303
  .flat()
304
+
305
+ return [
306
+ inputRulesPlugin({
307
+ editor,
308
+ rules: inputRules,
309
+ }),
310
+ ...pasteRulesPlugin({
311
+ editor,
312
+ rules: pasteRules,
313
+ }),
314
+ ...allPlugins,
315
+ ]
157
316
  }
158
317
 
159
318
  get attributes() {
@@ -165,15 +324,25 @@ export default class ExtensionManager {
165
324
  const { nodeExtensions } = splitExtensions(this.extensions)
166
325
 
167
326
  return Object.fromEntries(nodeExtensions
168
- .filter(extension => !!extension.config.addNodeView)
327
+ .filter(extension => !!getExtensionField(extension, 'addNodeView'))
169
328
  .map(extension => {
170
- const extensionAttributes = this.attributes.filter(attribute => attribute.type === extension.config.name)
329
+ const extensionAttributes = this.attributes.filter(attribute => attribute.type === extension.name)
171
330
  const context = {
331
+ name: extension.name,
172
332
  options: extension.options,
333
+ storage: extension.storage,
173
334
  editor,
174
- type: getNodeType(extension.config.name, this.schema),
335
+ type: getNodeType(extension.name, this.schema),
336
+ }
337
+ const addNodeView = getExtensionField<NodeConfig['addNodeView']>(
338
+ extension,
339
+ 'addNodeView',
340
+ context,
341
+ )
342
+
343
+ if (!addNodeView) {
344
+ return []
175
345
  }
176
- const renderer = extension.config.addNodeView?.call(context) as NodeViewRenderer
177
346
 
178
347
  const nodeview = (
179
348
  node: ProsemirrorNode,
@@ -183,7 +352,7 @@ export default class ExtensionManager {
183
352
  ) => {
184
353
  const HTMLAttributes = getRenderedAttributes(node, extensionAttributes)
185
354
 
186
- return renderer({
355
+ return addNodeView()({
187
356
  editor,
188
357
  node,
189
358
  getPos,
@@ -193,27 +362,7 @@ export default class ExtensionManager {
193
362
  })
194
363
  }
195
364
 
196
- return [extension.config.name, nodeview]
365
+ return [extension.name, nodeview]
197
366
  }))
198
367
  }
199
-
200
- get textSerializers() {
201
- const { editor } = this
202
- const { nodeExtensions } = splitExtensions(this.extensions)
203
-
204
- return Object.fromEntries(nodeExtensions
205
- .filter(extension => !!extension.config.renderText)
206
- .map(extension => {
207
- const context = {
208
- options: extension.options,
209
- editor,
210
- type: getNodeType(extension.config.name, this.schema),
211
- }
212
-
213
- const textSerializer = (props: { node: ProsemirrorNode }) => extension.config.renderText?.call(context, props)
214
-
215
- return [extension.config.name, textSerializer]
216
- }))
217
- }
218
-
219
368
  }
@@ -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
+ }