@portabletext/editor 1.52.7 → 1.53.0
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/lib/index.cjs +122 -76
- package/lib/index.cjs.map +1 -1
- package/lib/index.js +122 -76
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/behaviors/behavior.abstract.keyboard.ts +10 -0
- package/src/behaviors/behavior.abstract.split.ts +105 -87
- package/src/behaviors/behavior.core.insert-break.ts +14 -0
- package/src/behaviors/behavior.core.ts +1 -0
- package/src/editor/components/render-text-block.tsx +1 -1
- package/src/internal-utils/key-is.ts +1 -0
package/package.json
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import {keyIs} from '../internal-utils/key-is'
|
|
2
|
+
import * as selectors from '../selectors'
|
|
2
3
|
import {raise} from './behavior.types.action'
|
|
3
4
|
import {defineBehavior} from './behavior.types.behavior'
|
|
4
5
|
|
|
5
6
|
export const abstractKeyboardBehaviors = [
|
|
7
|
+
defineBehavior({
|
|
8
|
+
on: 'keyboard.keydown',
|
|
9
|
+
guard: ({snapshot, event}) =>
|
|
10
|
+
keyIs.break(event.originEvent) &&
|
|
11
|
+
selectors.isSelectionCollapsed(snapshot) &&
|
|
12
|
+
selectors.getFocusInlineObject(snapshot),
|
|
13
|
+
actions: [() => [raise({type: 'insert.break'})]],
|
|
14
|
+
}),
|
|
15
|
+
|
|
6
16
|
/**
|
|
7
17
|
* On WebKit, Shift+Enter results in an `insertParagraph` input event rather
|
|
8
18
|
* than an `insertLineBreak` input event. This Behavior makes sure we catch
|
|
@@ -1,111 +1,132 @@
|
|
|
1
1
|
import {isTextBlock, parseBlock} from '../internal-utils/parse-blocks'
|
|
2
2
|
import * as selectors from '../selectors'
|
|
3
|
-
import
|
|
4
|
-
import {getBlockEndPoint} from '../utils/util.get-block-end-point'
|
|
5
|
-
import {getSelectionEndPoint} from '../utils/util.get-selection-end-point'
|
|
6
|
-
import {sliceBlocks} from '../utils/util.slice-blocks'
|
|
3
|
+
import * as utils from '../utils'
|
|
7
4
|
import {raise} from './behavior.types.action'
|
|
8
5
|
import {defineBehavior} from './behavior.types.behavior'
|
|
9
6
|
|
|
10
7
|
export const abstractSplitBehaviors = [
|
|
8
|
+
/**
|
|
9
|
+
* You can't split an inline object.
|
|
10
|
+
*/
|
|
11
|
+
defineBehavior({
|
|
12
|
+
on: 'split',
|
|
13
|
+
guard: ({snapshot}) =>
|
|
14
|
+
selectors.isSelectionCollapsed(snapshot) &&
|
|
15
|
+
selectors.getFocusInlineObject(snapshot),
|
|
16
|
+
actions: [],
|
|
17
|
+
}),
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* You can't split a block object.
|
|
21
|
+
*/
|
|
22
|
+
defineBehavior({
|
|
23
|
+
on: 'split',
|
|
24
|
+
guard: ({snapshot}) =>
|
|
25
|
+
selectors.isSelectionCollapsed(snapshot) &&
|
|
26
|
+
selectors.getFocusBlockObject(snapshot),
|
|
27
|
+
actions: [],
|
|
28
|
+
}),
|
|
29
|
+
|
|
30
|
+
defineBehavior({
|
|
31
|
+
on: 'split',
|
|
32
|
+
guard: ({snapshot}) => {
|
|
33
|
+
const selection = snapshot.context.selection
|
|
34
|
+
|
|
35
|
+
if (!selection || utils.isSelectionCollapsed(selection)) {
|
|
36
|
+
return false
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const selectionStartBlock = selectors.getSelectionStartBlock(snapshot)
|
|
40
|
+
const selectionEndBlock = selectors.getSelectionEndBlock(snapshot)
|
|
41
|
+
|
|
42
|
+
if (!selectionStartBlock || !selectionEndBlock) {
|
|
43
|
+
return false
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (
|
|
47
|
+
!isTextBlock(snapshot.context, selectionStartBlock.node) &&
|
|
48
|
+
isTextBlock(snapshot.context, selectionEndBlock.node)
|
|
49
|
+
) {
|
|
50
|
+
return {selection}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return false
|
|
54
|
+
},
|
|
55
|
+
actions: [(_, {selection}) => [raise({type: 'delete', at: selection})]],
|
|
56
|
+
}),
|
|
57
|
+
|
|
58
|
+
defineBehavior({
|
|
59
|
+
on: 'split',
|
|
60
|
+
guard: ({snapshot}) => {
|
|
61
|
+
const selection = snapshot.context.selection
|
|
62
|
+
|
|
63
|
+
if (!selection || utils.isSelectionCollapsed(selection)) {
|
|
64
|
+
return false
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return {selection}
|
|
68
|
+
},
|
|
69
|
+
actions: [
|
|
70
|
+
(_, {selection}) => [
|
|
71
|
+
raise({type: 'delete', at: selection}),
|
|
72
|
+
raise({type: 'split'}),
|
|
73
|
+
],
|
|
74
|
+
],
|
|
75
|
+
}),
|
|
76
|
+
|
|
11
77
|
defineBehavior({
|
|
12
78
|
on: 'split',
|
|
13
79
|
guard: ({snapshot}) => {
|
|
14
|
-
|
|
80
|
+
const selection = snapshot.context.selection
|
|
81
|
+
|
|
82
|
+
if (!selection || !utils.isSelectionCollapsed(selection)) {
|
|
83
|
+
return false
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const selectionStartPoint = utils.getSelectionStartPoint(selection)
|
|
87
|
+
|
|
88
|
+
const focusTextBlock = selectors.getFocusTextBlock(snapshot)
|
|
89
|
+
|
|
90
|
+
if (!focusTextBlock) {
|
|
15
91
|
return false
|
|
16
92
|
}
|
|
17
93
|
|
|
18
|
-
const
|
|
19
|
-
snapshot.context
|
|
20
|
-
|
|
21
|
-
const selectionEndPoint = getSelectionEndPoint(snapshot.context.selection)
|
|
22
|
-
|
|
23
|
-
const focusTextBlock = selectors.getFocusTextBlock({
|
|
24
|
-
...snapshot,
|
|
25
|
-
context: {
|
|
26
|
-
...snapshot.context,
|
|
27
|
-
selection: {
|
|
28
|
-
anchor: selectionStartPoint,
|
|
29
|
-
focus: selectionEndPoint,
|
|
30
|
-
},
|
|
31
|
-
},
|
|
94
|
+
const blockEndPoint = utils.getBlockEndPoint({
|
|
95
|
+
context: snapshot.context,
|
|
96
|
+
block: focusTextBlock,
|
|
32
97
|
})
|
|
33
98
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
const newTextBlock = parseBlock({
|
|
44
|
-
block: sliceBlocks({
|
|
99
|
+
const newTextBlockSelection = {
|
|
100
|
+
anchor: selectionStartPoint,
|
|
101
|
+
focus: blockEndPoint,
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const newTextBlock = parseBlock({
|
|
105
|
+
block: utils
|
|
106
|
+
.sliceBlocks({
|
|
45
107
|
context: {
|
|
46
108
|
...snapshot.context,
|
|
47
109
|
selection: newTextBlockSelection,
|
|
48
110
|
},
|
|
49
111
|
blocks: [focusTextBlock.node],
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (!newTextBlock || !isTextBlock(snapshot.context, newTextBlock)) {
|
|
56
|
-
return false
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return {
|
|
60
|
-
newTextBlock,
|
|
61
|
-
newTextBlockSelection,
|
|
62
|
-
selection: {
|
|
63
|
-
anchor: selectionStartPoint,
|
|
64
|
-
focus: blockEndPoint,
|
|
65
|
-
},
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const focusBlockObject = selectors.getFocusBlockObject({
|
|
70
|
-
...snapshot,
|
|
71
|
-
context: {
|
|
72
|
-
...snapshot.context,
|
|
73
|
-
selection: {
|
|
74
|
-
anchor: selectionStartPoint,
|
|
75
|
-
focus: selectionEndPoint,
|
|
76
|
-
},
|
|
77
|
-
},
|
|
112
|
+
})
|
|
113
|
+
.at(0),
|
|
114
|
+
context: snapshot.context,
|
|
115
|
+
options: {refreshKeys: true, validateFields: true},
|
|
78
116
|
})
|
|
79
117
|
|
|
80
|
-
if (
|
|
81
|
-
|
|
82
|
-
block: {
|
|
83
|
-
_type: snapshot.context.schema.block.name,
|
|
84
|
-
children: [],
|
|
85
|
-
},
|
|
86
|
-
context: snapshot.context,
|
|
87
|
-
options: {refreshKeys: true, validateFields: true},
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
if (!newTextBlock) {
|
|
91
|
-
return false
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return {
|
|
95
|
-
newTextBlock,
|
|
96
|
-
newTextBlockSelection: {
|
|
97
|
-
anchor: selectionEndPoint,
|
|
98
|
-
focus: selectionEndPoint,
|
|
99
|
-
},
|
|
100
|
-
selection: snapshot.context.selection,
|
|
101
|
-
}
|
|
118
|
+
if (!newTextBlock) {
|
|
119
|
+
return false
|
|
102
120
|
}
|
|
103
121
|
|
|
104
|
-
return
|
|
122
|
+
return {
|
|
123
|
+
newTextBlock,
|
|
124
|
+
newTextBlockSelection,
|
|
125
|
+
}
|
|
105
126
|
},
|
|
106
127
|
actions: [
|
|
107
|
-
(_, {newTextBlock,
|
|
108
|
-
isSelectionCollapsed(
|
|
128
|
+
(_, {newTextBlock, newTextBlockSelection}) =>
|
|
129
|
+
utils.isSelectionCollapsed(newTextBlockSelection)
|
|
109
130
|
? [
|
|
110
131
|
raise({
|
|
111
132
|
type: 'insert.block',
|
|
@@ -115,10 +136,7 @@ export const abstractSplitBehaviors = [
|
|
|
115
136
|
}),
|
|
116
137
|
]
|
|
117
138
|
: [
|
|
118
|
-
raise({
|
|
119
|
-
type: 'delete',
|
|
120
|
-
at: selection,
|
|
121
|
-
}),
|
|
139
|
+
raise({type: 'delete', at: newTextBlockSelection}),
|
|
122
140
|
raise({
|
|
123
141
|
type: 'insert.block',
|
|
124
142
|
block: newTextBlock,
|
|
@@ -235,9 +235,23 @@ const breakingEntireBlocks = defineBehavior({
|
|
|
235
235
|
],
|
|
236
236
|
})
|
|
237
237
|
|
|
238
|
+
const breakingInlineObject = defineBehavior({
|
|
239
|
+
on: 'insert.break',
|
|
240
|
+
guard: ({snapshot}) => {
|
|
241
|
+
const selectionCollapsed = selectors.isSelectionCollapsed(snapshot)
|
|
242
|
+
const focusInlineObject = selectors.getFocusInlineObject(snapshot)
|
|
243
|
+
|
|
244
|
+
return selectionCollapsed && focusInlineObject
|
|
245
|
+
},
|
|
246
|
+
actions: [
|
|
247
|
+
() => [raise({type: 'move.forward', distance: 1}), raise({type: 'split'})],
|
|
248
|
+
],
|
|
249
|
+
})
|
|
250
|
+
|
|
238
251
|
export const coreInsertBreakBehaviors = {
|
|
239
252
|
breakingAtTheEndOfTextBlock,
|
|
240
253
|
breakingAtTheStartOfTextBlock,
|
|
241
254
|
breakingEntireDocument,
|
|
242
255
|
breakingEntireBlocks,
|
|
256
|
+
breakingInlineObject,
|
|
243
257
|
}
|
|
@@ -29,6 +29,7 @@ export const coreBehaviorsConfig = [
|
|
|
29
29
|
coreInsertBreakBehaviors.breakingAtTheStartOfTextBlock,
|
|
30
30
|
coreInsertBreakBehaviors.breakingEntireDocument,
|
|
31
31
|
coreInsertBreakBehaviors.breakingEntireBlocks,
|
|
32
|
+
coreInsertBreakBehaviors.breakingInlineObject,
|
|
32
33
|
].map((behavior) => ({
|
|
33
34
|
behavior,
|
|
34
35
|
priority: corePriority,
|