@tiptap/core 2.0.0-beta.99 → 2.0.0-rc.1

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