@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.
- package/LICENSE.md +21 -0
- package/README.md +5 -1
- package/dist/index.cjs +2627 -2651
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2423 -2688
- package/dist/index.d.ts +2423 -2688
- package/dist/index.js +2639 -2684
- package/dist/index.js.map +1 -1
- package/dist/jsx-runtime/jsx-runtime.cjs +56 -0
- package/dist/jsx-runtime/jsx-runtime.cjs.map +1 -0
- package/dist/jsx-runtime/jsx-runtime.d.cts +22 -0
- package/dist/jsx-runtime/jsx-runtime.d.ts +22 -0
- package/dist/jsx-runtime/jsx-runtime.js +26 -0
- package/dist/jsx-runtime/jsx-runtime.js.map +1 -0
- package/jsx-runtime/index.cjs +1 -0
- package/jsx-runtime/index.d.cts +1 -0
- package/jsx-runtime/index.d.ts +1 -0
- package/jsx-runtime/index.js +1 -0
- package/package.json +27 -6
- package/src/CommandManager.ts +2 -9
- package/src/Editor.ts +191 -94
- package/src/EventEmitter.ts +7 -10
- package/src/Extendable.ts +483 -0
- package/src/Extension.ts +5 -496
- package/src/ExtensionManager.ts +81 -135
- package/src/InputRule.ts +35 -48
- package/src/Mark.ts +135 -623
- package/src/MarkView.ts +66 -0
- package/src/Node.ts +325 -829
- package/src/NodePos.ts +1 -3
- package/src/NodeView.ts +10 -20
- package/src/PasteRule.ts +43 -55
- package/src/Tracker.ts +7 -9
- package/src/commands/blur.ts +14 -12
- package/src/commands/clearContent.ts +12 -5
- package/src/commands/clearNodes.ts +32 -30
- package/src/commands/command.ts +1 -1
- package/src/commands/createParagraphNear.ts +5 -3
- package/src/commands/cut.ts +12 -10
- package/src/commands/deleteCurrentNode.ts +23 -21
- package/src/commands/deleteNode.ts +18 -16
- package/src/commands/deleteRange.ts +10 -8
- package/src/commands/deleteSelection.ts +5 -3
- package/src/commands/enter.ts +6 -4
- package/src/commands/exitCode.ts +5 -3
- package/src/commands/extendMarkRange.ts +14 -12
- package/src/commands/first.ts +2 -4
- package/src/commands/focus.ts +51 -48
- package/src/commands/forEach.ts +2 -2
- package/src/commands/insertContent.ts +12 -14
- package/src/commands/insertContentAt.ts +105 -98
- package/src/commands/join.ts +20 -12
- package/src/commands/joinItemBackward.ts +16 -18
- package/src/commands/joinItemForward.ts +16 -18
- package/src/commands/joinTextblockBackward.ts +5 -3
- package/src/commands/joinTextblockForward.ts +5 -3
- package/src/commands/keyboardShortcut.ts +29 -34
- package/src/commands/lift.ts +10 -8
- package/src/commands/liftEmptyBlock.ts +6 -4
- package/src/commands/liftListItem.ts +6 -4
- package/src/commands/newlineInCode.ts +5 -3
- package/src/commands/resetAttributes.ts +36 -41
- package/src/commands/scrollIntoView.ts +9 -7
- package/src/commands/selectAll.ts +10 -8
- package/src/commands/selectNodeBackward.ts +5 -3
- package/src/commands/selectNodeForward.ts +5 -3
- package/src/commands/selectParentNode.ts +5 -3
- package/src/commands/selectTextblockEnd.ts +5 -3
- package/src/commands/selectTextblockStart.ts +5 -3
- package/src/commands/setContent.ts +37 -36
- package/src/commands/setMark.ts +55 -57
- package/src/commands/setMeta.ts +7 -5
- package/src/commands/setNode.ts +32 -30
- package/src/commands/setNodeSelection.ts +11 -9
- package/src/commands/setTextSelection.ts +15 -13
- package/src/commands/sinkListItem.ts +6 -4
- package/src/commands/splitBlock.ts +67 -76
- package/src/commands/splitListItem.ts +93 -106
- package/src/commands/toggleList.ts +73 -71
- package/src/commands/toggleMark.ts +11 -9
- package/src/commands/toggleNode.ts +18 -16
- package/src/commands/toggleWrap.ts +10 -8
- package/src/commands/undoInputRule.ts +31 -29
- package/src/commands/unsetAllMarks.ts +16 -14
- package/src/commands/unsetMark.ts +27 -25
- package/src/commands/updateAttributes.ts +92 -100
- package/src/commands/wrapIn.ts +6 -4
- package/src/commands/wrapInList.ts +6 -4
- package/src/extensions/clipboardTextSerializer.ts +2 -4
- package/src/extensions/delete.ts +89 -0
- package/src/extensions/focusEvents.ts +2 -6
- package/src/extensions/index.ts +1 -0
- package/src/extensions/keymap.ts +58 -50
- package/src/extensions/paste.ts +0 -1
- package/src/extensions/tabindex.ts +1 -1
- package/src/helpers/combineTransactionSteps.ts +1 -4
- package/src/helpers/createChainableState.ts +1 -4
- package/src/helpers/createDocument.ts +1 -3
- package/src/helpers/createNodeFromContent.ts +4 -10
- package/src/helpers/findChildrenInRange.ts +1 -5
- package/src/helpers/findParentNode.ts +3 -1
- package/src/helpers/flattenExtensions.ts +30 -0
- package/src/helpers/getAttributes.ts +1 -4
- package/src/helpers/getAttributesFromExtensions.ts +28 -37
- package/src/helpers/getChangedRanges.ts +13 -11
- package/src/helpers/getExtensionField.ts +11 -11
- package/src/helpers/getMarkAttributes.ts +1 -4
- package/src/helpers/getMarkRange.ts +5 -15
- package/src/helpers/getMarkType.ts +1 -3
- package/src/helpers/getNodeAttributes.ts +1 -4
- package/src/helpers/getNodeType.ts +1 -3
- package/src/helpers/getRenderedAttributes.ts +1 -3
- package/src/helpers/getSchema.ts +2 -2
- package/src/helpers/getSchemaByResolvedExtensions.ts +45 -77
- package/src/helpers/getSplittedAttributes.ts +4 -4
- package/src/helpers/getTextContentFromNodes.ts +8 -11
- package/src/helpers/index.ts +4 -0
- package/src/helpers/injectExtensionAttributesToParseRule.ts +1 -1
- package/src/helpers/isActive.ts +1 -5
- package/src/helpers/isExtensionRulesEnabled.ts +1 -3
- package/src/helpers/isNodeEmpty.ts +2 -2
- package/src/helpers/resolveExtensions.ts +25 -0
- package/src/helpers/resolveFocusPosition.ts +3 -14
- package/src/helpers/rewriteUnknownContent.ts +149 -0
- package/src/helpers/sortExtensions.ts +26 -0
- package/src/index.ts +3 -7
- package/src/inputRules/markInputRule.ts +1 -5
- package/src/inputRules/nodeInputRule.ts +2 -9
- package/src/inputRules/textInputRule.ts +1 -4
- package/src/inputRules/textblockTypeInputRule.ts +2 -8
- package/src/inputRules/wrappingInputRule.ts +13 -19
- package/src/jsx-runtime.ts +64 -0
- package/src/pasteRules/markPasteRule.ts +1 -3
- package/src/pasteRules/nodePasteRule.ts +2 -8
- package/src/pasteRules/textPasteRule.ts +1 -4
- package/src/types.ts +529 -174
- package/src/utilities/createStyleTag.ts +3 -1
- package/src/utilities/deleteProps.ts +7 -11
- package/src/utilities/elementFromString.ts +3 -0
- package/src/utilities/findDuplicates.ts +4 -1
- package/src/utilities/index.ts +1 -0
- package/src/utilities/isFunction.ts +1 -0
- package/src/utilities/isMacOS.ts +1 -3
- package/src/utilities/isiOS.ts +5 -10
- package/src/utilities/mergeAttributes.ts +17 -7
- package/src/utilities/removeDuplicates.ts +1 -3
package/src/NodePos.ts
CHANGED
package/src/NodeView.ts
CHANGED
|
@@ -14,7 +14,8 @@ export class NodeView<
|
|
|
14
14
|
Component,
|
|
15
15
|
NodeEditor extends CoreEditor = CoreEditor,
|
|
16
16
|
Options extends NodeViewRendererOptions = NodeViewRendererOptions,
|
|
17
|
-
> implements ProseMirrorNodeView
|
|
17
|
+
> implements ProseMirrorNodeView
|
|
18
|
+
{
|
|
18
19
|
component: Component
|
|
19
20
|
|
|
20
21
|
editor: NodeEditor
|
|
@@ -74,9 +75,8 @@ export class NodeView<
|
|
|
74
75
|
|
|
75
76
|
// get the drag handle element
|
|
76
77
|
// `closest` is not available for text nodes so we may have to use its parent
|
|
77
|
-
const dragHandle =
|
|
78
|
-
? target.parentElement?.closest('[data-drag-handle]')
|
|
79
|
-
: target.closest('[data-drag-handle]')
|
|
78
|
+
const dragHandle =
|
|
79
|
+
target.nodeType === 3 ? target.parentElement?.closest('[data-drag-handle]') : target.closest('[data-drag-handle]')
|
|
80
80
|
|
|
81
81
|
if (!this.dom || this.contentDOM?.contains(target) || !dragHandle) {
|
|
82
82
|
return
|
|
@@ -195,14 +195,7 @@ export class NodeView<
|
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
// these events are handled by prosemirror
|
|
198
|
-
if (
|
|
199
|
-
isDragging
|
|
200
|
-
|| isDropEvent
|
|
201
|
-
|| isCopyEvent
|
|
202
|
-
|| isPasteEvent
|
|
203
|
-
|| isCutEvent
|
|
204
|
-
|| (isClickEvent && isSelectable)
|
|
205
|
-
) {
|
|
198
|
+
if (isDragging || isDropEvent || isCopyEvent || isPasteEvent || isCutEvent || (isClickEvent && isSelectable)) {
|
|
206
199
|
return false
|
|
207
200
|
}
|
|
208
201
|
|
|
@@ -240,15 +233,12 @@ export class NodeView<
|
|
|
240
233
|
// see: https://github.com/ueberdosis/tiptap/issues/1214
|
|
241
234
|
// see: https://github.com/ueberdosis/tiptap/issues/2534
|
|
242
235
|
if (
|
|
243
|
-
this.dom.contains(mutation.target)
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
236
|
+
this.dom.contains(mutation.target) &&
|
|
237
|
+
mutation.type === 'childList' &&
|
|
238
|
+
(isiOS() || isAndroid()) &&
|
|
239
|
+
this.editor.isFocused
|
|
247
240
|
) {
|
|
248
|
-
const changedNodes = [
|
|
249
|
-
...Array.from(mutation.addedNodes),
|
|
250
|
-
...Array.from(mutation.removedNodes),
|
|
251
|
-
] as HTMLElement[]
|
|
241
|
+
const changedNodes = [...Array.from(mutation.addedNodes), ...Array.from(mutation.removedNodes)] as HTMLElement[]
|
|
252
242
|
|
|
253
243
|
// we’ll check if every changed node is contentEditable
|
|
254
244
|
// to make sure it’s probably mutated by ProseMirror
|
package/src/PasteRule.ts
CHANGED
|
@@ -5,27 +5,21 @@ import { CommandManager } from './CommandManager.js'
|
|
|
5
5
|
import { Editor } from './Editor.js'
|
|
6
6
|
import { createChainableState } from './helpers/createChainableState.js'
|
|
7
7
|
import { getHTMLFromFragment } from './helpers/getHTMLFromFragment.js'
|
|
8
|
-
import {
|
|
9
|
-
CanCommands,
|
|
10
|
-
ChainedCommands,
|
|
11
|
-
ExtendedRegExpMatchArray,
|
|
12
|
-
Range,
|
|
13
|
-
SingleCommands,
|
|
14
|
-
} from './types.js'
|
|
8
|
+
import { CanCommands, ChainedCommands, ExtendedRegExpMatchArray, Range, SingleCommands } from './types.js'
|
|
15
9
|
import { isNumber } from './utilities/isNumber.js'
|
|
16
10
|
import { isRegExp } from './utilities/isRegExp.js'
|
|
17
11
|
|
|
18
12
|
export type PasteRuleMatch = {
|
|
19
|
-
index: number
|
|
20
|
-
text: string
|
|
21
|
-
replaceWith?: string
|
|
22
|
-
match?: RegExpMatchArray
|
|
23
|
-
data?: Record<string, any
|
|
24
|
-
}
|
|
13
|
+
index: number
|
|
14
|
+
text: string
|
|
15
|
+
replaceWith?: string
|
|
16
|
+
match?: RegExpMatchArray
|
|
17
|
+
data?: Record<string, any>
|
|
18
|
+
}
|
|
25
19
|
|
|
26
20
|
export type PasteRuleFinder =
|
|
27
21
|
| RegExp
|
|
28
|
-
| ((text: string, event?: ClipboardEvent | null) => PasteRuleMatch[] | null | undefined)
|
|
22
|
+
| ((text: string, event?: ClipboardEvent | null) => PasteRuleMatch[] | null | undefined)
|
|
29
23
|
|
|
30
24
|
/**
|
|
31
25
|
* Paste rules are used to react to pasted content.
|
|
@@ -35,28 +29,28 @@ export class PasteRule {
|
|
|
35
29
|
find: PasteRuleFinder
|
|
36
30
|
|
|
37
31
|
handler: (props: {
|
|
38
|
-
state: EditorState
|
|
39
|
-
range: Range
|
|
40
|
-
match: ExtendedRegExpMatchArray
|
|
41
|
-
commands: SingleCommands
|
|
42
|
-
chain: () => ChainedCommands
|
|
43
|
-
can: () => CanCommands
|
|
44
|
-
pasteEvent: ClipboardEvent | null
|
|
45
|
-
dropEvent: DragEvent | null
|
|
32
|
+
state: EditorState
|
|
33
|
+
range: Range
|
|
34
|
+
match: ExtendedRegExpMatchArray
|
|
35
|
+
commands: SingleCommands
|
|
36
|
+
chain: () => ChainedCommands
|
|
37
|
+
can: () => CanCommands
|
|
38
|
+
pasteEvent: ClipboardEvent | null
|
|
39
|
+
dropEvent: DragEvent | null
|
|
46
40
|
}) => void | null
|
|
47
41
|
|
|
48
42
|
constructor(config: {
|
|
49
|
-
find: PasteRuleFinder
|
|
43
|
+
find: PasteRuleFinder
|
|
50
44
|
handler: (props: {
|
|
51
|
-
can: () => CanCommands
|
|
52
|
-
chain: () => ChainedCommands
|
|
53
|
-
commands: SingleCommands
|
|
54
|
-
dropEvent: DragEvent | null
|
|
55
|
-
match: ExtendedRegExpMatchArray
|
|
56
|
-
pasteEvent: ClipboardEvent | null
|
|
57
|
-
range: Range
|
|
58
|
-
state: EditorState
|
|
59
|
-
}) => void | null
|
|
45
|
+
can: () => CanCommands
|
|
46
|
+
chain: () => ChainedCommands
|
|
47
|
+
commands: SingleCommands
|
|
48
|
+
dropEvent: DragEvent | null
|
|
49
|
+
match: ExtendedRegExpMatchArray
|
|
50
|
+
pasteEvent: ClipboardEvent | null
|
|
51
|
+
range: Range
|
|
52
|
+
state: EditorState
|
|
53
|
+
}) => void | null
|
|
60
54
|
}) {
|
|
61
55
|
this.find = config.find
|
|
62
56
|
this.handler = config.handler
|
|
@@ -87,9 +81,7 @@ const pasteRuleMatcherHandler = (
|
|
|
87
81
|
|
|
88
82
|
if (pasteRuleMatch.replaceWith) {
|
|
89
83
|
if (!pasteRuleMatch.text.includes(pasteRuleMatch.replaceWith)) {
|
|
90
|
-
console.warn(
|
|
91
|
-
'[tiptap warn]: "pasteRuleMatch.replaceWith" must be part of "pasteRuleMatch.text".',
|
|
92
|
-
)
|
|
84
|
+
console.warn('[tiptap warn]: "pasteRuleMatch.replaceWith" must be part of "pasteRuleMatch.text".')
|
|
93
85
|
}
|
|
94
86
|
|
|
95
87
|
result.push(pasteRuleMatch.replaceWith)
|
|
@@ -100,17 +92,15 @@ const pasteRuleMatcherHandler = (
|
|
|
100
92
|
}
|
|
101
93
|
|
|
102
94
|
function run(config: {
|
|
103
|
-
editor: Editor
|
|
104
|
-
state: EditorState
|
|
105
|
-
from: number
|
|
106
|
-
to: number
|
|
107
|
-
rule: PasteRule
|
|
108
|
-
pasteEvent: ClipboardEvent | null
|
|
109
|
-
dropEvent: DragEvent | null
|
|
95
|
+
editor: Editor
|
|
96
|
+
state: EditorState
|
|
97
|
+
from: number
|
|
98
|
+
to: number
|
|
99
|
+
rule: PasteRule
|
|
100
|
+
pasteEvent: ClipboardEvent | null
|
|
101
|
+
dropEvent: DragEvent | null
|
|
110
102
|
}): boolean {
|
|
111
|
-
const {
|
|
112
|
-
editor, state, from, to, rule, pasteEvent, dropEvent,
|
|
113
|
-
} = config
|
|
103
|
+
const { editor, state, from, to, rule, pasteEvent, dropEvent } = config
|
|
114
104
|
|
|
115
105
|
const { commands, chain, can } = new CommandManager({
|
|
116
106
|
editor,
|
|
@@ -190,7 +180,7 @@ export function pasteRulesPlugin(props: { editor: Editor; rules: PasteRule[] }):
|
|
|
190
180
|
|
|
191
181
|
try {
|
|
192
182
|
dropEvent = typeof DragEvent !== 'undefined' ? new DragEvent('drop') : null
|
|
193
|
-
} catch
|
|
183
|
+
} catch {
|
|
194
184
|
dropEvent = null
|
|
195
185
|
}
|
|
196
186
|
|
|
@@ -201,11 +191,11 @@ export function pasteRulesPlugin(props: { editor: Editor; rules: PasteRule[] }):
|
|
|
201
191
|
rule,
|
|
202
192
|
pasteEvt,
|
|
203
193
|
}: {
|
|
204
|
-
state: EditorState
|
|
205
|
-
from: number
|
|
206
|
-
to: { b: number }
|
|
207
|
-
rule: PasteRule
|
|
208
|
-
pasteEvt: ClipboardEvent | null
|
|
194
|
+
state: EditorState
|
|
195
|
+
from: number
|
|
196
|
+
to: { b: number }
|
|
197
|
+
rule: PasteRule
|
|
198
|
+
pasteEvt: ClipboardEvent | null
|
|
209
199
|
}) => {
|
|
210
200
|
const tr = state.tr
|
|
211
201
|
const chainableState = createChainableState({
|
|
@@ -229,7 +219,7 @@ export function pasteRulesPlugin(props: { editor: Editor; rules: PasteRule[] }):
|
|
|
229
219
|
|
|
230
220
|
try {
|
|
231
221
|
dropEvent = typeof DragEvent !== 'undefined' ? new DragEvent('drop') : null
|
|
232
|
-
} catch
|
|
222
|
+
} catch {
|
|
233
223
|
dropEvent = null
|
|
234
224
|
}
|
|
235
225
|
pasteEvent = typeof ClipboardEvent !== 'undefined' ? new ClipboardEvent('paste') : null
|
|
@@ -242,9 +232,7 @@ export function pasteRulesPlugin(props: { editor: Editor; rules: PasteRule[] }):
|
|
|
242
232
|
// we register a global drag handler to track the current drag source element
|
|
243
233
|
view(view) {
|
|
244
234
|
const handleDragstart = (event: DragEvent) => {
|
|
245
|
-
dragSourceElement = view.dom.parentElement?.contains(event.target as Element)
|
|
246
|
-
? view.dom.parentElement
|
|
247
|
-
: null
|
|
235
|
+
dragSourceElement = view.dom.parentElement?.contains(event.target as Element) ? view.dom.parentElement : null
|
|
248
236
|
|
|
249
237
|
if (dragSourceElement) {
|
|
250
238
|
tiptapDragFromOtherEditor = editor
|
package/src/Tracker.ts
CHANGED
|
@@ -18,17 +18,15 @@ export class Tracker {
|
|
|
18
18
|
map(position: number): TrackerResult {
|
|
19
19
|
let deleted = false
|
|
20
20
|
|
|
21
|
-
const mappedPosition = this.transaction.steps
|
|
22
|
-
.
|
|
23
|
-
.reduce((newPosition, step) => {
|
|
24
|
-
const mapResult = step.getMap().mapResult(newPosition)
|
|
21
|
+
const mappedPosition = this.transaction.steps.slice(this.currentStep).reduce((newPosition, step) => {
|
|
22
|
+
const mapResult = step.getMap().mapResult(newPosition)
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
if (mapResult.deleted) {
|
|
25
|
+
deleted = true
|
|
26
|
+
}
|
|
29
27
|
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
return mapResult.pos
|
|
29
|
+
}, position)
|
|
32
30
|
|
|
33
31
|
return {
|
|
34
32
|
position: mappedPosition,
|
package/src/commands/blur.ts
CHANGED
|
@@ -7,21 +7,23 @@ declare module '@tiptap/core' {
|
|
|
7
7
|
* Removes focus from the editor.
|
|
8
8
|
* @example editor.commands.blur()
|
|
9
9
|
*/
|
|
10
|
-
blur: () => ReturnType
|
|
10
|
+
blur: () => ReturnType
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export const blur: RawCommands['blur'] =
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
export const blur: RawCommands['blur'] =
|
|
16
|
+
() =>
|
|
17
|
+
({ editor, view }) => {
|
|
18
|
+
requestAnimationFrame(() => {
|
|
19
|
+
if (!editor.isDestroyed) {
|
|
20
|
+
;(view.dom as HTMLElement).blur()
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
// Browsers should remove the caret on blur but safari does not.
|
|
23
|
+
// See: https://github.com/ueberdosis/tiptap/issues/2405
|
|
24
|
+
window?.getSelection()?.removeAllRanges()
|
|
25
|
+
}
|
|
26
|
+
})
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
+
return true
|
|
29
|
+
}
|
|
@@ -5,14 +5,21 @@ declare module '@tiptap/core' {
|
|
|
5
5
|
clearContent: {
|
|
6
6
|
/**
|
|
7
7
|
* Clear the whole document.
|
|
8
|
-
* @param emitUpdate Whether to emit an update event.
|
|
9
8
|
* @example editor.commands.clearContent()
|
|
10
9
|
*/
|
|
11
|
-
clearContent: (
|
|
10
|
+
clearContent: (
|
|
11
|
+
/**
|
|
12
|
+
* Whether to emit an update event.
|
|
13
|
+
* @default true
|
|
14
|
+
*/
|
|
15
|
+
emitUpdate?: boolean,
|
|
16
|
+
) => ReturnType
|
|
12
17
|
}
|
|
13
18
|
}
|
|
14
19
|
}
|
|
15
20
|
|
|
16
|
-
export const clearContent: RawCommands['clearContent'] =
|
|
17
|
-
|
|
18
|
-
}
|
|
21
|
+
export const clearContent: RawCommands['clearContent'] =
|
|
22
|
+
(emitUpdate = true) =>
|
|
23
|
+
({ commands }) => {
|
|
24
|
+
return commands.setContent('', { emitUpdate })
|
|
25
|
+
}
|
|
@@ -9,47 +9,49 @@ declare module '@tiptap/core' {
|
|
|
9
9
|
* Normalize nodes to a simple paragraph.
|
|
10
10
|
* @example editor.commands.clearNodes()
|
|
11
11
|
*/
|
|
12
|
-
clearNodes: () => ReturnType
|
|
12
|
+
clearNodes: () => ReturnType
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export const clearNodes: RawCommands['clearNodes'] =
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
export const clearNodes: RawCommands['clearNodes'] =
|
|
18
|
+
() =>
|
|
19
|
+
({ state, tr, dispatch }) => {
|
|
20
|
+
const { selection } = tr
|
|
21
|
+
const { ranges } = selection
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
if (!dispatch) {
|
|
24
|
+
return true
|
|
25
|
+
}
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
ranges.forEach(({ $from, $to }) => {
|
|
28
|
+
state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => {
|
|
29
|
+
if (node.type.isText) {
|
|
30
|
+
return
|
|
31
|
+
}
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
const { doc, mapping } = tr
|
|
34
|
+
const $mappedFrom = doc.resolve(mapping.map(pos))
|
|
35
|
+
const $mappedTo = doc.resolve(mapping.map(pos + node.nodeSize))
|
|
36
|
+
const nodeRange = $mappedFrom.blockRange($mappedTo)
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
if (!nodeRange) {
|
|
39
|
+
return
|
|
40
|
+
}
|
|
39
41
|
|
|
40
|
-
|
|
42
|
+
const targetLiftDepth = liftTarget(nodeRange)
|
|
41
43
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
if (node.type.isTextblock) {
|
|
45
|
+
const { defaultType } = $mappedFrom.parent.contentMatchAt($mappedFrom.index())
|
|
44
46
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
tr.setNodeMarkup(nodeRange.start, defaultType)
|
|
48
|
+
}
|
|
47
49
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
if (targetLiftDepth || targetLiftDepth === 0) {
|
|
51
|
+
tr.lift(nodeRange, targetLiftDepth)
|
|
52
|
+
}
|
|
53
|
+
})
|
|
51
54
|
})
|
|
52
|
-
})
|
|
53
55
|
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
+
return true
|
|
57
|
+
}
|
package/src/commands/command.ts
CHANGED
|
@@ -14,6 +14,8 @@ declare module '@tiptap/core' {
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export const createParagraphNear: RawCommands['createParagraphNear'] =
|
|
18
|
-
|
|
19
|
-
}
|
|
17
|
+
export const createParagraphNear: RawCommands['createParagraphNear'] =
|
|
18
|
+
() =>
|
|
19
|
+
({ state, dispatch }) => {
|
|
20
|
+
return originalCreateParagraphNear(state, dispatch)
|
|
21
|
+
}
|
package/src/commands/cut.ts
CHANGED
|
@@ -13,22 +13,24 @@ declare module '@tiptap/core' {
|
|
|
13
13
|
* @param targetPos The position to insert the content at.
|
|
14
14
|
* @example editor.commands.cut({ from: 1, to: 3 }, 5)
|
|
15
15
|
*/
|
|
16
|
-
cut: ({ from, to }: { from: number
|
|
16
|
+
cut: ({ from, to }: { from: number; to: number }, targetPos: number) => ReturnType
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
export const cut: RawCommands['cut'] =
|
|
22
|
-
|
|
21
|
+
export const cut: RawCommands['cut'] =
|
|
22
|
+
(originRange, targetPos) =>
|
|
23
|
+
({ editor, tr }) => {
|
|
24
|
+
const { state } = editor
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
const contentSlice = state.doc.slice(originRange.from, originRange.to)
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
tr.deleteRange(originRange.from, originRange.to)
|
|
29
|
+
const newPos = tr.mapping.map(targetPos)
|
|
28
30
|
|
|
29
|
-
|
|
31
|
+
tr.insert(newPos, contentSlice.content)
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
tr.setSelection(new TextSelection(tr.doc.resolve(newPos - 1)))
|
|
32
34
|
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
+
return true
|
|
36
|
+
}
|
|
@@ -7,36 +7,38 @@ declare module '@tiptap/core' {
|
|
|
7
7
|
* Delete the node that currently has the selection anchor.
|
|
8
8
|
* @example editor.commands.deleteCurrentNode()
|
|
9
9
|
*/
|
|
10
|
-
deleteCurrentNode: () => ReturnType
|
|
10
|
+
deleteCurrentNode: () => ReturnType
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export const deleteCurrentNode: RawCommands['deleteCurrentNode'] =
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
export const deleteCurrentNode: RawCommands['deleteCurrentNode'] =
|
|
16
|
+
() =>
|
|
17
|
+
({ tr, dispatch }) => {
|
|
18
|
+
const { selection } = tr
|
|
19
|
+
const currentNode = selection.$anchor.node()
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
// if there is content inside the current node, break out of this command
|
|
22
|
+
if (currentNode.content.size > 0) {
|
|
23
|
+
return false
|
|
24
|
+
}
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
const $pos = tr.selection.$anchor
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
29
|
+
const node = $pos.node(depth)
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
if (node.type === currentNode.type) {
|
|
32
|
+
if (dispatch) {
|
|
33
|
+
const from = $pos.before(depth)
|
|
34
|
+
const to = $pos.after(depth)
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
tr.delete(from, to).scrollIntoView()
|
|
37
|
+
}
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
return true
|
|
40
|
+
}
|
|
38
41
|
}
|
|
39
|
-
}
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
+
return false
|
|
44
|
+
}
|
|
@@ -11,29 +11,31 @@ declare module '@tiptap/core' {
|
|
|
11
11
|
* @param typeOrName The type or name of the node.
|
|
12
12
|
* @example editor.commands.deleteNode('paragraph')
|
|
13
13
|
*/
|
|
14
|
-
deleteNode: (typeOrName: string | NodeType) => ReturnType
|
|
14
|
+
deleteNode: (typeOrName: string | NodeType) => ReturnType
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
export const deleteNode: RawCommands['deleteNode'] =
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
export const deleteNode: RawCommands['deleteNode'] =
|
|
20
|
+
typeOrName =>
|
|
21
|
+
({ tr, state, dispatch }) => {
|
|
22
|
+
const type = getNodeType(typeOrName, state.schema)
|
|
23
|
+
const $pos = tr.selection.$anchor
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
26
|
+
const node = $pos.node(depth)
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
if (node.type === type) {
|
|
29
|
+
if (dispatch) {
|
|
30
|
+
const from = $pos.before(depth)
|
|
31
|
+
const to = $pos.after(depth)
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
tr.delete(from, to).scrollIntoView()
|
|
34
|
+
}
|
|
33
35
|
|
|
34
|
-
|
|
36
|
+
return true
|
|
37
|
+
}
|
|
35
38
|
}
|
|
36
|
-
}
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
+
return false
|
|
41
|
+
}
|
|
@@ -8,17 +8,19 @@ declare module '@tiptap/core' {
|
|
|
8
8
|
* @param range The range to delete.
|
|
9
9
|
* @example editor.commands.deleteRange({ from: 1, to: 3 })
|
|
10
10
|
*/
|
|
11
|
-
deleteRange: (range: Range) => ReturnType
|
|
11
|
+
deleteRange: (range: Range) => ReturnType
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
export const deleteRange: RawCommands['deleteRange'] =
|
|
17
|
-
|
|
16
|
+
export const deleteRange: RawCommands['deleteRange'] =
|
|
17
|
+
range =>
|
|
18
|
+
({ tr, dispatch }) => {
|
|
19
|
+
const { from, to } = range
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
if (dispatch) {
|
|
22
|
+
tr.delete(from, to)
|
|
23
|
+
}
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
+
return true
|
|
26
|
+
}
|
|
@@ -14,6 +14,8 @@ declare module '@tiptap/core' {
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export const deleteSelection: RawCommands['deleteSelection'] =
|
|
18
|
-
|
|
19
|
-
}
|
|
17
|
+
export const deleteSelection: RawCommands['deleteSelection'] =
|
|
18
|
+
() =>
|
|
19
|
+
({ state, dispatch }) => {
|
|
20
|
+
return originalDeleteSelection(state, dispatch)
|
|
21
|
+
}
|
package/src/commands/enter.ts
CHANGED
|
@@ -7,11 +7,13 @@ declare module '@tiptap/core' {
|
|
|
7
7
|
* Trigger enter.
|
|
8
8
|
* @example editor.commands.enter()
|
|
9
9
|
*/
|
|
10
|
-
enter: () => ReturnType
|
|
10
|
+
enter: () => ReturnType
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export const enter: RawCommands['enter'] =
|
|
16
|
-
|
|
17
|
-
}
|
|
15
|
+
export const enter: RawCommands['enter'] =
|
|
16
|
+
() =>
|
|
17
|
+
({ commands }) => {
|
|
18
|
+
return commands.keyboardShortcut('Enter')
|
|
19
|
+
}
|
package/src/commands/exitCode.ts
CHANGED
|
@@ -14,6 +14,8 @@ declare module '@tiptap/core' {
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export const exitCode: RawCommands['exitCode'] =
|
|
18
|
-
|
|
19
|
-
}
|
|
17
|
+
export const exitCode: RawCommands['exitCode'] =
|
|
18
|
+
() =>
|
|
19
|
+
({ state, dispatch }) => {
|
|
20
|
+
return originalExitCode(state, dispatch)
|
|
21
|
+
}
|