@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,34 +1,67 @@
1
- import { MarkType, ResolvedPos } from 'prosemirror-model'
1
+ import { Mark as ProseMirrorMark, MarkType, ResolvedPos } from '@tiptap/pm/model'
2
+
2
3
  import { Range } from '../types'
4
+ import { objectIncludes } from '../utilities/objectIncludes'
5
+
6
+ function findMarkInSet(
7
+ marks: ProseMirrorMark[],
8
+ type: MarkType,
9
+ attributes: Record<string, any> = {},
10
+ ): ProseMirrorMark | undefined {
11
+ return marks.find(item => {
12
+ return item.type === type && objectIncludes(item.attrs, attributes)
13
+ })
14
+ }
15
+
16
+ function isMarkInSet(
17
+ marks: ProseMirrorMark[],
18
+ type: MarkType,
19
+ attributes: Record<string, any> = {},
20
+ ): boolean {
21
+ return !!findMarkInSet(marks, type, attributes)
22
+ }
3
23
 
4
- export default function getMarkRange($pos: ResolvedPos, type: MarkType): Range | void {
24
+ export function getMarkRange(
25
+ $pos: ResolvedPos,
26
+ type: MarkType,
27
+ attributes: Record<string, any> = {},
28
+ ): Range | void {
5
29
  if (!$pos || !type) {
6
30
  return
7
31
  }
8
32
 
9
- const start = $pos.parent.childAfter($pos.parentOffset)
33
+ let start = $pos.parent.childAfter($pos.parentOffset)
34
+
35
+ if ($pos.parentOffset === start.offset && start.offset !== 0) {
36
+ start = $pos.parent.childBefore($pos.parentOffset)
37
+ }
10
38
 
11
39
  if (!start.node) {
12
40
  return
13
41
  }
14
42
 
15
- const link = start.node.marks.find(mark => mark.type === type)
43
+ const mark = findMarkInSet([...start.node.marks], type, attributes)
16
44
 
17
- if (!link) {
45
+ if (!mark) {
18
46
  return
19
47
  }
20
48
 
21
- let startIndex = $pos.index()
49
+ let startIndex = start.index
22
50
  let startPos = $pos.start() + start.offset
23
51
  let endIndex = startIndex + 1
24
52
  let endPos = startPos + start.node.nodeSize
25
53
 
26
- while (startIndex > 0 && link.isInSet($pos.parent.child(startIndex - 1).marks)) {
54
+ findMarkInSet([...start.node.marks], type, attributes)
55
+
56
+ while (startIndex > 0 && mark.isInSet($pos.parent.child(startIndex - 1).marks)) {
27
57
  startIndex -= 1
28
58
  startPos -= $pos.parent.child(startIndex).nodeSize
29
59
  }
30
60
 
31
- while (endIndex < $pos.parent.childCount && link.isInSet($pos.parent.child(endIndex).marks)) {
61
+ while (
62
+ endIndex < $pos.parent.childCount
63
+ && isMarkInSet([...$pos.parent.child(endIndex).marks], type, attributes)
64
+ ) {
32
65
  endPos += $pos.parent.child(endIndex).nodeSize
33
66
  endIndex += 1
34
67
  }
@@ -1,7 +1,13 @@
1
- import { MarkType, Schema } from 'prosemirror-model'
1
+ import { MarkType, Schema } from '@tiptap/pm/model'
2
2
 
3
- export default function getMarkType(nameOrType: string | MarkType, schema: Schema): MarkType {
3
+ export function getMarkType(nameOrType: string | MarkType, schema: Schema): MarkType {
4
4
  if (typeof nameOrType === 'string') {
5
+ if (!schema.marks[nameOrType]) {
6
+ throw Error(
7
+ `There is no mark type named '${nameOrType}'. Maybe you forgot to add the extension?`,
8
+ )
9
+ }
10
+
5
11
  return schema.marks[nameOrType]
6
12
  }
7
13
 
@@ -1,16 +1,40 @@
1
- import { EditorState } from 'prosemirror-state'
1
+ import { Node as ProseMirrorNode } from '@tiptap/pm/model'
2
+
2
3
  import { MarkRange } from '../types'
4
+ import { getMarkRange } from './getMarkRange'
5
+
6
+ export function getMarksBetween(from: number, to: number, doc: ProseMirrorNode): MarkRange[] {
7
+ const marks: MarkRange[] = []
8
+
9
+ // get all inclusive marks on empty selection
10
+ if (from === to) {
11
+ doc
12
+ .resolve(from)
13
+ .marks()
14
+ .forEach(mark => {
15
+ const $pos = doc.resolve(from - 1)
16
+ const range = getMarkRange($pos, mark.type)
3
17
 
4
- export default function getMarksBetween(from: number, to: number, state: EditorState): MarkRange[] {
5
- let marks: MarkRange[] = []
18
+ if (!range) {
19
+ return
20
+ }
6
21
 
7
- state.doc.nodesBetween(from, to, (node, pos) => {
8
- marks = [...marks, ...node.marks.map(mark => ({
9
- from: pos,
10
- to: pos + node.nodeSize,
11
- mark,
12
- }))]
13
- })
22
+ marks.push({
23
+ mark,
24
+ ...range,
25
+ })
26
+ })
27
+ } else {
28
+ doc.nodesBetween(from, to, (node, pos) => {
29
+ marks.push(
30
+ ...node.marks.map(mark => ({
31
+ from: pos,
32
+ to: pos + node.nodeSize,
33
+ mark,
34
+ })),
35
+ )
36
+ })
37
+ }
14
38
 
15
39
  return marks
16
40
  }
@@ -1,24 +1,25 @@
1
- import { EditorState } from 'prosemirror-state'
2
- import { Node, NodeType } from 'prosemirror-model'
3
- import getNodeType from './getNodeType'
4
- import { AnyObject } from '../types'
1
+ import { Node, NodeType } from '@tiptap/pm/model'
2
+ import { EditorState } from '@tiptap/pm/state'
5
3
 
6
- export default function getNodeAttributes(state: EditorState, typeOrName: string | NodeType): AnyObject {
4
+ import { getNodeType } from './getNodeType'
5
+
6
+ export function getNodeAttributes(
7
+ state: EditorState,
8
+ typeOrName: string | NodeType,
9
+ ): Record<string, any> {
7
10
  const type = getNodeType(typeOrName, state.schema)
8
11
  const { from, to } = state.selection
9
- let nodes: Node[] = []
12
+ const nodes: Node[] = []
10
13
 
11
14
  state.doc.nodesBetween(from, to, node => {
12
- nodes = [...nodes, node]
15
+ nodes.push(node)
13
16
  })
14
17
 
15
- const node = nodes
16
- .reverse()
17
- .find(nodeItem => nodeItem.type.name === type.name)
18
+ const node = nodes.reverse().find(nodeItem => nodeItem.type.name === type.name)
18
19
 
19
- if (node) {
20
- return { ...node.attrs }
20
+ if (!node) {
21
+ return {}
21
22
  }
22
23
 
23
- return {}
24
+ return { ...node.attrs }
24
25
  }
@@ -1,7 +1,13 @@
1
- import { NodeType, Schema } from 'prosemirror-model'
1
+ import { NodeType, Schema } from '@tiptap/pm/model'
2
2
 
3
- export default function getNodeType(nameOrType: string | NodeType, schema: Schema): NodeType {
3
+ export function getNodeType(nameOrType: string | NodeType, schema: Schema): NodeType {
4
4
  if (typeof nameOrType === 'string') {
5
+ if (!schema.nodes[nameOrType]) {
6
+ throw Error(
7
+ `There is no node type named '${nameOrType}'. Maybe you forgot to add the extension?`,
8
+ )
9
+ }
10
+
5
11
  return schema.nodes[nameOrType]
6
12
  }
7
13
 
@@ -1,8 +1,12 @@
1
- import { Node, Mark } from 'prosemirror-model'
2
- import { ExtensionAttribute, AnyObject } from '../types'
3
- import mergeAttributes from '../utilities/mergeAttributes'
1
+ import { Mark, Node } from '@tiptap/pm/model'
4
2
 
5
- export default function getRenderedAttributes(nodeOrMark: Node | Mark, extensionAttributes: ExtensionAttribute[]): AnyObject {
3
+ import { ExtensionAttribute } from '../types'
4
+ import { mergeAttributes } from '../utilities/mergeAttributes'
5
+
6
+ export function getRenderedAttributes(
7
+ nodeOrMark: Node | Mark,
8
+ extensionAttributes: ExtensionAttribute[],
9
+ ): Record<string, any> {
6
10
  return extensionAttributes
7
11
  .filter(item => item.attribute.rendered)
8
12
  .map(item => {
@@ -14,7 +18,5 @@ export default function getRenderedAttributes(nodeOrMark: Node | Mark, extension
14
18
 
15
19
  return item.attribute.renderHTML(nodeOrMark.attrs) || {}
16
20
  })
17
- .reduce((attributes, attribute) => {
18
- return mergeAttributes(attributes, attribute)
19
- }, {})
21
+ .reduce((attributes, attribute) => mergeAttributes(attributes, attribute), {})
20
22
  }
@@ -1,137 +1,11 @@
1
- import { NodeSpec, MarkSpec, Schema } from 'prosemirror-model'
2
- import { Extensions } from '../types'
3
- import { ExtensionConfig, NodeConfig, MarkConfig } from '..'
4
- import splitExtensions from './splitExtensions'
5
- import getAttributesFromExtensions from './getAttributesFromExtensions'
6
- import getRenderedAttributes from './getRenderedAttributes'
7
- import isEmptyObject from '../utilities/isEmptyObject'
8
- import injectExtensionAttributesToParseRule from './injectExtensionAttributesToParseRule'
9
- import callOrReturn from '../utilities/callOrReturn'
10
-
11
- function cleanUpSchemaItem<T>(data: T) {
12
- return Object.fromEntries(Object.entries(data).filter(([key, value]) => {
13
- if (key === 'attrs' && isEmptyObject(value)) {
14
- return false
15
- }
16
-
17
- return value !== null && value !== undefined
18
- })) as T
19
- }
20
-
21
- export default function getSchema(extensions: Extensions): Schema {
22
- const allAttributes = getAttributesFromExtensions(extensions)
23
- const { nodeExtensions, markExtensions } = splitExtensions(extensions)
24
- const topNode = nodeExtensions.find(extension => extension.config.topNode)?.config.name
25
- const nodeSchemaExtenders: (
26
- | ExtensionConfig['extendNodeSchema']
27
- | NodeConfig['extendNodeSchema']
28
- | MarkConfig['extendNodeSchema']
29
- )[] = []
30
- const markSchemaExtenders: (
31
- | ExtensionConfig['extendNodeSchema']
32
- | NodeConfig['extendNodeSchema']
33
- | MarkConfig['extendNodeSchema']
34
- )[] = []
35
-
36
- extensions.forEach(extension => {
37
- if (typeof extension.config.extendNodeSchema === 'function') {
38
- nodeSchemaExtenders.push(extension.config.extendNodeSchema)
39
- }
40
-
41
- if (typeof extension.config.extendMarkSchema === 'function') {
42
- markSchemaExtenders.push(extension.config.extendMarkSchema)
43
- }
44
- })
45
-
46
- const nodes = Object.fromEntries(nodeExtensions.map(extension => {
47
- const extensionAttributes = allAttributes.filter(attribute => attribute.type === extension.config.name)
48
- const context = { options: extension.options }
49
-
50
- const extraNodeFields = nodeSchemaExtenders.reduce((fields, nodeSchemaExtender) => {
51
- const extraFields = callOrReturn(nodeSchemaExtender, context, extension)
52
-
53
- return {
54
- ...fields,
55
- ...extraFields,
56
- }
57
- }, {})
1
+ import { Schema } from '@tiptap/pm/model'
58
2
 
59
- const schema: NodeSpec = cleanUpSchemaItem({
60
- ...extraNodeFields,
61
- content: callOrReturn(extension.config.content, context),
62
- marks: callOrReturn(extension.config.marks, context),
63
- group: callOrReturn(extension.config.group, context),
64
- inline: callOrReturn(extension.config.inline, context),
65
- atom: callOrReturn(extension.config.atom, context),
66
- selectable: callOrReturn(extension.config.selectable, context),
67
- draggable: callOrReturn(extension.config.draggable, context),
68
- code: callOrReturn(extension.config.code, context),
69
- defining: callOrReturn(extension.config.defining, context),
70
- isolating: callOrReturn(extension.config.isolating, context),
71
- attrs: Object.fromEntries(extensionAttributes.map(extensionAttribute => {
72
- return [extensionAttribute.name, { default: extensionAttribute?.attribute?.default }]
73
- })),
74
- })
75
-
76
- if (extension.config.parseHTML) {
77
- schema.parseDOM = extension.config.parseHTML
78
- .bind(context)()
79
- ?.map(parseRule => injectExtensionAttributesToParseRule(parseRule, extensionAttributes))
80
- }
81
-
82
- if (extension.config.renderHTML) {
83
- schema.toDOM = node => (extension.config.renderHTML as Function)?.bind(context)({
84
- node,
85
- HTMLAttributes: getRenderedAttributes(node, extensionAttributes),
86
- })
87
- }
88
-
89
- return [extension.config.name, schema]
90
- }))
91
-
92
- const marks = Object.fromEntries(markExtensions.map(extension => {
93
- const extensionAttributes = allAttributes.filter(attribute => attribute.type === extension.config.name)
94
- const context = { options: extension.options }
95
-
96
- const extraMarkFields = markSchemaExtenders.reduce((fields, markSchemaExtender) => {
97
- const extraFields = callOrReturn(markSchemaExtender, context, extension)
98
-
99
- return {
100
- ...fields,
101
- ...extraFields,
102
- }
103
- }, {})
104
-
105
- const schema: MarkSpec = cleanUpSchemaItem({
106
- ...extraMarkFields,
107
- inclusive: callOrReturn(extension.config.inclusive, context),
108
- excludes: callOrReturn(extension.config.excludes, context),
109
- group: callOrReturn(extension.config.group, context),
110
- spanning: callOrReturn(extension.config.spanning, context),
111
- attrs: Object.fromEntries(extensionAttributes.map(extensionAttribute => {
112
- return [extensionAttribute.name, { default: extensionAttribute?.attribute?.default }]
113
- })),
114
- })
115
-
116
- if (extension.config.parseHTML) {
117
- schema.parseDOM = extension.config.parseHTML
118
- .bind(context)()
119
- ?.map(parseRule => injectExtensionAttributesToParseRule(parseRule, extensionAttributes))
120
- }
121
-
122
- if (extension.config.renderHTML) {
123
- schema.toDOM = mark => (extension.config.renderHTML as Function)?.bind(context)({
124
- mark,
125
- HTMLAttributes: getRenderedAttributes(mark, extensionAttributes),
126
- })
127
- }
3
+ import { ExtensionManager } from '../ExtensionManager'
4
+ import { Extensions } from '../types'
5
+ import { getSchemaByResolvedExtensions } from './getSchemaByResolvedExtensions'
128
6
 
129
- return [extension.config.name, schema]
130
- }))
7
+ export function getSchema(extensions: Extensions): Schema {
8
+ const resolvedExtensions = ExtensionManager.resolve(extensions)
131
9
 
132
- return new Schema({
133
- topNode,
134
- nodes,
135
- marks,
136
- })
10
+ return getSchemaByResolvedExtensions(resolvedExtensions)
137
11
  }
@@ -0,0 +1,192 @@
1
+ import { MarkSpec, NodeSpec, Schema } from '@tiptap/pm/model'
2
+
3
+ import { MarkConfig, NodeConfig } from '..'
4
+ import { AnyConfig, Extensions } from '../types'
5
+ import { callOrReturn } from '../utilities/callOrReturn'
6
+ import { isEmptyObject } from '../utilities/isEmptyObject'
7
+ import { getAttributesFromExtensions } from './getAttributesFromExtensions'
8
+ import { getExtensionField } from './getExtensionField'
9
+ import { getRenderedAttributes } from './getRenderedAttributes'
10
+ import { injectExtensionAttributesToParseRule } from './injectExtensionAttributesToParseRule'
11
+ import { splitExtensions } from './splitExtensions'
12
+
13
+ function cleanUpSchemaItem<T>(data: T) {
14
+ return Object.fromEntries(
15
+ Object.entries(data).filter(([key, value]) => {
16
+ if (key === 'attrs' && isEmptyObject(value)) {
17
+ return false
18
+ }
19
+
20
+ return value !== null && value !== undefined
21
+ }),
22
+ ) as T
23
+ }
24
+
25
+ export function getSchemaByResolvedExtensions(extensions: Extensions): Schema {
26
+ const allAttributes = getAttributesFromExtensions(extensions)
27
+ const { nodeExtensions, markExtensions } = splitExtensions(extensions)
28
+ const topNode = nodeExtensions.find(extension => getExtensionField(extension, 'topNode'))?.name
29
+
30
+ const nodes = Object.fromEntries(
31
+ nodeExtensions.map(extension => {
32
+ const extensionAttributes = allAttributes.filter(
33
+ attribute => attribute.type === extension.name,
34
+ )
35
+ const context = {
36
+ name: extension.name,
37
+ options: extension.options,
38
+ storage: extension.storage,
39
+ }
40
+
41
+ const extraNodeFields = extensions.reduce((fields, e) => {
42
+ const extendNodeSchema = getExtensionField<AnyConfig['extendNodeSchema']>(
43
+ e,
44
+ 'extendNodeSchema',
45
+ context,
46
+ )
47
+
48
+ return {
49
+ ...fields,
50
+ ...(extendNodeSchema ? extendNodeSchema(extension) : {}),
51
+ }
52
+ }, {})
53
+
54
+ const schema: NodeSpec = cleanUpSchemaItem({
55
+ ...extraNodeFields,
56
+ content: callOrReturn(
57
+ getExtensionField<NodeConfig['content']>(extension, 'content', context),
58
+ ),
59
+ marks: callOrReturn(getExtensionField<NodeConfig['marks']>(extension, 'marks', context)),
60
+ group: callOrReturn(getExtensionField<NodeConfig['group']>(extension, 'group', context)),
61
+ inline: callOrReturn(getExtensionField<NodeConfig['inline']>(extension, 'inline', context)),
62
+ atom: callOrReturn(getExtensionField<NodeConfig['atom']>(extension, 'atom', context)),
63
+ selectable: callOrReturn(
64
+ getExtensionField<NodeConfig['selectable']>(extension, 'selectable', context),
65
+ ),
66
+ draggable: callOrReturn(
67
+ getExtensionField<NodeConfig['draggable']>(extension, 'draggable', context),
68
+ ),
69
+ code: callOrReturn(getExtensionField<NodeConfig['code']>(extension, 'code', context)),
70
+ defining: callOrReturn(
71
+ getExtensionField<NodeConfig['defining']>(extension, 'defining', context),
72
+ ),
73
+ isolating: callOrReturn(
74
+ getExtensionField<NodeConfig['isolating']>(extension, 'isolating', context),
75
+ ),
76
+ attrs: Object.fromEntries(
77
+ extensionAttributes.map(extensionAttribute => {
78
+ return [extensionAttribute.name, { default: extensionAttribute?.attribute?.default }]
79
+ }),
80
+ ),
81
+ })
82
+
83
+ const parseHTML = callOrReturn(
84
+ getExtensionField<NodeConfig['parseHTML']>(extension, 'parseHTML', context),
85
+ )
86
+
87
+ if (parseHTML) {
88
+ schema.parseDOM = parseHTML.map(parseRule => injectExtensionAttributesToParseRule(parseRule, extensionAttributes))
89
+ }
90
+
91
+ const renderHTML = getExtensionField<NodeConfig['renderHTML']>(
92
+ extension,
93
+ 'renderHTML',
94
+ context,
95
+ )
96
+
97
+ if (renderHTML) {
98
+ schema.toDOM = node => renderHTML({
99
+ node,
100
+ HTMLAttributes: getRenderedAttributes(node, extensionAttributes),
101
+ })
102
+ }
103
+
104
+ const renderText = getExtensionField<NodeConfig['renderText']>(
105
+ extension,
106
+ 'renderText',
107
+ context,
108
+ )
109
+
110
+ if (renderText) {
111
+ schema.toText = renderText
112
+ }
113
+
114
+ return [extension.name, schema]
115
+ }),
116
+ )
117
+
118
+ const marks = Object.fromEntries(
119
+ markExtensions.map(extension => {
120
+ const extensionAttributes = allAttributes.filter(
121
+ attribute => attribute.type === extension.name,
122
+ )
123
+ const context = {
124
+ name: extension.name,
125
+ options: extension.options,
126
+ storage: extension.storage,
127
+ }
128
+
129
+ const extraMarkFields = extensions.reduce((fields, e) => {
130
+ const extendMarkSchema = getExtensionField<AnyConfig['extendMarkSchema']>(
131
+ e,
132
+ 'extendMarkSchema',
133
+ context,
134
+ )
135
+
136
+ return {
137
+ ...fields,
138
+ ...(extendMarkSchema ? extendMarkSchema(extension) : {}),
139
+ }
140
+ }, {})
141
+
142
+ const schema: MarkSpec = cleanUpSchemaItem({
143
+ ...extraMarkFields,
144
+ inclusive: callOrReturn(
145
+ getExtensionField<MarkConfig['inclusive']>(extension, 'inclusive', context),
146
+ ),
147
+ excludes: callOrReturn(
148
+ getExtensionField<MarkConfig['excludes']>(extension, 'excludes', context),
149
+ ),
150
+ group: callOrReturn(getExtensionField<MarkConfig['group']>(extension, 'group', context)),
151
+ spanning: callOrReturn(
152
+ getExtensionField<MarkConfig['spanning']>(extension, 'spanning', context),
153
+ ),
154
+ code: callOrReturn(getExtensionField<MarkConfig['code']>(extension, 'code', context)),
155
+ attrs: Object.fromEntries(
156
+ extensionAttributes.map(extensionAttribute => {
157
+ return [extensionAttribute.name, { default: extensionAttribute?.attribute?.default }]
158
+ }),
159
+ ),
160
+ })
161
+
162
+ const parseHTML = callOrReturn(
163
+ getExtensionField<MarkConfig['parseHTML']>(extension, 'parseHTML', context),
164
+ )
165
+
166
+ if (parseHTML) {
167
+ schema.parseDOM = parseHTML.map(parseRule => injectExtensionAttributesToParseRule(parseRule, extensionAttributes))
168
+ }
169
+
170
+ const renderHTML = getExtensionField<MarkConfig['renderHTML']>(
171
+ extension,
172
+ 'renderHTML',
173
+ context,
174
+ )
175
+
176
+ if (renderHTML) {
177
+ schema.toDOM = mark => renderHTML({
178
+ mark,
179
+ HTMLAttributes: getRenderedAttributes(mark, extensionAttributes),
180
+ })
181
+ }
182
+
183
+ return [extension.name, schema]
184
+ }),
185
+ )
186
+
187
+ return new Schema({
188
+ topNode,
189
+ nodes,
190
+ marks,
191
+ })
192
+ }
@@ -1,13 +1,5 @@
1
- import { MarkType, NodeType, Schema } from 'prosemirror-model'
1
+ import { MarkType, NodeType, Schema } from '@tiptap/pm/model'
2
2
 
3
- export default function getSchemaTypeByName(name: string, schema: Schema): NodeType | MarkType | null {
4
- if (schema.nodes[name]) {
5
- return schema.nodes[name]
6
- }
7
-
8
- if (schema.marks[name]) {
9
- return schema.marks[name]
10
- }
11
-
12
- return null
3
+ export function getSchemaTypeByName(name: string, schema: Schema): NodeType | MarkType | null {
4
+ return schema.nodes[name] || schema.marks[name] || null
13
5
  }
@@ -1,6 +1,6 @@
1
- import { Schema } from 'prosemirror-model'
1
+ import { Schema } from '@tiptap/pm/model'
2
2
 
3
- export default function getSchemaTypeNameByName(name: string, schema: Schema): 'node' | 'mark' | null {
3
+ export function getSchemaTypeNameByName(name: string, schema: Schema): 'node' | 'mark' | null {
4
4
  if (schema.nodes[name]) {
5
5
  return 'node'
6
6
  }
@@ -1,10 +1,10 @@
1
- import { AnyObject, ExtensionAttribute } from '../types'
1
+ import { ExtensionAttribute } from '../types'
2
2
 
3
- export default function getSplittedAttributes(
3
+ export function getSplittedAttributes(
4
4
  extensionAttributes: ExtensionAttribute[],
5
5
  typeName: string,
6
- attributes: AnyObject,
7
- ): AnyObject {
6
+ attributes: Record<string, any>,
7
+ ): Record<string, any> {
8
8
  return Object.fromEntries(Object
9
9
  .entries(attributes)
10
10
  .filter(([name]) => {
@@ -0,0 +1,19 @@
1
+ import { Node as ProseMirrorNode } from '@tiptap/pm/model'
2
+
3
+ import { TextSerializer } from '../types'
4
+ import { getTextBetween } from './getTextBetween'
5
+
6
+ export function getText(
7
+ node: ProseMirrorNode,
8
+ options?: {
9
+ blockSeparator?: string
10
+ textSerializers?: Record<string, TextSerializer>
11
+ },
12
+ ) {
13
+ const range = {
14
+ from: 0,
15
+ to: node.content.size,
16
+ }
17
+
18
+ return getTextBetween(node, range, options)
19
+ }
@@ -0,0 +1,46 @@
1
+ import { Node as ProseMirrorNode } from '@tiptap/pm/model'
2
+
3
+ import { Range, TextSerializer } from '../types'
4
+
5
+ export function getTextBetween(
6
+ startNode: ProseMirrorNode,
7
+ range: Range,
8
+ options?: {
9
+ blockSeparator?: string
10
+ textSerializers?: Record<string, TextSerializer>
11
+ },
12
+ ): string {
13
+ const { from, to } = range
14
+ const { blockSeparator = '\n\n', textSerializers = {} } = options || {}
15
+ let text = ''
16
+ let separated = true
17
+
18
+ startNode.nodesBetween(from, to, (node, pos, parent, index) => {
19
+ const textSerializer = textSerializers?.[node.type.name]
20
+
21
+ if (textSerializer) {
22
+ if (node.isBlock && !separated) {
23
+ text += blockSeparator
24
+ separated = true
25
+ }
26
+
27
+ if (parent) {
28
+ text += textSerializer({
29
+ node,
30
+ pos,
31
+ parent,
32
+ index,
33
+ range,
34
+ })
35
+ }
36
+ } else if (node.isText) {
37
+ text += node?.text?.slice(Math.max(from, pos) - pos, to - pos) // eslint-disable-line
38
+ separated = false
39
+ } else if (node.isBlock && !separated) {
40
+ text += blockSeparator
41
+ separated = true
42
+ }
43
+ })
44
+
45
+ return text
46
+ }