@tiptap/core 2.0.0-beta.21 → 2.0.0-beta.211

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