@tiptap/core 3.4.4 → 3.4.6
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 +25 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +25 -13
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/Editor.ts +4 -0
- package/src/ExtensionManager.ts +58 -60
- package/src/InputRule.ts +12 -6
- package/src/inputRules/markInputRule.ts +2 -0
- package/src/inputRules/nodeInputRule.ts +7 -0
- package/src/inputRules/textInputRule.ts +2 -1
- package/src/inputRules/textblockTypeInputRule.ts +2 -0
- package/src/inputRules/wrappingInputRule.ts +2 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiptap/core",
|
|
3
3
|
"description": "headless rich text editor",
|
|
4
|
-
"version": "3.4.
|
|
4
|
+
"version": "3.4.6",
|
|
5
5
|
"homepage": "https://tiptap.dev",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"tiptap",
|
|
@@ -52,10 +52,10 @@
|
|
|
52
52
|
"jsx-dev-runtime"
|
|
53
53
|
],
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@tiptap/pm": "^3.4.
|
|
55
|
+
"@tiptap/pm": "^3.4.6"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
|
-
"@tiptap/pm": "^3.4.
|
|
58
|
+
"@tiptap/pm": "^3.4.6"
|
|
59
59
|
},
|
|
60
60
|
"repository": {
|
|
61
61
|
"type": "git",
|
package/src/Editor.ts
CHANGED
|
@@ -160,6 +160,10 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|
|
160
160
|
this.createView(el)
|
|
161
161
|
this.emit('mount', { editor: this })
|
|
162
162
|
|
|
163
|
+
if (this.css && !document.head.contains(this.css)) {
|
|
164
|
+
document.head.appendChild(this.css)
|
|
165
|
+
}
|
|
166
|
+
|
|
163
167
|
window.setTimeout(() => {
|
|
164
168
|
if (this.isDestroyed) {
|
|
165
169
|
return
|
package/src/ExtensionManager.ts
CHANGED
|
@@ -87,89 +87,87 @@ export class ExtensionManager {
|
|
|
87
87
|
// based on the `priority` option.
|
|
88
88
|
const extensions = sortExtensions([...this.extensions].reverse())
|
|
89
89
|
|
|
90
|
-
const allPlugins = extensions
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
90
|
+
const allPlugins = extensions.flatMap(extension => {
|
|
91
|
+
const context = {
|
|
92
|
+
name: extension.name,
|
|
93
|
+
options: extension.options,
|
|
94
|
+
storage: this.editor.extensionStorage[extension.name as keyof Storage],
|
|
95
|
+
editor,
|
|
96
|
+
type: getSchemaTypeByName(extension.name, this.schema),
|
|
97
|
+
}
|
|
99
98
|
|
|
100
|
-
|
|
99
|
+
const plugins: Plugin[] = []
|
|
101
100
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
101
|
+
const addKeyboardShortcuts = getExtensionField<AnyConfig['addKeyboardShortcuts']>(
|
|
102
|
+
extension,
|
|
103
|
+
'addKeyboardShortcuts',
|
|
104
|
+
context,
|
|
105
|
+
)
|
|
107
106
|
|
|
108
|
-
|
|
107
|
+
let defaultBindings: Record<string, () => boolean> = {}
|
|
109
108
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
109
|
+
// bind exit handling
|
|
110
|
+
if (extension.type === 'mark' && getExtensionField<MarkConfig['exitable']>(extension, 'exitable', context)) {
|
|
111
|
+
defaultBindings.ArrowRight = () => Mark.handleExit({ editor, mark: extension as Mark })
|
|
112
|
+
}
|
|
114
113
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
114
|
+
if (addKeyboardShortcuts) {
|
|
115
|
+
const bindings = Object.fromEntries(
|
|
116
|
+
Object.entries(addKeyboardShortcuts()).map(([shortcut, method]) => {
|
|
117
|
+
return [shortcut, () => method({ editor })]
|
|
118
|
+
}),
|
|
119
|
+
)
|
|
121
120
|
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
defaultBindings = { ...defaultBindings, ...bindings }
|
|
122
|
+
}
|
|
124
123
|
|
|
125
|
-
|
|
124
|
+
const keyMapPlugin = keymap(defaultBindings)
|
|
126
125
|
|
|
127
|
-
|
|
126
|
+
plugins.push(keyMapPlugin)
|
|
128
127
|
|
|
129
|
-
|
|
128
|
+
const addInputRules = getExtensionField<AnyConfig['addInputRules']>(extension, 'addInputRules', context)
|
|
130
129
|
|
|
131
|
-
|
|
132
|
-
|
|
130
|
+
if (isExtensionRulesEnabled(extension, editor.options.enableInputRules) && addInputRules) {
|
|
131
|
+
const rules = addInputRules()
|
|
133
132
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
133
|
+
if (rules && rules.length) {
|
|
134
|
+
const inputResult = inputRulesPlugin({
|
|
135
|
+
editor,
|
|
136
|
+
rules,
|
|
137
|
+
})
|
|
139
138
|
|
|
140
|
-
|
|
139
|
+
const inputPlugins = Array.isArray(inputResult) ? inputResult : [inputResult]
|
|
141
140
|
|
|
142
|
-
|
|
143
|
-
}
|
|
141
|
+
plugins.push(...inputPlugins)
|
|
144
142
|
}
|
|
143
|
+
}
|
|
145
144
|
|
|
146
|
-
|
|
145
|
+
const addPasteRules = getExtensionField<AnyConfig['addPasteRules']>(extension, 'addPasteRules', context)
|
|
147
146
|
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
if (isExtensionRulesEnabled(extension, editor.options.enablePasteRules) && addPasteRules) {
|
|
148
|
+
const rules = addPasteRules()
|
|
150
149
|
|
|
151
|
-
|
|
152
|
-
|
|
150
|
+
if (rules && rules.length) {
|
|
151
|
+
const pasteRules = pasteRulesPlugin({ editor, rules })
|
|
153
152
|
|
|
154
|
-
|
|
155
|
-
}
|
|
153
|
+
plugins.push(...pasteRules)
|
|
156
154
|
}
|
|
155
|
+
}
|
|
157
156
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
157
|
+
const addProseMirrorPlugins = getExtensionField<AnyConfig['addProseMirrorPlugins']>(
|
|
158
|
+
extension,
|
|
159
|
+
'addProseMirrorPlugins',
|
|
160
|
+
context,
|
|
161
|
+
)
|
|
163
162
|
|
|
164
|
-
|
|
165
|
-
|
|
163
|
+
if (addProseMirrorPlugins) {
|
|
164
|
+
const proseMirrorPlugins = addProseMirrorPlugins()
|
|
166
165
|
|
|
167
|
-
|
|
168
|
-
|
|
166
|
+
plugins.push(...proseMirrorPlugins)
|
|
167
|
+
}
|
|
169
168
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
.flat()
|
|
169
|
+
return plugins
|
|
170
|
+
})
|
|
173
171
|
|
|
174
172
|
return allPlugins
|
|
175
173
|
}
|
package/src/InputRule.ts
CHANGED
|
@@ -33,6 +33,8 @@ export class InputRule {
|
|
|
33
33
|
can: () => CanCommands
|
|
34
34
|
}) => void | null
|
|
35
35
|
|
|
36
|
+
undoable: boolean
|
|
37
|
+
|
|
36
38
|
constructor(config: {
|
|
37
39
|
find: InputRuleFinder
|
|
38
40
|
handler: (props: {
|
|
@@ -43,9 +45,11 @@ export class InputRule {
|
|
|
43
45
|
chain: () => ChainedCommands
|
|
44
46
|
can: () => CanCommands
|
|
45
47
|
}) => void | null
|
|
48
|
+
undoable?: boolean
|
|
46
49
|
}) {
|
|
47
50
|
this.find = config.find
|
|
48
51
|
this.handler = config.handler
|
|
52
|
+
this.undoable = config.undoable ?? true
|
|
49
53
|
}
|
|
50
54
|
}
|
|
51
55
|
|
|
@@ -149,12 +153,14 @@ function run(config: {
|
|
|
149
153
|
|
|
150
154
|
// store transform as meta data
|
|
151
155
|
// so we can undo input rules within the `undoInputRules` command
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
156
|
+
if (rule.undoable) {
|
|
157
|
+
tr.setMeta(plugin, {
|
|
158
|
+
transform: tr,
|
|
159
|
+
from,
|
|
160
|
+
to,
|
|
161
|
+
text,
|
|
162
|
+
})
|
|
163
|
+
}
|
|
158
164
|
|
|
159
165
|
view.dispatch(tr)
|
|
160
166
|
matched = true
|
|
@@ -14,6 +14,7 @@ import { callOrReturn } from '../utilities/callOrReturn.js'
|
|
|
14
14
|
export function markInputRule(config: {
|
|
15
15
|
find: InputRuleFinder
|
|
16
16
|
type: MarkType
|
|
17
|
+
undoable?: boolean
|
|
17
18
|
getAttributes?: Record<string, any> | ((match: ExtendedRegExpMatchArray) => Record<string, any>) | false | null
|
|
18
19
|
}) {
|
|
19
20
|
return new InputRule({
|
|
@@ -62,5 +63,6 @@ export function markInputRule(config: {
|
|
|
62
63
|
tr.removeStoredMark(config.type)
|
|
63
64
|
}
|
|
64
65
|
},
|
|
66
|
+
undoable: config.undoable,
|
|
65
67
|
})
|
|
66
68
|
}
|
|
@@ -21,6 +21,12 @@ export function nodeInputRule(config: {
|
|
|
21
21
|
*/
|
|
22
22
|
type: NodeType
|
|
23
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Whether the input rule should be undoable
|
|
26
|
+
* when the user presses backspace.
|
|
27
|
+
*/
|
|
28
|
+
undoable?: boolean
|
|
29
|
+
|
|
24
30
|
/**
|
|
25
31
|
* A function that returns the attributes for the node
|
|
26
32
|
* can also be an object of attributes
|
|
@@ -62,5 +68,6 @@ export function nodeInputRule(config: {
|
|
|
62
68
|
|
|
63
69
|
tr.scrollIntoView()
|
|
64
70
|
},
|
|
71
|
+
undoable: config.undoable,
|
|
65
72
|
})
|
|
66
73
|
}
|
|
@@ -6,7 +6,7 @@ import { InputRule } from '../InputRule.js'
|
|
|
6
6
|
* matched text is typed into it.
|
|
7
7
|
* @see https://tiptap.dev/docs/editor/extensions/custom-extensions/extend-existing#input-rules
|
|
8
8
|
*/
|
|
9
|
-
export function textInputRule(config: { find: InputRuleFinder; replace: string }) {
|
|
9
|
+
export function textInputRule(config: { find: InputRuleFinder; replace: string; undoable?: boolean }) {
|
|
10
10
|
return new InputRule({
|
|
11
11
|
find: config.find,
|
|
12
12
|
handler: ({ state, range, match }) => {
|
|
@@ -30,5 +30,6 @@ export function textInputRule(config: { find: InputRuleFinder; replace: string }
|
|
|
30
30
|
|
|
31
31
|
state.tr.insertText(insert, start, end)
|
|
32
32
|
},
|
|
33
|
+
undoable: config.undoable,
|
|
33
34
|
})
|
|
34
35
|
}
|
|
@@ -15,6 +15,7 @@ import { callOrReturn } from '../utilities/callOrReturn.js'
|
|
|
15
15
|
export function textblockTypeInputRule(config: {
|
|
16
16
|
find: InputRuleFinder
|
|
17
17
|
type: NodeType
|
|
18
|
+
undoable?: boolean
|
|
18
19
|
getAttributes?: Record<string, any> | ((match: ExtendedRegExpMatchArray) => Record<string, any>) | false | null
|
|
19
20
|
}) {
|
|
20
21
|
return new InputRule({
|
|
@@ -29,5 +30,6 @@ export function textblockTypeInputRule(config: {
|
|
|
29
30
|
|
|
30
31
|
state.tr.delete(range.from, range.to).setBlockType(range.from, range.from, config.type, attributes)
|
|
31
32
|
},
|
|
33
|
+
undoable: config.undoable,
|
|
32
34
|
})
|
|
33
35
|
}
|
|
@@ -28,6 +28,7 @@ export function wrappingInputRule(config: {
|
|
|
28
28
|
keepMarks?: boolean
|
|
29
29
|
keepAttributes?: boolean
|
|
30
30
|
editor?: Editor
|
|
31
|
+
undoable?: boolean
|
|
31
32
|
getAttributes?: Record<string, any> | ((match: ExtendedRegExpMatchArray) => Record<string, any>) | false | null
|
|
32
33
|
joinPredicate?: (match: ExtendedRegExpMatchArray, node: ProseMirrorNode) => boolean
|
|
33
34
|
}) {
|
|
@@ -76,5 +77,6 @@ export function wrappingInputRule(config: {
|
|
|
76
77
|
tr.join(range.from - 1)
|
|
77
78
|
}
|
|
78
79
|
},
|
|
80
|
+
undoable: config.undoable,
|
|
79
81
|
})
|
|
80
82
|
}
|