@tiptap/core 2.0.0-beta.17 → 2.0.0-beta.170

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 (318) 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 +23 -18
  5. package/dist/packages/core/src/EventEmitter.d.ts +8 -4
  6. package/dist/packages/core/src/Extension.d.ts +102 -26
  7. package/dist/packages/core/src/ExtensionManager.d.ts +7 -12
  8. package/dist/packages/core/src/InputRule.d.ts +42 -0
  9. package/dist/packages/core/src/Mark.d.ts +134 -30
  10. package/dist/packages/core/src/Node.d.ts +160 -32
  11. package/dist/packages/core/src/NodeView.d.ts +5 -9
  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/insertContent.d.ts +7 -3
  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 +21 -15
  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 -4
  74. package/dist/packages/core/src/helpers/createNodeFromContent.d.ts +4 -5
  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 +1 -1
  79. package/dist/packages/core/src/helpers/findParentNodeClosestToPos.d.ts +1 -1
  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 +1 -1
  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 +1 -2
  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 +1 -2
  94. package/dist/packages/core/src/helpers/getNodeType.d.ts +1 -1
  95. package/dist/packages/core/src/helpers/getRenderedAttributes.d.ts +2 -2
  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/getTextSeralizersFromSchema.d.ts +3 -0
  104. package/dist/packages/core/src/helpers/injectExtensionAttributesToParseRule.d.ts +1 -1
  105. package/dist/packages/core/src/helpers/isActive.d.ts +1 -2
  106. package/dist/packages/core/src/helpers/isExtensionRulesEnabled.d.ts +2 -0
  107. package/dist/packages/core/src/helpers/isList.d.ts +1 -1
  108. package/dist/packages/core/src/helpers/isMarkActive.d.ts +1 -2
  109. package/dist/packages/core/src/helpers/isNodeActive.d.ts +1 -2
  110. package/dist/packages/core/src/helpers/isNodeEmpty.d.ts +1 -1
  111. package/dist/packages/core/src/helpers/isNodeSelection.d.ts +1 -1
  112. package/dist/packages/core/src/helpers/isTextSelection.d.ts +1 -1
  113. package/dist/packages/core/src/helpers/posToDOMRect.d.ts +2 -0
  114. package/dist/packages/core/src/helpers/resolveFocusPosition.d.ts +4 -0
  115. package/dist/packages/core/src/helpers/selectionToInsertionEnd.d.ts +1 -1
  116. package/dist/packages/core/src/helpers/splitExtensions.d.ts +4 -4
  117. package/dist/packages/core/src/index.d.ts +51 -20
  118. package/dist/packages/core/src/inputRules/markInputRule.d.ts +11 -2
  119. package/dist/packages/core/src/inputRules/nodeInputRule.d.ts +11 -2
  120. package/dist/packages/core/src/inputRules/textInputRule.d.ts +9 -0
  121. package/dist/packages/core/src/inputRules/textblockTypeInputRule.d.ts +14 -0
  122. package/dist/packages/core/src/inputRules/wrappingInputRule.d.ts +23 -0
  123. package/dist/packages/core/src/pasteRules/markPasteRule.d.ts +11 -2
  124. package/dist/packages/core/src/pasteRules/textPasteRule.d.ts +9 -0
  125. package/dist/packages/core/src/style.d.ts +1 -2
  126. package/dist/packages/core/src/types.d.ts +105 -52
  127. package/dist/packages/core/src/utilities/callOrReturn.d.ts +2 -1
  128. package/dist/packages/core/src/utilities/createStyleTag.d.ts +1 -1
  129. package/dist/packages/core/src/utilities/deleteProps.d.ts +1 -2
  130. package/dist/packages/core/src/utilities/elementFromString.d.ts +1 -1
  131. package/dist/packages/core/src/utilities/escapeForRegEx.d.ts +1 -0
  132. package/dist/packages/core/src/utilities/findDuplicates.d.ts +1 -0
  133. package/dist/packages/core/src/utilities/fromString.d.ts +1 -1
  134. package/dist/packages/core/src/utilities/isClass.d.ts +1 -1
  135. package/dist/packages/core/src/utilities/isEmptyObject.d.ts +1 -1
  136. package/dist/packages/core/src/utilities/isFunction.d.ts +1 -0
  137. package/dist/packages/core/src/utilities/isMacOS.d.ts +1 -0
  138. package/dist/packages/core/src/utilities/isNumber.d.ts +1 -0
  139. package/dist/packages/core/src/utilities/isObject.d.ts +1 -1
  140. package/dist/packages/core/src/utilities/isPlainObject.d.ts +1 -1
  141. package/dist/packages/core/src/utilities/isRegExp.d.ts +1 -0
  142. package/dist/packages/core/src/utilities/isiOS.d.ts +1 -0
  143. package/dist/packages/core/src/utilities/mergeAttributes.d.ts +1 -2
  144. package/dist/packages/core/src/utilities/mergeDeep.d.ts +1 -2
  145. package/dist/packages/core/src/utilities/minMax.d.ts +1 -1
  146. package/dist/packages/core/src/utilities/objectIncludes.d.ts +3 -2
  147. package/dist/packages/core/src/utilities/removeDuplicates.d.ts +8 -0
  148. package/dist/tiptap-core.cjs.js +3572 -2041
  149. package/dist/tiptap-core.cjs.js.map +1 -1
  150. package/dist/tiptap-core.esm.js +3544 -2044
  151. package/dist/tiptap-core.esm.js.map +1 -1
  152. package/dist/tiptap-core.umd.js +3430 -1898
  153. package/dist/tiptap-core.umd.js.map +1 -1
  154. package/package.json +20 -16
  155. package/src/CommandManager.ts +60 -62
  156. package/src/Editor.ts +109 -74
  157. package/src/EventEmitter.ts +14 -4
  158. package/src/Extension.ts +196 -41
  159. package/src/ExtensionManager.ts +242 -78
  160. package/src/InputRule.ts +268 -0
  161. package/src/Mark.ts +242 -47
  162. package/src/Node.ts +279 -52
  163. package/src/NodeView.ts +105 -42
  164. package/src/PasteRule.ts +246 -0
  165. package/src/Tracker.ts +42 -0
  166. package/src/commands/blur.ts +12 -6
  167. package/src/commands/clearContent.ts +3 -3
  168. package/src/commands/clearNodes.ts +29 -18
  169. package/src/commands/command.ts +2 -2
  170. package/src/commands/createParagraphNear.ts +3 -3
  171. package/src/commands/deleteNode.ts +36 -0
  172. package/src/commands/deleteRange.ts +3 -3
  173. package/src/commands/deleteSelection.ts +3 -3
  174. package/src/commands/enter.ts +3 -3
  175. package/src/commands/exitCode.ts +3 -3
  176. package/src/commands/extendMarkRange.ts +10 -10
  177. package/src/commands/first.ts +3 -3
  178. package/src/commands/focus.ts +45 -44
  179. package/src/commands/forEach.ts +24 -0
  180. package/src/commands/insertContent.ts +12 -24
  181. package/src/commands/insertContentAt.ts +107 -0
  182. package/src/commands/joinBackward.ts +3 -3
  183. package/src/commands/joinForward.ts +3 -3
  184. package/src/commands/keyboardShortcut.ts +6 -6
  185. package/src/commands/lift.ts +5 -5
  186. package/src/commands/liftEmptyBlock.ts +3 -3
  187. package/src/commands/liftListItem.ts +4 -4
  188. package/src/commands/newlineInCode.ts +3 -3
  189. package/src/commands/resetAttributes.ts +61 -0
  190. package/src/commands/scrollIntoView.ts +3 -3
  191. package/src/commands/selectAll.ts +8 -6
  192. package/src/commands/selectNodeBackward.ts +3 -3
  193. package/src/commands/selectNodeForward.ts +3 -3
  194. package/src/commands/selectParentNode.ts +3 -3
  195. package/src/commands/selectTextblockEnd.ts +19 -0
  196. package/src/commands/selectTextblockStart.ts +19 -0
  197. package/src/commands/setContent.ts +7 -11
  198. package/src/commands/setMark.ts +35 -12
  199. package/src/commands/setMeta.ts +18 -0
  200. package/src/commands/setNode.ts +27 -6
  201. package/src/commands/setNodeSelection.ts +28 -0
  202. package/src/commands/setTextSelection.ts +32 -0
  203. package/src/commands/sinkListItem.ts +4 -4
  204. package/src/commands/splitBlock.ts +14 -9
  205. package/src/commands/splitListItem.ts +41 -15
  206. package/src/commands/toggleList.ts +82 -18
  207. package/src/commands/toggleMark.ts +17 -7
  208. package/src/commands/toggleNode.ts +5 -5
  209. package/src/commands/toggleWrap.ts +8 -9
  210. package/src/commands/undoInputRule.ts +34 -5
  211. package/src/commands/unsetAllMarks.ts +7 -11
  212. package/src/commands/unsetMark.ts +34 -22
  213. package/src/commands/updateAttributes.ts +72 -0
  214. package/src/commands/wrapIn.ts +4 -10
  215. package/src/commands/wrapInList.ts +4 -4
  216. package/src/extensions/clipboardTextSerializer.ts +13 -35
  217. package/src/extensions/commands.ts +30 -21
  218. package/src/extensions/focusEvents.ts +0 -3
  219. package/src/extensions/index.ts +1 -0
  220. package/src/extensions/keymap.ts +111 -13
  221. package/src/extensions/tabindex.ts +19 -0
  222. package/src/helpers/combineTransactionSteps.ts +18 -0
  223. package/src/helpers/createChainableState.ts +37 -0
  224. package/src/helpers/createDocument.ts +5 -7
  225. package/src/helpers/createNodeFromContent.ts +15 -18
  226. package/src/helpers/defaultBlockAt.ts +13 -0
  227. package/src/helpers/findChildren.ts +17 -0
  228. package/src/helpers/findChildrenInRange.ts +31 -0
  229. package/src/helpers/findParentNode.ts +2 -2
  230. package/src/helpers/findParentNodeClosestToPos.ts +1 -1
  231. package/src/helpers/generateHTML.ts +5 -5
  232. package/src/helpers/generateJSON.ts +13 -0
  233. package/src/helpers/generateText.ts +29 -0
  234. package/src/helpers/getAttributes.ts +27 -0
  235. package/src/helpers/getAttributesFromExtensions.ts +28 -7
  236. package/src/helpers/getChangedRanges.ts +82 -0
  237. package/src/helpers/getDebugJSON.ts +53 -0
  238. package/src/helpers/getExtensionField.ts +25 -0
  239. package/src/helpers/getHTMLFromFragment.ts +6 -5
  240. package/src/helpers/getMarkAttributes.ts +12 -9
  241. package/src/helpers/getMarkRange.ts +34 -6
  242. package/src/helpers/getMarkType.ts +5 -1
  243. package/src/helpers/getMarksBetween.ts +31 -10
  244. package/src/helpers/getNodeAttributes.ts +7 -8
  245. package/src/helpers/getNodeType.ts +5 -1
  246. package/src/helpers/getRenderedAttributes.ts +4 -6
  247. package/src/helpers/getSchema.ts +6 -133
  248. package/src/helpers/getSchemaByResolvedExtensions.ts +147 -0
  249. package/src/helpers/getSchemaTypeByName.ts +2 -10
  250. package/src/helpers/getSchemaTypeNameByName.ts +1 -1
  251. package/src/helpers/getSplittedAttributes.ts +4 -4
  252. package/src/helpers/getText.ts +18 -0
  253. package/src/helpers/getTextBetween.ts +45 -0
  254. package/src/helpers/getTextSeralizersFromSchema.ts +9 -0
  255. package/src/helpers/injectExtensionAttributesToParseRule.ts +15 -17
  256. package/src/helpers/isActive.ts +4 -5
  257. package/src/helpers/isExtensionRulesEnabled.ts +15 -0
  258. package/src/helpers/isList.ts +14 -7
  259. package/src/helpers/isMarkActive.ts +43 -19
  260. package/src/helpers/isNodeActive.ts +26 -34
  261. package/src/helpers/isNodeEmpty.ts +1 -1
  262. package/src/helpers/isNodeSelection.ts +2 -2
  263. package/src/helpers/isTextSelection.ts +2 -2
  264. package/src/helpers/posToDOMRect.ts +34 -0
  265. package/src/helpers/resolveFocusPosition.ts +34 -0
  266. package/src/helpers/selectionToInsertionEnd.ts +1 -1
  267. package/src/helpers/splitExtensions.ts +1 -1
  268. package/src/index.ts +53 -20
  269. package/src/inputRules/markInputRule.ts +58 -39
  270. package/src/inputRules/nodeInputRule.ts +44 -11
  271. package/src/inputRules/textInputRule.ts +35 -0
  272. package/src/inputRules/textblockTypeInputRule.ts +37 -0
  273. package/src/inputRules/wrappingInputRule.ts +59 -0
  274. package/src/pasteRules/markPasteRule.ts +61 -53
  275. package/src/pasteRules/textPasteRule.ts +35 -0
  276. package/src/style.ts +16 -3
  277. package/src/types.ts +119 -37
  278. package/src/utilities/callOrReturn.ts +6 -3
  279. package/src/utilities/createStyleTag.ts +8 -1
  280. package/src/utilities/deleteProps.ts +2 -4
  281. package/src/utilities/elementFromString.ts +4 -5
  282. package/src/utilities/escapeForRegEx.ts +4 -0
  283. package/src/utilities/findDuplicates.ts +5 -0
  284. package/src/utilities/fromString.ts +2 -2
  285. package/src/utilities/isClass.ts +2 -2
  286. package/src/utilities/isEmptyObject.ts +2 -2
  287. package/src/utilities/isFunction.ts +3 -0
  288. package/src/utilities/isMacOS.ts +5 -0
  289. package/src/utilities/isNumber.ts +3 -0
  290. package/src/utilities/isObject.ts +6 -6
  291. package/src/utilities/isPlainObject.ts +8 -5
  292. package/src/utilities/isRegExp.ts +3 -0
  293. package/src/utilities/isString.ts +3 -0
  294. package/src/utilities/isiOS.ts +12 -0
  295. package/src/utilities/mergeAttributes.ts +2 -3
  296. package/src/utilities/mergeDeep.ts +2 -3
  297. package/src/utilities/minMax.ts +1 -1
  298. package/src/utilities/objectIncludes.ts +17 -5
  299. package/src/utilities/removeDuplicates.ts +15 -0
  300. package/CHANGELOG.md +0 -324
  301. package/dist/packages/core/src/commands/insertHTML.d.ts +0 -12
  302. package/dist/packages/core/src/commands/insertNode.d.ts +0 -13
  303. package/dist/packages/core/src/commands/insertText.d.ts +0 -12
  304. package/dist/packages/core/src/commands/replace.d.ts +0 -13
  305. package/dist/packages/core/src/commands/replaceRange.d.ts +0 -13
  306. package/dist/packages/core/src/commands/resetNodeAttributes.d.ts +0 -13
  307. package/dist/packages/core/src/commands/updateNodeAttributes.d.ts +0 -13
  308. package/dist/packages/core/src/utilities/removeElement.d.ts +0 -1
  309. package/dist/tiptap-core.bundle.umd.min.js +0 -17
  310. package/dist/tiptap-core.bundle.umd.min.js.map +0 -1
  311. package/src/commands/insertHTML.ts +0 -30
  312. package/src/commands/insertNode.ts +0 -33
  313. package/src/commands/insertText.ts +0 -22
  314. package/src/commands/replace.ts +0 -20
  315. package/src/commands/replaceRange.ts +0 -36
  316. package/src/commands/resetNodeAttributes.ts +0 -31
  317. package/src/commands/updateNodeAttributes.ts +0 -33
  318. package/src/utilities/removeElement.ts +0 -5
package/src/NodeView.ts CHANGED
@@ -3,19 +3,21 @@ import { NodeSelection } from 'prosemirror-state'
3
3
  import { Node as ProseMirrorNode } from 'prosemirror-model'
4
4
  import { Editor as CoreEditor } from './Editor'
5
5
  import { Node } from './Node'
6
- import { NodeViewRendererProps } from './types'
6
+ import { isiOS } from './utilities/isiOS'
7
+ import { NodeViewRendererProps, NodeViewRendererOptions } from './types'
7
8
 
8
- interface NodeViewRendererOptions {
9
- stopEvent: ((event: Event) => boolean) | null,
10
- update: ((node: ProseMirrorNode, decorations: Decoration[]) => boolean) | null,
11
- }
12
-
13
- export class NodeView<Component, Editor extends CoreEditor = CoreEditor> implements ProseMirrorNodeView {
9
+ export class NodeView<
10
+ Component,
11
+ Editor extends CoreEditor = CoreEditor,
12
+ Options extends NodeViewRendererOptions = NodeViewRendererOptions,
13
+ > implements ProseMirrorNodeView {
14
14
 
15
15
  component: Component
16
16
 
17
17
  editor: Editor
18
18
 
19
+ options: Options
20
+
19
21
  extension: Node
20
22
 
21
23
  node: ProseMirrorNode
@@ -26,15 +28,14 @@ export class NodeView<Component, Editor extends CoreEditor = CoreEditor> impleme
26
28
 
27
29
  isDragging = false
28
30
 
29
- options: NodeViewRendererOptions = {
30
- stopEvent: null,
31
- update: null,
32
- }
33
-
34
- constructor(component: Component, props: NodeViewRendererProps, options?: Partial<NodeViewRendererOptions>) {
31
+ constructor(component: Component, props: NodeViewRendererProps, options?: Partial<Options>) {
35
32
  this.component = component
36
- this.options = { ...this.options, ...options }
37
33
  this.editor = props.editor as Editor
34
+ this.options = {
35
+ stopEvent: null,
36
+ ignoreMutation: null,
37
+ ...options,
38
+ } as Options
38
39
  this.extension = props.extension
39
40
  this.node = props.node
40
41
  this.decorations = props.decorations
@@ -56,20 +57,39 @@ export class NodeView<Component, Editor extends CoreEditor = CoreEditor> impleme
56
57
  }
57
58
 
58
59
  onDragStart(event: DragEvent) {
59
- if (!this.dom) {
60
- return
61
- }
62
-
63
60
  const { view } = this.editor
64
61
  const target = (event.target as HTMLElement)
65
62
 
66
- if (this.contentDOM?.contains(target)) {
63
+ // get the drag handle element
64
+ // `closest` is not available for text nodes so we may have to use its parent
65
+ const dragHandle = target.nodeType === 3
66
+ ? target.parentElement?.closest('[data-drag-handle]')
67
+ : target.closest('[data-drag-handle]')
68
+
69
+ if (
70
+ !this.dom
71
+ || this.contentDOM?.contains(target)
72
+ || !dragHandle
73
+ ) {
67
74
  return
68
75
  }
69
76
 
70
- // sometimes `event.target` is not the `dom` element
71
- event.dataTransfer?.setDragImage(this.dom, 0, 0)
77
+ let x = 0
78
+ let y = 0
79
+
80
+ // calculate offset for drag element if we use a different drag handle element
81
+ if (this.dom !== dragHandle) {
82
+ const domBox = this.dom.getBoundingClientRect()
83
+ const handleBox = dragHandle.getBoundingClientRect()
84
+
85
+ x = handleBox.x - domBox.x + event.offsetX
86
+ y = handleBox.y - domBox.y + event.offsetY
87
+ }
88
+
89
+ event.dataTransfer?.setDragImage(this.dom, x, y)
72
90
 
91
+ // we need to tell ProseMirror that we want to move the whole node
92
+ // so we create a NodeSelection
73
93
  const selection = NodeSelection.create(view.state.doc, this.getPos())
74
94
  const transaction = view.state.tr.setSelection(selection)
75
95
 
@@ -82,7 +102,7 @@ export class NodeView<Component, Editor extends CoreEditor = CoreEditor> impleme
82
102
  }
83
103
 
84
104
  if (typeof this.options.stopEvent === 'function') {
85
- return this.options.stopEvent(event)
105
+ return this.options.stopEvent({ event })
86
106
  }
87
107
 
88
108
  const target = (event.target as HTMLElement)
@@ -93,11 +113,12 @@ export class NodeView<Component, Editor extends CoreEditor = CoreEditor> impleme
93
113
  return false
94
114
  }
95
115
 
116
+ const isDropEvent = event.type === 'drop'
96
117
  const isInput = ['INPUT', 'BUTTON', 'SELECT', 'TEXTAREA'].includes(target.tagName)
97
118
  || target.isContentEditable
98
119
 
99
120
  // any input event within node views should be ignored by ProseMirror
100
- if (isInput) {
121
+ if (isInput && !isDropEvent) {
101
122
  return true
102
123
  }
103
124
 
@@ -109,7 +130,7 @@ export class NodeView<Component, Editor extends CoreEditor = CoreEditor> impleme
109
130
  const isPasteEvent = event.type === 'paste'
110
131
  const isCutEvent = event.type === 'cut'
111
132
  const isClickEvent = event.type === 'mousedown'
112
- const isDragEvent = event.type.startsWith('drag') || event.type === 'drop'
133
+ const isDragEvent = event.type.startsWith('drag')
113
134
 
114
135
  // ProseMirror tries to drag selectable nodes
115
136
  // even if `draggable` is set to `false`
@@ -145,6 +166,7 @@ export class NodeView<Component, Editor extends CoreEditor = CoreEditor> impleme
145
166
  // these events are handled by prosemirror
146
167
  if (
147
168
  isDragging
169
+ || isDropEvent
148
170
  || isCopyEvent
149
171
  || isPasteEvent
150
172
  || isCutEvent
@@ -157,37 +179,78 @@ export class NodeView<Component, Editor extends CoreEditor = CoreEditor> impleme
157
179
  }
158
180
 
159
181
  ignoreMutation(mutation: MutationRecord | { type: 'selection', target: Element }) {
160
- if (mutation.type === 'selection') {
161
- if (this.node.isLeaf) {
162
- return true
163
- }
182
+ if (!this.dom || !this.contentDOM) {
183
+ return true
184
+ }
164
185
 
186
+ if (typeof this.options.ignoreMutation === 'function') {
187
+ return this.options.ignoreMutation({ mutation })
188
+ }
189
+
190
+ // a leaf/atom node is like a black box for ProseMirror
191
+ // and should be fully handled by the node view
192
+ if (this.node.isLeaf || this.node.isAtom) {
193
+ return true
194
+ }
195
+
196
+ // ProseMirror should handle any selections
197
+ if (mutation.type === 'selection') {
165
198
  return false
166
199
  }
167
200
 
168
- if (!this.contentDOM) {
201
+ // try to prevent a bug on iOS that will break node views on enter
202
+ // this is because ProseMirror can’t preventDispatch on enter
203
+ // this will lead to a re-render of the node view on enter
204
+ // see: https://github.com/ueberdosis/tiptap/issues/1214
205
+ if (
206
+ this.dom.contains(mutation.target)
207
+ && mutation.type === 'childList'
208
+ && isiOS()
209
+ && this.editor.isFocused
210
+ ) {
211
+ const changedNodes = [
212
+ ...Array.from(mutation.addedNodes),
213
+ ...Array.from(mutation.removedNodes),
214
+ ] as HTMLElement[]
215
+
216
+ // we’ll check if every changed node is contentEditable
217
+ // to make sure it’s probably mutated by ProseMirror
218
+ if (changedNodes.every(node => node.isContentEditable)) {
219
+ return false
220
+ }
221
+ }
222
+
223
+ // we will allow mutation contentDOM with attributes
224
+ // so we can for example adding classes within our node view
225
+ if (this.contentDOM === mutation.target && mutation.type === 'attributes') {
169
226
  return true
170
227
  }
171
228
 
172
- const contentDOMHasChanged = !this.contentDOM.contains(mutation.target)
173
- || this.contentDOM === mutation.target
229
+ // ProseMirror should handle any changes within contentDOM
230
+ if (this.contentDOM.contains(mutation.target)) {
231
+ return false
232
+ }
174
233
 
175
- return contentDOMHasChanged
234
+ return true
176
235
  }
177
236
 
178
237
  updateAttributes(attributes: {}) {
179
- if (!this.editor.view.editable) {
180
- return
181
- }
238
+ this.editor.commands.command(({ tr }) => {
239
+ const pos = this.getPos()
182
240
 
183
- const { state } = this.editor.view
184
- const pos = this.getPos()
185
- const transaction = state.tr.setNodeMarkup(pos, undefined, {
186
- ...this.node.attrs,
187
- ...attributes,
188
- })
241
+ tr.setNodeMarkup(pos, undefined, {
242
+ ...this.node.attrs,
243
+ ...attributes,
244
+ })
189
245
 
190
- this.editor.view.dispatch(transaction)
246
+ return true
247
+ })
191
248
  }
192
249
 
250
+ deleteNode(): void {
251
+ const from = this.getPos()
252
+ const to = from + this.node.nodeSize
253
+
254
+ this.editor.commands.deleteRange({ from, to })
255
+ }
193
256
  }
@@ -0,0 +1,246 @@
1
+ import { EditorState, Plugin } from 'prosemirror-state'
2
+ import { Editor } from './Editor'
3
+ import { CommandManager } from './CommandManager'
4
+ import { createChainableState } from './helpers/createChainableState'
5
+ import { isRegExp } from './utilities/isRegExp'
6
+ import { isNumber } from './utilities/isNumber'
7
+ import {
8
+ Range,
9
+ ExtendedRegExpMatchArray,
10
+ SingleCommands,
11
+ ChainedCommands,
12
+ CanCommands,
13
+ } from './types'
14
+
15
+ export type PasteRuleMatch = {
16
+ index: number,
17
+ text: string,
18
+ replaceWith?: string,
19
+ match?: RegExpMatchArray,
20
+ data?: Record<string, any>,
21
+ }
22
+
23
+ export type PasteRuleFinder =
24
+ | RegExp
25
+ | ((text: string) => PasteRuleMatch[] | null | undefined)
26
+
27
+ export class PasteRule {
28
+ find: PasteRuleFinder
29
+
30
+ handler: (props: {
31
+ state: EditorState,
32
+ range: Range,
33
+ match: ExtendedRegExpMatchArray,
34
+ commands: SingleCommands,
35
+ chain: () => ChainedCommands,
36
+ can: () => CanCommands,
37
+ }) => void | null
38
+
39
+ constructor(config: {
40
+ find: PasteRuleFinder,
41
+ handler: (props: {
42
+ state: EditorState,
43
+ range: Range,
44
+ match: ExtendedRegExpMatchArray,
45
+ commands: SingleCommands,
46
+ chain: () => ChainedCommands,
47
+ can: () => CanCommands,
48
+ }) => void | null,
49
+ }) {
50
+ this.find = config.find
51
+ this.handler = config.handler
52
+ }
53
+ }
54
+
55
+ const pasteRuleMatcherHandler = (text: string, find: PasteRuleFinder): ExtendedRegExpMatchArray[] => {
56
+ if (isRegExp(find)) {
57
+ return [...text.matchAll(find)]
58
+ }
59
+
60
+ const matches = find(text)
61
+
62
+ if (!matches) {
63
+ return []
64
+ }
65
+
66
+ return matches.map(pasteRuleMatch => {
67
+ const result: ExtendedRegExpMatchArray = []
68
+
69
+ result.push(pasteRuleMatch.text)
70
+ result.index = pasteRuleMatch.index
71
+ result.input = text
72
+ result.data = pasteRuleMatch.data
73
+
74
+ if (pasteRuleMatch.replaceWith) {
75
+ if (!pasteRuleMatch.text.includes(pasteRuleMatch.replaceWith)) {
76
+ console.warn('[tiptap warn]: "pasteRuleMatch.replaceWith" must be part of "pasteRuleMatch.text".')
77
+ }
78
+
79
+ result.push(pasteRuleMatch.replaceWith)
80
+ }
81
+
82
+ return result
83
+ })
84
+ }
85
+
86
+ function run(config: {
87
+ editor: Editor,
88
+ state: EditorState,
89
+ from: number,
90
+ to: number,
91
+ rule: PasteRule,
92
+ }): boolean {
93
+ const {
94
+ editor,
95
+ state,
96
+ from,
97
+ to,
98
+ rule,
99
+ } = config
100
+
101
+ const { commands, chain, can } = new CommandManager({
102
+ editor,
103
+ state,
104
+ })
105
+
106
+ const handlers: (void | null)[] = []
107
+
108
+ state.doc.nodesBetween(from, to, (node, pos) => {
109
+ if (!node.isTextblock || node.type.spec.code) {
110
+ return
111
+ }
112
+
113
+ const resolvedFrom = Math.max(from, pos)
114
+ const resolvedTo = Math.min(to, pos + node.content.size)
115
+ const textToMatch = node.textBetween(
116
+ resolvedFrom - pos,
117
+ resolvedTo - pos,
118
+ undefined,
119
+ '\ufffc',
120
+ )
121
+
122
+ const matches = pasteRuleMatcherHandler(textToMatch, rule.find)
123
+
124
+ matches.forEach(match => {
125
+ if (match.index === undefined) {
126
+ return
127
+ }
128
+
129
+ const start = resolvedFrom + match.index + 1
130
+ const end = start + match[0].length
131
+ const range = {
132
+ from: state.tr.mapping.map(start),
133
+ to: state.tr.mapping.map(end),
134
+ }
135
+
136
+ const handler = rule.handler({
137
+ state,
138
+ range,
139
+ match,
140
+ commands,
141
+ chain,
142
+ can,
143
+ })
144
+
145
+ handlers.push(handler)
146
+ })
147
+ })
148
+
149
+ const success = handlers.every(handler => handler !== null)
150
+
151
+ return success
152
+ }
153
+
154
+ /**
155
+ * Create an paste rules plugin. When enabled, it will cause pasted
156
+ * text that matches any of the given rules to trigger the rule’s
157
+ * action.
158
+ */
159
+ export function pasteRulesPlugin(props: { editor: Editor, rules: PasteRule[] }): Plugin[] {
160
+ const { editor, rules } = props
161
+ let dragSourceElement: Element | null = null
162
+ let isPastedFromProseMirror = false
163
+ let isDroppedFromProseMirror = false
164
+
165
+ const plugins = rules.map(rule => {
166
+ return new Plugin({
167
+ // we register a global drag handler to track the current drag source element
168
+ view(view) {
169
+ const handleDragstart = (event: DragEvent) => {
170
+ dragSourceElement = view.dom.parentElement?.contains(event.target as Element)
171
+ ? view.dom.parentElement
172
+ : null
173
+ }
174
+
175
+ window.addEventListener('dragstart', handleDragstart)
176
+
177
+ return {
178
+ destroy() {
179
+ window.removeEventListener('dragstart', handleDragstart)
180
+ },
181
+ }
182
+ },
183
+
184
+ props: {
185
+ handleDOMEvents: {
186
+ drop: view => {
187
+ isDroppedFromProseMirror = dragSourceElement === view.dom.parentElement
188
+
189
+ return false
190
+ },
191
+
192
+ paste: (view, event) => {
193
+ const html = event.clipboardData?.getData('text/html')
194
+
195
+ isPastedFromProseMirror = !!html?.includes('data-pm-slice')
196
+
197
+ return false
198
+ },
199
+ },
200
+ },
201
+
202
+ appendTransaction: (transactions, oldState, state) => {
203
+ const transaction = transactions[0]
204
+ const isPaste = transaction.getMeta('uiEvent') === 'paste' && !isPastedFromProseMirror
205
+ const isDrop = transaction.getMeta('uiEvent') === 'drop' && !isDroppedFromProseMirror
206
+
207
+ if (!isPaste && !isDrop) {
208
+ return
209
+ }
210
+
211
+ // stop if there is no changed range
212
+ const from = oldState.doc.content.findDiffStart(state.doc.content)
213
+ const to = oldState.doc.content.findDiffEnd(state.doc.content)
214
+
215
+ if (!isNumber(from) || !to || from === to.b) {
216
+ return
217
+ }
218
+
219
+ // build a chainable state
220
+ // so we can use a single transaction for all paste rules
221
+ const tr = state.tr
222
+ const chainableState = createChainableState({
223
+ state,
224
+ transaction: tr,
225
+ })
226
+
227
+ const handler = run({
228
+ editor,
229
+ state: chainableState,
230
+ from: Math.max(from - 1, 0),
231
+ to: to.b,
232
+ rule,
233
+ })
234
+
235
+ // stop if there are no changes
236
+ if (!handler || !tr.steps.length) {
237
+ return
238
+ }
239
+
240
+ return tr
241
+ },
242
+ })
243
+ })
244
+
245
+ return plugins
246
+ }
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,13 +1,13 @@
1
1
  import { liftTarget } from 'prosemirror-transform'
2
- import { Command, RawCommands } from '../types'
2
+ import { RawCommands } from '../types'
3
3
 
4
4
  declare module '@tiptap/core' {
5
- interface Commands {
5
+ interface Commands<ReturnType> {
6
6
  clearNodes: {
7
7
  /**
8
8
  * Normalize nodes to a simple paragraph.
9
9
  */
10
- clearNodes: () => Command,
10
+ clearNodes: () => ReturnType,
11
11
  }
12
12
  }
13
13
  }
@@ -16,24 +16,35 @@ export const clearNodes: RawCommands['clearNodes'] = () => ({ state, tr, dispatc
16
16
  const { selection } = tr
17
17
  const { ranges } = selection
18
18
 
19
- ranges.forEach(range => {
20
- state.doc.nodesBetween(range.$from.pos, range.$to.pos, (node, pos) => {
21
- if (!node.type.isText) {
22
- const fromPos = tr.doc.resolve(tr.mapping.map(pos + 1))
23
- const toPos = tr.doc.resolve(tr.mapping.map(pos + node.nodeSize - 1))
24
- const nodeRange = fromPos.blockRange(toPos)
19
+ if (!dispatch) {
20
+ return true
21
+ }
22
+
23
+ ranges.forEach(({ $from, $to }) => {
24
+ state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => {
25
+ if (node.type.isText) {
26
+ return
27
+ }
28
+
29
+ const { doc, mapping } = tr
30
+ const $mappedFrom = doc.resolve(mapping.map(pos))
31
+ const $mappedTo = doc.resolve(mapping.map(pos + node.nodeSize))
32
+ const nodeRange = $mappedFrom.blockRange($mappedTo)
25
33
 
26
- if (nodeRange) {
27
- const targetLiftDepth = liftTarget(nodeRange)
34
+ if (!nodeRange) {
35
+ return
36
+ }
37
+
38
+ const targetLiftDepth = liftTarget(nodeRange)
28
39
 
29
- if (node.type.isTextblock && dispatch) {
30
- tr.setNodeMarkup(nodeRange.start, state.doc.type.contentMatch.defaultType)
31
- }
40
+ if (node.type.isTextblock) {
41
+ const { defaultType } = $mappedFrom.parent.contentMatchAt($mappedFrom.index())
42
+
43
+ tr.setNodeMarkup(nodeRange.start, defaultType)
44
+ }
32
45
 
33
- if ((targetLiftDepth || targetLiftDepth === 0) && dispatch) {
34
- tr.lift(nodeRange, targetLiftDepth)
35
- }
36
- }
46
+ if (targetLiftDepth || targetLiftDepth === 0) {
47
+ tr.lift(nodeRange, targetLiftDepth)
37
48
  }
38
49
  })
39
50
  })
@@ -1,12 +1,12 @@
1
1
  import { Command, RawCommands } from '../types'
2
2
 
3
3
  declare module '@tiptap/core' {
4
- interface Commands {
4
+ interface Commands<ReturnType> {
5
5
  command: {
6
6
  /**
7
7
  * Define a command inline.
8
8
  */
9
- command: (fn: (props: Parameters<Command>[0]) => boolean) => Command,
9
+ command: (fn: (props: Parameters<Command>[0]) => boolean) => ReturnType,
10
10
  }
11
11
  }
12
12
  }
@@ -1,13 +1,13 @@
1
1
  import { createParagraphNear as originalCreateParagraphNear } from 'prosemirror-commands'
2
- import { Command, RawCommands } from '../types'
2
+ import { RawCommands } from '../types'
3
3
 
4
4
  declare module '@tiptap/core' {
5
- interface Commands {
5
+ interface Commands<ReturnType> {
6
6
  createParagraphNear: {
7
7
  /**
8
8
  * Create a paragraph nearby.
9
9
  */
10
- createParagraphNear: () => Command,
10
+ createParagraphNear: () => ReturnType,
11
11
  }
12
12
  }
13
13
  }