@tiptap/core 3.0.0-next.0 → 3.0.0-next.2
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/dist/index.cjs +4934 -4574
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3576 -0
- package/dist/index.d.ts +3576 -0
- package/dist/index.js +4839 -4481
- package/dist/index.js.map +1 -1
- package/package.json +6 -8
- package/src/Editor.ts +66 -10
- package/src/EventEmitter.ts +9 -0
- package/src/Extension.ts +4 -3
- package/src/ExtensionManager.ts +18 -12
- package/src/InputRule.ts +45 -30
- package/src/Mark.ts +4 -3
- package/src/Node.ts +23 -3
- package/src/NodePos.ts +9 -4
- package/src/NodeView.ts +43 -12
- package/src/PasteRule.ts +96 -42
- package/src/commands/focus.ts +1 -6
- package/src/commands/insertContent.ts +9 -9
- package/src/commands/insertContentAt.ts +23 -3
- package/src/commands/selectAll.ts +10 -5
- package/src/commands/setContent.ts +10 -14
- package/src/commands/setMeta.ts +3 -1
- package/src/commands/setNode.ts +9 -2
- package/src/commands/splitListItem.ts +27 -17
- package/src/commands/toggleNode.ts +11 -2
- package/src/commands/updateAttributes.ts +72 -12
- package/src/extensions/drop.ts +26 -0
- package/src/extensions/index.ts +2 -0
- package/src/extensions/keymap.ts +5 -2
- package/src/extensions/paste.ts +26 -0
- package/src/helpers/createDocument.ts +4 -2
- package/src/helpers/createNodeFromContent.ts +11 -2
- package/src/helpers/getAttributesFromExtensions.ts +1 -1
- package/src/helpers/getMarkRange.ts +35 -8
- package/src/helpers/getMarksBetween.ts +1 -1
- package/src/helpers/getRenderedAttributes.ts +3 -0
- package/src/helpers/getSchemaByResolvedExtensions.ts +3 -2
- package/src/helpers/isList.ts +1 -1
- package/src/helpers/isNodeEmpty.ts +33 -12
- package/src/inputRules/markInputRule.ts +1 -1
- package/src/inputRules/nodeInputRule.ts +1 -1
- package/src/inputRules/textInputRule.ts +1 -1
- package/src/inputRules/textblockTypeInputRule.ts +1 -1
- package/src/inputRules/wrappingInputRule.ts +1 -1
- package/src/pasteRules/markPasteRule.ts +1 -1
- package/src/pasteRules/nodePasteRule.ts +15 -6
- package/src/pasteRules/textPasteRule.ts +1 -1
- package/src/style.ts +2 -2
- package/src/types.ts +107 -19
- package/src/utilities/mergeAttributes.ts +18 -1
- package/dist/index.umd.js +0 -5130
- package/dist/index.umd.js.map +0 -1
- package/dist/packages/core/src/CommandManager.d.ts +0 -20
- package/dist/packages/core/src/Editor.d.ts +0 -159
- package/dist/packages/core/src/EventEmitter.d.ts +0 -11
- package/dist/packages/core/src/Extension.d.ts +0 -343
- package/dist/packages/core/src/ExtensionManager.d.ts +0 -55
- package/dist/packages/core/src/InputRule.d.ts +0 -42
- package/dist/packages/core/src/Mark.d.ts +0 -451
- package/dist/packages/core/src/Node.d.ts +0 -611
- package/dist/packages/core/src/NodePos.d.ts +0 -44
- package/dist/packages/core/src/NodeView.d.ts +0 -31
- package/dist/packages/core/src/PasteRule.d.ts +0 -50
- package/dist/packages/core/src/Tracker.d.ts +0 -11
- package/dist/packages/core/src/commands/blur.d.ts +0 -13
- package/dist/packages/core/src/commands/clearContent.d.ts +0 -14
- package/dist/packages/core/src/commands/clearNodes.d.ts +0 -13
- package/dist/packages/core/src/commands/command.d.ts +0 -18
- package/dist/packages/core/src/commands/createParagraphNear.d.ts +0 -13
- package/dist/packages/core/src/commands/cut.d.ts +0 -20
- package/dist/packages/core/src/commands/deleteCurrentNode.d.ts +0 -13
- package/dist/packages/core/src/commands/deleteNode.d.ts +0 -15
- package/dist/packages/core/src/commands/deleteRange.d.ts +0 -14
- package/dist/packages/core/src/commands/deleteSelection.d.ts +0 -13
- package/dist/packages/core/src/commands/enter.d.ts +0 -13
- package/dist/packages/core/src/commands/exitCode.d.ts +0 -13
- package/dist/packages/core/src/commands/extendMarkRange.d.ts +0 -25
- package/dist/packages/core/src/commands/first.d.ts +0 -14
- package/dist/packages/core/src/commands/focus.d.ts +0 -27
- package/dist/packages/core/src/commands/forEach.d.ts +0 -14
- package/dist/packages/core/src/commands/index.d.ts +0 -55
- package/dist/packages/core/src/commands/insertContent.d.ts +0 -34
- package/dist/packages/core/src/commands/insertContentAt.d.ts +0 -47
- package/dist/packages/core/src/commands/join.d.ts +0 -41
- package/dist/packages/core/src/commands/joinItemBackward.d.ts +0 -13
- package/dist/packages/core/src/commands/joinItemForward.d.ts +0 -13
- package/dist/packages/core/src/commands/joinTextblockBackward.d.ts +0 -12
- package/dist/packages/core/src/commands/joinTextblockForward.d.ts +0 -12
- package/dist/packages/core/src/commands/keyboardShortcut.d.ts +0 -14
- package/dist/packages/core/src/commands/lift.d.ts +0 -17
- package/dist/packages/core/src/commands/liftEmptyBlock.d.ts +0 -13
- package/dist/packages/core/src/commands/liftListItem.d.ts +0 -15
- package/dist/packages/core/src/commands/newlineInCode.d.ts +0 -13
- package/dist/packages/core/src/commands/resetAttributes.d.ts +0 -16
- package/dist/packages/core/src/commands/scrollIntoView.d.ts +0 -13
- package/dist/packages/core/src/commands/selectAll.d.ts +0 -13
- package/dist/packages/core/src/commands/selectNodeBackward.d.ts +0 -13
- package/dist/packages/core/src/commands/selectNodeForward.d.ts +0 -13
- package/dist/packages/core/src/commands/selectParentNode.d.ts +0 -13
- package/dist/packages/core/src/commands/selectTextblockEnd.d.ts +0 -13
- package/dist/packages/core/src/commands/selectTextblockStart.d.ts +0 -13
- package/dist/packages/core/src/commands/setContent.d.ts +0 -40
- package/dist/packages/core/src/commands/setMark.d.ts +0 -15
- package/dist/packages/core/src/commands/setMeta.d.ts +0 -15
- package/dist/packages/core/src/commands/setNode.d.ts +0 -16
- package/dist/packages/core/src/commands/setNodeSelection.d.ts +0 -14
- package/dist/packages/core/src/commands/setTextSelection.d.ts +0 -14
- package/dist/packages/core/src/commands/sinkListItem.d.ts +0 -15
- package/dist/packages/core/src/commands/splitBlock.d.ts +0 -17
- package/dist/packages/core/src/commands/splitListItem.d.ts +0 -15
- package/dist/packages/core/src/commands/toggleList.d.ts +0 -18
- package/dist/packages/core/src/commands/toggleMark.d.ts +0 -30
- package/dist/packages/core/src/commands/toggleNode.d.ts +0 -17
- package/dist/packages/core/src/commands/toggleWrap.d.ts +0 -16
- package/dist/packages/core/src/commands/undoInputRule.d.ts +0 -13
- package/dist/packages/core/src/commands/unsetAllMarks.d.ts +0 -13
- package/dist/packages/core/src/commands/unsetMark.d.ts +0 -25
- package/dist/packages/core/src/commands/updateAttributes.d.ts +0 -24
- package/dist/packages/core/src/commands/wrapIn.d.ts +0 -16
- package/dist/packages/core/src/commands/wrapInList.d.ts +0 -16
- package/dist/packages/core/src/extensions/clipboardTextSerializer.d.ts +0 -5
- package/dist/packages/core/src/extensions/commands.d.ts +0 -3
- package/dist/packages/core/src/extensions/editable.d.ts +0 -2
- package/dist/packages/core/src/extensions/focusEvents.d.ts +0 -2
- package/dist/packages/core/src/extensions/index.d.ts +0 -6
- package/dist/packages/core/src/extensions/keymap.d.ts +0 -2
- package/dist/packages/core/src/extensions/tabindex.d.ts +0 -2
- package/dist/packages/core/src/helpers/combineTransactionSteps.d.ts +0 -10
- package/dist/packages/core/src/helpers/createChainableState.d.ts +0 -10
- package/dist/packages/core/src/helpers/createDocument.d.ts +0 -12
- package/dist/packages/core/src/helpers/createNodeFromContent.d.ts +0 -15
- package/dist/packages/core/src/helpers/defaultBlockAt.d.ts +0 -7
- package/dist/packages/core/src/helpers/findChildren.d.ts +0 -9
- package/dist/packages/core/src/helpers/findChildrenInRange.d.ts +0 -10
- package/dist/packages/core/src/helpers/findParentNode.d.ts +0 -16
- package/dist/packages/core/src/helpers/findParentNodeClosestToPos.d.ts +0 -17
- package/dist/packages/core/src/helpers/generateHTML.d.ts +0 -8
- package/dist/packages/core/src/helpers/generateJSON.d.ts +0 -8
- package/dist/packages/core/src/helpers/generateText.d.ts +0 -12
- package/dist/packages/core/src/helpers/getAttributes.d.ts +0 -9
- package/dist/packages/core/src/helpers/getAttributesFromExtensions.d.ts +0 -6
- package/dist/packages/core/src/helpers/getChangedRanges.d.ts +0 -11
- package/dist/packages/core/src/helpers/getDebugJSON.d.ts +0 -8
- package/dist/packages/core/src/helpers/getExtensionField.d.ts +0 -9
- package/dist/packages/core/src/helpers/getHTMLFromFragment.d.ts +0 -2
- package/dist/packages/core/src/helpers/getMarkAttributes.d.ts +0 -3
- package/dist/packages/core/src/helpers/getMarkRange.d.ts +0 -3
- package/dist/packages/core/src/helpers/getMarkType.d.ts +0 -2
- package/dist/packages/core/src/helpers/getMarksBetween.d.ts +0 -3
- package/dist/packages/core/src/helpers/getNodeAtPosition.d.ts +0 -11
- package/dist/packages/core/src/helpers/getNodeAttributes.d.ts +0 -3
- package/dist/packages/core/src/helpers/getNodeType.d.ts +0 -2
- package/dist/packages/core/src/helpers/getRenderedAttributes.d.ts +0 -3
- package/dist/packages/core/src/helpers/getSchema.d.ts +0 -4
- package/dist/packages/core/src/helpers/getSchemaByResolvedExtensions.d.ts +0 -10
- package/dist/packages/core/src/helpers/getSchemaTypeByName.d.ts +0 -8
- package/dist/packages/core/src/helpers/getSchemaTypeNameByName.d.ts +0 -8
- package/dist/packages/core/src/helpers/getSplittedAttributes.d.ts +0 -9
- package/dist/packages/core/src/helpers/getText.d.ts +0 -15
- package/dist/packages/core/src/helpers/getTextBetween.d.ts +0 -14
- package/dist/packages/core/src/helpers/getTextContentFromNodes.d.ts +0 -8
- package/dist/packages/core/src/helpers/getTextSerializersFromSchema.d.ts +0 -8
- package/dist/packages/core/src/helpers/index.d.ts +0 -50
- package/dist/packages/core/src/helpers/injectExtensionAttributesToParseRule.d.ts +0 -9
- package/dist/packages/core/src/helpers/isActive.d.ts +0 -2
- package/dist/packages/core/src/helpers/isAtEndOfNode.d.ts +0 -2
- package/dist/packages/core/src/helpers/isAtStartOfNode.d.ts +0 -2
- package/dist/packages/core/src/helpers/isExtensionRulesEnabled.d.ts +0 -2
- package/dist/packages/core/src/helpers/isList.d.ts +0 -2
- package/dist/packages/core/src/helpers/isMarkActive.d.ts +0 -3
- package/dist/packages/core/src/helpers/isNodeActive.d.ts +0 -3
- package/dist/packages/core/src/helpers/isNodeEmpty.d.ts +0 -8
- package/dist/packages/core/src/helpers/isNodeSelection.d.ts +0 -2
- package/dist/packages/core/src/helpers/isTextSelection.d.ts +0 -2
- package/dist/packages/core/src/helpers/posToDOMRect.d.ts +0 -2
- package/dist/packages/core/src/helpers/resolveFocusPosition.d.ts +0 -4
- package/dist/packages/core/src/helpers/selectionToInsertionEnd.d.ts +0 -2
- package/dist/packages/core/src/helpers/splitExtensions.d.ts +0 -9
- package/dist/packages/core/src/index.d.ts +0 -24
- package/dist/packages/core/src/inputRules/index.d.ts +0 -5
- package/dist/packages/core/src/inputRules/markInputRule.d.ts +0 -13
- package/dist/packages/core/src/inputRules/nodeInputRule.d.ts +0 -23
- package/dist/packages/core/src/inputRules/textInputRule.d.ts +0 -10
- package/dist/packages/core/src/inputRules/textblockTypeInputRule.d.ts +0 -15
- package/dist/packages/core/src/inputRules/wrappingInputRule.d.ts +0 -28
- package/dist/packages/core/src/pasteRules/index.d.ts +0 -3
- package/dist/packages/core/src/pasteRules/markPasteRule.d.ts +0 -13
- package/dist/packages/core/src/pasteRules/nodePasteRule.d.ts +0 -13
- package/dist/packages/core/src/pasteRules/textPasteRule.d.ts +0 -10
- package/dist/packages/core/src/style.d.ts +0 -1
- package/dist/packages/core/src/types.d.ts +0 -253
- package/dist/packages/core/src/utilities/callOrReturn.d.ts +0 -9
- package/dist/packages/core/src/utilities/createStyleTag.d.ts +0 -1
- package/dist/packages/core/src/utilities/deleteProps.d.ts +0 -6
- package/dist/packages/core/src/utilities/elementFromString.d.ts +0 -1
- package/dist/packages/core/src/utilities/escapeForRegEx.d.ts +0 -1
- package/dist/packages/core/src/utilities/findDuplicates.d.ts +0 -1
- package/dist/packages/core/src/utilities/fromString.d.ts +0 -1
- package/dist/packages/core/src/utilities/index.d.ts +0 -20
- package/dist/packages/core/src/utilities/isAndroid.d.ts +0 -1
- package/dist/packages/core/src/utilities/isEmptyObject.d.ts +0 -1
- package/dist/packages/core/src/utilities/isFunction.d.ts +0 -1
- package/dist/packages/core/src/utilities/isMacOS.d.ts +0 -1
- package/dist/packages/core/src/utilities/isNumber.d.ts +0 -1
- package/dist/packages/core/src/utilities/isPlainObject.d.ts +0 -1
- package/dist/packages/core/src/utilities/isRegExp.d.ts +0 -1
- package/dist/packages/core/src/utilities/isString.d.ts +0 -1
- package/dist/packages/core/src/utilities/isiOS.d.ts +0 -1
- package/dist/packages/core/src/utilities/mergeAttributes.d.ts +0 -1
- package/dist/packages/core/src/utilities/mergeDeep.d.ts +0 -1
- package/dist/packages/core/src/utilities/minMax.d.ts +0 -1
- package/dist/packages/core/src/utilities/objectIncludes.d.ts +0 -8
- package/dist/packages/core/src/utilities/removeDuplicates.d.ts +0 -8
package/src/PasteRule.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { Fragment, Node as ProseMirrorNode } from '@tiptap/pm/model'
|
|
1
2
|
import { EditorState, Plugin } from '@tiptap/pm/state'
|
|
2
3
|
|
|
3
4
|
import { CommandManager } from './CommandManager.js'
|
|
4
5
|
import { Editor } from './Editor.js'
|
|
5
6
|
import { createChainableState } from './helpers/createChainableState.js'
|
|
7
|
+
import { getHTMLFromFragment } from './helpers/getHTMLFromFragment.js'
|
|
6
8
|
import {
|
|
7
9
|
CanCommands,
|
|
8
10
|
ChainedCommands,
|
|
@@ -14,45 +16,47 @@ import { isNumber } from './utilities/isNumber.js'
|
|
|
14
16
|
import { isRegExp } from './utilities/isRegExp.js'
|
|
15
17
|
|
|
16
18
|
export type PasteRuleMatch = {
|
|
17
|
-
index: number
|
|
18
|
-
text: string
|
|
19
|
-
replaceWith?: string
|
|
20
|
-
match?: RegExpMatchArray
|
|
21
|
-
data?: Record<string, any
|
|
22
|
-
}
|
|
19
|
+
index: number;
|
|
20
|
+
text: string;
|
|
21
|
+
replaceWith?: string;
|
|
22
|
+
match?: RegExpMatchArray;
|
|
23
|
+
data?: Record<string, any>;
|
|
24
|
+
};
|
|
23
25
|
|
|
24
|
-
export type PasteRuleFinder =
|
|
26
|
+
export type PasteRuleFinder =
|
|
27
|
+
| RegExp
|
|
28
|
+
| ((text: string, event?: ClipboardEvent | null) => PasteRuleMatch[] | null | undefined);
|
|
25
29
|
|
|
26
30
|
/**
|
|
27
31
|
* Paste rules are used to react to pasted content.
|
|
28
|
-
* @see https://tiptap.dev/
|
|
32
|
+
* @see https://tiptap.dev/docs/editor/extensions/custom-extensions/extend-existing#paste-rules
|
|
29
33
|
*/
|
|
30
34
|
export class PasteRule {
|
|
31
35
|
find: PasteRuleFinder
|
|
32
36
|
|
|
33
37
|
handler: (props: {
|
|
34
|
-
state: EditorState
|
|
35
|
-
range: Range
|
|
36
|
-
match: ExtendedRegExpMatchArray
|
|
37
|
-
commands: SingleCommands
|
|
38
|
-
chain: () => ChainedCommands
|
|
39
|
-
can: () => CanCommands
|
|
40
|
-
pasteEvent: ClipboardEvent | null
|
|
41
|
-
dropEvent: DragEvent | null
|
|
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;
|
|
42
46
|
}) => void | null
|
|
43
47
|
|
|
44
48
|
constructor(config: {
|
|
45
|
-
find: PasteRuleFinder
|
|
49
|
+
find: PasteRuleFinder;
|
|
46
50
|
handler: (props: {
|
|
47
|
-
can: () => CanCommands
|
|
48
|
-
chain: () => ChainedCommands
|
|
49
|
-
commands: SingleCommands
|
|
50
|
-
dropEvent: DragEvent | null
|
|
51
|
-
match: ExtendedRegExpMatchArray
|
|
52
|
-
pasteEvent: ClipboardEvent | null
|
|
53
|
-
range: Range
|
|
54
|
-
state: EditorState
|
|
55
|
-
}) => void | null
|
|
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;
|
|
56
60
|
}) {
|
|
57
61
|
this.find = config.find
|
|
58
62
|
this.handler = config.handler
|
|
@@ -96,13 +100,13 @@ const pasteRuleMatcherHandler = (
|
|
|
96
100
|
}
|
|
97
101
|
|
|
98
102
|
function run(config: {
|
|
99
|
-
editor: Editor
|
|
100
|
-
state: EditorState
|
|
101
|
-
from: number
|
|
102
|
-
to: number
|
|
103
|
-
rule: PasteRule
|
|
104
|
-
pasteEvent: ClipboardEvent | null
|
|
105
|
-
dropEvent: DragEvent | null
|
|
103
|
+
editor: Editor;
|
|
104
|
+
state: EditorState;
|
|
105
|
+
from: number;
|
|
106
|
+
to: number;
|
|
107
|
+
rule: PasteRule;
|
|
108
|
+
pasteEvent: ClipboardEvent | null;
|
|
109
|
+
dropEvent: DragEvent | null;
|
|
106
110
|
}): boolean {
|
|
107
111
|
const {
|
|
108
112
|
editor, state, from, to, rule, pasteEvent, dropEvent,
|
|
@@ -158,6 +162,9 @@ function run(config: {
|
|
|
158
162
|
return success
|
|
159
163
|
}
|
|
160
164
|
|
|
165
|
+
// When dragging across editors, must get another editor instance to delete selection content.
|
|
166
|
+
let tiptapDragFromOtherEditor: Editor | null = null
|
|
167
|
+
|
|
161
168
|
const createClipboardPasteEvent = (text: string) => {
|
|
162
169
|
const event = new ClipboardEvent('paste', {
|
|
163
170
|
clipboardData: new DataTransfer(),
|
|
@@ -179,7 +186,13 @@ export function pasteRulesPlugin(props: { editor: Editor; rules: PasteRule[] }):
|
|
|
179
186
|
let isPastedFromProseMirror = false
|
|
180
187
|
let isDroppedFromProseMirror = false
|
|
181
188
|
let pasteEvent = typeof ClipboardEvent !== 'undefined' ? new ClipboardEvent('paste') : null
|
|
182
|
-
let dropEvent
|
|
189
|
+
let dropEvent: DragEvent | null
|
|
190
|
+
|
|
191
|
+
try {
|
|
192
|
+
dropEvent = typeof DragEvent !== 'undefined' ? new DragEvent('drop') : null
|
|
193
|
+
} catch (e) {
|
|
194
|
+
dropEvent = null
|
|
195
|
+
}
|
|
183
196
|
|
|
184
197
|
const processEvent = ({
|
|
185
198
|
state,
|
|
@@ -188,11 +201,11 @@ export function pasteRulesPlugin(props: { editor: Editor; rules: PasteRule[] }):
|
|
|
188
201
|
rule,
|
|
189
202
|
pasteEvt,
|
|
190
203
|
}: {
|
|
191
|
-
state: EditorState
|
|
192
|
-
from: number
|
|
193
|
-
to: { b: number }
|
|
194
|
-
rule: PasteRule
|
|
195
|
-
pasteEvt: ClipboardEvent | null
|
|
204
|
+
state: EditorState;
|
|
205
|
+
from: number;
|
|
206
|
+
to: { b: number };
|
|
207
|
+
rule: PasteRule;
|
|
208
|
+
pasteEvt: ClipboardEvent | null;
|
|
196
209
|
}) => {
|
|
197
210
|
const tr = state.tr
|
|
198
211
|
const chainableState = createChainableState({
|
|
@@ -214,7 +227,11 @@ export function pasteRulesPlugin(props: { editor: Editor; rules: PasteRule[] }):
|
|
|
214
227
|
return
|
|
215
228
|
}
|
|
216
229
|
|
|
217
|
-
|
|
230
|
+
try {
|
|
231
|
+
dropEvent = typeof DragEvent !== 'undefined' ? new DragEvent('drop') : null
|
|
232
|
+
} catch (e) {
|
|
233
|
+
dropEvent = null
|
|
234
|
+
}
|
|
218
235
|
pasteEvent = typeof ClipboardEvent !== 'undefined' ? new ClipboardEvent('paste') : null
|
|
219
236
|
|
|
220
237
|
return tr
|
|
@@ -228,13 +245,25 @@ export function pasteRulesPlugin(props: { editor: Editor; rules: PasteRule[] }):
|
|
|
228
245
|
dragSourceElement = view.dom.parentElement?.contains(event.target as Element)
|
|
229
246
|
? view.dom.parentElement
|
|
230
247
|
: null
|
|
248
|
+
|
|
249
|
+
if (dragSourceElement) {
|
|
250
|
+
tiptapDragFromOtherEditor = editor
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const handleDragend = () => {
|
|
255
|
+
if (tiptapDragFromOtherEditor) {
|
|
256
|
+
tiptapDragFromOtherEditor = null
|
|
257
|
+
}
|
|
231
258
|
}
|
|
232
259
|
|
|
233
260
|
window.addEventListener('dragstart', handleDragstart)
|
|
261
|
+
window.addEventListener('dragend', handleDragend)
|
|
234
262
|
|
|
235
263
|
return {
|
|
236
264
|
destroy() {
|
|
237
265
|
window.removeEventListener('dragstart', handleDragstart)
|
|
266
|
+
window.removeEventListener('dragend', handleDragend)
|
|
238
267
|
},
|
|
239
268
|
}
|
|
240
269
|
},
|
|
@@ -245,6 +274,20 @@ export function pasteRulesPlugin(props: { editor: Editor; rules: PasteRule[] }):
|
|
|
245
274
|
isDroppedFromProseMirror = dragSourceElement === view.dom.parentElement
|
|
246
275
|
dropEvent = event as DragEvent
|
|
247
276
|
|
|
277
|
+
if (!isDroppedFromProseMirror) {
|
|
278
|
+
const dragFromOtherEditor = tiptapDragFromOtherEditor
|
|
279
|
+
|
|
280
|
+
if (dragFromOtherEditor) {
|
|
281
|
+
// setTimeout to avoid the wrong content after drop, timeout arg can't be empty or 0
|
|
282
|
+
setTimeout(() => {
|
|
283
|
+
const selection = dragFromOtherEditor.state.selection
|
|
284
|
+
|
|
285
|
+
if (selection) {
|
|
286
|
+
dragFromOtherEditor.commands.deleteRange({ from: selection.from, to: selection.to })
|
|
287
|
+
}
|
|
288
|
+
}, 10)
|
|
289
|
+
}
|
|
290
|
+
}
|
|
248
291
|
return false
|
|
249
292
|
},
|
|
250
293
|
|
|
@@ -266,7 +309,9 @@ export function pasteRulesPlugin(props: { editor: Editor; rules: PasteRule[] }):
|
|
|
266
309
|
const isDrop = transaction.getMeta('uiEvent') === 'drop' && !isDroppedFromProseMirror
|
|
267
310
|
|
|
268
311
|
// if PasteRule is triggered by insertContent()
|
|
269
|
-
const simulatedPasteMeta = transaction.getMeta('applyPasteRules')
|
|
312
|
+
const simulatedPasteMeta = transaction.getMeta('applyPasteRules') as
|
|
313
|
+
| undefined
|
|
314
|
+
| { from: number; text: string | ProseMirrorNode | Fragment }
|
|
270
315
|
const isSimulatedPaste = !!simulatedPasteMeta
|
|
271
316
|
|
|
272
317
|
if (!isPaste && !isDrop && !isSimulatedPaste) {
|
|
@@ -275,8 +320,17 @@ export function pasteRulesPlugin(props: { editor: Editor; rules: PasteRule[] }):
|
|
|
275
320
|
|
|
276
321
|
// Handle simulated paste
|
|
277
322
|
if (isSimulatedPaste) {
|
|
278
|
-
|
|
323
|
+
let { text } = simulatedPasteMeta
|
|
324
|
+
|
|
325
|
+
if (typeof text === 'string') {
|
|
326
|
+
text = text as string
|
|
327
|
+
} else {
|
|
328
|
+
text = getHTMLFromFragment(Fragment.from(text), state.schema)
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const { from } = simulatedPasteMeta
|
|
279
332
|
const to = from + text.length
|
|
333
|
+
|
|
280
334
|
const pasteEvt = createClipboardPasteEvent(text)
|
|
281
335
|
|
|
282
336
|
return processEvent({
|
package/src/commands/focus.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { isTextSelection } from '../helpers/isTextSelection.js'
|
|
2
2
|
import { resolveFocusPosition } from '../helpers/resolveFocusPosition.js'
|
|
3
3
|
import { FocusPosition, RawCommands } from '../types.js'
|
|
4
|
-
import { isiOS } from '../utilities/isiOS.js'
|
|
5
4
|
|
|
6
5
|
declare module '@tiptap/core' {
|
|
7
6
|
interface Commands<ReturnType> {
|
|
@@ -43,11 +42,7 @@ export const focus: RawCommands['focus'] = (position = null, options = {}) => ({
|
|
|
43
42
|
}
|
|
44
43
|
|
|
45
44
|
const delayedFocus = () => {
|
|
46
|
-
|
|
47
|
-
// so we have to call this
|
|
48
|
-
if (isiOS()) {
|
|
49
|
-
(view.dom as HTMLElement).focus()
|
|
50
|
-
}
|
|
45
|
+
(view.dom as HTMLElement).focus()
|
|
51
46
|
|
|
52
47
|
// For React we have to focus asynchronously. Otherwise wild things happen.
|
|
53
48
|
// see: https://github.com/ueberdosis/tiptap/issues/1520
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ParseOptions } from '@tiptap/pm/model'
|
|
1
|
+
import { Fragment, Node as ProseMirrorNode, ParseOptions } from '@tiptap/pm/model'
|
|
2
2
|
|
|
3
3
|
import { Content, RawCommands } from '../types.js'
|
|
4
4
|
|
|
@@ -14,7 +14,7 @@ declare module '@tiptap/core' {
|
|
|
14
14
|
/**
|
|
15
15
|
* The ProseMirror content to insert.
|
|
16
16
|
*/
|
|
17
|
-
value: Content,
|
|
17
|
+
value: Content | ProseMirrorNode | Fragment,
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Optional options
|
|
@@ -23,17 +23,17 @@ declare module '@tiptap/core' {
|
|
|
23
23
|
/**
|
|
24
24
|
* Options for parsing the content.
|
|
25
25
|
*/
|
|
26
|
-
parseOptions?: ParseOptions
|
|
26
|
+
parseOptions?: ParseOptions;
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Whether to update the selection after inserting the content.
|
|
30
30
|
*/
|
|
31
|
-
updateSelection?: boolean
|
|
32
|
-
applyInputRules?: boolean
|
|
33
|
-
applyPasteRules?: boolean
|
|
34
|
-
}
|
|
35
|
-
) => ReturnType
|
|
36
|
-
}
|
|
31
|
+
updateSelection?: boolean;
|
|
32
|
+
applyInputRules?: boolean;
|
|
33
|
+
applyPasteRules?: boolean;
|
|
34
|
+
}
|
|
35
|
+
) => ReturnType;
|
|
36
|
+
};
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -20,7 +20,7 @@ declare module '@tiptap/core' {
|
|
|
20
20
|
/**
|
|
21
21
|
* The ProseMirror content to insert.
|
|
22
22
|
*/
|
|
23
|
-
value: Content,
|
|
23
|
+
value: Content | ProseMirrorNode | Fragment,
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Optional options
|
|
@@ -63,7 +63,7 @@ const isFragment = (nodeOrFragment: ProseMirrorNode | Fragment): nodeOrFragment
|
|
|
63
63
|
export const insertContentAt: RawCommands['insertContentAt'] = (position, value, options) => ({ tr, dispatch, editor }) => {
|
|
64
64
|
if (dispatch) {
|
|
65
65
|
options = {
|
|
66
|
-
parseOptions:
|
|
66
|
+
parseOptions: editor.options.parseOptions,
|
|
67
67
|
updateSelection: true,
|
|
68
68
|
applyInputRules: false,
|
|
69
69
|
applyPasteRules: false,
|
|
@@ -71,6 +71,7 @@ export const insertContentAt: RawCommands['insertContentAt'] = (position, value,
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
let content: Fragment | ProseMirrorNode
|
|
74
|
+
const { selection } = editor.state
|
|
74
75
|
|
|
75
76
|
try {
|
|
76
77
|
content = createNodeFromContent(value, editor.schema, {
|
|
@@ -85,7 +86,9 @@ export const insertContentAt: RawCommands['insertContentAt'] = (position, value,
|
|
|
85
86
|
editor,
|
|
86
87
|
error: e as Error,
|
|
87
88
|
disableCollaboration: () => {
|
|
88
|
-
|
|
89
|
+
if (editor.storage.collaboration) {
|
|
90
|
+
editor.storage.collaboration.isDisabled = true
|
|
91
|
+
}
|
|
89
92
|
},
|
|
90
93
|
})
|
|
91
94
|
return false
|
|
@@ -130,6 +133,16 @@ export const insertContentAt: RawCommands['insertContentAt'] = (position, value,
|
|
|
130
133
|
// otherwise if it is an array, we have to join it
|
|
131
134
|
if (Array.isArray(value)) {
|
|
132
135
|
newContent = value.map(v => v.text || '').join('')
|
|
136
|
+
} else if (value instanceof Fragment) {
|
|
137
|
+
let text = ''
|
|
138
|
+
|
|
139
|
+
value.forEach(node => {
|
|
140
|
+
if (node.text) {
|
|
141
|
+
text += node.text
|
|
142
|
+
}
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
newContent = text
|
|
133
146
|
} else if (typeof value === 'object' && !!value && !!value.text) {
|
|
134
147
|
newContent = value.text
|
|
135
148
|
} else {
|
|
@@ -140,6 +153,13 @@ export const insertContentAt: RawCommands['insertContentAt'] = (position, value,
|
|
|
140
153
|
} else {
|
|
141
154
|
newContent = content
|
|
142
155
|
|
|
156
|
+
const fromSelectionAtStart = selection.$from.parentOffset === 0
|
|
157
|
+
const isTextSelection = selection.$from.node().isText || selection.$from.node().isTextblock
|
|
158
|
+
|
|
159
|
+
if (fromSelectionAtStart && isTextSelection) {
|
|
160
|
+
from = Math.max(0, from - 1)
|
|
161
|
+
}
|
|
162
|
+
|
|
143
163
|
tr.replaceWith(from, to, newContent)
|
|
144
164
|
}
|
|
145
165
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { AllSelection } from '@tiptap/pm/state'
|
|
2
|
+
|
|
1
3
|
import { RawCommands } from '../types.js'
|
|
2
4
|
|
|
3
5
|
declare module '@tiptap/core' {
|
|
@@ -12,9 +14,12 @@ declare module '@tiptap/core' {
|
|
|
12
14
|
}
|
|
13
15
|
}
|
|
14
16
|
|
|
15
|
-
export const selectAll: RawCommands['selectAll'] = () => ({ tr,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
export const selectAll: RawCommands['selectAll'] = () => ({ tr, dispatch }) => {
|
|
18
|
+
if (dispatch) {
|
|
19
|
+
const selection = new AllSelection(tr.doc)
|
|
20
|
+
|
|
21
|
+
tr.setSelection(selection)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return true
|
|
20
25
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ParseOptions } from '@tiptap/pm/model'
|
|
1
|
+
import { Fragment, Node as ProseMirrorNode, ParseOptions } from '@tiptap/pm/model'
|
|
2
2
|
|
|
3
3
|
import { createDocument } from '../helpers/createDocument.js'
|
|
4
4
|
import { Content, RawCommands } from '../types.js'
|
|
@@ -17,7 +17,7 @@ declare module '@tiptap/core' {
|
|
|
17
17
|
/**
|
|
18
18
|
* The new content.
|
|
19
19
|
*/
|
|
20
|
-
content: Content,
|
|
20
|
+
content: Content | Fragment | ProseMirrorNode,
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Whether to emit an update event.
|
|
@@ -37,10 +37,10 @@ declare module '@tiptap/core' {
|
|
|
37
37
|
/**
|
|
38
38
|
* Whether to throw an error if the content is invalid.
|
|
39
39
|
*/
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
) => ReturnType
|
|
43
|
-
}
|
|
40
|
+
errorOnInvalidContent?: boolean;
|
|
41
|
+
}
|
|
42
|
+
) => ReturnType;
|
|
43
|
+
};
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -66,12 +66,8 @@ export const setContent: RawCommands['setContent'] = (content, emitUpdate = fals
|
|
|
66
66
|
tr.setMeta('preventUpdate', !emitUpdate)
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
return commands.insertContentAt(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
parseOptions,
|
|
74
|
-
errorOnInvalidContent: options.errorOnInvalidContent ?? editor.options.enableContentCheck,
|
|
75
|
-
},
|
|
76
|
-
)
|
|
69
|
+
return commands.insertContentAt({ from: 0, to: doc.content.size }, content, {
|
|
70
|
+
parseOptions,
|
|
71
|
+
errorOnInvalidContent: options.errorOnInvalidContent ?? editor.options.enableContentCheck,
|
|
72
|
+
})
|
|
77
73
|
}
|
package/src/commands/setMeta.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { Plugin, PluginKey } from '@tiptap/pm/state'
|
|
2
|
+
|
|
1
3
|
import { RawCommands } from '../types.js'
|
|
2
4
|
|
|
3
5
|
declare module '@tiptap/core' {
|
|
@@ -9,7 +11,7 @@ declare module '@tiptap/core' {
|
|
|
9
11
|
* @param value The value to store.
|
|
10
12
|
* @example editor.commands.setMeta('foo', 'bar')
|
|
11
13
|
*/
|
|
12
|
-
setMeta: (key: string, value: any) => ReturnType,
|
|
14
|
+
setMeta: (key: string | Plugin | PluginKey, value: any) => ReturnType,
|
|
13
15
|
}
|
|
14
16
|
}
|
|
15
17
|
}
|
package/src/commands/setNode.ts
CHANGED
|
@@ -21,6 +21,13 @@ declare module '@tiptap/core' {
|
|
|
21
21
|
export const setNode: RawCommands['setNode'] = (typeOrName, attributes = {}) => ({ state, dispatch, chain }) => {
|
|
22
22
|
const type = getNodeType(typeOrName, state.schema)
|
|
23
23
|
|
|
24
|
+
let attributesToCopy: Record<string, any> | undefined
|
|
25
|
+
|
|
26
|
+
if (state.selection.$anchor.sameParent(state.selection.$head)) {
|
|
27
|
+
// only copy attributes if the selection is pointing to a node of the same type
|
|
28
|
+
attributesToCopy = state.selection.$anchor.parent.attrs
|
|
29
|
+
}
|
|
30
|
+
|
|
24
31
|
// TODO: use a fallback like insertContent?
|
|
25
32
|
if (!type.isTextblock) {
|
|
26
33
|
console.warn('[tiptap warn]: Currently "setNode()" only supports text block nodes.')
|
|
@@ -32,7 +39,7 @@ export const setNode: RawCommands['setNode'] = (typeOrName, attributes = {}) =>
|
|
|
32
39
|
chain()
|
|
33
40
|
// try to convert node to default node if needed
|
|
34
41
|
.command(({ commands }) => {
|
|
35
|
-
const canSetBlock = setBlockType(type, attributes)(state)
|
|
42
|
+
const canSetBlock = setBlockType(type, { ...attributesToCopy, ...attributes })(state)
|
|
36
43
|
|
|
37
44
|
if (canSetBlock) {
|
|
38
45
|
return true
|
|
@@ -41,7 +48,7 @@ export const setNode: RawCommands['setNode'] = (typeOrName, attributes = {}) =>
|
|
|
41
48
|
return commands.clearNodes()
|
|
42
49
|
})
|
|
43
50
|
.command(({ state: updatedState }) => {
|
|
44
|
-
return setBlockType(type, attributes)(updatedState, dispatch)
|
|
51
|
+
return setBlockType(type, { ...attributesToCopy, ...attributes })(updatedState, dispatch)
|
|
45
52
|
})
|
|
46
53
|
.run()
|
|
47
54
|
)
|
|
@@ -14,14 +14,15 @@ declare module '@tiptap/core' {
|
|
|
14
14
|
/**
|
|
15
15
|
* Splits one list item into two list items.
|
|
16
16
|
* @param typeOrName The type or name of the node.
|
|
17
|
+
* @param overrideAttrs The attributes to ensure on the new node.
|
|
17
18
|
* @example editor.commands.splitListItem('listItem')
|
|
18
19
|
*/
|
|
19
|
-
splitListItem: (typeOrName: string | NodeType) => ReturnType
|
|
20
|
+
splitListItem: (typeOrName: string | NodeType, overrideAttrs?: Record<string, any>) => ReturnType
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
24
|
|
|
24
|
-
export const splitListItem: RawCommands['splitListItem'] = typeOrName => ({
|
|
25
|
+
export const splitListItem: RawCommands['splitListItem'] = (typeOrName, overrideAttrs = {}) => ({
|
|
25
26
|
tr, state, dispatch, editor,
|
|
26
27
|
}) => {
|
|
27
28
|
const type = getNodeType(typeOrName, state.schema)
|
|
@@ -70,11 +71,14 @@ export const splitListItem: RawCommands['splitListItem'] = typeOrName => ({
|
|
|
70
71
|
const depthAfter = $from.indexAfter(-1) < $from.node(-2).childCount ? 1 : $from.indexAfter(-2) < $from.node(-3).childCount ? 2 : 3
|
|
71
72
|
|
|
72
73
|
// Add a second list item with an empty default start node
|
|
73
|
-
const newNextTypeAttributes =
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
const newNextTypeAttributes = {
|
|
75
|
+
...getSplittedAttributes(
|
|
76
|
+
extensionAttributes,
|
|
77
|
+
$from.node().type.name,
|
|
78
|
+
$from.node().attrs,
|
|
79
|
+
),
|
|
80
|
+
...overrideAttrs,
|
|
81
|
+
}
|
|
78
82
|
const nextType = type.contentMatch.defaultType?.createAndFill(newNextTypeAttributes) || undefined
|
|
79
83
|
|
|
80
84
|
wrap = wrap.append(Fragment.from(type.createAndFill(null, nextType) || undefined))
|
|
@@ -107,16 +111,22 @@ export const splitListItem: RawCommands['splitListItem'] = typeOrName => ({
|
|
|
107
111
|
|
|
108
112
|
const nextType = $to.pos === $from.end() ? grandParent.contentMatchAt(0).defaultType : null
|
|
109
113
|
|
|
110
|
-
const newTypeAttributes =
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
114
|
+
const newTypeAttributes = {
|
|
115
|
+
...getSplittedAttributes(
|
|
116
|
+
extensionAttributes,
|
|
117
|
+
grandParent.type.name,
|
|
118
|
+
grandParent.attrs,
|
|
119
|
+
),
|
|
120
|
+
...overrideAttrs,
|
|
121
|
+
}
|
|
122
|
+
const newNextTypeAttributes = {
|
|
123
|
+
...getSplittedAttributes(
|
|
124
|
+
extensionAttributes,
|
|
125
|
+
$from.node().type.name,
|
|
126
|
+
$from.node().attrs,
|
|
127
|
+
),
|
|
128
|
+
...overrideAttrs,
|
|
129
|
+
}
|
|
120
130
|
|
|
121
131
|
tr.delete($from.pos, $to.pos)
|
|
122
132
|
|
|
@@ -28,9 +28,18 @@ export const toggleNode: RawCommands['toggleNode'] = (typeOrName, toggleTypeOrNa
|
|
|
28
28
|
const toggleType = getNodeType(toggleTypeOrName, state.schema)
|
|
29
29
|
const isActive = isNodeActive(state, type, attributes)
|
|
30
30
|
|
|
31
|
+
let attributesToCopy: Record<string, any> | undefined
|
|
32
|
+
|
|
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
|
+
}
|
|
37
|
+
|
|
31
38
|
if (isActive) {
|
|
32
|
-
return commands.setNode(toggleType)
|
|
39
|
+
return commands.setNode(toggleType, attributesToCopy)
|
|
33
40
|
}
|
|
34
41
|
|
|
35
|
-
|
|
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 })
|
|
36
45
|
}
|