@portabletext/editor 1.35.2 → 1.35.4
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/_chunks-cjs/editor-provider.cjs +186 -71
- package/lib/_chunks-cjs/editor-provider.cjs.map +1 -1
- package/lib/_chunks-es/editor-provider.js +187 -72
- package/lib/_chunks-es/editor-provider.js.map +1 -1
- package/lib/behaviors/index.d.cts +117 -72
- package/lib/behaviors/index.d.ts +117 -72
- package/lib/index.d.cts +117 -72
- package/lib/index.d.ts +117 -72
- package/lib/plugins/index.cjs +42 -31
- package/lib/plugins/index.cjs.map +1 -1
- package/lib/plugins/index.d.cts +117 -72
- package/lib/plugins/index.d.ts +117 -72
- package/lib/plugins/index.js +42 -31
- package/lib/plugins/index.js.map +1 -1
- package/lib/selectors/index.d.cts +117 -72
- package/lib/selectors/index.d.ts +117 -72
- package/lib/utils/index.d.cts +117 -72
- package/lib/utils/index.d.ts +117 -72
- package/package.json +4 -4
- package/src/editor/__tests__/self-solving.test.tsx +33 -1
- package/src/editor/components/Synchronizer.tsx +17 -3
- package/src/editor/editor-machine.ts +27 -14
- package/src/editor/mutation-machine.ts +160 -46
- package/src/editor/plugins/create-with-event-listeners.ts +1 -0
- package/src/editor/plugins/createWithPatches.ts +10 -3
- package/src/editor/with-applying-behavior-actions.ts +8 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@portabletext/editor",
|
|
3
|
-
"version": "1.35.
|
|
3
|
+
"version": "1.35.4",
|
|
4
4
|
"description": "Portable Text Editor made in React",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"get-random-values-esm": "^1.0.2",
|
|
74
74
|
"lodash": "^4.17.21",
|
|
75
75
|
"lodash.startcase": "^4.4.0",
|
|
76
|
-
"react-compiler-runtime": "19.0.0-beta-
|
|
76
|
+
"react-compiler-runtime": "19.0.0-beta-e1e972c-20250221",
|
|
77
77
|
"slate": "0.112.0",
|
|
78
78
|
"slate-dom": "^0.112.2",
|
|
79
79
|
"slate-react": "0.112.1",
|
|
@@ -100,9 +100,9 @@
|
|
|
100
100
|
"@vitejs/plugin-react": "^4.3.4",
|
|
101
101
|
"@vitest/browser": "^3.0.5",
|
|
102
102
|
"@vitest/coverage-istanbul": "^3.0.5",
|
|
103
|
-
"babel-plugin-react-compiler": "19.0.0-beta-
|
|
103
|
+
"babel-plugin-react-compiler": "19.0.0-beta-e1e972c-20250221",
|
|
104
104
|
"eslint": "8.57.1",
|
|
105
|
-
"eslint-plugin-react-compiler": "19.0.0-beta-
|
|
105
|
+
"eslint-plugin-react-compiler": "19.0.0-beta-e1e972c-20250221",
|
|
106
106
|
"eslint-plugin-react-hooks": "experimental",
|
|
107
107
|
"jsdom": "^26.0.0",
|
|
108
108
|
"react": "^19.0.0",
|
|
@@ -147,7 +147,39 @@ describe('Feature: Self-solving', () => {
|
|
|
147
147
|
})
|
|
148
148
|
expect(onChange).toHaveBeenNthCalledWith(8, {
|
|
149
149
|
type: 'mutation',
|
|
150
|
-
patches: [spanPatch, blockPatch
|
|
150
|
+
patches: [spanPatch, blockPatch],
|
|
151
|
+
snapshot: [
|
|
152
|
+
block({
|
|
153
|
+
_key: 'b1',
|
|
154
|
+
children: [
|
|
155
|
+
span({
|
|
156
|
+
_key: 's1',
|
|
157
|
+
text: 'foo',
|
|
158
|
+
marks: [],
|
|
159
|
+
}),
|
|
160
|
+
],
|
|
161
|
+
style: 'normal',
|
|
162
|
+
markDefs: [],
|
|
163
|
+
}),
|
|
164
|
+
],
|
|
165
|
+
value: [
|
|
166
|
+
block({
|
|
167
|
+
_key: 'b1',
|
|
168
|
+
children: [
|
|
169
|
+
span({
|
|
170
|
+
_key: 's1',
|
|
171
|
+
text: 'foo',
|
|
172
|
+
marks: [],
|
|
173
|
+
}),
|
|
174
|
+
],
|
|
175
|
+
style: 'normal',
|
|
176
|
+
markDefs: [],
|
|
177
|
+
}),
|
|
178
|
+
],
|
|
179
|
+
})
|
|
180
|
+
expect(onChange).toHaveBeenNthCalledWith(9, {
|
|
181
|
+
type: 'mutation',
|
|
182
|
+
patches: [strongPatch],
|
|
151
183
|
snapshot: [
|
|
152
184
|
block({
|
|
153
185
|
_key: 'b1',
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {useActorRef, useSelector} from '@xstate/react'
|
|
2
2
|
import {useEffect} from 'react'
|
|
3
3
|
import {debugWithName} from '../../internal-utils/debug'
|
|
4
|
+
import {fromSlateValue} from '../../internal-utils/values'
|
|
5
|
+
import {KEY_TO_VALUE_ELEMENT} from '../../internal-utils/weakMaps'
|
|
4
6
|
import type {PortableTextSlateEditor} from '../../types/editor'
|
|
5
7
|
import type {EditorActor} from '../editor-machine'
|
|
6
8
|
import {mutationMachine} from '../mutation-machine'
|
|
@@ -80,6 +82,18 @@ export function Synchronizer(props: SynchronizerProps) {
|
|
|
80
82
|
type: 'notify.value changed',
|
|
81
83
|
})
|
|
82
84
|
break
|
|
85
|
+
case 'patch':
|
|
86
|
+
props.editorActor.send({
|
|
87
|
+
...event,
|
|
88
|
+
type: 'internal.patch',
|
|
89
|
+
value: fromSlateValue(
|
|
90
|
+
slateEditor.children,
|
|
91
|
+
props.editorActor.getSnapshot().context.schema.block.name,
|
|
92
|
+
KEY_TO_VALUE_ELEMENT.get(slateEditor),
|
|
93
|
+
),
|
|
94
|
+
})
|
|
95
|
+
break
|
|
96
|
+
|
|
83
97
|
default:
|
|
84
98
|
props.editorActor.send(event)
|
|
85
99
|
}
|
|
@@ -88,7 +102,7 @@ export function Synchronizer(props: SynchronizerProps) {
|
|
|
88
102
|
return () => {
|
|
89
103
|
subscription.unsubscribe()
|
|
90
104
|
}
|
|
91
|
-
}, [props.editorActor, syncActorRef])
|
|
105
|
+
}, [props.editorActor, slateEditor, syncActorRef])
|
|
92
106
|
|
|
93
107
|
useEffect(() => {
|
|
94
108
|
syncActorRef.send({type: 'update readOnly', readOnly})
|
|
@@ -102,8 +116,8 @@ export function Synchronizer(props: SynchronizerProps) {
|
|
|
102
116
|
// Subscribe to, and handle changes from the editor
|
|
103
117
|
useEffect(() => {
|
|
104
118
|
debug('Subscribing to patch events')
|
|
105
|
-
const sub = editorActor.on('patch', (event) => {
|
|
106
|
-
mutationActorRef.send(event)
|
|
119
|
+
const sub = editorActor.on('internal.patch', (event) => {
|
|
120
|
+
mutationActorRef.send({...event, type: 'patch'})
|
|
107
121
|
})
|
|
108
122
|
return () => {
|
|
109
123
|
debug('Unsubscribing to patch events')
|
|
@@ -151,6 +151,11 @@ type PatchEvent = {
|
|
|
151
151
|
patch: Patch
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
+
type InternalPatchEvent = NamespaceEvent<PatchEvent, 'internal'> & {
|
|
155
|
+
actionId?: string
|
|
156
|
+
value: Array<PortableTextBlock>
|
|
157
|
+
}
|
|
158
|
+
|
|
154
159
|
type UnsetEvent = {
|
|
155
160
|
type: 'unset'
|
|
156
161
|
previousValue: Array<PortableTextBlock>
|
|
@@ -191,9 +196,9 @@ export type InternalEditorEvent =
|
|
|
191
196
|
| CustomBehaviorEvent
|
|
192
197
|
| ExternalEditorEvent
|
|
193
198
|
| MutationEvent
|
|
199
|
+
| InternalPatchEvent
|
|
194
200
|
| NamespaceEvent<EditorEmittedEvent, 'notify'>
|
|
195
201
|
| NamespaceEvent<UnsetEvent, 'notify'>
|
|
196
|
-
| PatchEvent
|
|
197
202
|
| SyntheticBehaviorEvent
|
|
198
203
|
| {type: 'dragstart'}
|
|
199
204
|
| {type: 'dragend'}
|
|
@@ -204,6 +209,7 @@ export type InternalEditorEvent =
|
|
|
204
209
|
*/
|
|
205
210
|
export type InternalEditorEmittedEvent =
|
|
206
211
|
| EditorEmittedEvent
|
|
212
|
+
| InternalPatchEvent
|
|
207
213
|
| PatchesEvent
|
|
208
214
|
| UnsetEvent
|
|
209
215
|
| {
|
|
@@ -221,7 +227,7 @@ export const editorMachine = setup({
|
|
|
221
227
|
behaviors: Set<Behavior>
|
|
222
228
|
converters: Set<Converter>
|
|
223
229
|
keyGenerator: () => string
|
|
224
|
-
pendingEvents: Array<
|
|
230
|
+
pendingEvents: Array<InternalPatchEvent | MutationEvent>
|
|
225
231
|
schema: EditorSchema
|
|
226
232
|
initialReadOnly: boolean
|
|
227
233
|
maxBlocks: number | undefined
|
|
@@ -270,9 +276,11 @@ export const editorMachine = setup({
|
|
|
270
276
|
return event.schema
|
|
271
277
|
},
|
|
272
278
|
}),
|
|
273
|
-
'emit patch event':
|
|
274
|
-
assertEvent(event, 'patch')
|
|
275
|
-
|
|
279
|
+
'emit patch event': enqueueActions(({event, enqueue}) => {
|
|
280
|
+
assertEvent(event, 'internal.patch')
|
|
281
|
+
|
|
282
|
+
enqueue.emit(event)
|
|
283
|
+
enqueue.emit({type: 'patch', patch: event.patch})
|
|
276
284
|
}),
|
|
277
285
|
'emit mutation event': emit(({event}) => {
|
|
278
286
|
assertEvent(event, 'mutation')
|
|
@@ -282,13 +290,18 @@ export const editorMachine = setup({
|
|
|
282
290
|
'emit editable': emit({type: 'editable'}),
|
|
283
291
|
'defer event': assign({
|
|
284
292
|
pendingEvents: ({context, event}) => {
|
|
285
|
-
assertEvent(event, ['patch', 'mutation'])
|
|
293
|
+
assertEvent(event, ['internal.patch', 'mutation'])
|
|
286
294
|
return [...context.pendingEvents, event]
|
|
287
295
|
},
|
|
288
296
|
}),
|
|
289
297
|
'emit pending events': enqueueActions(({context, enqueue}) => {
|
|
290
298
|
for (const event of context.pendingEvents) {
|
|
291
|
-
|
|
299
|
+
if (event.type === 'internal.patch') {
|
|
300
|
+
enqueue.emit(event)
|
|
301
|
+
enqueue.emit({type: 'patch', patch: event.patch})
|
|
302
|
+
} else {
|
|
303
|
+
enqueue.emit(event)
|
|
304
|
+
}
|
|
292
305
|
}
|
|
293
306
|
}),
|
|
294
307
|
'emit ready': emit({type: 'ready'}),
|
|
@@ -664,7 +677,7 @@ export const editorMachine = setup({
|
|
|
664
677
|
'setting up': {
|
|
665
678
|
exit: ['emit ready'],
|
|
666
679
|
on: {
|
|
667
|
-
'patch': {
|
|
680
|
+
'internal.patch': {
|
|
668
681
|
actions: 'defer event',
|
|
669
682
|
},
|
|
670
683
|
'mutation': {
|
|
@@ -680,14 +693,14 @@ export const editorMachine = setup({
|
|
|
680
693
|
states: {
|
|
681
694
|
idle: {
|
|
682
695
|
on: {
|
|
683
|
-
normalizing: {
|
|
696
|
+
'normalizing': {
|
|
684
697
|
target: 'normalizing',
|
|
685
698
|
},
|
|
686
|
-
patch: {
|
|
699
|
+
'internal.patch': {
|
|
687
700
|
actions: 'defer event',
|
|
688
701
|
target: '#editor.setup.dirty',
|
|
689
702
|
},
|
|
690
|
-
mutation: {
|
|
703
|
+
'mutation': {
|
|
691
704
|
actions: 'defer event',
|
|
692
705
|
target: '#editor.setup.dirty',
|
|
693
706
|
},
|
|
@@ -698,7 +711,7 @@ export const editorMachine = setup({
|
|
|
698
711
|
'done normalizing': {
|
|
699
712
|
target: 'idle',
|
|
700
713
|
},
|
|
701
|
-
'patch': {
|
|
714
|
+
'internal.patch': {
|
|
702
715
|
actions: 'defer event',
|
|
703
716
|
},
|
|
704
717
|
'mutation': {
|
|
@@ -711,10 +724,10 @@ export const editorMachine = setup({
|
|
|
711
724
|
'dirty': {
|
|
712
725
|
entry: ['emit pending events', 'clear pending events'],
|
|
713
726
|
on: {
|
|
714
|
-
patch: {
|
|
727
|
+
'internal.patch': {
|
|
715
728
|
actions: 'emit patch event',
|
|
716
729
|
},
|
|
717
|
-
mutation: {
|
|
730
|
+
'mutation': {
|
|
718
731
|
actions: 'emit mutation event',
|
|
719
732
|
},
|
|
720
733
|
},
|
|
@@ -1,25 +1,48 @@
|
|
|
1
1
|
import type {Patch} from '@portabletext/patches'
|
|
2
2
|
import type {PortableTextBlock} from '@sanity/types'
|
|
3
3
|
import {Editor} from 'slate'
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
import {
|
|
5
|
+
and,
|
|
6
|
+
assertEvent,
|
|
7
|
+
assign,
|
|
8
|
+
emit,
|
|
9
|
+
enqueueActions,
|
|
10
|
+
fromCallback,
|
|
11
|
+
not,
|
|
12
|
+
setup,
|
|
13
|
+
stateIn,
|
|
14
|
+
type AnyEventObject,
|
|
15
|
+
} from 'xstate'
|
|
7
16
|
import type {PortableTextSlateEditor} from '../types/editor'
|
|
8
17
|
import type {EditorSchema} from './define-schema'
|
|
9
18
|
|
|
10
|
-
const FLUSH_PATCHES_THROTTLED_MS = process.env.NODE_ENV === 'test' ? 500 : 1000
|
|
11
|
-
|
|
12
19
|
/**
|
|
13
20
|
* Makes sure editor mutation events are debounced
|
|
14
21
|
*/
|
|
15
22
|
export const mutationMachine = setup({
|
|
16
23
|
types: {
|
|
17
24
|
context: {} as {
|
|
18
|
-
|
|
25
|
+
pendingMutations: Array<{
|
|
26
|
+
actionId?: string
|
|
27
|
+
value: Array<PortableTextBlock> | undefined
|
|
28
|
+
patches: Array<Patch>
|
|
29
|
+
}>
|
|
19
30
|
schema: EditorSchema
|
|
20
31
|
slateEditor: PortableTextSlateEditor
|
|
21
32
|
},
|
|
22
|
-
events: {} as
|
|
33
|
+
events: {} as
|
|
34
|
+
| {
|
|
35
|
+
type: 'patch'
|
|
36
|
+
patch: Patch
|
|
37
|
+
actionId?: string
|
|
38
|
+
value: Array<PortableTextBlock>
|
|
39
|
+
}
|
|
40
|
+
| {
|
|
41
|
+
type: 'typing'
|
|
42
|
+
}
|
|
43
|
+
| {
|
|
44
|
+
type: 'not typing'
|
|
45
|
+
},
|
|
23
46
|
input: {} as {
|
|
24
47
|
schema: EditorSchema
|
|
25
48
|
slateEditor: PortableTextSlateEditor
|
|
@@ -36,65 +59,156 @@ export const mutationMachine = setup({
|
|
|
36
59
|
},
|
|
37
60
|
actions: {
|
|
38
61
|
'emit has pending patches': emit({type: 'has pending patches'}),
|
|
39
|
-
'emit
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
})
|
|
48
|
-
'clear pending
|
|
49
|
-
|
|
62
|
+
'emit mutations': enqueueActions(({context, enqueue}) => {
|
|
63
|
+
for (const bulk of context.pendingMutations) {
|
|
64
|
+
enqueue.emit({
|
|
65
|
+
type: 'mutation',
|
|
66
|
+
patches: bulk.patches,
|
|
67
|
+
snapshot: bulk.value,
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
}),
|
|
71
|
+
'clear pending mutations': assign({
|
|
72
|
+
pendingMutations: [],
|
|
50
73
|
}),
|
|
51
74
|
'defer patch': assign({
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
75
|
+
pendingMutations: ({context, event}) => {
|
|
76
|
+
assertEvent(event, 'patch')
|
|
77
|
+
|
|
78
|
+
if (context.pendingMutations.length === 0) {
|
|
79
|
+
return [
|
|
80
|
+
{
|
|
81
|
+
actionId: event.actionId,
|
|
82
|
+
value: event.value,
|
|
83
|
+
patches: [event.patch],
|
|
84
|
+
},
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const lastBulk = context.pendingMutations.at(-1)
|
|
89
|
+
|
|
90
|
+
if (lastBulk && lastBulk.actionId === event.actionId) {
|
|
91
|
+
return context.pendingMutations.slice(0, -1).concat({
|
|
92
|
+
value: event.value,
|
|
93
|
+
actionId: lastBulk.actionId,
|
|
94
|
+
patches: [...lastBulk.patches, event.patch],
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return context.pendingMutations.concat({
|
|
99
|
+
value: event.value,
|
|
100
|
+
actionId: event.actionId,
|
|
101
|
+
patches: [event.patch],
|
|
102
|
+
})
|
|
103
|
+
},
|
|
104
|
+
}),
|
|
105
|
+
},
|
|
106
|
+
actors: {
|
|
107
|
+
'type listener': fromCallback<
|
|
108
|
+
AnyEventObject,
|
|
109
|
+
{slateEditor: PortableTextSlateEditor},
|
|
110
|
+
{type: 'typing'} | {type: 'not typing'}
|
|
111
|
+
>(({input, sendBack}) => {
|
|
112
|
+
const originalApply = input.slateEditor.apply
|
|
113
|
+
|
|
114
|
+
input.slateEditor.apply = (op) => {
|
|
115
|
+
if (op.type === 'insert_text' || op.type === 'remove_text') {
|
|
116
|
+
sendBack({type: 'typing'})
|
|
117
|
+
} else {
|
|
118
|
+
sendBack({type: 'not typing'})
|
|
119
|
+
}
|
|
120
|
+
originalApply(op)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return () => {
|
|
124
|
+
input.slateEditor.apply = originalApply
|
|
125
|
+
}
|
|
56
126
|
}),
|
|
57
127
|
},
|
|
58
128
|
guards: {
|
|
129
|
+
'is typing': stateIn({typing: 'typing'}),
|
|
130
|
+
'no pending mutations': ({context}) =>
|
|
131
|
+
context.pendingMutations.length === 0,
|
|
59
132
|
'slate is normalizing': ({context}) =>
|
|
60
133
|
Editor.isNormalizing(context.slateEditor),
|
|
61
134
|
},
|
|
135
|
+
delays: {
|
|
136
|
+
'mutation debounce': process.env.NODE_ENV === 'test' ? 250 : 0,
|
|
137
|
+
'type debounce': process.env.NODE_ENV === 'test' ? 0 : 250,
|
|
138
|
+
},
|
|
62
139
|
}).createMachine({
|
|
63
140
|
id: 'mutation',
|
|
64
141
|
context: ({input}) => ({
|
|
65
|
-
|
|
142
|
+
pendingMutations: [],
|
|
66
143
|
schema: input.schema,
|
|
67
144
|
slateEditor: input.slateEditor,
|
|
68
145
|
}),
|
|
69
|
-
|
|
146
|
+
type: 'parallel',
|
|
70
147
|
states: {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
148
|
+
typing: {
|
|
149
|
+
initial: 'idle',
|
|
150
|
+
invoke: {
|
|
151
|
+
src: 'type listener',
|
|
152
|
+
input: ({context}) => ({slateEditor: context.slateEditor}),
|
|
153
|
+
},
|
|
154
|
+
states: {
|
|
155
|
+
idle: {
|
|
156
|
+
on: {
|
|
157
|
+
typing: {
|
|
158
|
+
target: 'typing',
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
typing: {
|
|
163
|
+
after: {
|
|
164
|
+
'type debounce': {
|
|
165
|
+
target: 'idle',
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
on: {
|
|
169
|
+
'not typing': {
|
|
170
|
+
target: 'idle',
|
|
171
|
+
},
|
|
172
|
+
'typing': {
|
|
173
|
+
target: 'typing',
|
|
174
|
+
reenter: true,
|
|
175
|
+
},
|
|
176
|
+
},
|
|
76
177
|
},
|
|
77
178
|
},
|
|
78
179
|
},
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
180
|
+
mutations: {
|
|
181
|
+
initial: 'idle',
|
|
182
|
+
states: {
|
|
183
|
+
'idle': {
|
|
184
|
+
on: {
|
|
185
|
+
patch: {
|
|
186
|
+
actions: ['defer patch', 'emit has pending patches'],
|
|
187
|
+
target: 'emitting mutations',
|
|
188
|
+
},
|
|
86
189
|
},
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
190
|
+
},
|
|
191
|
+
'emitting mutations': {
|
|
192
|
+
after: {
|
|
193
|
+
'mutation debounce': [
|
|
194
|
+
{
|
|
195
|
+
guard: and([not('is typing'), 'slate is normalizing']),
|
|
196
|
+
target: 'idle',
|
|
197
|
+
actions: ['emit mutations', 'clear pending mutations'],
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
target: 'emitting mutations',
|
|
201
|
+
reenter: true,
|
|
202
|
+
},
|
|
203
|
+
],
|
|
204
|
+
},
|
|
205
|
+
on: {
|
|
206
|
+
patch: {
|
|
207
|
+
target: 'emitting mutations',
|
|
208
|
+
actions: ['defer patch'],
|
|
209
|
+
reenter: true,
|
|
210
|
+
},
|
|
90
211
|
},
|
|
91
|
-
],
|
|
92
|
-
},
|
|
93
|
-
on: {
|
|
94
|
-
patch: {
|
|
95
|
-
target: 'has pending patches',
|
|
96
|
-
actions: ['defer patch'],
|
|
97
|
-
reenter: true,
|
|
98
212
|
},
|
|
99
213
|
},
|
|
100
214
|
},
|
|
@@ -30,6 +30,7 @@ import type {
|
|
|
30
30
|
PortableTextSlateEditor,
|
|
31
31
|
} from '../../types/editor'
|
|
32
32
|
import type {EditorActor} from '../editor-machine'
|
|
33
|
+
import {getCurrentActionId} from '../with-applying-behavior-actions'
|
|
33
34
|
import {withoutSaving} from './createWithUndoRedo'
|
|
34
35
|
|
|
35
36
|
const debug = debugWithName('plugin:withPatches')
|
|
@@ -287,12 +288,18 @@ export function createWithPatches({
|
|
|
287
288
|
|
|
288
289
|
// Emit all patches
|
|
289
290
|
if (patches.length > 0) {
|
|
290
|
-
|
|
291
|
+
for (const patch of patches) {
|
|
291
292
|
editorActor.send({
|
|
292
|
-
type: 'patch',
|
|
293
|
+
type: 'internal.patch',
|
|
293
294
|
patch: {...patch, origin: 'local'},
|
|
295
|
+
actionId: getCurrentActionId(editor),
|
|
296
|
+
value: fromSlateValue(
|
|
297
|
+
editor.children,
|
|
298
|
+
schemaTypes.block.name,
|
|
299
|
+
KEY_TO_VALUE_ELEMENT.get(editor),
|
|
300
|
+
),
|
|
294
301
|
})
|
|
295
|
-
}
|
|
302
|
+
}
|
|
296
303
|
}
|
|
297
304
|
return editor
|
|
298
305
|
}
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import {Editor} from 'slate'
|
|
2
2
|
import {defaultKeyGenerator} from './key-generator'
|
|
3
3
|
|
|
4
|
-
const
|
|
5
|
-
new WeakMap()
|
|
4
|
+
const CURRENT_ACTION_ID: WeakMap<Editor, string | undefined> = new WeakMap()
|
|
6
5
|
|
|
7
6
|
export function withApplyingBehaviorActions(editor: Editor, fn: () => void) {
|
|
8
|
-
|
|
9
|
-
IS_APPLYING_BEHAVIOR_ACTIONS.set(editor, true)
|
|
7
|
+
CURRENT_ACTION_ID.set(editor, defaultKeyGenerator())
|
|
10
8
|
Editor.withoutNormalizing(editor, fn)
|
|
11
|
-
|
|
9
|
+
CURRENT_ACTION_ID.set(editor, undefined)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function getCurrentActionId(editor: Editor) {
|
|
13
|
+
return CURRENT_ACTION_ID.get(editor)
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
export function isApplyingBehaviorActions(editor: Editor) {
|
|
15
|
-
return
|
|
17
|
+
return getCurrentActionId(editor) !== undefined
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
////////
|