@tiptap/core 3.0.0-next.3 → 3.0.0-next.5

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 (146) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +5 -1
  3. package/dist/index.cjs +2627 -2651
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.cts +2423 -2688
  6. package/dist/index.d.ts +2423 -2688
  7. package/dist/index.js +2639 -2684
  8. package/dist/index.js.map +1 -1
  9. package/dist/jsx-runtime/jsx-runtime.cjs +56 -0
  10. package/dist/jsx-runtime/jsx-runtime.cjs.map +1 -0
  11. package/dist/jsx-runtime/jsx-runtime.d.cts +22 -0
  12. package/dist/jsx-runtime/jsx-runtime.d.ts +22 -0
  13. package/dist/jsx-runtime/jsx-runtime.js +26 -0
  14. package/dist/jsx-runtime/jsx-runtime.js.map +1 -0
  15. package/jsx-runtime/index.cjs +1 -0
  16. package/jsx-runtime/index.d.cts +1 -0
  17. package/jsx-runtime/index.d.ts +1 -0
  18. package/jsx-runtime/index.js +1 -0
  19. package/package.json +27 -6
  20. package/src/CommandManager.ts +2 -9
  21. package/src/Editor.ts +191 -94
  22. package/src/EventEmitter.ts +7 -10
  23. package/src/Extendable.ts +483 -0
  24. package/src/Extension.ts +5 -496
  25. package/src/ExtensionManager.ts +81 -135
  26. package/src/InputRule.ts +35 -48
  27. package/src/Mark.ts +135 -623
  28. package/src/MarkView.ts +66 -0
  29. package/src/Node.ts +325 -829
  30. package/src/NodePos.ts +1 -3
  31. package/src/NodeView.ts +10 -20
  32. package/src/PasteRule.ts +43 -55
  33. package/src/Tracker.ts +7 -9
  34. package/src/commands/blur.ts +14 -12
  35. package/src/commands/clearContent.ts +12 -5
  36. package/src/commands/clearNodes.ts +32 -30
  37. package/src/commands/command.ts +1 -1
  38. package/src/commands/createParagraphNear.ts +5 -3
  39. package/src/commands/cut.ts +12 -10
  40. package/src/commands/deleteCurrentNode.ts +23 -21
  41. package/src/commands/deleteNode.ts +18 -16
  42. package/src/commands/deleteRange.ts +10 -8
  43. package/src/commands/deleteSelection.ts +5 -3
  44. package/src/commands/enter.ts +6 -4
  45. package/src/commands/exitCode.ts +5 -3
  46. package/src/commands/extendMarkRange.ts +14 -12
  47. package/src/commands/first.ts +2 -4
  48. package/src/commands/focus.ts +51 -48
  49. package/src/commands/forEach.ts +2 -2
  50. package/src/commands/insertContent.ts +12 -14
  51. package/src/commands/insertContentAt.ts +105 -98
  52. package/src/commands/join.ts +20 -12
  53. package/src/commands/joinItemBackward.ts +16 -18
  54. package/src/commands/joinItemForward.ts +16 -18
  55. package/src/commands/joinTextblockBackward.ts +5 -3
  56. package/src/commands/joinTextblockForward.ts +5 -3
  57. package/src/commands/keyboardShortcut.ts +29 -34
  58. package/src/commands/lift.ts +10 -8
  59. package/src/commands/liftEmptyBlock.ts +6 -4
  60. package/src/commands/liftListItem.ts +6 -4
  61. package/src/commands/newlineInCode.ts +5 -3
  62. package/src/commands/resetAttributes.ts +36 -41
  63. package/src/commands/scrollIntoView.ts +9 -7
  64. package/src/commands/selectAll.ts +10 -8
  65. package/src/commands/selectNodeBackward.ts +5 -3
  66. package/src/commands/selectNodeForward.ts +5 -3
  67. package/src/commands/selectParentNode.ts +5 -3
  68. package/src/commands/selectTextblockEnd.ts +5 -3
  69. package/src/commands/selectTextblockStart.ts +5 -3
  70. package/src/commands/setContent.ts +37 -36
  71. package/src/commands/setMark.ts +55 -57
  72. package/src/commands/setMeta.ts +7 -5
  73. package/src/commands/setNode.ts +32 -30
  74. package/src/commands/setNodeSelection.ts +11 -9
  75. package/src/commands/setTextSelection.ts +15 -13
  76. package/src/commands/sinkListItem.ts +6 -4
  77. package/src/commands/splitBlock.ts +67 -76
  78. package/src/commands/splitListItem.ts +93 -106
  79. package/src/commands/toggleList.ts +73 -71
  80. package/src/commands/toggleMark.ts +11 -9
  81. package/src/commands/toggleNode.ts +18 -16
  82. package/src/commands/toggleWrap.ts +10 -8
  83. package/src/commands/undoInputRule.ts +31 -29
  84. package/src/commands/unsetAllMarks.ts +16 -14
  85. package/src/commands/unsetMark.ts +27 -25
  86. package/src/commands/updateAttributes.ts +92 -100
  87. package/src/commands/wrapIn.ts +6 -4
  88. package/src/commands/wrapInList.ts +6 -4
  89. package/src/extensions/clipboardTextSerializer.ts +2 -4
  90. package/src/extensions/delete.ts +89 -0
  91. package/src/extensions/focusEvents.ts +2 -6
  92. package/src/extensions/index.ts +1 -0
  93. package/src/extensions/keymap.ts +58 -50
  94. package/src/extensions/paste.ts +0 -1
  95. package/src/extensions/tabindex.ts +1 -1
  96. package/src/helpers/combineTransactionSteps.ts +1 -4
  97. package/src/helpers/createChainableState.ts +1 -4
  98. package/src/helpers/createDocument.ts +1 -3
  99. package/src/helpers/createNodeFromContent.ts +4 -10
  100. package/src/helpers/findChildrenInRange.ts +1 -5
  101. package/src/helpers/findParentNode.ts +3 -1
  102. package/src/helpers/flattenExtensions.ts +30 -0
  103. package/src/helpers/getAttributes.ts +1 -4
  104. package/src/helpers/getAttributesFromExtensions.ts +28 -37
  105. package/src/helpers/getChangedRanges.ts +13 -11
  106. package/src/helpers/getExtensionField.ts +11 -11
  107. package/src/helpers/getMarkAttributes.ts +1 -4
  108. package/src/helpers/getMarkRange.ts +5 -15
  109. package/src/helpers/getMarkType.ts +1 -3
  110. package/src/helpers/getNodeAttributes.ts +1 -4
  111. package/src/helpers/getNodeType.ts +1 -3
  112. package/src/helpers/getRenderedAttributes.ts +1 -3
  113. package/src/helpers/getSchema.ts +2 -2
  114. package/src/helpers/getSchemaByResolvedExtensions.ts +45 -77
  115. package/src/helpers/getSplittedAttributes.ts +4 -4
  116. package/src/helpers/getTextContentFromNodes.ts +8 -11
  117. package/src/helpers/index.ts +4 -0
  118. package/src/helpers/injectExtensionAttributesToParseRule.ts +1 -1
  119. package/src/helpers/isActive.ts +1 -5
  120. package/src/helpers/isExtensionRulesEnabled.ts +1 -3
  121. package/src/helpers/isNodeEmpty.ts +2 -2
  122. package/src/helpers/resolveExtensions.ts +25 -0
  123. package/src/helpers/resolveFocusPosition.ts +3 -14
  124. package/src/helpers/rewriteUnknownContent.ts +149 -0
  125. package/src/helpers/sortExtensions.ts +26 -0
  126. package/src/index.ts +3 -7
  127. package/src/inputRules/markInputRule.ts +1 -5
  128. package/src/inputRules/nodeInputRule.ts +2 -9
  129. package/src/inputRules/textInputRule.ts +1 -4
  130. package/src/inputRules/textblockTypeInputRule.ts +2 -8
  131. package/src/inputRules/wrappingInputRule.ts +13 -19
  132. package/src/jsx-runtime.ts +64 -0
  133. package/src/pasteRules/markPasteRule.ts +1 -3
  134. package/src/pasteRules/nodePasteRule.ts +2 -8
  135. package/src/pasteRules/textPasteRule.ts +1 -4
  136. package/src/types.ts +529 -174
  137. package/src/utilities/createStyleTag.ts +3 -1
  138. package/src/utilities/deleteProps.ts +7 -11
  139. package/src/utilities/elementFromString.ts +3 -0
  140. package/src/utilities/findDuplicates.ts +4 -1
  141. package/src/utilities/index.ts +1 -0
  142. package/src/utilities/isFunction.ts +1 -0
  143. package/src/utilities/isMacOS.ts +1 -3
  144. package/src/utilities/isiOS.ts +5 -10
  145. package/src/utilities/mergeAttributes.ts +17 -7
  146. package/src/utilities/removeDuplicates.ts +1 -3
@@ -68,90 +68,92 @@ declare module '@tiptap/core' {
68
68
  * @param attributes Attributes for the new list.
69
69
  * @example editor.commands.toggleList('bulletList', 'listItem')
70
70
  */
71
- toggleList: (listTypeOrName: string | NodeType, itemTypeOrName: string | NodeType, keepMarks?: boolean, attributes?: Record<string, any>) => ReturnType;
71
+ toggleList: (
72
+ listTypeOrName: string | NodeType,
73
+ itemTypeOrName: string | NodeType,
74
+ keepMarks?: boolean,
75
+ attributes?: Record<string, any>,
76
+ ) => ReturnType
72
77
  }
73
78
  }
74
79
  }
75
80
 
76
- export const toggleList: RawCommands['toggleList'] = (listTypeOrName, itemTypeOrName, keepMarks, attributes = {}) => ({
77
- editor, tr, state, dispatch, chain, commands, can,
78
- }) => {
79
- const { extensions, splittableMarks } = editor.extensionManager
80
- const listType = getNodeType(listTypeOrName, state.schema)
81
- const itemType = getNodeType(itemTypeOrName, state.schema)
82
- const { selection, storedMarks } = state
83
- const { $from, $to } = selection
84
- const range = $from.blockRange($to)
81
+ export const toggleList: RawCommands['toggleList'] =
82
+ (listTypeOrName, itemTypeOrName, keepMarks, attributes = {}) =>
83
+ ({ editor, tr, state, dispatch, chain, commands, can }) => {
84
+ const { extensions, splittableMarks } = editor.extensionManager
85
+ const listType = getNodeType(listTypeOrName, state.schema)
86
+ const itemType = getNodeType(itemTypeOrName, state.schema)
87
+ const { selection, storedMarks } = state
88
+ const { $from, $to } = selection
89
+ const range = $from.blockRange($to)
85
90
 
86
- const marks = storedMarks || (selection.$to.parentOffset && selection.$from.marks())
91
+ const marks = storedMarks || (selection.$to.parentOffset && selection.$from.marks())
87
92
 
88
- if (!range) {
89
- return false
90
- }
91
-
92
- const parentList = findParentNode(node => isList(node.type.name, extensions))(selection)
93
+ if (!range) {
94
+ return false
95
+ }
93
96
 
94
- if (range.depth >= 1 && parentList && range.depth - parentList.depth <= 1) {
95
- // remove list
96
- if (parentList.node.type === listType) {
97
- return commands.liftListItem(itemType)
97
+ const parentList = findParentNode(node => isList(node.type.name, extensions))(selection)
98
+
99
+ if (range.depth >= 1 && parentList && range.depth - parentList.depth <= 1) {
100
+ // remove list
101
+ if (parentList.node.type === listType) {
102
+ return commands.liftListItem(itemType)
103
+ }
104
+
105
+ // change list type
106
+ if (isList(parentList.node.type.name, extensions) && listType.validContent(parentList.node.content) && dispatch) {
107
+ return chain()
108
+ .command(() => {
109
+ tr.setNodeMarkup(parentList.pos, listType)
110
+
111
+ return true
112
+ })
113
+ .command(() => joinListBackwards(tr, listType))
114
+ .command(() => joinListForwards(tr, listType))
115
+ .run()
116
+ }
117
+ }
118
+ if (!keepMarks || !marks || !dispatch) {
119
+ return (
120
+ chain()
121
+ // try to convert node to default node if needed
122
+ .command(() => {
123
+ const canWrapInList = can().wrapInList(listType, attributes)
124
+
125
+ if (canWrapInList) {
126
+ return true
127
+ }
128
+
129
+ return commands.clearNodes()
130
+ })
131
+ .wrapInList(listType, attributes)
132
+ .command(() => joinListBackwards(tr, listType))
133
+ .command(() => joinListForwards(tr, listType))
134
+ .run()
135
+ )
98
136
  }
99
137
 
100
- // change list type
101
- if (
102
- isList(parentList.node.type.name, extensions)
103
- && listType.validContent(parentList.node.content)
104
- && dispatch
105
- ) {
106
- return chain()
138
+ return (
139
+ chain()
140
+ // try to convert node to default node if needed
107
141
  .command(() => {
108
- tr.setNodeMarkup(parentList.pos, listType)
142
+ const canWrapInList = can().wrapInList(listType, attributes)
109
143
 
110
- return true
144
+ const filteredMarks = marks.filter(mark => splittableMarks.includes(mark.type.name))
145
+
146
+ tr.ensureMarks(filteredMarks)
147
+
148
+ if (canWrapInList) {
149
+ return true
150
+ }
151
+
152
+ return commands.clearNodes()
111
153
  })
154
+ .wrapInList(listType, attributes)
112
155
  .command(() => joinListBackwards(tr, listType))
113
156
  .command(() => joinListForwards(tr, listType))
114
157
  .run()
115
- }
158
+ )
116
159
  }
117
- if (!keepMarks || !marks || !dispatch) {
118
-
119
- return chain()
120
- // try to convert node to default node if needed
121
- .command(() => {
122
- const canWrapInList = can().wrapInList(listType, attributes)
123
-
124
- if (canWrapInList) {
125
- return true
126
- }
127
-
128
- return commands.clearNodes()
129
- })
130
- .wrapInList(listType, attributes)
131
- .command(() => joinListBackwards(tr, listType))
132
- .command(() => joinListForwards(tr, listType))
133
- .run()
134
- }
135
-
136
- return (
137
- chain()
138
- // try to convert node to default node if needed
139
- .command(() => {
140
- const canWrapInList = can().wrapInList(listType, attributes)
141
-
142
- const filteredMarks = marks.filter(mark => splittableMarks.includes(mark.type.name))
143
-
144
- tr.ensureMarks(filteredMarks)
145
-
146
- if (canWrapInList) {
147
- return true
148
- }
149
-
150
- return commands.clearNodes()
151
- })
152
- .wrapInList(listType, attributes)
153
- .command(() => joinListBackwards(tr, listType))
154
- .command(() => joinListForwards(tr, listType))
155
- .run()
156
- )
157
- }
@@ -36,14 +36,16 @@ declare module '@tiptap/core' {
36
36
  }
37
37
  }
38
38
 
39
- export const toggleMark: RawCommands['toggleMark'] = (typeOrName, attributes = {}, options = {}) => ({ state, commands }) => {
40
- const { extendEmptyMarkRange = false } = options
41
- const type = getMarkType(typeOrName, state.schema)
42
- const isActive = isMarkActive(state, type, attributes)
39
+ export const toggleMark: RawCommands['toggleMark'] =
40
+ (typeOrName, attributes = {}, options = {}) =>
41
+ ({ state, commands }) => {
42
+ const { extendEmptyMarkRange = false } = options
43
+ const type = getMarkType(typeOrName, state.schema)
44
+ const isActive = isMarkActive(state, type, attributes)
43
45
 
44
- if (isActive) {
45
- return commands.unsetMark(type, { extendEmptyMarkRange })
46
- }
46
+ if (isActive) {
47
+ return commands.unsetMark(type, { extendEmptyMarkRange })
48
+ }
47
49
 
48
- return commands.setMark(type, attributes)
49
- }
50
+ return commands.setMark(type, attributes)
51
+ }
@@ -23,23 +23,25 @@ declare module '@tiptap/core' {
23
23
  }
24
24
  }
25
25
 
26
- export const toggleNode: RawCommands['toggleNode'] = (typeOrName, toggleTypeOrName, attributes = {}) => ({ state, commands }) => {
27
- const type = getNodeType(typeOrName, state.schema)
28
- const toggleType = getNodeType(toggleTypeOrName, state.schema)
29
- const isActive = isNodeActive(state, type, attributes)
26
+ export const toggleNode: RawCommands['toggleNode'] =
27
+ (typeOrName, toggleTypeOrName, attributes = {}) =>
28
+ ({ state, commands }) => {
29
+ const type = getNodeType(typeOrName, state.schema)
30
+ const toggleType = getNodeType(toggleTypeOrName, state.schema)
31
+ const isActive = isNodeActive(state, type, attributes)
30
32
 
31
- let attributesToCopy: Record<string, any> | undefined
33
+ let attributesToCopy: Record<string, any> | undefined
32
34
 
33
- if (state.selection.$anchor.sameParent(state.selection.$head)) {
34
- // only copy attributes if the selection is pointing to a node of the same type
35
- attributesToCopy = state.selection.$anchor.parent.attrs
36
- }
35
+ if (state.selection.$anchor.sameParent(state.selection.$head)) {
36
+ // only copy attributes if the selection is pointing to a node of the same type
37
+ attributesToCopy = state.selection.$anchor.parent.attrs
38
+ }
37
39
 
38
- if (isActive) {
39
- return commands.setNode(toggleType, attributesToCopy)
40
- }
40
+ if (isActive) {
41
+ return commands.setNode(toggleType, attributesToCopy)
42
+ }
41
43
 
42
- // If the node is not active, we want to set the new node type with the given attributes
43
- // Copying over the attributes from the current node if the selection is pointing to a node of the same type
44
- return commands.setNode(type, { ...attributesToCopy, ...attributes })
45
- }
44
+ // If the node is not active, we want to set the new node type with the given attributes
45
+ // Copying over the attributes from the current node if the selection is pointing to a node of the same type
46
+ return commands.setNode(type, { ...attributesToCopy, ...attributes })
47
+ }
@@ -18,13 +18,15 @@ declare module '@tiptap/core' {
18
18
  }
19
19
  }
20
20
 
21
- export const toggleWrap: RawCommands['toggleWrap'] = (typeOrName, attributes = {}) => ({ state, commands }) => {
22
- const type = getNodeType(typeOrName, state.schema)
23
- const isActive = isNodeActive(state, type, attributes)
21
+ export const toggleWrap: RawCommands['toggleWrap'] =
22
+ (typeOrName, attributes = {}) =>
23
+ ({ state, commands }) => {
24
+ const type = getNodeType(typeOrName, state.schema)
25
+ const isActive = isNodeActive(state, type, attributes)
24
26
 
25
- if (isActive) {
26
- return commands.lift(type)
27
- }
27
+ if (isActive) {
28
+ return commands.lift(type)
29
+ }
28
30
 
29
- return commands.wrapIn(type, attributes)
30
- }
31
+ return commands.wrapIn(type, attributes)
32
+ }
@@ -7,41 +7,43 @@ declare module '@tiptap/core' {
7
7
  * Undo an input rule.
8
8
  * @example editor.commands.undoInputRule()
9
9
  */
10
- undoInputRule: () => ReturnType,
10
+ undoInputRule: () => ReturnType
11
11
  }
12
12
  }
13
13
  }
14
14
 
15
- export const undoInputRule: RawCommands['undoInputRule'] = () => ({ state, dispatch }) => {
16
- const plugins = state.plugins
17
-
18
- for (let i = 0; i < plugins.length; i += 1) {
19
- const plugin = plugins[i]
20
- let undoable
21
-
22
- // @ts-ignore
23
- // eslint-disable-next-line
24
- if (plugin.spec.isInputRules && (undoable = plugin.getState(state))) {
25
- if (dispatch) {
26
- const tr = state.tr
27
- const toUndo = undoable.transform
28
-
29
- for (let j = toUndo.steps.length - 1; j >= 0; j -= 1) {
30
- tr.step(toUndo.steps[j].invert(toUndo.docs[j]))
15
+ export const undoInputRule: RawCommands['undoInputRule'] =
16
+ () =>
17
+ ({ state, dispatch }) => {
18
+ const plugins = state.plugins
19
+
20
+ for (let i = 0; i < plugins.length; i += 1) {
21
+ const plugin = plugins[i]
22
+ let undoable
23
+
24
+ // @ts-ignore
25
+ // eslint-disable-next-line
26
+ if (plugin.spec.isInputRules && (undoable = plugin.getState(state))) {
27
+ if (dispatch) {
28
+ const tr = state.tr
29
+ const toUndo = undoable.transform
30
+
31
+ for (let j = toUndo.steps.length - 1; j >= 0; j -= 1) {
32
+ tr.step(toUndo.steps[j].invert(toUndo.docs[j]))
33
+ }
34
+
35
+ if (undoable.text) {
36
+ const marks = tr.doc.resolve(undoable.from).marks()
37
+
38
+ tr.replaceWith(undoable.from, undoable.to, state.schema.text(undoable.text, marks))
39
+ } else {
40
+ tr.delete(undoable.from, undoable.to)
41
+ }
31
42
  }
32
43
 
33
- if (undoable.text) {
34
- const marks = tr.doc.resolve(undoable.from).marks()
35
-
36
- tr.replaceWith(undoable.from, undoable.to, state.schema.text(undoable.text, marks))
37
- } else {
38
- tr.delete(undoable.from, undoable.to)
39
- }
44
+ return true
40
45
  }
41
-
42
- return true
43
46
  }
44
- }
45
47
 
46
- return false
47
- }
48
+ return false
49
+ }
@@ -7,24 +7,26 @@ declare module '@tiptap/core' {
7
7
  * Remove all marks in the current selection.
8
8
  * @example editor.commands.unsetAllMarks()
9
9
  */
10
- unsetAllMarks: () => ReturnType,
10
+ unsetAllMarks: () => ReturnType
11
11
  }
12
12
  }
13
13
  }
14
14
 
15
- export const unsetAllMarks: RawCommands['unsetAllMarks'] = () => ({ tr, dispatch }) => {
16
- const { selection } = tr
17
- const { empty, ranges } = selection
15
+ export const unsetAllMarks: RawCommands['unsetAllMarks'] =
16
+ () =>
17
+ ({ tr, dispatch }) => {
18
+ const { selection } = tr
19
+ const { empty, ranges } = selection
18
20
 
19
- if (empty) {
20
- return true
21
- }
21
+ if (empty) {
22
+ return true
23
+ }
22
24
 
23
- if (dispatch) {
24
- ranges.forEach(range => {
25
- tr.removeMark(range.$from.pos, range.$to.pos)
26
- })
27
- }
25
+ if (dispatch) {
26
+ ranges.forEach(range => {
27
+ tr.removeMark(range.$from.pos, range.$to.pos)
28
+ })
29
+ }
28
30
 
29
- return true
30
- }
31
+ return true
32
+ }
@@ -30,34 +30,36 @@ declare module '@tiptap/core' {
30
30
  }
31
31
  }
32
32
 
33
- export const unsetMark: RawCommands['unsetMark'] = (typeOrName, options = {}) => ({ tr, state, dispatch }) => {
34
- const { extendEmptyMarkRange = false } = options
35
- const { selection } = tr
36
- const type = getMarkType(typeOrName, state.schema)
37
- const { $from, empty, ranges } = selection
33
+ export const unsetMark: RawCommands['unsetMark'] =
34
+ (typeOrName, options = {}) =>
35
+ ({ tr, state, dispatch }) => {
36
+ const { extendEmptyMarkRange = false } = options
37
+ const { selection } = tr
38
+ const type = getMarkType(typeOrName, state.schema)
39
+ const { $from, empty, ranges } = selection
38
40
 
39
- if (!dispatch) {
40
- return true
41
- }
41
+ if (!dispatch) {
42
+ return true
43
+ }
42
44
 
43
- if (empty && extendEmptyMarkRange) {
44
- let { from, to } = selection
45
- const attrs = $from.marks().find(mark => mark.type === type)?.attrs
46
- const range = getMarkRange($from, type, attrs)
45
+ if (empty && extendEmptyMarkRange) {
46
+ let { from, to } = selection
47
+ const attrs = $from.marks().find(mark => mark.type === type)?.attrs
48
+ const range = getMarkRange($from, type, attrs)
47
49
 
48
- if (range) {
49
- from = range.from
50
- to = range.to
51
- }
50
+ if (range) {
51
+ from = range.from
52
+ to = range.to
53
+ }
52
54
 
53
- tr.removeMark(from, to, type)
54
- } else {
55
- ranges.forEach(range => {
56
- tr.removeMark(range.$from.pos, range.$to.pos, type)
57
- })
58
- }
55
+ tr.removeMark(from, to, type)
56
+ } else {
57
+ ranges.forEach(range => {
58
+ tr.removeMark(range.$from.pos, range.$to.pos, type)
59
+ })
60
+ }
59
61
 
60
- tr.removeStoredMark(type)
62
+ tr.removeStoredMark(type)
61
63
 
62
- return true
63
- }
64
+ return true
65
+ }
@@ -1,6 +1,4 @@
1
- import {
2
- Mark, MarkType, Node, NodeType,
3
- } from '@tiptap/pm/model'
1
+ import { Mark, MarkType, Node, NodeType } from '@tiptap/pm/model'
4
2
  import { SelectionRange } from '@tiptap/pm/state'
5
3
 
6
4
  import { getMarkType } from '../helpers/getMarkType.js'
@@ -32,117 +30,111 @@ declare module '@tiptap/core' {
32
30
  }
33
31
  }
34
32
 
35
- export const updateAttributes: RawCommands['updateAttributes'] = (typeOrName, attributes = {}) => ({ tr, state, dispatch }) => {
33
+ export const updateAttributes: RawCommands['updateAttributes'] =
34
+ (typeOrName, attributes = {}) =>
35
+ ({ tr, state, dispatch }) => {
36
+ let nodeType: NodeType | null = null
37
+ let markType: MarkType | null = null
36
38
 
37
- let nodeType: NodeType | null = null
38
- let markType: MarkType | null = null
39
+ const schemaType = getSchemaTypeNameByName(
40
+ typeof typeOrName === 'string' ? typeOrName : typeOrName.name,
41
+ state.schema,
42
+ )
39
43
 
40
- const schemaType = getSchemaTypeNameByName(
41
- typeof typeOrName === 'string' ? typeOrName : typeOrName.name,
42
- state.schema,
43
- )
44
-
45
- if (!schemaType) {
46
- return false
47
- }
48
-
49
- if (schemaType === 'node') {
50
- nodeType = getNodeType(typeOrName as NodeType, state.schema)
51
- }
52
-
53
- if (schemaType === 'mark') {
54
- markType = getMarkType(typeOrName as MarkType, state.schema)
55
- }
56
-
57
- if (dispatch) {
58
- tr.selection.ranges.forEach((range: SelectionRange) => {
44
+ if (!schemaType) {
45
+ return false
46
+ }
59
47
 
60
- const from = range.$from.pos
61
- const to = range.$to.pos
48
+ if (schemaType === 'node') {
49
+ nodeType = getNodeType(typeOrName as NodeType, state.schema)
50
+ }
62
51
 
63
- let lastPos: number | undefined
64
- let lastNode: Node | undefined
65
- let trimmedFrom: number
66
- let trimmedTo: number
52
+ if (schemaType === 'mark') {
53
+ markType = getMarkType(typeOrName as MarkType, state.schema)
54
+ }
67
55
 
68
- if (tr.selection.empty) {
69
- state.doc.nodesBetween(from, to, (node: Node, pos: number) => {
56
+ if (dispatch) {
57
+ tr.selection.ranges.forEach((range: SelectionRange) => {
58
+ const from = range.$from.pos
59
+ const to = range.$to.pos
70
60
 
71
- if (nodeType && nodeType === node.type) {
72
- trimmedFrom = Math.max(pos, from)
73
- trimmedTo = Math.min(pos + node.nodeSize, to)
74
- lastPos = pos
75
- lastNode = node
76
- }
77
- })
78
- } else {
79
- state.doc.nodesBetween(from, to, (node: Node, pos: number) => {
80
-
81
- if (pos < from && nodeType && nodeType === node.type) {
82
- trimmedFrom = Math.max(pos, from)
83
- trimmedTo = Math.min(pos + node.nodeSize, to)
84
- lastPos = pos
85
- lastNode = node
86
- }
87
-
88
- if (pos >= from && pos <= to) {
61
+ let lastPos: number | undefined
62
+ let lastNode: Node | undefined
63
+ let trimmedFrom: number
64
+ let trimmedTo: number
89
65
 
66
+ if (tr.selection.empty) {
67
+ state.doc.nodesBetween(from, to, (node: Node, pos: number) => {
90
68
  if (nodeType && nodeType === node.type) {
91
- tr.setNodeMarkup(pos, undefined, {
92
- ...node.attrs,
93
- ...attributes,
94
- })
69
+ trimmedFrom = Math.max(pos, from)
70
+ trimmedTo = Math.min(pos + node.nodeSize, to)
71
+ lastPos = pos
72
+ lastNode = node
95
73
  }
96
-
97
- if (markType && node.marks.length) {
98
- node.marks.forEach((mark: Mark) => {
99
-
100
- if (markType === mark.type) {
101
- const trimmedFrom2 = Math.max(pos, from)
102
- const trimmedTo2 = Math.min(pos + node.nodeSize, to)
103
-
104
- tr.addMark(
105
- trimmedFrom2,
106
- trimmedTo2,
107
- markType.create({
108
- ...mark.attrs,
109
- ...attributes,
110
- }),
111
- )
112
- }
113
- })
74
+ })
75
+ } else {
76
+ state.doc.nodesBetween(from, to, (node: Node, pos: number) => {
77
+ if (pos < from && nodeType && nodeType === node.type) {
78
+ trimmedFrom = Math.max(pos, from)
79
+ trimmedTo = Math.min(pos + node.nodeSize, to)
80
+ lastPos = pos
81
+ lastNode = node
114
82
  }
115
- }
116
- })
117
- }
118
83
 
119
- if (lastNode) {
120
-
121
- if (lastPos !== undefined) {
122
- tr.setNodeMarkup(lastPos, undefined, {
123
- ...lastNode.attrs,
124
- ...attributes,
84
+ if (pos >= from && pos <= to) {
85
+ if (nodeType && nodeType === node.type) {
86
+ tr.setNodeMarkup(pos, undefined, {
87
+ ...node.attrs,
88
+ ...attributes,
89
+ })
90
+ }
91
+
92
+ if (markType && node.marks.length) {
93
+ node.marks.forEach((mark: Mark) => {
94
+ if (markType === mark.type) {
95
+ const trimmedFrom2 = Math.max(pos, from)
96
+ const trimmedTo2 = Math.min(pos + node.nodeSize, to)
97
+
98
+ tr.addMark(
99
+ trimmedFrom2,
100
+ trimmedTo2,
101
+ markType.create({
102
+ ...mark.attrs,
103
+ ...attributes,
104
+ }),
105
+ )
106
+ }
107
+ })
108
+ }
109
+ }
125
110
  })
126
111
  }
127
112
 
128
- if (markType && lastNode.marks.length) {
129
- lastNode.marks.forEach((mark: Mark) => {
113
+ if (lastNode) {
114
+ if (lastPos !== undefined) {
115
+ tr.setNodeMarkup(lastPos, undefined, {
116
+ ...lastNode.attrs,
117
+ ...attributes,
118
+ })
119
+ }
130
120
 
131
- if (markType === mark.type) {
132
- tr.addMark(
133
- trimmedFrom,
134
- trimmedTo,
135
- markType.create({
136
- ...mark.attrs,
137
- ...attributes,
138
- }),
139
- )
140
- }
141
- })
121
+ if (markType && lastNode.marks.length) {
122
+ lastNode.marks.forEach((mark: Mark) => {
123
+ if (markType === mark.type) {
124
+ tr.addMark(
125
+ trimmedFrom,
126
+ trimmedTo,
127
+ markType.create({
128
+ ...mark.attrs,
129
+ ...attributes,
130
+ }),
131
+ )
132
+ }
133
+ })
134
+ }
142
135
  }
143
- }
144
- })
145
- }
136
+ })
137
+ }
146
138
 
147
- return true
148
- }
139
+ return true
140
+ }
@@ -18,8 +18,10 @@ declare module '@tiptap/core' {
18
18
  }
19
19
  }
20
20
 
21
- export const wrapIn: RawCommands['wrapIn'] = (typeOrName, attributes = {}) => ({ state, dispatch }) => {
22
- const type = getNodeType(typeOrName, state.schema)
21
+ export const wrapIn: RawCommands['wrapIn'] =
22
+ (typeOrName, attributes = {}) =>
23
+ ({ state, dispatch }) => {
24
+ const type = getNodeType(typeOrName, state.schema)
23
25
 
24
- return originalWrapIn(type, attributes)(state, dispatch)
25
- }
26
+ return originalWrapIn(type, attributes)(state, dispatch)
27
+ }