@portabletext/editor 2.9.2 → 2.11.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/_chunks-cjs/util.merge-text-blocks.cjs +1 -0
- package/lib/_chunks-cjs/util.merge-text-blocks.cjs.map +1 -1
- package/lib/_chunks-cjs/util.slice-blocks.cjs +6 -1
- package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -1
- package/lib/_chunks-dts/behavior.types.action.d.cts +79 -69
- package/lib/_chunks-dts/behavior.types.action.d.ts +79 -69
- package/lib/_chunks-es/util.merge-text-blocks.js +1 -0
- package/lib/_chunks-es/util.merge-text-blocks.js.map +1 -1
- package/lib/_chunks-es/util.slice-blocks.js +6 -1
- package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
- package/lib/index.cjs +232 -68
- package/lib/index.cjs.map +1 -1
- package/lib/index.js +234 -70
- package/lib/index.js.map +1 -1
- package/lib/plugins/index.d.cts +3 -3
- package/lib/plugins/index.d.ts +3 -3
- package/lib/utils/index.d.cts +2 -2
- package/package.json +10 -10
- package/src/behaviors/behavior.abstract.insert.ts +109 -24
- package/src/behaviors/behavior.abstract.split.ts +1 -0
- package/src/behaviors/behavior.perform-event.ts +89 -67
- package/src/behaviors/behavior.types.event.ts +10 -3
- package/src/converters/converter.portable-text.ts +1 -0
- package/src/converters/converter.text-html.ts +1 -0
- package/src/converters/converter.text-plain.ts +1 -0
- package/src/editor/Editable.tsx +1 -0
- package/src/editor/editor-selector.ts +10 -1
- package/src/editor/without-normalizing-conditional.ts +13 -0
- package/src/internal-utils/parse-blocks.test.ts +14 -14
- package/src/internal-utils/parse-blocks.ts +9 -2
- package/src/internal-utils/test-editor.tsx +1 -25
- package/src/operations/behavior.operation.block.set.ts +4 -3
- package/src/operations/behavior.operation.block.unset.ts +8 -2
- package/src/operations/behavior.operation.insert.block.ts +4 -1
- package/src/operations/behavior.operation.insert.child.ts +95 -0
- package/src/operations/behavior.operations.ts +9 -0
- package/src/selectors/selector.get-trimmed-selection.test.ts +1 -0
- package/src/types/block-with-optional-key.ts +13 -1
- package/src/utils/util.merge-text-blocks.ts +1 -1
- package/src/utils/util.slice-blocks.ts +3 -3
- package/src/utils/util.slice-text-block.test.ts +54 -28
- package/src/plugins/plugin.internal.editor-actor-ref.tsx +0 -15
package/lib/plugins/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Behavior, Editor, EditorEmittedEvent, EditorSchema } from "../_chunks-dts/behavior.types.action.cjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react22 from "react";
|
|
3
3
|
import React from "react";
|
|
4
4
|
/**
|
|
5
5
|
* @beta
|
|
@@ -181,7 +181,7 @@ type MarkdownPluginConfig = MarkdownBehaviorsConfig & {
|
|
|
181
181
|
*/
|
|
182
182
|
declare function MarkdownPlugin(props: {
|
|
183
183
|
config: MarkdownPluginConfig;
|
|
184
|
-
}):
|
|
184
|
+
}): react22.JSX.Element;
|
|
185
185
|
/**
|
|
186
186
|
* @beta
|
|
187
187
|
* Restrict the editor to one line. The plugin takes care of blocking
|
|
@@ -192,5 +192,5 @@ declare function MarkdownPlugin(props: {
|
|
|
192
192
|
*
|
|
193
193
|
* @deprecated Install the plugin from `@portabletext/plugin-one-line`
|
|
194
194
|
*/
|
|
195
|
-
declare function OneLinePlugin():
|
|
195
|
+
declare function OneLinePlugin(): react22.JSX.Element;
|
|
196
196
|
export { BehaviorPlugin, DecoratorShortcutPlugin, EditorRefPlugin, EventListenerPlugin, MarkdownPlugin, type MarkdownPluginConfig, OneLinePlugin };
|
package/lib/plugins/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Behavior, Editor, EditorEmittedEvent, EditorSchema } from "../_chunks-dts/behavior.types.action.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react21 from "react";
|
|
3
3
|
import React from "react";
|
|
4
4
|
/**
|
|
5
5
|
* @beta
|
|
@@ -181,7 +181,7 @@ type MarkdownPluginConfig = MarkdownBehaviorsConfig & {
|
|
|
181
181
|
*/
|
|
182
182
|
declare function MarkdownPlugin(props: {
|
|
183
183
|
config: MarkdownPluginConfig;
|
|
184
|
-
}):
|
|
184
|
+
}): react21.JSX.Element;
|
|
185
185
|
/**
|
|
186
186
|
* @beta
|
|
187
187
|
* Restrict the editor to one line. The plugin takes care of blocking
|
|
@@ -192,5 +192,5 @@ declare function MarkdownPlugin(props: {
|
|
|
192
192
|
*
|
|
193
193
|
* @deprecated Install the plugin from `@portabletext/plugin-one-line`
|
|
194
194
|
*/
|
|
195
|
-
declare function OneLinePlugin():
|
|
195
|
+
declare function OneLinePlugin(): react21.JSX.Element;
|
|
196
196
|
export { BehaviorPlugin, DecoratorShortcutPlugin, EditorRefPlugin, EventListenerPlugin, MarkdownPlugin, type MarkdownPluginConfig, OneLinePlugin };
|
package/lib/utils/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BlockOffset, BlockPath, ChildPath, EditorContext, EditorSelection, EditorSelectionPoint } from "../_chunks-dts/behavior.types.action.cjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as _sanity_types8 from "@sanity/types";
|
|
3
3
|
import { KeyedSegment, PortableTextBlock, PortableTextTextBlock } from "@sanity/types";
|
|
4
4
|
import { isSpan, isTextBlock } from "@portabletext/schema";
|
|
5
5
|
/**
|
|
@@ -143,7 +143,7 @@ declare function mergeTextBlocks({
|
|
|
143
143
|
context: Pick<EditorContext, 'keyGenerator' | 'schema'>;
|
|
144
144
|
targetBlock: PortableTextTextBlock;
|
|
145
145
|
incomingBlock: PortableTextTextBlock;
|
|
146
|
-
}): PortableTextTextBlock<
|
|
146
|
+
}): PortableTextTextBlock<_sanity_types8.PortableTextObject | _sanity_types8.PortableTextSpan>;
|
|
147
147
|
/**
|
|
148
148
|
* @public
|
|
149
149
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@portabletext/editor",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.11.0",
|
|
4
4
|
"description": "Portable Text Editor made in React",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
@@ -79,16 +79,16 @@
|
|
|
79
79
|
"slate-dom": "^0.118.1",
|
|
80
80
|
"slate-react": "0.117.4",
|
|
81
81
|
"xstate": "^5.21.0",
|
|
82
|
-
"@portabletext/block-tools": "^3.5.
|
|
82
|
+
"@portabletext/block-tools": "^3.5.6",
|
|
83
|
+
"@portabletext/patches": "^1.1.8",
|
|
83
84
|
"@portabletext/schema": "^1.2.0",
|
|
84
|
-
"@portabletext/keyboard-shortcuts": "^1.1.1"
|
|
85
|
-
"@portabletext/patches": "^1.1.8"
|
|
85
|
+
"@portabletext/keyboard-shortcuts": "^1.1.1"
|
|
86
86
|
},
|
|
87
87
|
"devDependencies": {
|
|
88
88
|
"@sanity/diff-match-patch": "^3.2.0",
|
|
89
89
|
"@sanity/pkg-utils": "^8.1.4",
|
|
90
|
-
"@sanity/schema": "^4.
|
|
91
|
-
"@sanity/types": "^4.
|
|
90
|
+
"@sanity/schema": "^4.9.0",
|
|
91
|
+
"@sanity/types": "^4.9.0",
|
|
92
92
|
"@types/debug": "^4.1.12",
|
|
93
93
|
"@types/lodash": "^4.17.20",
|
|
94
94
|
"@types/lodash.startcase": "^4.4.9",
|
|
@@ -110,14 +110,14 @@
|
|
|
110
110
|
"vite": "^7.1.3",
|
|
111
111
|
"vitest": "^3.2.4",
|
|
112
112
|
"vitest-browser-react": "^1.0.1",
|
|
113
|
-
"@portabletext/sanity-bridge": "1.1.
|
|
113
|
+
"@portabletext/sanity-bridge": "1.1.10",
|
|
114
114
|
"@portabletext/test": "^0.0.0",
|
|
115
115
|
"racejar": "1.2.15"
|
|
116
116
|
},
|
|
117
117
|
"peerDependencies": {
|
|
118
|
-
"@portabletext/sanity-bridge": "^1.1.
|
|
119
|
-
"@sanity/schema": "^4.
|
|
120
|
-
"@sanity/types": "^4.
|
|
118
|
+
"@portabletext/sanity-bridge": "^1.1.10",
|
|
119
|
+
"@sanity/schema": "^4.9.0",
|
|
120
|
+
"@sanity/types": "^4.9.0",
|
|
121
121
|
"react": "^18.3 || ^19",
|
|
122
122
|
"rxjs": "^7.8.2"
|
|
123
123
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {getFocusTextBlock} from '../selectors'
|
|
1
|
+
import {getFocusTextBlock, getLastBlock} from '../selectors'
|
|
2
2
|
import {
|
|
3
3
|
getBlockEndPoint,
|
|
4
4
|
getBlockStartPoint,
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
isEqualSelectionPoints,
|
|
7
7
|
} from '../utils'
|
|
8
8
|
import {sliceTextBlock} from '../utils/util.slice-text-block'
|
|
9
|
-
import {
|
|
9
|
+
import {raise} from './behavior.types.action'
|
|
10
10
|
import {defineBehavior} from './behavior.types.behavior'
|
|
11
11
|
|
|
12
12
|
export const abstractInsertBehaviors = [
|
|
@@ -328,23 +328,77 @@ export const abstractInsertBehaviors = [
|
|
|
328
328
|
actions: [() => [raise({type: 'split'})]],
|
|
329
329
|
}),
|
|
330
330
|
defineBehavior({
|
|
331
|
-
on: 'insert.
|
|
331
|
+
on: 'insert.child',
|
|
332
|
+
guard: ({snapshot}) => {
|
|
333
|
+
const lastBlock = getLastBlock(snapshot)
|
|
334
|
+
|
|
335
|
+
if (!lastBlock) {
|
|
336
|
+
return false
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
if (snapshot.context.selection) {
|
|
340
|
+
return false
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const lastBlockEndPoint = getBlockEndPoint({
|
|
344
|
+
context: snapshot.context,
|
|
345
|
+
block: lastBlock,
|
|
346
|
+
})
|
|
347
|
+
|
|
348
|
+
return {lastBlockEndPoint}
|
|
349
|
+
},
|
|
350
|
+
actions: [
|
|
351
|
+
({event}, {lastBlockEndPoint}) => [
|
|
352
|
+
raise({
|
|
353
|
+
type: 'select',
|
|
354
|
+
at: {
|
|
355
|
+
anchor: lastBlockEndPoint,
|
|
356
|
+
focus: lastBlockEndPoint,
|
|
357
|
+
},
|
|
358
|
+
}),
|
|
359
|
+
raise(event),
|
|
360
|
+
],
|
|
361
|
+
],
|
|
362
|
+
}),
|
|
363
|
+
defineBehavior({
|
|
364
|
+
on: 'insert.child',
|
|
365
|
+
guard: ({snapshot}) => {
|
|
366
|
+
const focusTextBlock = getFocusTextBlock(snapshot)
|
|
367
|
+
|
|
368
|
+
return snapshot.context.selection && !focusTextBlock
|
|
369
|
+
},
|
|
332
370
|
actions: [
|
|
333
371
|
({snapshot, event}) => [
|
|
334
|
-
|
|
372
|
+
raise({
|
|
335
373
|
type: 'insert.block',
|
|
336
374
|
block: {
|
|
337
375
|
_type: snapshot.context.schema.block.name,
|
|
338
376
|
children: [
|
|
339
377
|
{
|
|
340
|
-
_type:
|
|
341
|
-
|
|
378
|
+
_type: snapshot.context.schema.span.name,
|
|
379
|
+
text: '',
|
|
380
|
+
marks: [],
|
|
342
381
|
},
|
|
343
382
|
],
|
|
344
383
|
},
|
|
345
384
|
placement: 'auto',
|
|
346
385
|
select: 'end',
|
|
347
386
|
}),
|
|
387
|
+
raise(event),
|
|
388
|
+
],
|
|
389
|
+
],
|
|
390
|
+
}),
|
|
391
|
+
defineBehavior({
|
|
392
|
+
on: 'insert.inline object',
|
|
393
|
+
actions: [
|
|
394
|
+
({event}) => [
|
|
395
|
+
raise({
|
|
396
|
+
type: 'insert.child',
|
|
397
|
+
child: {
|
|
398
|
+
_type: event.inlineObject.name,
|
|
399
|
+
...event.inlineObject.value,
|
|
400
|
+
},
|
|
401
|
+
}),
|
|
348
402
|
],
|
|
349
403
|
],
|
|
350
404
|
}),
|
|
@@ -354,37 +408,68 @@ export const abstractInsertBehaviors = [
|
|
|
354
408
|
}),
|
|
355
409
|
defineBehavior({
|
|
356
410
|
on: 'insert.span',
|
|
357
|
-
guard: ({snapshot
|
|
358
|
-
const markDefs =
|
|
359
|
-
event.annotations?.map((annotation) => ({
|
|
360
|
-
_type: annotation.name,
|
|
361
|
-
_key: snapshot.context.keyGenerator(),
|
|
362
|
-
...annotation.value,
|
|
363
|
-
})) ?? []
|
|
364
|
-
|
|
365
|
-
return {markDefs}
|
|
366
|
-
},
|
|
411
|
+
guard: ({snapshot}) => !getFocusTextBlock(snapshot),
|
|
367
412
|
actions: [
|
|
368
|
-
({snapshot, event}
|
|
369
|
-
|
|
413
|
+
({snapshot, event}) => [
|
|
414
|
+
raise({
|
|
370
415
|
type: 'insert.block',
|
|
371
416
|
block: {
|
|
372
417
|
_type: snapshot.context.schema.block.name,
|
|
373
418
|
children: [
|
|
374
419
|
{
|
|
375
420
|
_type: snapshot.context.schema.span.name,
|
|
376
|
-
text:
|
|
377
|
-
marks: [
|
|
378
|
-
...(event.decorators ?? []),
|
|
379
|
-
...markDefs.map((markDef) => markDef._key),
|
|
380
|
-
],
|
|
421
|
+
text: '',
|
|
422
|
+
marks: [],
|
|
381
423
|
},
|
|
382
424
|
],
|
|
383
|
-
markDefs,
|
|
384
425
|
},
|
|
385
426
|
placement: 'auto',
|
|
386
427
|
select: 'end',
|
|
387
428
|
}),
|
|
429
|
+
raise(event),
|
|
430
|
+
],
|
|
431
|
+
],
|
|
432
|
+
}),
|
|
433
|
+
defineBehavior({
|
|
434
|
+
on: 'insert.span',
|
|
435
|
+
guard: ({snapshot, event}) => {
|
|
436
|
+
const focusTextBlock = getFocusTextBlock(snapshot)
|
|
437
|
+
const markDefs =
|
|
438
|
+
event.annotations?.map((annotation) => ({
|
|
439
|
+
_type: annotation.name,
|
|
440
|
+
_key: snapshot.context.keyGenerator(),
|
|
441
|
+
...annotation.value,
|
|
442
|
+
})) ?? []
|
|
443
|
+
|
|
444
|
+
return {markDefs, focusTextBlock}
|
|
445
|
+
},
|
|
446
|
+
actions: [
|
|
447
|
+
({snapshot, event}, {markDefs, focusTextBlock}) => [
|
|
448
|
+
...(focusTextBlock
|
|
449
|
+
? [
|
|
450
|
+
raise({
|
|
451
|
+
type: 'block.set',
|
|
452
|
+
at: focusTextBlock.path,
|
|
453
|
+
props: {
|
|
454
|
+
markDefs: [
|
|
455
|
+
...(focusTextBlock.node.markDefs ?? []),
|
|
456
|
+
...markDefs,
|
|
457
|
+
],
|
|
458
|
+
},
|
|
459
|
+
}),
|
|
460
|
+
]
|
|
461
|
+
: []),
|
|
462
|
+
raise({
|
|
463
|
+
type: 'insert.child',
|
|
464
|
+
child: {
|
|
465
|
+
_type: snapshot.context.schema.span.name,
|
|
466
|
+
text: event.text,
|
|
467
|
+
marks: [
|
|
468
|
+
...(event.decorators ?? []),
|
|
469
|
+
...markDefs.map((markDef) => markDef._key),
|
|
470
|
+
],
|
|
471
|
+
},
|
|
472
|
+
}),
|
|
388
473
|
],
|
|
389
474
|
],
|
|
390
475
|
}),
|
|
@@ -3,6 +3,7 @@ import type {EditorSchema} from '../editor/editor-schema'
|
|
|
3
3
|
import type {EditorSnapshot} from '../editor/editor-snapshot'
|
|
4
4
|
import {withPerformingBehaviorOperation} from '../editor/with-performing-behavior-operation'
|
|
5
5
|
import {clearUndoStep, createUndoStep} from '../editor/with-undo-step'
|
|
6
|
+
import {withoutNormalizingConditional} from '../editor/without-normalizing-conditional'
|
|
6
7
|
import {debugWithName} from '../internal-utils/debug'
|
|
7
8
|
import {performOperation} from '../operations/behavior.operations'
|
|
8
9
|
import type {PortableTextSlateEditor} from '../types/editor'
|
|
@@ -210,75 +211,96 @@ export function performEvent({
|
|
|
210
211
|
undoStepCreated = true
|
|
211
212
|
}
|
|
212
213
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
214
|
+
const actionTypes = actions.map((action) => action.type)
|
|
215
|
+
const uniqueActionTypes = new Set(actionTypes)
|
|
216
|
+
|
|
217
|
+
// The set of actions are all `raise` actions
|
|
218
|
+
const raiseGroup =
|
|
219
|
+
actionTypes.length > 1 &&
|
|
220
|
+
uniqueActionTypes.size === 1 &&
|
|
221
|
+
uniqueActionTypes.has('raise')
|
|
222
|
+
|
|
223
|
+
// The set of actions are all `execute` actions
|
|
224
|
+
const executeGroup =
|
|
225
|
+
actionTypes.length > 1 &&
|
|
226
|
+
uniqueActionTypes.size === 1 &&
|
|
227
|
+
uniqueActionTypes.has('execute')
|
|
228
|
+
|
|
229
|
+
withoutNormalizingConditional(
|
|
230
|
+
editor,
|
|
231
|
+
() => raiseGroup || executeGroup,
|
|
232
|
+
() => {
|
|
233
|
+
for (const action of actions) {
|
|
234
|
+
if (action.type === 'effect') {
|
|
235
|
+
try {
|
|
236
|
+
action.effect({
|
|
237
|
+
send: sendBack,
|
|
238
|
+
})
|
|
239
|
+
} catch (error) {
|
|
240
|
+
console.error(
|
|
241
|
+
new Error(
|
|
242
|
+
`Executing effect as a result of "${event.type}" failed due to: ${error.message}`,
|
|
243
|
+
),
|
|
244
|
+
)
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
continue
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (action.type === 'forward') {
|
|
251
|
+
const remainingEventBehaviors = eventBehaviors.slice(
|
|
252
|
+
eventBehaviorIndex + 1,
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
performEvent({
|
|
256
|
+
mode: mode === 'execute' ? 'execute' : 'forward',
|
|
257
|
+
behaviors,
|
|
258
|
+
remainingEventBehaviors: remainingEventBehaviors,
|
|
259
|
+
event: action.event,
|
|
260
|
+
editor,
|
|
261
|
+
keyGenerator,
|
|
262
|
+
schema,
|
|
263
|
+
getSnapshot,
|
|
264
|
+
nativeEvent,
|
|
265
|
+
sendBack,
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
continue
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (action.type === 'raise') {
|
|
272
|
+
performEvent({
|
|
273
|
+
mode: mode === 'execute' ? 'execute' : 'raise',
|
|
274
|
+
behaviors,
|
|
275
|
+
remainingEventBehaviors:
|
|
276
|
+
mode === 'execute' ? remainingEventBehaviors : behaviors,
|
|
277
|
+
event: action.event,
|
|
278
|
+
editor,
|
|
279
|
+
keyGenerator,
|
|
280
|
+
schema,
|
|
281
|
+
getSnapshot,
|
|
282
|
+
nativeEvent,
|
|
283
|
+
sendBack,
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
continue
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
performEvent({
|
|
290
|
+
mode: 'execute',
|
|
291
|
+
behaviors,
|
|
292
|
+
remainingEventBehaviors: [],
|
|
293
|
+
event: action.event,
|
|
294
|
+
editor,
|
|
295
|
+
keyGenerator,
|
|
296
|
+
schema,
|
|
297
|
+
getSnapshot,
|
|
298
|
+
nativeEvent: undefined,
|
|
299
|
+
sendBack,
|
|
218
300
|
})
|
|
219
|
-
} catch (error) {
|
|
220
|
-
console.error(
|
|
221
|
-
new Error(
|
|
222
|
-
`Executing effect as a result of "${event.type}" failed due to: ${error.message}`,
|
|
223
|
-
),
|
|
224
|
-
)
|
|
225
301
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
if (action.type === 'forward') {
|
|
231
|
-
const remainingEventBehaviors = eventBehaviors.slice(
|
|
232
|
-
eventBehaviorIndex + 1,
|
|
233
|
-
)
|
|
234
|
-
|
|
235
|
-
performEvent({
|
|
236
|
-
mode: mode === 'execute' ? 'execute' : 'forward',
|
|
237
|
-
behaviors,
|
|
238
|
-
remainingEventBehaviors: remainingEventBehaviors,
|
|
239
|
-
event: action.event,
|
|
240
|
-
editor,
|
|
241
|
-
keyGenerator,
|
|
242
|
-
schema,
|
|
243
|
-
getSnapshot,
|
|
244
|
-
nativeEvent,
|
|
245
|
-
sendBack,
|
|
246
|
-
})
|
|
247
|
-
|
|
248
|
-
continue
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
if (action.type === 'raise') {
|
|
252
|
-
performEvent({
|
|
253
|
-
mode: mode === 'execute' ? 'execute' : 'raise',
|
|
254
|
-
behaviors,
|
|
255
|
-
remainingEventBehaviors:
|
|
256
|
-
mode === 'execute' ? remainingEventBehaviors : behaviors,
|
|
257
|
-
event: action.event,
|
|
258
|
-
editor,
|
|
259
|
-
keyGenerator,
|
|
260
|
-
schema,
|
|
261
|
-
getSnapshot,
|
|
262
|
-
nativeEvent,
|
|
263
|
-
sendBack,
|
|
264
|
-
})
|
|
265
|
-
|
|
266
|
-
continue
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
performEvent({
|
|
270
|
-
mode: 'execute',
|
|
271
|
-
behaviors,
|
|
272
|
-
remainingEventBehaviors: [],
|
|
273
|
-
event: action.event,
|
|
274
|
-
editor,
|
|
275
|
-
keyGenerator,
|
|
276
|
-
schema,
|
|
277
|
-
getSnapshot,
|
|
278
|
-
nativeEvent: undefined,
|
|
279
|
-
sendBack,
|
|
280
|
-
})
|
|
281
|
-
}
|
|
302
|
+
},
|
|
303
|
+
)
|
|
282
304
|
|
|
283
305
|
if (undoStepCreated) {
|
|
284
306
|
clearUndoStep(editor)
|
|
@@ -3,7 +3,10 @@ import type {EventPosition} from '../internal-utils/event-position'
|
|
|
3
3
|
import type {MIMEType} from '../internal-utils/mime-type'
|
|
4
4
|
import type {OmitFromUnion, PickFromUnion, StrictExtract} from '../type-utils'
|
|
5
5
|
import type {BlockOffset} from '../types/block-offset'
|
|
6
|
-
import type {
|
|
6
|
+
import type {
|
|
7
|
+
BlockWithOptionalKey,
|
|
8
|
+
ChildWithOptionalKey,
|
|
9
|
+
} from '../types/block-with-optional-key'
|
|
7
10
|
import type {EditorSelection} from '../types/editor'
|
|
8
11
|
import type {AnnotationPath, BlockPath, ChildPath} from '../types/paths'
|
|
9
12
|
|
|
@@ -52,8 +55,7 @@ export type ExternalBehaviorEvent =
|
|
|
52
55
|
value?: {[prop: string]: unknown}
|
|
53
56
|
}
|
|
54
57
|
}
|
|
55
|
-
|
|
|
56
|
-
| CustomBehaviorEvent
|
|
58
|
+
| BehaviorEvent
|
|
57
59
|
|
|
58
60
|
/**************************************
|
|
59
61
|
* Synthetic events
|
|
@@ -72,6 +74,7 @@ const syntheticBehaviorEventTypes = [
|
|
|
72
74
|
'history.redo',
|
|
73
75
|
'history.undo',
|
|
74
76
|
'insert.block',
|
|
77
|
+
'insert.child',
|
|
75
78
|
'insert.text',
|
|
76
79
|
'move.backward',
|
|
77
80
|
'move.block',
|
|
@@ -159,6 +162,10 @@ export type SyntheticBehaviorEvent =
|
|
|
159
162
|
placement: InsertPlacement
|
|
160
163
|
select?: 'start' | 'end' | 'none'
|
|
161
164
|
}
|
|
165
|
+
| {
|
|
166
|
+
type: StrictExtract<SyntheticBehaviorEventType, 'insert.child'>
|
|
167
|
+
child: ChildWithOptionalKey
|
|
168
|
+
}
|
|
162
169
|
| {
|
|
163
170
|
type: StrictExtract<SyntheticBehaviorEventType, 'insert.text'>
|
|
164
171
|
text: string
|
package/src/editor/Editable.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {useSelector} from '@xstate/react'
|
|
2
2
|
import type {Editor} from '../editor'
|
|
3
|
+
import {slateRangeToSelection} from '../internal-utils/slate-utils'
|
|
3
4
|
import type {PortableTextSlateEditor} from '../types/editor'
|
|
4
5
|
import type {InternalEditor} from './create-editor'
|
|
5
6
|
import type {EditorActor} from './editor-machine'
|
|
@@ -65,6 +66,14 @@ export function getEditorSnapshot({
|
|
|
65
66
|
editorActorSnapshot: ReturnType<EditorActor['getSnapshot']>
|
|
66
67
|
slateEditorInstance: PortableTextSlateEditor
|
|
67
68
|
}): EditorSnapshot {
|
|
69
|
+
const selection = slateEditorInstance.selection
|
|
70
|
+
? slateRangeToSelection({
|
|
71
|
+
schema: editorActorSnapshot.context.schema,
|
|
72
|
+
editor: slateEditorInstance,
|
|
73
|
+
range: slateEditorInstance.selection,
|
|
74
|
+
})
|
|
75
|
+
: null
|
|
76
|
+
|
|
68
77
|
return {
|
|
69
78
|
blockIndexMap: slateEditorInstance.blockIndexMap,
|
|
70
79
|
context: {
|
|
@@ -72,7 +81,7 @@ export function getEditorSnapshot({
|
|
|
72
81
|
keyGenerator: editorActorSnapshot.context.keyGenerator,
|
|
73
82
|
readOnly: editorActorSnapshot.matches({'edit mode': 'read only'}),
|
|
74
83
|
schema: editorActorSnapshot.context.schema,
|
|
75
|
-
selection
|
|
84
|
+
selection,
|
|
76
85
|
value: slateEditorInstance.value,
|
|
77
86
|
},
|
|
78
87
|
decoratorState: slateEditorInstance.decoratorState,
|