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

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,58 +1,50 @@
1
1
  import {
2
- Schema,
3
2
  DOMParser,
4
- Node as ProseMirrorNode,
5
3
  Fragment,
6
- } from 'prosemirror-model'
7
- import elementFromString from '../utilities/elementFromString'
8
- import { AnyObject } from '../types'
4
+ Node as ProseMirrorNode,
5
+ ParseOptions,
6
+ Schema,
7
+ } from '@tiptap/pm/model'
9
8
 
10
- export type Content = string | JSON | null
9
+ import { Content } from '../types'
10
+ import { elementFromString } from '../utilities/elementFromString'
11
11
 
12
12
  export type CreateNodeFromContentOptions = {
13
- slice?: boolean,
14
- parseOptions?: AnyObject,
13
+ slice?: boolean
14
+ parseOptions?: ParseOptions
15
15
  }
16
16
 
17
- export default function createNodeFromContent(
17
+ export function createNodeFromContent(
18
18
  content: Content,
19
19
  schema: Schema,
20
20
  options?: CreateNodeFromContentOptions,
21
- ): string | ProseMirrorNode | Fragment {
21
+ ): ProseMirrorNode | Fragment {
22
22
  options = {
23
23
  slice: true,
24
24
  parseOptions: {},
25
25
  ...options,
26
26
  }
27
27
 
28
- if (content && typeof content === 'object') {
28
+ if (typeof content === 'object' && content !== null) {
29
29
  try {
30
+ if (Array.isArray(content)) {
31
+ return Fragment.fromArray(content.map(item => schema.nodeFromJSON(item)))
32
+ }
33
+
30
34
  return schema.nodeFromJSON(content)
31
35
  } catch (error) {
32
- console.warn(
33
- '[tiptap warn]: Invalid content.',
34
- 'Passed value:',
35
- content,
36
- 'Error:',
37
- error,
38
- )
36
+ console.warn('[tiptap warn]: Invalid content.', 'Passed value:', content, 'Error:', error)
39
37
 
40
38
  return createNodeFromContent('', schema, options)
41
39
  }
42
40
  }
43
41
 
44
42
  if (typeof content === 'string') {
45
- const isHTML = content.trim().startsWith('<') && content.trim().endsWith('>')
46
-
47
- if (isHTML || !options.slice) {
48
- const parser = DOMParser.fromSchema(schema)
49
-
50
- return options.slice
51
- ? parser.parseSlice(elementFromString(content), options.parseOptions).content
52
- : parser.parse(elementFromString(content), options.parseOptions)
53
- }
43
+ const parser = DOMParser.fromSchema(schema)
54
44
 
55
- return content
45
+ return options.slice
46
+ ? parser.parseSlice(elementFromString(content), options.parseOptions).content
47
+ : parser.parse(elementFromString(content), options.parseOptions)
56
48
  }
57
49
 
58
50
  return createNodeFromContent('', schema, options)
@@ -0,0 +1,13 @@
1
+ import { ContentMatch, NodeType } from '@tiptap/pm/model'
2
+
3
+ export function defaultBlockAt(match: ContentMatch): NodeType | null {
4
+ for (let i = 0; i < match.edgeCount; i += 1) {
5
+ const { type } = match.edge(i)
6
+
7
+ if (type.isTextblock && !type.hasRequiredAttrs()) {
8
+ return type
9
+ }
10
+ }
11
+
12
+ return null
13
+ }
@@ -0,0 +1,18 @@
1
+ import { Node as ProseMirrorNode } from '@tiptap/pm/model'
2
+
3
+ import { NodeWithPos, Predicate } from '../types'
4
+
5
+ export function findChildren(node: ProseMirrorNode, predicate: Predicate): NodeWithPos[] {
6
+ const nodesWithPos: NodeWithPos[] = []
7
+
8
+ node.descendants((child, pos) => {
9
+ if (predicate(child)) {
10
+ nodesWithPos.push({
11
+ node: child,
12
+ pos,
13
+ })
14
+ }
15
+ })
16
+
17
+ return nodesWithPos
18
+ }
@@ -0,0 +1,36 @@
1
+ import { Node as ProseMirrorNode } from '@tiptap/pm/model'
2
+
3
+ import { NodeWithPos, Predicate, Range } from '../types'
4
+
5
+ /**
6
+ * Same as `findChildren` but searches only within a `range`.
7
+ */
8
+ export function findChildrenInRange(
9
+ node: ProseMirrorNode,
10
+ range: Range,
11
+ predicate: Predicate,
12
+ ): NodeWithPos[] {
13
+ const nodesWithPos: NodeWithPos[] = []
14
+
15
+ // if (range.from === range.to) {
16
+ // const nodeAt = node.nodeAt(range.from)
17
+
18
+ // if (nodeAt) {
19
+ // nodesWithPos.push({
20
+ // node: nodeAt,
21
+ // pos: range.from,
22
+ // })
23
+ // }
24
+ // }
25
+
26
+ node.nodesBetween(range.from, range.to, (child, pos) => {
27
+ if (predicate(child)) {
28
+ nodesWithPos.push({
29
+ node: child,
30
+ pos,
31
+ })
32
+ }
33
+ })
34
+
35
+ return nodesWithPos
36
+ }
@@ -1,7 +1,8 @@
1
- import { Selection } from 'prosemirror-state'
2
- import findParentNodeClosestToPos from './findParentNodeClosestToPos'
1
+ import { Selection } from '@tiptap/pm/state'
2
+
3
3
  import { Predicate } from '../types'
4
+ import { findParentNodeClosestToPos } from './findParentNodeClosestToPos'
4
5
 
5
- export default function findParentNode(predicate: Predicate) {
6
+ export function findParentNode(predicate: Predicate) {
6
7
  return (selection: Selection) => findParentNodeClosestToPos(selection.$from, predicate)
7
8
  }
@@ -1,12 +1,18 @@
1
- import { ResolvedPos, Node as ProseMirrorNode } from 'prosemirror-model'
1
+ import { Node as ProseMirrorNode, ResolvedPos } from '@tiptap/pm/model'
2
+
2
3
  import { Predicate } from '../types'
3
4
 
4
- export default function findParentNodeClosestToPos($pos: ResolvedPos, predicate: Predicate): ({
5
- pos: number,
6
- start: number,
7
- depth: number,
8
- node: ProseMirrorNode,
9
- } | undefined) {
5
+ export function findParentNodeClosestToPos(
6
+ $pos: ResolvedPos,
7
+ predicate: Predicate,
8
+ ):
9
+ | {
10
+ pos: number
11
+ start: number
12
+ depth: number
13
+ node: ProseMirrorNode
14
+ }
15
+ | undefined {
10
16
  for (let i = $pos.depth; i > 0; i -= 1) {
11
17
  const node = $pos.node(i)
12
18
 
@@ -1,11 +1,12 @@
1
- import { Node } from 'prosemirror-model'
2
- import getSchema from './getSchema'
3
- import getHTMLFromFragment from './getHTMLFromFragment'
4
- import { Extensions } from '../types'
1
+ import { Node } from '@tiptap/pm/model'
5
2
 
6
- export default function generateHTML(doc: object, extensions: Extensions): string {
3
+ import { Extensions, JSONContent } from '../types'
4
+ import { getHTMLFromFragment } from './getHTMLFromFragment'
5
+ import { getSchema } from './getSchema'
6
+
7
+ export function generateHTML(doc: JSONContent, extensions: Extensions): string {
7
8
  const schema = getSchema(extensions)
8
9
  const contentNode = Node.fromJSON(schema, doc)
9
10
 
10
- return getHTMLFromFragment(contentNode, schema)
11
+ return getHTMLFromFragment(contentNode.content, schema)
11
12
  }
@@ -0,0 +1,12 @@
1
+ import { DOMParser } from '@tiptap/pm/model'
2
+
3
+ import { Extensions } from '../types'
4
+ import { elementFromString } from '../utilities/elementFromString'
5
+ import { getSchema } from './getSchema'
6
+
7
+ export function generateJSON(html: string, extensions: Extensions): Record<string, any> {
8
+ const schema = getSchema(extensions)
9
+ const dom = elementFromString(html)
10
+
11
+ return DOMParser.fromSchema(schema).parse(dom).toJSON()
12
+ }
@@ -0,0 +1,27 @@
1
+ import { Node } from '@tiptap/pm/model'
2
+
3
+ import { Extensions, JSONContent, TextSerializer } from '../types'
4
+ import { getSchema } from './getSchema'
5
+ import { getText } from './getText'
6
+ import { getTextSerializersFromSchema } from './getTextSerializersFromSchema'
7
+
8
+ export function generateText(
9
+ doc: JSONContent,
10
+ extensions: Extensions,
11
+ options?: {
12
+ blockSeparator?: string
13
+ textSerializers?: Record<string, TextSerializer>
14
+ },
15
+ ): string {
16
+ const { blockSeparator = '\n\n', textSerializers = {} } = options || {}
17
+ const schema = getSchema(extensions)
18
+ const contentNode = Node.fromJSON(schema, doc)
19
+
20
+ return getText(contentNode, {
21
+ blockSeparator,
22
+ textSerializers: {
23
+ ...getTextSerializersFromSchema(schema),
24
+ ...textSerializers,
25
+ },
26
+ })
27
+ }
@@ -0,0 +1,26 @@
1
+ import { MarkType, NodeType } from '@tiptap/pm/model'
2
+ import { EditorState } from '@tiptap/pm/state'
3
+
4
+ import { getMarkAttributes } from './getMarkAttributes'
5
+ import { getNodeAttributes } from './getNodeAttributes'
6
+ import { getSchemaTypeNameByName } from './getSchemaTypeNameByName'
7
+
8
+ export function getAttributes(
9
+ state: EditorState,
10
+ typeOrName: string | NodeType | MarkType,
11
+ ): Record<string, any> {
12
+ const schemaType = getSchemaTypeNameByName(
13
+ typeof typeOrName === 'string' ? typeOrName : typeOrName.name,
14
+ state.schema,
15
+ )
16
+
17
+ if (schemaType === 'node') {
18
+ return getNodeAttributes(state, typeOrName as NodeType)
19
+ }
20
+
21
+ if (schemaType === 'mark') {
22
+ return getMarkAttributes(state, typeOrName as MarkType)
23
+ }
24
+
25
+ return {}
26
+ }
@@ -1,17 +1,20 @@
1
- import splitExtensions from './splitExtensions'
1
+ import { MarkConfig, NodeConfig } from '..'
2
2
  import {
3
- Extensions,
4
- GlobalAttributes,
5
- Attributes,
3
+ AnyConfig,
6
4
  Attribute,
5
+ Attributes,
7
6
  ExtensionAttribute,
7
+ Extensions,
8
+ GlobalAttributes,
8
9
  } from '../types'
10
+ import { getExtensionField } from './getExtensionField'
11
+ import { splitExtensions } from './splitExtensions'
9
12
 
10
13
  /**
11
14
  * Get a list of all extension attributes defined in `addAttribute` and `addGlobalAttribute`.
12
15
  * @param extensions List of extensions
13
16
  */
14
- export default function getAttributesFromExtensions(extensions: Extensions): ExtensionAttribute[] {
17
+ export function getAttributesFromExtensions(extensions: Extensions): ExtensionAttribute[] {
15
18
  const extensionAttributes: ExtensionAttribute[] = []
16
19
  const { nodeExtensions, markExtensions } = splitExtensions(extensions)
17
20
  const nodeAndMarkExtensions = [...nodeExtensions, ...markExtensions]
@@ -21,18 +24,28 @@ export default function getAttributesFromExtensions(extensions: Extensions): Ext
21
24
  renderHTML: null,
22
25
  parseHTML: null,
23
26
  keepOnSplit: true,
27
+ isRequired: false,
24
28
  }
25
29
 
26
30
  extensions.forEach(extension => {
27
31
  const context = {
32
+ name: extension.name,
28
33
  options: extension.options,
34
+ storage: extension.storage,
29
35
  }
30
36
 
31
- if (!extension.config.addGlobalAttributes) {
37
+ const addGlobalAttributes = getExtensionField<AnyConfig['addGlobalAttributes']>(
38
+ extension,
39
+ 'addGlobalAttributes',
40
+ context,
41
+ )
42
+
43
+ if (!addGlobalAttributes) {
32
44
  return
33
45
  }
34
46
 
35
- const globalAttributes = extension.config.addGlobalAttributes.bind(context)() as GlobalAttributes
47
+ // TODO: remove `as GlobalAttributes`
48
+ const globalAttributes = addGlobalAttributes() as GlobalAttributes
36
49
 
37
50
  globalAttributes.forEach(globalAttribute => {
38
51
  globalAttribute.types.forEach(type => {
@@ -54,25 +67,40 @@ export default function getAttributesFromExtensions(extensions: Extensions): Ext
54
67
 
55
68
  nodeAndMarkExtensions.forEach(extension => {
56
69
  const context = {
70
+ name: extension.name,
57
71
  options: extension.options,
72
+ storage: extension.storage,
58
73
  }
59
74
 
60
- if (!extension.config.addAttributes) {
75
+ const addAttributes = getExtensionField<NodeConfig['addAttributes'] | MarkConfig['addAttributes']>(
76
+ extension,
77
+ 'addAttributes',
78
+ context,
79
+ )
80
+
81
+ if (!addAttributes) {
61
82
  return
62
83
  }
63
84
 
64
- const attributes = extension.config.addAttributes.bind(context)() as Attributes
85
+ // TODO: remove `as Attributes`
86
+ const attributes = addAttributes() as Attributes
65
87
 
66
88
  Object
67
89
  .entries(attributes)
68
90
  .forEach(([name, attribute]) => {
91
+ const mergedAttr = {
92
+ ...defaultAttribute,
93
+ ...attribute,
94
+ }
95
+
96
+ if (attribute?.isRequired && attribute?.default === undefined) {
97
+ delete mergedAttr.default
98
+ }
99
+
69
100
  extensionAttributes.push({
70
- type: extension.config.name,
101
+ type: extension.name,
71
102
  name,
72
- attribute: {
73
- ...defaultAttribute,
74
- ...attribute,
75
- },
103
+ attribute: mergedAttr,
76
104
  })
77
105
  })
78
106
  })
@@ -0,0 +1,83 @@
1
+ import { Step, Transform } from '@tiptap/pm/transform'
2
+
3
+ import { Range } from '../types'
4
+ import { removeDuplicates } from '../utilities/removeDuplicates'
5
+
6
+ export type ChangedRange = {
7
+ oldRange: Range,
8
+ newRange: Range,
9
+ }
10
+
11
+ /**
12
+ * Removes duplicated ranges and ranges that are
13
+ * fully captured by other ranges.
14
+ */
15
+ function simplifyChangedRanges(changes: ChangedRange[]): ChangedRange[] {
16
+ const uniqueChanges = removeDuplicates(changes)
17
+
18
+ return uniqueChanges.length === 1
19
+ ? uniqueChanges
20
+ : uniqueChanges.filter((change, index) => {
21
+ const rest = uniqueChanges.filter((_, i) => i !== index)
22
+
23
+ return !rest.some(otherChange => {
24
+ return change.oldRange.from >= otherChange.oldRange.from
25
+ && change.oldRange.to <= otherChange.oldRange.to
26
+ && change.newRange.from >= otherChange.newRange.from
27
+ && change.newRange.to <= otherChange.newRange.to
28
+ })
29
+ })
30
+ }
31
+
32
+ /**
33
+ * Returns a list of changed ranges
34
+ * based on the first and last state of all steps.
35
+ */
36
+ export function getChangedRanges(transform: Transform): ChangedRange[] {
37
+ const { mapping, steps } = transform
38
+ const changes: ChangedRange[] = []
39
+
40
+ mapping.maps.forEach((stepMap, index) => {
41
+ const ranges: Range[] = []
42
+
43
+ // This accounts for step changes where no range was actually altered
44
+ // e.g. when setting a mark, node attribute, etc.
45
+ // @ts-ignore
46
+ if (!stepMap.ranges.length) {
47
+ const { from, to } = steps[index] as Step & {
48
+ from?: number,
49
+ to?: number,
50
+ }
51
+
52
+ if (from === undefined || to === undefined) {
53
+ return
54
+ }
55
+
56
+ ranges.push({ from, to })
57
+ } else {
58
+ stepMap.forEach((from, to) => {
59
+ ranges.push({ from, to })
60
+ })
61
+ }
62
+
63
+ ranges.forEach(({ from, to }) => {
64
+ const newStart = mapping.slice(index).map(from, -1)
65
+ const newEnd = mapping.slice(index).map(to)
66
+ const oldStart = mapping.invert().map(newStart, -1)
67
+ const oldEnd = mapping.invert().map(newEnd)
68
+
69
+ changes.push({
70
+ oldRange: {
71
+ from: oldStart,
72
+ to: oldEnd,
73
+ },
74
+ newRange: {
75
+ from: newStart,
76
+ to: newEnd,
77
+ },
78
+ })
79
+ })
80
+ })
81
+
82
+ return simplifyChangedRanges(changes)
83
+ }
@@ -0,0 +1,54 @@
1
+ import { Node as ProseMirrorNode } from '@tiptap/pm/model'
2
+
3
+ import { JSONContent } from '../types'
4
+
5
+ interface DebugJSONContent extends JSONContent {
6
+ from: number
7
+ to: number
8
+ }
9
+
10
+ export function getDebugJSON(node: ProseMirrorNode, startOffset = 0): DebugJSONContent {
11
+ const isTopNode = node.type === node.type.schema.topNodeType
12
+ const increment = isTopNode ? 0 : 1
13
+ const from = startOffset
14
+ const to = from + node.nodeSize
15
+ const marks = node.marks.map(mark => {
16
+ const output: { type: string; attrs?: Record<string, any> } = {
17
+ type: mark.type.name,
18
+ }
19
+
20
+ if (Object.keys(mark.attrs).length) {
21
+ output.attrs = { ...mark.attrs }
22
+ }
23
+
24
+ return output
25
+ })
26
+ const attrs = { ...node.attrs }
27
+ const output: DebugJSONContent = {
28
+ type: node.type.name,
29
+ from,
30
+ to,
31
+ }
32
+
33
+ if (Object.keys(attrs).length) {
34
+ output.attrs = attrs
35
+ }
36
+
37
+ if (marks.length) {
38
+ output.marks = marks
39
+ }
40
+
41
+ if (node.content.childCount) {
42
+ output.content = []
43
+
44
+ node.forEach((child, offset) => {
45
+ output.content?.push(getDebugJSON(child, startOffset + offset + increment))
46
+ })
47
+ }
48
+
49
+ if (node.text) {
50
+ output.text = node.text
51
+ }
52
+
53
+ return output
54
+ }
@@ -0,0 +1,25 @@
1
+ import { AnyExtension, MaybeThisParameterType, RemoveThis } from '../types'
2
+
3
+ export function getExtensionField<T = any>(
4
+ extension: AnyExtension,
5
+ field: string,
6
+ context?: Omit<MaybeThisParameterType<T>, 'parent'>,
7
+ ): RemoveThis<T> {
8
+
9
+ if (extension.config[field] === undefined && extension.parent) {
10
+ return getExtensionField(extension.parent, field, context)
11
+ }
12
+
13
+ if (typeof extension.config[field] === 'function') {
14
+ const value = extension.config[field].bind({
15
+ ...context,
16
+ parent: extension.parent
17
+ ? getExtensionField(extension.parent, field, context)
18
+ : null,
19
+ })
20
+
21
+ return value
22
+ }
23
+
24
+ return extension.config[field]
25
+ }
@@ -1,13 +1,12 @@
1
- import { Node, DOMSerializer, Schema } from 'prosemirror-model'
1
+ import { DOMSerializer, Fragment, Schema } from '@tiptap/pm/model'
2
2
 
3
- export default function getHTMLFromFragment(doc: Node, schema: Schema): string {
4
- const fragment = DOMSerializer
5
- .fromSchema(schema)
6
- .serializeFragment(doc.content)
3
+ export function getHTMLFromFragment(fragment: Fragment, schema: Schema): string {
4
+ const documentFragment = DOMSerializer.fromSchema(schema).serializeFragment(fragment)
7
5
 
8
6
  const temporaryDocument = document.implementation.createHTMLDocument()
9
7
  const container = temporaryDocument.createElement('div')
10
- container.appendChild(fragment)
8
+
9
+ container.appendChild(documentFragment)
11
10
 
12
11
  return container.innerHTML
13
12
  }
@@ -1,26 +1,33 @@
1
- import { EditorState } from 'prosemirror-state'
2
- import { Mark, MarkType } from 'prosemirror-model'
3
- import getMarkType from './getMarkType'
4
- import { AnyObject } from '../types'
1
+ import { Mark, MarkType } from '@tiptap/pm/model'
2
+ import { EditorState } from '@tiptap/pm/state'
5
3
 
6
- export default function getMarkAttributes(state: EditorState, typeOrName: string | MarkType): AnyObject {
4
+ import { getMarkType } from './getMarkType'
5
+
6
+ export function getMarkAttributes(
7
+ state: EditorState,
8
+ typeOrName: string | MarkType,
9
+ ): Record<string, any> {
7
10
  const type = getMarkType(typeOrName, state.schema)
8
11
  const { from, to, empty } = state.selection
9
- let marks: Mark[] = []
12
+ const marks: Mark[] = []
10
13
 
11
14
  if (empty) {
12
- marks = state.selection.$head.marks()
15
+ if (state.storedMarks) {
16
+ marks.push(...state.storedMarks)
17
+ }
18
+
19
+ marks.push(...state.selection.$head.marks())
13
20
  } else {
14
21
  state.doc.nodesBetween(from, to, node => {
15
- marks = [...marks, ...node.marks]
22
+ marks.push(...node.marks)
16
23
  })
17
24
  }
18
25
 
19
26
  const mark = marks.find(markItem => markItem.type.name === type.name)
20
27
 
21
- if (mark) {
22
- return { ...mark.attrs }
28
+ if (!mark) {
29
+ return {}
23
30
  }
24
31
 
25
- return {}
32
+ return { ...mark.attrs }
26
33
  }