@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
@@ -0,0 +1,84 @@
1
+ import { Node as ProseMirrorNode, NodeType } from '@tiptap/pm/model'
2
+ import { canJoin, findWrapping } from '@tiptap/pm/transform'
3
+
4
+ import { Editor } from '../Editor'
5
+ import { InputRule, InputRuleFinder } from '../InputRule'
6
+ import { ExtendedRegExpMatchArray } from '../types'
7
+ import { callOrReturn } from '../utilities/callOrReturn'
8
+
9
+ /**
10
+ * Build an input rule for automatically wrapping a textblock when a
11
+ * given string is typed. When using a regular expresion you’ll
12
+ * probably want the regexp to start with `^`, so that the pattern can
13
+ * only occur at the start of a textblock.
14
+ *
15
+ * `type` is the type of node to wrap in.
16
+ *
17
+ * By default, if there’s a node with the same type above the newly
18
+ * wrapped node, the rule will try to join those
19
+ * two nodes. You can pass a join predicate, which takes a regular
20
+ * expression match and the node before the wrapped node, and can
21
+ * return a boolean to indicate whether a join should happen.
22
+ */
23
+ export function wrappingInputRule(config: {
24
+ find: InputRuleFinder,
25
+ type: NodeType,
26
+ keepMarks?: boolean,
27
+ keepAttributes?: boolean,
28
+ editor?: Editor
29
+ getAttributes?:
30
+ | Record<string, any>
31
+ | ((match: ExtendedRegExpMatchArray) => Record<string, any>)
32
+ | false
33
+ | null
34
+ ,
35
+ joinPredicate?: (match: ExtendedRegExpMatchArray, node: ProseMirrorNode) => boolean,
36
+ }) {
37
+ return new InputRule({
38
+ find: config.find,
39
+ handler: ({
40
+ state, range, match, chain,
41
+ }) => {
42
+ const attributes = callOrReturn(config.getAttributes, undefined, match) || {}
43
+ const tr = state.tr.delete(range.from, range.to)
44
+ const $start = tr.doc.resolve(range.from)
45
+ const blockRange = $start.blockRange()
46
+ const wrapping = blockRange && findWrapping(blockRange, config.type, attributes)
47
+
48
+ if (!wrapping) {
49
+ return null
50
+ }
51
+
52
+ tr.wrap(blockRange, wrapping)
53
+
54
+ if (config.keepMarks && config.editor) {
55
+ const { selection, storedMarks } = state
56
+ const { splittableMarks } = config.editor.extensionManager
57
+ const marks = storedMarks || (selection.$to.parentOffset && selection.$from.marks())
58
+
59
+ if (marks) {
60
+ const filteredMarks = marks.filter(mark => splittableMarks.includes(mark.type.name))
61
+
62
+ tr.ensureMarks(filteredMarks)
63
+ }
64
+ }
65
+ if (config.keepAttributes) {
66
+ /** If the nodeType is `bulletList` or `orderedList` set the `nodeType` as `listItem` */
67
+ const nodeType = config.type.name === 'bulletList' || config.type.name === 'orderedList' ? 'listItem' : 'taskList'
68
+
69
+ chain().updateAttributes(nodeType, attributes).run()
70
+ }
71
+
72
+ const before = tr.doc.resolve(range.from - 1).nodeBefore
73
+
74
+ if (
75
+ before
76
+ && before.type === config.type
77
+ && canJoin(tr.doc, range.from - 1)
78
+ && (!config.joinPredicate || config.joinPredicate(match, before))
79
+ ) {
80
+ tr.join(range.from - 1)
81
+ }
82
+ },
83
+ })
84
+ }
@@ -0,0 +1,3 @@
1
+ export * from './markPasteRule'
2
+ export * from './nodePasteRule'
3
+ export * from './textPasteRule'
@@ -1,76 +1,69 @@
1
- import { Plugin, PluginKey } from 'prosemirror-state'
2
- import { Slice, Fragment, MarkType } from 'prosemirror-model'
1
+ import { MarkType } from '@tiptap/pm/model'
3
2
 
4
- export default function (
5
- regexp: RegExp,
6
- type: MarkType,
3
+ import { getMarksBetween } from '../helpers/getMarksBetween'
4
+ import { PasteRule, PasteRuleFinder } from '../PasteRule'
5
+ import { ExtendedRegExpMatchArray } from '../types'
6
+ import { callOrReturn } from '../utilities/callOrReturn'
7
+
8
+ /**
9
+ * Build an paste rule that adds a mark when the
10
+ * matched text is pasted into it.
11
+ */
12
+ export function markPasteRule(config: {
13
+ find: PasteRuleFinder
14
+ type: MarkType
7
15
  getAttributes?:
8
16
  | Record<string, any>
9
- | ((match: RegExpExecArray) => Record<string, any>)
17
+ | ((match: ExtendedRegExpMatchArray) => Record<string, any>)
10
18
  | false
11
19
  | null
12
- ,
13
- ): Plugin {
14
- const handler = (fragment: Fragment, parent?: any) => {
15
- const nodes: any[] = []
20
+ }) {
21
+ return new PasteRule({
22
+ find: config.find,
23
+ handler: ({ state, range, match }) => {
24
+ const attributes = callOrReturn(config.getAttributes, undefined, match)
16
25
 
17
- fragment.forEach(child => {
18
- if (child.isText && child.text) {
19
- const { text } = child
20
- let pos = 0
21
- let match
26
+ if (attributes === false || attributes === null) {
27
+ return null
28
+ }
22
29
 
23
- // eslint-disable-next-line
24
- while ((match = regexp.exec(text)) !== null) {
25
- const outerMatch = Math.max(match.length - 2, 0)
26
- const innerMatch = Math.max(match.length - 1, 0)
30
+ const { tr } = state
31
+ const captureGroup = match[match.length - 1]
32
+ const fullMatch = match[0]
33
+ let markEnd = range.to
27
34
 
28
- if (parent?.type.allowsMarkType(type)) {
29
- const start = match.index
30
- const matchStart = start + match[0].indexOf(match[outerMatch])
31
- const matchEnd = matchStart + match[outerMatch].length
32
- const textStart = matchStart + match[outerMatch].lastIndexOf(match[innerMatch])
33
- const textEnd = textStart + match[innerMatch].length
34
- const attrs = getAttributes instanceof Function
35
- ? getAttributes(match)
36
- : getAttributes
35
+ if (captureGroup) {
36
+ const startSpaces = fullMatch.search(/\S/)
37
+ const textStart = range.from + fullMatch.indexOf(captureGroup)
38
+ const textEnd = textStart + captureGroup.length
37
39
 
38
- if (!attrs && attrs !== undefined) {
39
- continue
40
- }
40
+ const excludedMarks = getMarksBetween(range.from, range.to, state.doc)
41
+ .filter(item => {
42
+ // @ts-ignore
43
+ const excluded = item.mark.type.excluded as MarkType[]
41
44
 
42
- // adding text before markdown to nodes
43
- if (matchStart > 0) {
44
- nodes.push(child.cut(pos, matchStart))
45
- }
45
+ return excluded.find(type => type === config.type && type !== item.mark.type)
46
+ })
47
+ .filter(item => item.to > textStart)
46
48
 
47
- // adding the markdown part to nodes
48
- nodes.push(child
49
- .cut(textStart, textEnd)
50
- .mark(type.create(attrs).addToSet(child.marks)))
49
+ if (excludedMarks.length) {
50
+ return null
51
+ }
51
52
 
52
- pos = matchEnd
53
- }
53
+ if (textEnd < range.to) {
54
+ tr.delete(textEnd, range.to)
54
55
  }
55
56
 
56
- // adding rest of text to nodes
57
- if (pos < text.length) {
58
- nodes.push(child.cut(pos))
57
+ if (textStart > range.from) {
58
+ tr.delete(range.from + startSpaces, textStart)
59
59
  }
60
- } else {
61
- nodes.push(child.copy(handler(child.content, child)))
62
- }
63
- })
64
60
 
65
- return Fragment.fromArray(nodes)
66
- }
61
+ markEnd = range.from + startSpaces + captureGroup.length
62
+
63
+ tr.addMark(range.from + startSpaces, markEnd, config.type.create(attributes || {}))
67
64
 
68
- return new Plugin({
69
- key: new PluginKey('markPasteRule'),
70
- props: {
71
- transformPasted: slice => {
72
- return new Slice(handler(slice.content), slice.openStart, slice.openEnd)
73
- },
65
+ tr.removeStoredMark(config.type)
66
+ }
74
67
  },
75
68
  })
76
69
  }
@@ -0,0 +1,37 @@
1
+ import { NodeType } from '@tiptap/pm/model'
2
+
3
+ import { PasteRule, PasteRuleFinder } from '../PasteRule'
4
+ import { ExtendedRegExpMatchArray } from '../types'
5
+ import { callOrReturn } from '../utilities'
6
+
7
+ /**
8
+ * Build an paste rule that adds a node when the
9
+ * matched text is pasted into it.
10
+ */
11
+ export function nodePasteRule(config: {
12
+ find: PasteRuleFinder
13
+ type: NodeType
14
+ getAttributes?:
15
+ | Record<string, any>
16
+ | ((match: ExtendedRegExpMatchArray) => Record<string, any>)
17
+ | false
18
+ | null
19
+ }) {
20
+ return new PasteRule({
21
+ find: config.find,
22
+ handler({ match, chain, range }) {
23
+ const attributes = callOrReturn(config.getAttributes, undefined, match)
24
+
25
+ if (attributes === false || attributes === null) {
26
+ return null
27
+ }
28
+
29
+ if (match.input) {
30
+ chain().deleteRange(range).insertContentAt(range.from, {
31
+ type: config.type.name,
32
+ attrs: attributes,
33
+ })
34
+ }
35
+ },
36
+ })
37
+ }
@@ -0,0 +1,35 @@
1
+ import { PasteRule, PasteRuleFinder } from '../PasteRule'
2
+
3
+ /**
4
+ * Build an paste rule that replaces text when the
5
+ * matched text is pasted into it.
6
+ */
7
+ export function textPasteRule(config: {
8
+ find: PasteRuleFinder,
9
+ replace: string,
10
+ }) {
11
+ return new PasteRule({
12
+ find: config.find,
13
+ handler: ({ state, range, match }) => {
14
+ let insert = config.replace
15
+ let start = range.from
16
+ const end = range.to
17
+
18
+ if (match[1]) {
19
+ const offset = match[0].lastIndexOf(match[1])
20
+
21
+ insert += match[0].slice(offset + match[1].length)
22
+ start += offset
23
+
24
+ const cutOff = start - end
25
+
26
+ if (cutOff > 0) {
27
+ insert = match[0].slice(offset - cutOff, offset) + insert
28
+ start = end
29
+ }
30
+ }
31
+
32
+ state.tr.insertText(insert, start, end)
33
+ },
34
+ })
35
+ }
package/src/style.ts CHANGED
@@ -1,12 +1,14 @@
1
- const style = `.ProseMirror {
1
+ export const style = `.ProseMirror {
2
2
  position: relative;
3
3
  }
4
4
 
5
5
  .ProseMirror {
6
6
  word-wrap: break-word;
7
7
  white-space: pre-wrap;
8
+ white-space: break-spaces;
8
9
  -webkit-font-variant-ligatures: none;
9
10
  font-variant-ligatures: none;
11
+ font-feature-settings: "liga" 0; /* the above doesn't seem to work in Edge */
10
12
  }
11
13
 
12
14
  .ProseMirror [contenteditable="false"] {
@@ -21,10 +23,19 @@ const style = `.ProseMirror {
21
23
  white-space: pre-wrap;
22
24
  }
23
25
 
26
+ img.ProseMirror-separator {
27
+ display: inline !important;
28
+ border: none !important;
29
+ margin: 0 !important;
30
+ width: 1px !important;
31
+ height: 1px !important;
32
+ }
33
+
24
34
  .ProseMirror-gapcursor {
25
35
  display: none;
26
36
  pointer-events: none;
27
37
  position: absolute;
38
+ margin: 0;
28
39
  }
29
40
 
30
41
  .ProseMirror-gapcursor:after {
@@ -62,5 +73,3 @@ const style = `.ProseMirror {
62
73
  .tippy-box[data-animation=fade][data-state=hidden] {
63
74
  opacity: 0
64
75
  }`
65
-
66
- export default style
package/src/types.ts CHANGED
@@ -1,25 +1,18 @@
1
1
  import {
2
- Node as ProseMirrorNode,
3
- Mark as ProseMirrorMark,
4
- ParseOptions,
5
- } from 'prosemirror-model'
2
+ Mark as ProseMirrorMark, Node as ProseMirrorNode, NodeType, ParseOptions,
3
+ } from '@tiptap/pm/model'
4
+ import { EditorState, Transaction } from '@tiptap/pm/state'
6
5
  import {
7
- EditorView,
8
- Decoration,
9
- NodeView,
10
- EditorProps,
11
- } from 'prosemirror-view'
12
- import { EditorState, Transaction } from 'prosemirror-state'
13
- import { Extension } from './Extension'
14
- import { Node } from './Node'
15
- import { Mark } from './Mark'
16
- import { Editor } from './Editor'
6
+ Decoration, EditorProps, EditorView, NodeView,
7
+ } from '@tiptap/pm/view'
8
+
17
9
  import {
18
- Commands,
19
- ExtensionConfig,
20
- NodeConfig,
21
- MarkConfig,
10
+ Commands, ExtensionConfig, MarkConfig, NodeConfig,
22
11
  } from '.'
12
+ import { Editor } from './Editor'
13
+ import { Extension } from './Extension'
14
+ import { Mark } from './Mark'
15
+ import { Node } from './Node'
23
16
 
24
17
  export type AnyConfig = ExtensionConfig | NodeConfig | MarkConfig
25
18
  export type AnyExtension = Extension | Node | Mark
@@ -31,61 +24,80 @@ export type ParentConfig<T> = Partial<{
31
24
  : T[P]
32
25
  }>
33
26
 
27
+ export type Primitive = null | undefined | string | number | boolean | symbol | bigint
28
+
34
29
  export type RemoveThis<T> = T extends (...args: any) => any
35
30
  ? (...args: Parameters<T>) => ReturnType<T>
36
31
  : T
37
32
 
38
- export type MaybeReturnType<T> = T extends (...args: any) => any
39
- ? ReturnType<T>
40
- : T
33
+ export type MaybeReturnType<T> = T extends (...args: any) => any ? ReturnType<T> : T
34
+
35
+ export type MaybeThisParameterType<T> = Exclude<T, Primitive> extends (...args: any) => any
36
+ ? ThisParameterType<Exclude<T, Primitive>>
37
+ : any
38
+
39
+ export interface EditorEvents {
40
+ beforeCreate: { editor: Editor }
41
+ create: { editor: Editor }
42
+ update: { editor: Editor; transaction: Transaction }
43
+ selectionUpdate: { editor: Editor; transaction: Transaction }
44
+ transaction: { editor: Editor; transaction: Transaction }
45
+ focus: { editor: Editor; event: FocusEvent; transaction: Transaction }
46
+ blur: { editor: Editor; event: FocusEvent; transaction: Transaction }
47
+ destroy: void
48
+ }
49
+
50
+ export type EnableRules = (AnyExtension | string)[] | boolean
41
51
 
42
52
  export interface EditorOptions {
43
- element: Element,
44
- content: Content,
45
- extensions: Extensions,
46
- injectCSS: boolean,
47
- autofocus: FocusPosition,
48
- editable: boolean,
49
- editorProps: EditorProps,
50
- parseOptions: ParseOptions,
51
- enableInputRules: boolean,
52
- enablePasteRules: boolean,
53
- onBeforeCreate: (props: { editor: Editor }) => void,
54
- onCreate: (props: { editor: Editor }) => void,
55
- onUpdate: (props: { editor: Editor, transaction: Transaction }) => void,
56
- onSelectionUpdate: (props: { editor: Editor, transaction: Transaction }) => void,
57
- onTransaction: (props: { editor: Editor, transaction: Transaction }) => void,
58
- onFocus: (props: { editor: Editor, event: FocusEvent, transaction: Transaction }) => void,
59
- onBlur: (props: { editor: Editor, event: FocusEvent, transaction: Transaction }) => void,
60
- onDestroy: () => void,
53
+ element: Element
54
+ content: Content
55
+ extensions: Extensions
56
+ injectCSS: boolean
57
+ injectNonce: string | undefined
58
+ autofocus: FocusPosition
59
+ editable: boolean
60
+ editorProps: EditorProps
61
+ parseOptions: ParseOptions
62
+ enableInputRules: EnableRules
63
+ enablePasteRules: EnableRules
64
+ enableCoreExtensions: boolean
65
+ onBeforeCreate: (props: EditorEvents['beforeCreate']) => void
66
+ onCreate: (props: EditorEvents['create']) => void
67
+ onUpdate: (props: EditorEvents['update']) => void
68
+ onSelectionUpdate: (props: EditorEvents['selectionUpdate']) => void
69
+ onTransaction: (props: EditorEvents['transaction']) => void
70
+ onFocus: (props: EditorEvents['focus']) => void
71
+ onBlur: (props: EditorEvents['blur']) => void
72
+ onDestroy: (props: EditorEvents['destroy']) => void
61
73
  }
62
74
 
63
75
  export type HTMLContent = string
64
76
 
65
77
  export type JSONContent = {
66
- type: string,
67
- attrs?: Record<string, any>,
68
- content?: JSONContent[],
78
+ type?: string
79
+ attrs?: Record<string, any>
80
+ content?: JSONContent[]
69
81
  marks?: {
70
- type: string,
71
- attrs?: Record<string, any>,
72
- [key: string]: any,
73
- }[],
74
- text?: string,
75
- [key: string]: any,
82
+ type: string
83
+ attrs?: Record<string, any>
84
+ [key: string]: any
85
+ }[]
86
+ text?: string
87
+ [key: string]: any
76
88
  }
77
89
 
78
90
  export type Content = HTMLContent | JSONContent | JSONContent[] | null
79
91
 
80
92
  export type CommandProps = {
81
- editor: Editor,
82
- tr: Transaction,
83
- commands: SingleCommands,
84
- can: () => CanCommands,
85
- chain: () => ChainedCommands,
86
- state: EditorState,
87
- view: EditorView,
88
- dispatch: ((args?: any) => any) | undefined,
93
+ editor: Editor
94
+ tr: Transaction
95
+ commands: SingleCommands
96
+ can: () => CanCommands
97
+ chain: () => ChainedCommands
98
+ state: EditorState
99
+ view: EditorView
100
+ dispatch: ((args?: any) => any) | undefined
89
101
  }
90
102
 
91
103
  export type Command = (props: CommandProps) => boolean
@@ -95,79 +107,87 @@ export type CommandSpec = (...args: any[]) => Command
95
107
  export type KeyboardShortcutCommand = (props: { editor: Editor }) => boolean
96
108
 
97
109
  export type Attribute = {
98
- default: any,
99
- rendered?: boolean,
100
- renderHTML?: ((attributes: Record<string, any>) => Record<string, any> | null) | null,
101
- parseHTML?: ((element: HTMLElement) => Record<string, any> | null) | null,
102
- keepOnSplit: boolean,
110
+ default: any
111
+ rendered?: boolean
112
+ renderHTML?: ((attributes: Record<string, any>) => Record<string, any> | null) | null
113
+ parseHTML?: ((element: HTMLElement) => any | null) | null
114
+ keepOnSplit: boolean
115
+ isRequired?: boolean
103
116
  }
104
117
 
105
118
  export type Attributes = {
106
- [key: string]: Attribute,
119
+ [key: string]: Attribute
107
120
  }
108
121
 
109
122
  export type ExtensionAttribute = {
110
- type: string,
111
- name: string,
112
- attribute: Required<Attribute>,
123
+ type: string
124
+ name: string
125
+ attribute: Required<Attribute>
113
126
  }
114
127
 
115
128
  export type GlobalAttributes = {
116
- types: string[],
129
+ types: string[]
117
130
  attributes: {
118
131
  [key: string]: Attribute
119
- },
132
+ }
120
133
  }[]
121
134
 
122
135
  export type PickValue<T, K extends keyof T> = T[K]
123
136
 
124
- export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I)=>void)
137
+ export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
138
+ k: infer I,
139
+ ) => void
125
140
  ? I
126
141
  : never
127
142
 
128
- export type Diff<T extends keyof any, U extends keyof any> =
129
- ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T]
143
+ export type Diff<T extends keyof any, U extends keyof any> = ({ [P in T]: P } & {
144
+ [P in U]: never
145
+ } & { [x: string]: never })[T]
146
+
147
+ export type Overwrite<T, U> = Pick<T, Diff<keyof T, keyof U>> & U
130
148
 
131
- export type Overwrite<T, U> = Pick<T, Diff<keyof T, keyof U>> & U;
149
+ export type ValuesOf<T> = T[keyof T]
132
150
 
133
- export type ValuesOf<T> = T[keyof T];
151
+ export type KeysWithTypeOf<T, Type> = { [P in keyof T]: T[P] extends Type ? P : never }[keyof T]
134
152
 
135
- export type KeysWithTypeOf<T, Type> = ({[P in keyof T]: T[P] extends Type ? P : never })[keyof T]
153
+ export type DecorationWithType = Decoration & {
154
+ type: NodeType
155
+ }
136
156
 
137
157
  export type NodeViewProps = {
138
- editor: Editor,
139
- node: ProseMirrorNode,
140
- decorations: Decoration[],
141
- selected: boolean,
142
- extension: Node,
143
- getPos: () => number,
144
- updateAttributes: (attributes: Record<string, any>) => void,
145
- deleteNode: () => void,
158
+ editor: Editor
159
+ node: ProseMirrorNode
160
+ decorations: DecorationWithType[]
161
+ selected: boolean
162
+ extension: Node
163
+ getPos: () => number
164
+ updateAttributes: (attributes: Record<string, any>) => void
165
+ deleteNode: () => void
146
166
  }
147
167
 
148
168
  export interface NodeViewRendererOptions {
149
- stopEvent: ((props: {
150
- event: Event
151
- }) => boolean) | null,
152
- ignoreMutation: ((props: {
153
- mutation: MutationRecord | { type: 'selection', target: Element }
154
- }) => boolean) | null,
169
+ stopEvent: ((props: { event: Event }) => boolean) | null
170
+ ignoreMutation:
171
+ | ((props: { mutation: MutationRecord | { type: 'selection'; target: Element } }) => boolean)
172
+ | null
155
173
  }
156
174
 
157
175
  export type NodeViewRendererProps = {
158
- editor: Editor,
159
- node: ProseMirrorNode,
160
- getPos: (() => number) | boolean,
161
- HTMLAttributes: Record<string, any>,
162
- decorations: Decoration[],
163
- extension: Node,
176
+ editor: Editor
177
+ node: ProseMirrorNode
178
+ getPos: (() => number) | boolean
179
+ HTMLAttributes: Record<string, any>
180
+ decorations: Decoration[]
181
+ extension: Node
164
182
  }
165
183
 
166
- export type NodeViewRenderer = (props: NodeViewRendererProps) => (NodeView | {})
184
+ export type NodeViewRenderer = (props: NodeViewRendererProps) => NodeView | {}
167
185
 
168
186
  export type AnyCommands = Record<string, (...args: any[]) => Command>
169
187
 
170
- export type UnionCommands<T = Command> = UnionToIntersection<ValuesOf<Pick<Commands<T>, KeysWithTypeOf<Commands<T>, {}>>>>
188
+ export type UnionCommands<T = Command> = UnionToIntersection<
189
+ ValuesOf<Pick<Commands<T>, KeysWithTypeOf<Commands<T>, {}>>>
190
+ >
171
191
 
172
192
  export type RawCommands = {
173
193
  [Item in keyof UnionCommands]: UnionCommands<Command>[Item]
@@ -185,28 +205,42 @@ export type ChainedCommands = {
185
205
 
186
206
  export type CanCommands = SingleCommands & { chain: () => ChainedCommands }
187
207
 
188
- export type FocusPosition = 'start' | 'end' | number | boolean | null
208
+ export type FocusPosition = 'start' | 'end' | 'all' | number | boolean | null
189
209
 
190
210
  export type Range = {
191
- from: number,
192
- to: number,
211
+ from: number
212
+ to: number
193
213
  }
194
214
 
195
215
  export type NodeRange = {
196
- node: ProseMirrorNode,
197
- from: number,
198
- to: number,
216
+ node: ProseMirrorNode
217
+ from: number
218
+ to: number
199
219
  }
200
220
 
201
221
  export type MarkRange = {
202
- mark: ProseMirrorMark,
203
- from: number,
204
- to: number,
222
+ mark: ProseMirrorMark
223
+ from: number
224
+ to: number
205
225
  }
206
226
 
207
227
  export type Predicate = (node: ProseMirrorNode) => boolean
208
228
 
209
229
  export type NodeWithPos = {
210
- node: ProseMirrorNode,
211
- pos: number,
230
+ node: ProseMirrorNode
231
+ pos: number
212
232
  }
233
+
234
+ export type TextSerializer = (props: {
235
+ node: ProseMirrorNode
236
+ pos: number
237
+ parent: ProseMirrorNode
238
+ index: number
239
+ range: Range
240
+ }) => string
241
+
242
+ export type ExtendedRegExpMatchArray = RegExpMatchArray & {
243
+ data?: Record<string, any>
244
+ }
245
+
246
+ export type Dispatch = ((args?: any) => any) | undefined