@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
@@ -0,0 +1,261 @@
1
+ import { Node as ProseMirrorNode } from 'prosemirror-model'
2
+ import { NodeSelection } from 'prosemirror-state'
3
+ import { Decoration, NodeView as ProseMirrorNodeView } from 'prosemirror-view'
4
+
5
+ import { Editor as CoreEditor } from './Editor'
6
+ import { Node } from './Node'
7
+ import { NodeViewRendererOptions, NodeViewRendererProps } from './types'
8
+ import { isiOS } from './utilities/isiOS'
9
+
10
+ export class NodeView<
11
+ Component,
12
+ Editor extends CoreEditor = CoreEditor,
13
+ Options extends NodeViewRendererOptions = NodeViewRendererOptions,
14
+ > implements ProseMirrorNodeView {
15
+
16
+ component: Component
17
+
18
+ editor: Editor
19
+
20
+ options: Options
21
+
22
+ extension: Node
23
+
24
+ node: ProseMirrorNode
25
+
26
+ decorations: Decoration[]
27
+
28
+ getPos: any
29
+
30
+ isDragging = false
31
+
32
+ constructor(component: Component, props: NodeViewRendererProps, options?: Partial<Options>) {
33
+ this.component = component
34
+ this.editor = props.editor as Editor
35
+ this.options = {
36
+ stopEvent: null,
37
+ ignoreMutation: null,
38
+ ...options,
39
+ } as Options
40
+ this.extension = props.extension
41
+ this.node = props.node
42
+ this.decorations = props.decorations
43
+ this.getPos = props.getPos
44
+ this.mount()
45
+ }
46
+
47
+ mount() {
48
+ // eslint-disable-next-line
49
+ return
50
+ }
51
+
52
+ get dom(): HTMLElement {
53
+ return this.editor.view.dom as HTMLElement
54
+ }
55
+
56
+ get contentDOM(): HTMLElement | null {
57
+ return null
58
+ }
59
+
60
+ onDragStart(event: DragEvent) {
61
+ const { view } = this.editor
62
+ const target = (event.target as HTMLElement)
63
+
64
+ // get the drag handle element
65
+ // `closest` is not available for text nodes so we may have to use its parent
66
+ const dragHandle = target.nodeType === 3
67
+ ? target.parentElement?.closest('[data-drag-handle]')
68
+ : target.closest('[data-drag-handle]')
69
+
70
+ if (
71
+ !this.dom
72
+ || this.contentDOM?.contains(target)
73
+ || !dragHandle
74
+ ) {
75
+ return
76
+ }
77
+
78
+ let x = 0
79
+ let y = 0
80
+
81
+ // calculate offset for drag element if we use a different drag handle element
82
+ if (this.dom !== dragHandle) {
83
+ const domBox = this.dom.getBoundingClientRect()
84
+ const handleBox = dragHandle.getBoundingClientRect()
85
+
86
+ // In React, we have to go through nativeEvent to reach offsetX/offsetY.
87
+ const offsetX = event.offsetX ?? (event as any).nativeEvent?.offsetX
88
+ const offsetY = event.offsetY ?? (event as any).nativeEvent?.offsetY
89
+
90
+ x = handleBox.x - domBox.x + offsetX
91
+ y = handleBox.y - domBox.y + offsetY
92
+ }
93
+
94
+ event.dataTransfer?.setDragImage(this.dom, x, y)
95
+
96
+ // we need to tell ProseMirror that we want to move the whole node
97
+ // so we create a NodeSelection
98
+ const selection = NodeSelection.create(view.state.doc, this.getPos())
99
+ const transaction = view.state.tr.setSelection(selection)
100
+
101
+ view.dispatch(transaction)
102
+ }
103
+
104
+ stopEvent(event: Event) {
105
+ if (!this.dom) {
106
+ return false
107
+ }
108
+
109
+ if (typeof this.options.stopEvent === 'function') {
110
+ return this.options.stopEvent({ event })
111
+ }
112
+
113
+ const target = (event.target as HTMLElement)
114
+ const isInElement = this.dom.contains(target) && !this.contentDOM?.contains(target)
115
+
116
+ // any event from child nodes should be handled by ProseMirror
117
+ if (!isInElement) {
118
+ return false
119
+ }
120
+
121
+ const isDropEvent = event.type === 'drop'
122
+ const isInput = ['INPUT', 'BUTTON', 'SELECT', 'TEXTAREA'].includes(target.tagName)
123
+ || target.isContentEditable
124
+
125
+ // any input event within node views should be ignored by ProseMirror
126
+ if (isInput && !isDropEvent) {
127
+ return true
128
+ }
129
+
130
+ const { isEditable } = this.editor
131
+ const { isDragging } = this
132
+ const isDraggable = !!this.node.type.spec.draggable
133
+ const isSelectable = NodeSelection.isSelectable(this.node)
134
+ const isCopyEvent = event.type === 'copy'
135
+ const isPasteEvent = event.type === 'paste'
136
+ const isCutEvent = event.type === 'cut'
137
+ const isClickEvent = event.type === 'mousedown'
138
+ const isDragEvent = event.type.startsWith('drag')
139
+
140
+ // ProseMirror tries to drag selectable nodes
141
+ // even if `draggable` is set to `false`
142
+ // this fix prevents that
143
+ if (!isDraggable && isSelectable && isDragEvent) {
144
+ event.preventDefault()
145
+ }
146
+
147
+ if (isDraggable && isDragEvent && !isDragging) {
148
+ event.preventDefault()
149
+ return false
150
+ }
151
+
152
+ // we have to store that dragging started
153
+ if (isDraggable && isEditable && !isDragging && isClickEvent) {
154
+ const dragHandle = target.closest('[data-drag-handle]')
155
+ const isValidDragHandle = dragHandle
156
+ && (this.dom === dragHandle || (this.dom.contains(dragHandle)))
157
+
158
+ if (isValidDragHandle) {
159
+ this.isDragging = true
160
+
161
+ document.addEventListener('dragend', () => {
162
+ this.isDragging = false
163
+ }, { once: true })
164
+
165
+ document.addEventListener('mouseup', () => {
166
+ this.isDragging = false
167
+ }, { once: true })
168
+ }
169
+ }
170
+
171
+ // these events are handled by prosemirror
172
+ if (
173
+ isDragging
174
+ || isDropEvent
175
+ || isCopyEvent
176
+ || isPasteEvent
177
+ || isCutEvent
178
+ || (isClickEvent && isSelectable)
179
+ ) {
180
+ return false
181
+ }
182
+
183
+ return true
184
+ }
185
+
186
+ ignoreMutation(mutation: MutationRecord | { type: 'selection', target: Element }) {
187
+ if (!this.dom || !this.contentDOM) {
188
+ return true
189
+ }
190
+
191
+ if (typeof this.options.ignoreMutation === 'function') {
192
+ return this.options.ignoreMutation({ mutation })
193
+ }
194
+
195
+ // a leaf/atom node is like a black box for ProseMirror
196
+ // and should be fully handled by the node view
197
+ if (this.node.isLeaf || this.node.isAtom) {
198
+ return true
199
+ }
200
+
201
+ // ProseMirror should handle any selections
202
+ if (mutation.type === 'selection') {
203
+ return false
204
+ }
205
+
206
+ // try to prevent a bug on iOS that will break node views on enter
207
+ // this is because ProseMirror can’t preventDispatch on enter
208
+ // this will lead to a re-render of the node view on enter
209
+ // see: https://github.com/ueberdosis/tiptap/issues/1214
210
+ if (
211
+ this.dom.contains(mutation.target)
212
+ && mutation.type === 'childList'
213
+ && isiOS()
214
+ && this.editor.isFocused
215
+ ) {
216
+ const changedNodes = [
217
+ ...Array.from(mutation.addedNodes),
218
+ ...Array.from(mutation.removedNodes),
219
+ ] as HTMLElement[]
220
+
221
+ // we’ll check if every changed node is contentEditable
222
+ // to make sure it’s probably mutated by ProseMirror
223
+ if (changedNodes.every(node => node.isContentEditable)) {
224
+ return false
225
+ }
226
+ }
227
+
228
+ // we will allow mutation contentDOM with attributes
229
+ // so we can for example adding classes within our node view
230
+ if (this.contentDOM === mutation.target && mutation.type === 'attributes') {
231
+ return true
232
+ }
233
+
234
+ // ProseMirror should handle any changes within contentDOM
235
+ if (this.contentDOM.contains(mutation.target)) {
236
+ return false
237
+ }
238
+
239
+ return true
240
+ }
241
+
242
+ updateAttributes(attributes: {}) {
243
+ this.editor.commands.command(({ tr }) => {
244
+ const pos = this.getPos()
245
+
246
+ tr.setNodeMarkup(pos, undefined, {
247
+ ...this.node.attrs,
248
+ ...attributes,
249
+ })
250
+
251
+ return true
252
+ })
253
+ }
254
+
255
+ deleteNode(): void {
256
+ const from = this.getPos()
257
+ const to = from + this.node.nodeSize
258
+
259
+ this.editor.commands.deleteRange({ from, to })
260
+ }
261
+ }
@@ -0,0 +1,280 @@
1
+ import { EditorState, Plugin } from 'prosemirror-state'
2
+
3
+ import { CommandManager } from './CommandManager'
4
+ import { Editor } from './Editor'
5
+ import { createChainableState } from './helpers/createChainableState'
6
+ import {
7
+ CanCommands,
8
+ ChainedCommands,
9
+ ExtendedRegExpMatchArray,
10
+ Range,
11
+ SingleCommands,
12
+ } from './types'
13
+ import { isNumber } from './utilities/isNumber'
14
+ import { isRegExp } from './utilities/isRegExp'
15
+
16
+ export type PasteRuleMatch = {
17
+ index: number,
18
+ text: string,
19
+ replaceWith?: string,
20
+ match?: RegExpMatchArray,
21
+ data?: Record<string, any>,
22
+ }
23
+
24
+ export type PasteRuleFinder =
25
+ | RegExp
26
+ | ((text: string) => PasteRuleMatch[] | null | undefined)
27
+
28
+ export class PasteRule {
29
+ find: PasteRuleFinder
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: PasteRuleFinder,
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 pasteRuleMatcherHandler = (text: string, find: PasteRuleFinder): ExtendedRegExpMatchArray[] => {
57
+ if (isRegExp(find)) {
58
+ return [...text.matchAll(find)]
59
+ }
60
+
61
+ const matches = find(text)
62
+
63
+ if (!matches) {
64
+ return []
65
+ }
66
+
67
+ return matches.map(pasteRuleMatch => {
68
+ const result: ExtendedRegExpMatchArray = []
69
+
70
+ result.push(pasteRuleMatch.text)
71
+ result.index = pasteRuleMatch.index
72
+ result.input = text
73
+ result.data = pasteRuleMatch.data
74
+
75
+ if (pasteRuleMatch.replaceWith) {
76
+ if (!pasteRuleMatch.text.includes(pasteRuleMatch.replaceWith)) {
77
+ console.warn('[tiptap warn]: "pasteRuleMatch.replaceWith" must be part of "pasteRuleMatch.text".')
78
+ }
79
+
80
+ result.push(pasteRuleMatch.replaceWith)
81
+ }
82
+
83
+ return result
84
+ })
85
+ }
86
+
87
+ function run(config: {
88
+ editor: Editor,
89
+ state: EditorState,
90
+ from: number,
91
+ to: number,
92
+ rule: PasteRule,
93
+ }): boolean {
94
+ const {
95
+ editor,
96
+ state,
97
+ from,
98
+ to,
99
+ rule,
100
+ } = config
101
+
102
+ const { commands, chain, can } = new CommandManager({
103
+ editor,
104
+ state,
105
+ })
106
+
107
+ const handlers: (void | null)[] = []
108
+
109
+ state.doc.nodesBetween(from, to, (node, pos) => {
110
+ if (!node.isTextblock || node.type.spec.code) {
111
+ return
112
+ }
113
+
114
+ const resolvedFrom = Math.max(from, pos)
115
+ const resolvedTo = Math.min(to, pos + node.content.size)
116
+ const textToMatch = node.textBetween(
117
+ resolvedFrom - pos,
118
+ resolvedTo - pos,
119
+ undefined,
120
+ '\ufffc',
121
+ )
122
+
123
+ const matches = pasteRuleMatcherHandler(textToMatch, rule.find)
124
+
125
+ matches.forEach(match => {
126
+ if (match.index === undefined) {
127
+ return
128
+ }
129
+
130
+ const start = resolvedFrom + match.index + 1
131
+ const end = start + match[0].length
132
+ const range = {
133
+ from: state.tr.mapping.map(start),
134
+ to: state.tr.mapping.map(end),
135
+ }
136
+
137
+ const handler = rule.handler({
138
+ state,
139
+ range,
140
+ match,
141
+ commands,
142
+ chain,
143
+ can,
144
+ })
145
+
146
+ handlers.push(handler)
147
+ })
148
+ })
149
+
150
+ const success = handlers.every(handler => handler !== null)
151
+
152
+ return success
153
+ }
154
+
155
+ /**
156
+ * Create an paste rules plugin. When enabled, it will cause pasted
157
+ * text that matches any of the given rules to trigger the rule’s
158
+ * action.
159
+ */
160
+ export function pasteRulesPlugin(props: { editor: Editor, rules: PasteRule[] }): Plugin[] {
161
+ const { editor, rules } = props
162
+ let dragSourceElement: Element | null = null
163
+ let draggedElement: any
164
+ let draggedText: Selection | null = null
165
+ let caretOffset: number | undefined
166
+ let isPastedFromProseMirror = false
167
+ let isDroppedFromProseMirror = false
168
+
169
+ const plugins = rules.map(rule => {
170
+ return new Plugin({
171
+ // we register a global drag handler to track the current drag source element
172
+ view(view) {
173
+ const handleDragstart = (event: DragEvent) => {
174
+ draggedElement = event.target
175
+ draggedText = window.getSelection()
176
+ event.dataTransfer?.setData('text/plain', draggedText?.toString() as string)
177
+ dragSourceElement = view.dom.parentElement?.contains(event.target as Element)
178
+ ? view.dom.parentElement
179
+ : null
180
+ }
181
+
182
+ const handleDragEnter = (event: DragEvent) => {
183
+ event.preventDefault()
184
+ }
185
+
186
+ const handleDragOver = (event: DragEvent) => {
187
+ event.preventDefault()
188
+ let caretData
189
+
190
+ if (document.caretRangeFromPoint) {
191
+ caretData = document.caretRangeFromPoint(event.clientX, event.clientY)
192
+ }
193
+ caretOffset = caretData?.startOffset
194
+ }
195
+
196
+ window.addEventListener('dragstart', handleDragstart)
197
+
198
+ window.addEventListener('dragenter', handleDragEnter)
199
+
200
+ window.addEventListener('dragover', handleDragOver)
201
+
202
+ return {
203
+ destroy() {
204
+ window.removeEventListener('dragstart', handleDragstart)
205
+ window.removeEventListener('dragenter', handleDragEnter)
206
+ window.removeEventListener('dragover', handleDragOver)
207
+ },
208
+ }
209
+ },
210
+
211
+ props: {
212
+ handleDOMEvents: {
213
+ drop: (view, event: any) => {
214
+ isDroppedFromProseMirror = dragSourceElement === view.dom.parentElement
215
+ event.preventDefault()
216
+
217
+ const data = event.dataTransfer?.getData('text/plain')
218
+
219
+ if (event.target.parentElement.className === 'ProseMirror') {
220
+ draggedElement.textContent = draggedElement.textContent.replace(data, '')
221
+ event.target.textContent = event.target.textContent.slice(0, caretOffset) + data + event.target.textContent.slice(caretOffset)
222
+ }
223
+ return false
224
+ },
225
+
226
+ paste: (view, event: Event) => {
227
+ const html = (event as ClipboardEvent).clipboardData?.getData('text/html')
228
+
229
+ isPastedFromProseMirror = !!html?.includes('data-pm-slice')
230
+
231
+ return false
232
+ },
233
+ },
234
+ },
235
+
236
+ appendTransaction: (transactions, oldState, state) => {
237
+ const transaction = transactions[0]
238
+ const isPaste = transaction.getMeta('uiEvent') === 'paste' && !isPastedFromProseMirror
239
+ const isDrop = transaction.getMeta('uiEvent') === 'drop' && !isDroppedFromProseMirror
240
+
241
+ if (!isPaste && !isDrop) {
242
+ return
243
+ }
244
+
245
+ // stop if there is no changed range
246
+ const from = oldState.doc.content.findDiffStart(state.doc.content)
247
+ const to = oldState.doc.content.findDiffEnd(state.doc.content)
248
+
249
+ if (!isNumber(from) || !to || from === to.b) {
250
+ return
251
+ }
252
+
253
+ // build a chainable state
254
+ // so we can use a single transaction for all paste rules
255
+ const tr = state.tr
256
+ const chainableState = createChainableState({
257
+ state,
258
+ transaction: tr,
259
+ })
260
+
261
+ const handler = run({
262
+ editor,
263
+ state: chainableState,
264
+ from: Math.max(from - 1, 0),
265
+ to: to.b - 1,
266
+ rule,
267
+ })
268
+
269
+ // stop if there are no changes
270
+ if (!handler || !tr.steps.length) {
271
+ return
272
+ }
273
+
274
+ return tr
275
+ },
276
+ })
277
+ })
278
+
279
+ return plugins
280
+ }
package/src/Tracker.ts ADDED
@@ -0,0 +1,42 @@
1
+ import { Transaction } from 'prosemirror-state'
2
+
3
+ export interface TrackerResult {
4
+ position: number,
5
+ deleted: boolean,
6
+ }
7
+
8
+ export class Tracker {
9
+
10
+ transaction: Transaction
11
+
12
+ currentStep: number
13
+
14
+ constructor(transaction: Transaction) {
15
+ this.transaction = transaction
16
+ this.currentStep = this.transaction.steps.length
17
+ }
18
+
19
+ map(position: number): TrackerResult {
20
+ let deleted = false
21
+
22
+ const mappedPosition = this.transaction.steps
23
+ .slice(this.currentStep)
24
+ .reduce((newPosition, step) => {
25
+ const mapResult = step
26
+ .getMap()
27
+ .mapResult(newPosition)
28
+
29
+ if (mapResult.deleted) {
30
+ deleted = true
31
+ }
32
+
33
+ return mapResult.pos
34
+ }, position)
35
+
36
+ return {
37
+ position: mappedPosition,
38
+ deleted,
39
+ }
40
+ }
41
+
42
+ }
@@ -1,20 +1,26 @@
1
- import { Command, RawCommands } from '../types'
1
+ import { RawCommands } from '../types'
2
2
 
3
3
  declare module '@tiptap/core' {
4
- interface Commands {
4
+ interface Commands<ReturnType> {
5
5
  blur: {
6
6
  /**
7
7
  * Removes focus from the editor.
8
8
  */
9
- blur: () => Command,
9
+ blur: () => ReturnType,
10
10
  }
11
11
  }
12
12
  }
13
13
 
14
- export const blur: RawCommands['blur'] = () => ({ view }) => {
15
- const element = view.dom as HTMLElement
14
+ export const blur: RawCommands['blur'] = () => ({ editor, view }) => {
15
+ requestAnimationFrame(() => {
16
+ if (!editor.isDestroyed) {
17
+ (view.dom as HTMLElement).blur()
16
18
 
17
- element.blur()
19
+ // Browsers should remove the caret on blur but safari does not.
20
+ // See: https://github.com/ueberdosis/tiptap/issues/2405
21
+ window?.getSelection()?.removeAllRanges()
22
+ }
23
+ })
18
24
 
19
25
  return true
20
26
  }
@@ -1,12 +1,12 @@
1
- import { Command, RawCommands } from '../types'
1
+ import { RawCommands } from '../types'
2
2
 
3
3
  declare module '@tiptap/core' {
4
- interface Commands {
4
+ interface Commands<ReturnType> {
5
5
  clearContent: {
6
6
  /**
7
7
  * Clear the whole document.
8
8
  */
9
- clearContent: (emitUpdate: Boolean) => Command,
9
+ clearContent: (emitUpdate?: boolean) => ReturnType,
10
10
  }
11
11
  }
12
12
  }
@@ -1,39 +1,53 @@
1
1
  import { liftTarget } from 'prosemirror-transform'
2
- import { Command, RawCommands } from '../types'
2
+
3
+ import { RawCommands } from '../types'
3
4
 
4
5
  declare module '@tiptap/core' {
5
- interface Commands {
6
+ interface Commands<ReturnType> {
6
7
  clearNodes: {
7
8
  /**
8
9
  * Normalize nodes to a simple paragraph.
9
10
  */
10
- clearNodes: () => Command,
11
+ clearNodes: () => ReturnType,
11
12
  }
12
13
  }
13
14
  }
14
15
 
15
16
  export const clearNodes: RawCommands['clearNodes'] = () => ({ state, tr, dispatch }) => {
16
17
  const { selection } = tr
17
- const { from, to } = selection
18
+ const { ranges } = selection
18
19
 
19
- state.doc.nodesBetween(from, to, (node, pos) => {
20
- if (!node.type.isText) {
21
- const fromPos = tr.doc.resolve(tr.mapping.map(pos + 1))
22
- const toPos = tr.doc.resolve(tr.mapping.map(pos + node.nodeSize - 1))
23
- const nodeRange = fromPos.blockRange(toPos)
20
+ if (!dispatch) {
21
+ return true
22
+ }
24
23
 
25
- if (nodeRange) {
26
- const targetLiftDepth = liftTarget(nodeRange)
24
+ ranges.forEach(({ $from, $to }) => {
25
+ state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => {
26
+ if (node.type.isText) {
27
+ return
28
+ }
27
29
 
28
- if (node.type.isTextblock && dispatch) {
29
- tr.setNodeMarkup(nodeRange.start, state.doc.type.contentMatch.defaultType)
30
- }
30
+ const { doc, mapping } = tr
31
+ const $mappedFrom = doc.resolve(mapping.map(pos))
32
+ const $mappedTo = doc.resolve(mapping.map(pos + node.nodeSize))
33
+ const nodeRange = $mappedFrom.blockRange($mappedTo)
31
34
 
32
- if ((targetLiftDepth || targetLiftDepth === 0) && dispatch) {
33
- tr.lift(nodeRange, targetLiftDepth)
34
- }
35
+ if (!nodeRange) {
36
+ return
35
37
  }
36
- }
38
+
39
+ const targetLiftDepth = liftTarget(nodeRange)
40
+
41
+ if (node.type.isTextblock) {
42
+ const { defaultType } = $mappedFrom.parent.contentMatchAt($mappedFrom.index())
43
+
44
+ tr.setNodeMarkup(nodeRange.start, defaultType)
45
+ }
46
+
47
+ if (targetLiftDepth || targetLiftDepth === 0) {
48
+ tr.lift(nodeRange, targetLiftDepth)
49
+ }
50
+ })
37
51
  })
38
52
 
39
53
  return true