@tiptap/core 2.0.0-beta.164 → 2.0.0-beta.168
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/packages/core/src/commands/selectTextblockEnd.d.ts +12 -0
- package/dist/packages/core/src/commands/selectTextblockStart.d.ts +12 -0
- package/dist/packages/core/src/extensions/commands.d.ts +4 -0
- package/dist/packages/core/src/utilities/isMacOS.d.ts +1 -0
- package/dist/tiptap-core.cjs.js +74 -16
- package/dist/tiptap-core.cjs.js.map +1 -1
- package/dist/tiptap-core.esm.js +75 -17
- package/dist/tiptap-core.esm.js.map +1 -1
- package/dist/tiptap-core.umd.js +74 -16
- package/dist/tiptap-core.umd.js.map +1 -1
- package/package.json +5 -5
- package/src/commands/blur.ts +4 -0
- package/src/commands/insertContentAt.ts +12 -1
- package/src/commands/keyboardShortcut.ts +3 -3
- package/src/commands/selectTextblockEnd.ts +19 -0
- package/src/commands/selectTextblockStart.ts +19 -0
- package/src/extensions/commands.ts +6 -0
- package/src/extensions/keymap.ts +35 -7
- package/src/helpers/injectExtensionAttributesToParseRule.ts +14 -20
- package/src/utilities/isMacOS.ts +5 -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": "2.0.0-beta.
|
|
4
|
+
"version": "2.0.0-beta.168",
|
|
5
5
|
"homepage": "https://tiptap.dev",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"tiptap",
|
|
@@ -30,14 +30,14 @@
|
|
|
30
30
|
"@types/prosemirror-schema-list": "^1.0.3",
|
|
31
31
|
"@types/prosemirror-state": "^1.2.8",
|
|
32
32
|
"@types/prosemirror-transform": "^1.1.5",
|
|
33
|
-
"@types/prosemirror-view": "^1.
|
|
34
|
-
"prosemirror-commands": "^1.1
|
|
33
|
+
"@types/prosemirror-view": "^1.23.1",
|
|
34
|
+
"prosemirror-commands": "^1.2.1",
|
|
35
35
|
"prosemirror-keymap": "^1.1.5",
|
|
36
36
|
"prosemirror-model": "^1.16.1",
|
|
37
37
|
"prosemirror-schema-list": "^1.1.6",
|
|
38
38
|
"prosemirror-state": "^1.3.4",
|
|
39
39
|
"prosemirror-transform": "^1.3.3",
|
|
40
|
-
"prosemirror-view": "^1.23.
|
|
40
|
+
"prosemirror-view": "^1.23.6"
|
|
41
41
|
},
|
|
42
42
|
"repository": {
|
|
43
43
|
"type": "git",
|
|
@@ -45,5 +45,5 @@
|
|
|
45
45
|
"directory": "packages/core"
|
|
46
46
|
},
|
|
47
47
|
"sideEffects": false,
|
|
48
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "31efb0802e77e32c8c1b65e1a8456a5d3262b0ae"
|
|
49
49
|
}
|
package/src/commands/blur.ts
CHANGED
|
@@ -15,6 +15,10 @@ export const blur: RawCommands['blur'] = () => ({ editor, view }) => {
|
|
|
15
15
|
requestAnimationFrame(() => {
|
|
16
16
|
if (!editor.isDestroyed) {
|
|
17
17
|
(view.dom as HTMLElement).blur()
|
|
18
|
+
|
|
19
|
+
// Browsers should remove the caret on blur but safari does not.
|
|
20
|
+
// See: https://github.com/ueberdosis/tiptap/issues/2405
|
|
21
|
+
window?.getSelection()?.removeAllRanges()
|
|
18
22
|
}
|
|
19
23
|
})
|
|
20
24
|
|
|
@@ -53,6 +53,7 @@ export const insertContentAt: RawCommands['insertContentAt'] = (position, value,
|
|
|
53
53
|
? { from: position, to: position }
|
|
54
54
|
: position
|
|
55
55
|
|
|
56
|
+
let isOnlyTextContent = true
|
|
56
57
|
let isOnlyBlockContent = true
|
|
57
58
|
const nodes = isFragment(content)
|
|
58
59
|
? content
|
|
@@ -62,6 +63,10 @@ export const insertContentAt: RawCommands['insertContentAt'] = (position, value,
|
|
|
62
63
|
// check if added node is valid
|
|
63
64
|
node.check()
|
|
64
65
|
|
|
66
|
+
isOnlyTextContent = isOnlyTextContent
|
|
67
|
+
? node.isText && node.marks.length === 0
|
|
68
|
+
: false
|
|
69
|
+
|
|
65
70
|
isOnlyBlockContent = isOnlyBlockContent
|
|
66
71
|
? node.isBlock
|
|
67
72
|
: false
|
|
@@ -84,7 +89,13 @@ export const insertContentAt: RawCommands['insertContentAt'] = (position, value,
|
|
|
84
89
|
}
|
|
85
90
|
}
|
|
86
91
|
|
|
87
|
-
|
|
92
|
+
// if there is only plain text we have to use `insertText`
|
|
93
|
+
// because this will keep the current marks
|
|
94
|
+
if (isOnlyTextContent) {
|
|
95
|
+
tr.insertText(value as string, from, to)
|
|
96
|
+
} else {
|
|
97
|
+
tr.replaceWith(from, to, content)
|
|
98
|
+
}
|
|
88
99
|
|
|
89
100
|
// set cursor at end of inserted content
|
|
90
101
|
if (options.updateSelection) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RawCommands } from '../types'
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import { isiOS } from '../utilities/isiOS'
|
|
3
|
+
import { isMacOS } from '../utilities/isMacOS'
|
|
4
4
|
|
|
5
5
|
function normalizeKeyName(name: string) {
|
|
6
6
|
const parts = name.split(/-(?!$)/)
|
|
@@ -27,7 +27,7 @@ function normalizeKeyName(name: string) {
|
|
|
27
27
|
} else if (/^s(hift)?$/i.test(mod)) {
|
|
28
28
|
shift = true
|
|
29
29
|
} else if (/^mod$/i.test(mod)) {
|
|
30
|
-
if (
|
|
30
|
+
if (isiOS() || isMacOS()) {
|
|
31
31
|
meta = true
|
|
32
32
|
} else {
|
|
33
33
|
ctrl = true
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// @ts-ignore
|
|
2
|
+
// TODO: add types to @types/prosemirror-commands
|
|
3
|
+
import { selectTextblockEnd as originalSelectTextblockEnd } from 'prosemirror-commands'
|
|
4
|
+
import { RawCommands } from '../types'
|
|
5
|
+
|
|
6
|
+
declare module '@tiptap/core' {
|
|
7
|
+
interface Commands<ReturnType> {
|
|
8
|
+
selectTextblockEnd: {
|
|
9
|
+
/**
|
|
10
|
+
* Moves the cursor to the end of current text block.
|
|
11
|
+
*/
|
|
12
|
+
selectTextblockEnd: () => ReturnType,
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const selectTextblockEnd: RawCommands['selectTextblockEnd'] = () => ({ state, dispatch }) => {
|
|
18
|
+
return originalSelectTextblockEnd(state, dispatch)
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// @ts-ignore
|
|
2
|
+
// TODO: add types to @types/prosemirror-commands
|
|
3
|
+
import { selectTextblockStart as originalSelectTextblockStart } from 'prosemirror-commands'
|
|
4
|
+
import { RawCommands } from '../types'
|
|
5
|
+
|
|
6
|
+
declare module '@tiptap/core' {
|
|
7
|
+
interface Commands<ReturnType> {
|
|
8
|
+
selectTextblockStart: {
|
|
9
|
+
/**
|
|
10
|
+
* Moves the cursor to the start of current text block.
|
|
11
|
+
*/
|
|
12
|
+
selectTextblockStart: () => ReturnType,
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const selectTextblockStart: RawCommands['selectTextblockStart'] = () => ({ state, dispatch }) => {
|
|
18
|
+
return originalSelectTextblockStart(state, dispatch)
|
|
19
|
+
}
|
|
@@ -28,6 +28,8 @@ import * as selectAll from '../commands/selectAll'
|
|
|
28
28
|
import * as selectNodeBackward from '../commands/selectNodeBackward'
|
|
29
29
|
import * as selectNodeForward from '../commands/selectNodeForward'
|
|
30
30
|
import * as selectParentNode from '../commands/selectParentNode'
|
|
31
|
+
import * as selectTextblockEnd from '../commands/selectTextblockEnd'
|
|
32
|
+
import * as selectTextblockStart from '../commands/selectTextblockStart'
|
|
31
33
|
import * as setContent from '../commands/setContent'
|
|
32
34
|
import * as setMark from '../commands/setMark'
|
|
33
35
|
import * as setMeta from '../commands/setMeta'
|
|
@@ -77,6 +79,8 @@ export { selectAll }
|
|
|
77
79
|
export { selectNodeBackward }
|
|
78
80
|
export { selectNodeForward }
|
|
79
81
|
export { selectParentNode }
|
|
82
|
+
export { selectTextblockEnd }
|
|
83
|
+
export { selectTextblockStart }
|
|
80
84
|
export { setContent }
|
|
81
85
|
export { setMark }
|
|
82
86
|
export { setMeta }
|
|
@@ -131,6 +135,8 @@ export const Commands = Extension.create({
|
|
|
131
135
|
...selectNodeBackward,
|
|
132
136
|
...selectNodeForward,
|
|
133
137
|
...selectParentNode,
|
|
138
|
+
...selectTextblockEnd,
|
|
139
|
+
...selectTextblockStart,
|
|
134
140
|
...setContent,
|
|
135
141
|
...setMark,
|
|
136
142
|
...setMeta,
|
package/src/extensions/keymap.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Plugin, PluginKey, Selection } from 'prosemirror-state'
|
|
2
2
|
import { createChainableState } from '../helpers/createChainableState'
|
|
3
|
+
import { isiOS } from '../utilities/isiOS'
|
|
4
|
+
import { isMacOS } from '../utilities/isMacOS'
|
|
3
5
|
import { CommandManager } from '../CommandManager'
|
|
4
6
|
import { Extension } from '../Extension'
|
|
5
7
|
|
|
@@ -38,13 +40,15 @@ export const Keymap = Extension.create({
|
|
|
38
40
|
() => commands.selectNodeForward(),
|
|
39
41
|
])
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
const handleEnter = () => this.editor.commands.first(({ commands }) => [
|
|
44
|
+
() => commands.newlineInCode(),
|
|
45
|
+
() => commands.createParagraphNear(),
|
|
46
|
+
() => commands.liftEmptyBlock(),
|
|
47
|
+
() => commands.splitBlock(),
|
|
48
|
+
])
|
|
49
|
+
|
|
50
|
+
const baseKeymap = {
|
|
51
|
+
Enter: handleEnter,
|
|
48
52
|
'Mod-Enter': () => this.editor.commands.exitCode(),
|
|
49
53
|
Backspace: handleBackspace,
|
|
50
54
|
'Mod-Backspace': handleBackspace,
|
|
@@ -53,6 +57,30 @@ export const Keymap = Extension.create({
|
|
|
53
57
|
'Mod-Delete': handleDelete,
|
|
54
58
|
'Mod-a': () => this.editor.commands.selectAll(),
|
|
55
59
|
}
|
|
60
|
+
|
|
61
|
+
const pcKeymap = {
|
|
62
|
+
...baseKeymap,
|
|
63
|
+
Home: () => this.editor.commands.selectTextblockStart(),
|
|
64
|
+
End: () => this.editor.commands.selectTextblockStart(),
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const macKeymap = {
|
|
68
|
+
...baseKeymap,
|
|
69
|
+
'Ctrl-h': handleBackspace,
|
|
70
|
+
'Alt-Backspace': handleBackspace,
|
|
71
|
+
'Ctrl-d': handleDelete,
|
|
72
|
+
'Ctrl-Alt-Backspace': handleDelete,
|
|
73
|
+
'Alt-Delete': handleDelete,
|
|
74
|
+
'Alt-d': handleDelete,
|
|
75
|
+
'Ctrl-a': () => this.editor.commands.selectTextblockStart(),
|
|
76
|
+
'Ctrl-e': () => this.editor.commands.selectTextblockEnd(),
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (isiOS() || isMacOS()) {
|
|
80
|
+
return macKeymap
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return pcKeymap
|
|
56
84
|
},
|
|
57
85
|
|
|
58
86
|
addProseMirrorPlugins() {
|
|
@@ -25,26 +25,20 @@ export function injectExtensionAttributesToParseRule(parseRule: ParseRule, exten
|
|
|
25
25
|
return false
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
const newAttributes = extensionAttributes
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
...items,
|
|
45
|
-
[item.name]: value,
|
|
46
|
-
}
|
|
47
|
-
}, {})
|
|
28
|
+
const newAttributes = extensionAttributes.reduce((items, item) => {
|
|
29
|
+
const value = item.attribute.parseHTML
|
|
30
|
+
? item.attribute.parseHTML(node as HTMLElement)
|
|
31
|
+
: fromString((node as HTMLElement).getAttribute(item.name))
|
|
32
|
+
|
|
33
|
+
if (value === null || value === undefined) {
|
|
34
|
+
return items
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
...items,
|
|
39
|
+
[item.name]: value,
|
|
40
|
+
}
|
|
41
|
+
}, {})
|
|
48
42
|
|
|
49
43
|
return { ...oldAttributes, ...newAttributes }
|
|
50
44
|
},
|