@portabletext/editor 1.1.4 → 1.1.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/README.md +4 -0
- package/lib/index.d.mts +631 -30
- package/lib/index.d.ts +631 -30
- package/lib/index.esm.js +303 -200
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +295 -192
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +303 -200
- package/lib/index.mjs.map +1 -1
- package/package.json +30 -25
- package/src/editor/Editable.tsx +11 -11
- package/src/editor/PortableTextEditor.tsx +37 -32
- package/src/editor/__tests__/self-solving.test.tsx +1 -1
- package/src/editor/behavior/behavior.actions.ts +39 -0
- package/src/editor/behavior/behavior.core.ts +37 -0
- package/src/editor/behavior/behavior.types.ts +106 -0
- package/src/editor/behavior/behavior.utils.ts +34 -0
- package/src/editor/components/SlateContainer.tsx +2 -13
- package/src/editor/components/Synchronizer.tsx +0 -3
- package/src/editor/editor-machine.ts +120 -3
- package/src/editor/hooks/useSyncValue.ts +3 -5
- package/src/editor/key-generator.ts +6 -0
- package/src/editor/plugins/createWithEditableAPI.ts +8 -5
- package/src/editor/plugins/createWithHotKeys.ts +1 -32
- package/src/editor/plugins/createWithInsertBreak.ts +6 -2
- package/src/editor/plugins/createWithInsertData.ts +7 -4
- package/src/editor/plugins/createWithObjectKeys.ts +12 -5
- package/src/editor/plugins/createWithPatches.ts +0 -1
- package/src/editor/plugins/createWithPortableTextMarkModel.ts +85 -114
- package/src/editor/plugins/createWithSchemaTypes.ts +3 -4
- package/src/editor/plugins/createWithUtils.ts +5 -4
- package/src/editor/plugins/index.ts +5 -13
- package/src/index.ts +11 -2
- package/src/types/options.ts +0 -1
- package/src/utils/__tests__/operationToPatches.test.ts +0 -2
- package/src/utils/__tests__/patchToOperations.test.ts +1 -2
- package/src/utils/sibling-utils.ts +55 -0
- package/src/editor/hooks/usePortableTextEditorKeyGenerator.ts +0 -27
package/lib/index.esm.js
CHANGED
|
@@ -5,23 +5,23 @@ import { useRef, useState, useMemo, useEffect, useCallback, createContext, useCo
|
|
|
5
5
|
import { Editor, Element as Element$1, Range, Point, Text, Path, Transforms, Node, Operation, createEditor } from "slate";
|
|
6
6
|
import { useSlateStatic, ReactEditor, useSelected, withReact, Slate, useSlate, Editable } from "slate-react";
|
|
7
7
|
import debug$m from "debug";
|
|
8
|
-
import { isKeySegment,
|
|
8
|
+
import { isKeySegment, isPortableTextTextBlock, isPortableTextSpan, isPortableTextListBlock } from "@sanity/types";
|
|
9
9
|
import { styled } from "styled-components";
|
|
10
10
|
import uniq from "lodash/uniq.js";
|
|
11
11
|
import { Subject } from "rxjs";
|
|
12
|
-
import { fromCallback, setup,
|
|
12
|
+
import { fromCallback, setup, assertEvent, assign, emit, enqueueActions, createActor } from "xstate";
|
|
13
13
|
import { Schema } from "@sanity/schema";
|
|
14
|
+
import { isHotkey } from "is-hotkey-esm";
|
|
14
15
|
import { diffMatchPatch as diffMatchPatch$1, set, insert, setIfMissing, unset, applyAll } from "@portabletext/patches";
|
|
15
16
|
import get from "lodash/get.js";
|
|
16
17
|
import isUndefined from "lodash/isUndefined.js";
|
|
17
18
|
import omitBy from "lodash/omitBy.js";
|
|
18
19
|
import flatten from "lodash/flatten.js";
|
|
19
|
-
import { isHotkey } from "is-hotkey-esm";
|
|
20
20
|
import { htmlToBlocks, normalizeBlock } from "@sanity/block-tools";
|
|
21
21
|
import isPlainObject from "lodash/isPlainObject.js";
|
|
22
22
|
import throttle from "lodash/throttle.js";
|
|
23
|
-
import { randomKey } from "@sanity/util/content";
|
|
24
23
|
import debounce from "lodash/debounce.js";
|
|
24
|
+
import { randomKey } from "@sanity/util/content";
|
|
25
25
|
const rootName = "sanity-pte:";
|
|
26
26
|
debug$m(rootName);
|
|
27
27
|
function debugWithName(name) {
|
|
@@ -808,7 +808,28 @@ function compileType(rawType) {
|
|
|
808
808
|
types: [rawType]
|
|
809
809
|
}).get(rawType.name);
|
|
810
810
|
}
|
|
811
|
-
|
|
811
|
+
function getFocusBlock(context) {
|
|
812
|
+
const key = context.selection && isKeySegment(context.selection.focus.path[0]) ? context.selection.focus.path[0]._key : void 0, node = key ? context.value.find((block) => block._key === key) : void 0;
|
|
813
|
+
return node && key ? { node, path: [{ _key: key }] } : void 0;
|
|
814
|
+
}
|
|
815
|
+
function getFocusBlockObject(context) {
|
|
816
|
+
const focusBlock = getFocusBlock(context);
|
|
817
|
+
return focusBlock && !isPortableTextTextBlock(focusBlock.node) ? { node: focusBlock.node, path: focusBlock.path } : void 0;
|
|
818
|
+
}
|
|
819
|
+
const overwriteSoftReturn = {
|
|
820
|
+
on: "key down",
|
|
821
|
+
guard: ({ event }) => isHotkey("shift+enter", event.nativeEvent),
|
|
822
|
+
actions: [
|
|
823
|
+
({ event }) => (event.nativeEvent.preventDefault(), { type: "insert text", text: `
|
|
824
|
+
` })
|
|
825
|
+
]
|
|
826
|
+
}, enterOnVoidBlock = {
|
|
827
|
+
on: "key down",
|
|
828
|
+
guard: ({ context, event }) => isHotkey("enter", event.nativeEvent) ? !!getFocusBlockObject(context) : !1,
|
|
829
|
+
actions: [
|
|
830
|
+
({ event }) => (event.nativeEvent.preventDefault(), { type: "insert text block", decorators: [] })
|
|
831
|
+
]
|
|
832
|
+
}, coreBehaviors = [overwriteSoftReturn, enterOnVoidBlock], debug$k = debugWithName("operationToPatches");
|
|
812
833
|
function createOperationToPatches(types) {
|
|
813
834
|
const textBlockName = types.block.name;
|
|
814
835
|
function insertTextPatch(editor, operation, beforeValue) {
|
|
@@ -1084,7 +1105,7 @@ function createOperationToPatches(types) {
|
|
|
1084
1105
|
};
|
|
1085
1106
|
}
|
|
1086
1107
|
const debug$j = debugWithName("API:editable");
|
|
1087
|
-
function createWithEditableAPI(portableTextEditor, types
|
|
1108
|
+
function createWithEditableAPI(editorActor, portableTextEditor, types) {
|
|
1088
1109
|
return function(editor) {
|
|
1089
1110
|
return portableTextEditor.setEditable({
|
|
1090
1111
|
focus: () => {
|
|
@@ -1164,11 +1185,11 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1164
1185
|
const child = toSlateValue(
|
|
1165
1186
|
[
|
|
1166
1187
|
{
|
|
1167
|
-
_key: keyGenerator(),
|
|
1188
|
+
_key: editorActor.getSnapshot().context.keyGenerator(),
|
|
1168
1189
|
_type: types.block.name,
|
|
1169
1190
|
children: [
|
|
1170
1191
|
{
|
|
1171
|
-
_key: keyGenerator(),
|
|
1192
|
+
_key: editorActor.getSnapshot().context.keyGenerator(),
|
|
1172
1193
|
_type: type.name,
|
|
1173
1194
|
...value || {}
|
|
1174
1195
|
}
|
|
@@ -1196,7 +1217,7 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1196
1217
|
const block = toSlateValue(
|
|
1197
1218
|
[
|
|
1198
1219
|
{
|
|
1199
|
-
_key: keyGenerator(),
|
|
1220
|
+
_key: editorActor.getSnapshot().context.keyGenerator(),
|
|
1200
1221
|
_type: type.name,
|
|
1201
1222
|
...value || {}
|
|
1202
1223
|
}
|
|
@@ -1329,14 +1350,14 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1329
1350
|
})
|
|
1330
1351
|
];
|
|
1331
1352
|
if (spans.length === 0 || spans.some(
|
|
1332
|
-
([span]) => !isPortableTextSpan
|
|
1353
|
+
([span]) => !isPortableTextSpan(span) || !span.marks || span.marks?.length === 0
|
|
1333
1354
|
))
|
|
1334
1355
|
return !1;
|
|
1335
1356
|
const selectionMarkDefs = spans.reduce((accMarkDefs, [, path]) => {
|
|
1336
1357
|
const [block] = Editor.node(editor, path, { depth: 1 });
|
|
1337
1358
|
return editor.isTextBlock(block) && block.markDefs ? [...accMarkDefs, ...block.markDefs] : accMarkDefs;
|
|
1338
1359
|
}, []);
|
|
1339
|
-
return spans.every(([span]) => isPortableTextSpan
|
|
1360
|
+
return spans.every(([span]) => isPortableTextSpan(span) ? span.marks?.map(
|
|
1340
1361
|
(markKey) => selectionMarkDefs.find((def) => def?._key === markKey)?._type
|
|
1341
1362
|
)?.includes(annotationType) : !1);
|
|
1342
1363
|
} catch {
|
|
@@ -1360,7 +1381,7 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1360
1381
|
for (const [block, blockPath] of selectedBlocks) {
|
|
1361
1382
|
if (block.children.length === 0 || block.children.length === 1 && block.children[0].text === "")
|
|
1362
1383
|
continue;
|
|
1363
|
-
const annotationKey = keyGenerator(), markDefs = block.markDefs ?? [];
|
|
1384
|
+
const annotationKey = editorActor.getSnapshot().context.keyGenerator(), markDefs = block.markDefs ?? [];
|
|
1364
1385
|
markDefs.find(
|
|
1365
1386
|
(markDef) => markDef._type === type.name && markDef._key === annotationKey
|
|
1366
1387
|
) === void 0 && (Transforms.setNodes(
|
|
@@ -1569,7 +1590,7 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1569
1590
|
}), editor;
|
|
1570
1591
|
};
|
|
1571
1592
|
}
|
|
1572
|
-
function createWithInsertBreak(
|
|
1593
|
+
function createWithInsertBreak(editorActor, types) {
|
|
1573
1594
|
return function(editor) {
|
|
1574
1595
|
const { insertBreak } = editor;
|
|
1575
1596
|
return editor.insertBreak = () => {
|
|
@@ -1658,7 +1679,10 @@ function createWithInsertBreak(types, keyGenerator) {
|
|
|
1658
1679
|
(decorator) => decorator.value === mark
|
|
1659
1680
|
) || prevNodeSpans.some(
|
|
1660
1681
|
(prevNodeSpan) => prevNodeSpan.marks?.includes(mark)
|
|
1661
|
-
) && !newMarkDefKeys.has(mark) && newMarkDefKeys.set(
|
|
1682
|
+
) && !newMarkDefKeys.has(mark) && newMarkDefKeys.set(
|
|
1683
|
+
mark,
|
|
1684
|
+
editorActor.getSnapshot().context.keyGenerator()
|
|
1685
|
+
);
|
|
1662
1686
|
const newMarks = marks.map(
|
|
1663
1687
|
(mark) => newMarkDefKeys.get(mark) ?? mark
|
|
1664
1688
|
);
|
|
@@ -1739,7 +1763,7 @@ function createWithMaxBlocks(maxBlocks) {
|
|
|
1739
1763
|
}, editor;
|
|
1740
1764
|
};
|
|
1741
1765
|
}
|
|
1742
|
-
function createWithObjectKeys(editorActor, schemaTypes
|
|
1766
|
+
function createWithObjectKeys(editorActor, schemaTypes) {
|
|
1743
1767
|
return function(editor) {
|
|
1744
1768
|
const { apply: apply2, normalizeNode } = editor;
|
|
1745
1769
|
return editor.apply = (operation) => {
|
|
@@ -1756,7 +1780,7 @@ function createWithObjectKeys(editorActor, schemaTypes, keyGenerator) {
|
|
|
1756
1780
|
...operation,
|
|
1757
1781
|
properties: {
|
|
1758
1782
|
...operation.properties,
|
|
1759
|
-
_key: keyGenerator()
|
|
1783
|
+
_key: editorActor.getSnapshot().context.keyGenerator()
|
|
1760
1784
|
}
|
|
1761
1785
|
});
|
|
1762
1786
|
return;
|
|
@@ -1766,7 +1790,7 @@ function createWithObjectKeys(editorActor, schemaTypes, keyGenerator) {
|
|
|
1766
1790
|
...operation,
|
|
1767
1791
|
node: {
|
|
1768
1792
|
...operation.node,
|
|
1769
|
-
_key: keyGenerator()
|
|
1793
|
+
_key: editorActor.getSnapshot().context.keyGenerator()
|
|
1770
1794
|
}
|
|
1771
1795
|
});
|
|
1772
1796
|
return;
|
|
@@ -1776,12 +1800,20 @@ function createWithObjectKeys(editorActor, schemaTypes, keyGenerator) {
|
|
|
1776
1800
|
const [node, path] = entry;
|
|
1777
1801
|
if (Element$1.isElement(node) && node._type === schemaTypes.block.name) {
|
|
1778
1802
|
if (!node._key) {
|
|
1779
|
-
editorActor.send({ type: "normalizing" }), Transforms.setNodes(
|
|
1803
|
+
editorActor.send({ type: "normalizing" }), Transforms.setNodes(
|
|
1804
|
+
editor,
|
|
1805
|
+
{ _key: editorActor.getSnapshot().context.keyGenerator() },
|
|
1806
|
+
{ at: path }
|
|
1807
|
+
), editorActor.send({ type: "done normalizing" });
|
|
1780
1808
|
return;
|
|
1781
1809
|
}
|
|
1782
1810
|
for (const [child, childPath] of Node.children(editor, path))
|
|
1783
1811
|
if (!child._key) {
|
|
1784
|
-
editorActor.send({ type: "normalizing" }), Transforms.setNodes(
|
|
1812
|
+
editorActor.send({ type: "normalizing" }), Transforms.setNodes(
|
|
1813
|
+
editor,
|
|
1814
|
+
{ _key: editorActor.getSnapshot().context.keyGenerator() },
|
|
1815
|
+
{ at: childPath }
|
|
1816
|
+
), editorActor.send({ type: "done normalizing" });
|
|
1785
1817
|
return;
|
|
1786
1818
|
}
|
|
1787
1819
|
}
|
|
@@ -3257,9 +3289,6 @@ function createWithPortableTextLists(types) {
|
|
|
3257
3289
|
}, editor;
|
|
3258
3290
|
};
|
|
3259
3291
|
}
|
|
3260
|
-
function isPortableTextSpan(node) {
|
|
3261
|
-
return node._type === "span" && "text" in node && typeof node.text == "string" && (typeof node.marks > "u" || Array.isArray(node.marks) && node.marks.every((mark) => typeof mark == "string"));
|
|
3262
|
-
}
|
|
3263
3292
|
function isPortableTextBlock(node) {
|
|
3264
3293
|
return (
|
|
3265
3294
|
// A block doesn't _have_ to be named 'block' - to differentiate between
|
|
@@ -3272,8 +3301,36 @@ function isPortableTextBlock(node) {
|
|
|
3272
3301
|
node.children.every((child) => typeof child == "object" && "_type" in child)
|
|
3273
3302
|
);
|
|
3274
3303
|
}
|
|
3304
|
+
function getPreviousSpan({
|
|
3305
|
+
editor,
|
|
3306
|
+
blockPath,
|
|
3307
|
+
spanPath
|
|
3308
|
+
}) {
|
|
3309
|
+
let previousSpan;
|
|
3310
|
+
for (const [child, childPath] of Node.children(editor, blockPath, {
|
|
3311
|
+
reverse: !0
|
|
3312
|
+
}))
|
|
3313
|
+
if (editor.isTextSpan(child) && Path.isBefore(childPath, spanPath)) {
|
|
3314
|
+
previousSpan = child;
|
|
3315
|
+
break;
|
|
3316
|
+
}
|
|
3317
|
+
return previousSpan;
|
|
3318
|
+
}
|
|
3319
|
+
function getNextSpan({
|
|
3320
|
+
editor,
|
|
3321
|
+
blockPath,
|
|
3322
|
+
spanPath
|
|
3323
|
+
}) {
|
|
3324
|
+
let nextSpan;
|
|
3325
|
+
for (const [child, childPath] of Node.children(editor, blockPath))
|
|
3326
|
+
if (editor.isTextSpan(child) && Path.isAfter(childPath, spanPath)) {
|
|
3327
|
+
nextSpan = child;
|
|
3328
|
+
break;
|
|
3329
|
+
}
|
|
3330
|
+
return nextSpan;
|
|
3331
|
+
}
|
|
3275
3332
|
const debug$c = debugWithName("plugin:withPortableTextMarkModel");
|
|
3276
|
-
function createWithPortableTextMarkModel(editorActor, types
|
|
3333
|
+
function createWithPortableTextMarkModel(editorActor, types) {
|
|
3277
3334
|
return function(editor) {
|
|
3278
3335
|
const { apply: apply2, normalizeNode } = editor, decorators = types.decorators.map((t) => t.value), forceNewSelection = () => {
|
|
3279
3336
|
editor.selection && (Transforms.select(editor, { ...editor.selection }), editor.selection = { ...editor.selection });
|
|
@@ -3411,98 +3468,85 @@ function createWithPortableTextMarkModel(editorActor, types, keyGenerator) {
|
|
|
3411
3468
|
})
|
|
3412
3469
|
)[0] ?? [void 0, void 0], marks = span.marks ?? [], marksWithoutAnnotations = marks.filter(
|
|
3413
3470
|
(mark) => decorators.includes(mark)
|
|
3414
|
-
), spanHasAnnotations = marks.length > marksWithoutAnnotations.length, spanIsEmpty = span.text.length === 0, atTheBeginningOfSpan = selection.anchor.offset === 0, atTheEndOfSpan = selection.anchor.offset === span.text.length
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
reverse: !0
|
|
3418
|
-
}))
|
|
3419
|
-
if (editor.isTextSpan(child) && Path.isBefore(childPath, spanPath)) {
|
|
3420
|
-
previousSpan = child;
|
|
3421
|
-
break;
|
|
3422
|
-
}
|
|
3423
|
-
for (const [child, childPath] of Node.children(editor, blockPath))
|
|
3424
|
-
if (editor.isTextSpan(child) && Path.isAfter(childPath, spanPath)) {
|
|
3425
|
-
nextSpan = child;
|
|
3426
|
-
break;
|
|
3427
|
-
}
|
|
3428
|
-
const previousSpanHasSameAnnotation = previousSpan ? previousSpan.marks?.some(
|
|
3471
|
+
), spanHasAnnotations = marks.length > marksWithoutAnnotations.length, spanIsEmpty = span.text.length === 0, atTheBeginningOfSpan = selection.anchor.offset === 0, atTheEndOfSpan = selection.anchor.offset === span.text.length, previousSpan = getPreviousSpan({ editor, blockPath, spanPath }), nextSpan = getNextSpan({ editor, blockPath, spanPath }), nextSpanAnnotations = nextSpan?.marks?.filter((mark) => !decorators.includes(mark)) ?? [], spanAnnotations = marks.filter(
|
|
3472
|
+
(mark) => !decorators.includes(mark)
|
|
3473
|
+
), previousSpanHasSameAnnotation = previousSpan ? previousSpan.marks?.some(
|
|
3429
3474
|
(mark) => !decorators.includes(mark) && marks.includes(mark)
|
|
3430
|
-
) : !1, previousSpanHasSameMarks = previousSpan ? previousSpan.marks?.every((mark) => marks.includes(mark)) : !1,
|
|
3431
|
-
(mark) =>
|
|
3432
|
-
)
|
|
3475
|
+
) : !1, previousSpanHasSameMarks = previousSpan ? previousSpan.marks?.every((mark) => marks.includes(mark)) : !1, nextSpanSharesSomeAnnotations = spanAnnotations.some(
|
|
3476
|
+
(mark) => nextSpanAnnotations?.includes(mark)
|
|
3477
|
+
);
|
|
3433
3478
|
if (spanHasAnnotations && !spanIsEmpty) {
|
|
3434
3479
|
if (atTheBeginningOfSpan) {
|
|
3435
3480
|
previousSpanHasSameMarks ? Transforms.insertNodes(editor, {
|
|
3436
3481
|
_type: "span",
|
|
3437
|
-
_key: keyGenerator(),
|
|
3482
|
+
_key: editorActor.getSnapshot().context.keyGenerator(),
|
|
3438
3483
|
text: op.text,
|
|
3439
3484
|
marks: previousSpan?.marks ?? []
|
|
3440
3485
|
}) : previousSpanHasSameAnnotation ? apply2(op) : Transforms.insertNodes(editor, {
|
|
3441
3486
|
_type: "span",
|
|
3442
|
-
_key: keyGenerator(),
|
|
3487
|
+
_key: editorActor.getSnapshot().context.keyGenerator(),
|
|
3443
3488
|
text: op.text,
|
|
3444
3489
|
marks: []
|
|
3445
3490
|
});
|
|
3446
3491
|
return;
|
|
3447
3492
|
}
|
|
3448
3493
|
if (atTheEndOfSpan) {
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3494
|
+
if (nextSpan && nextSpanSharesSomeAnnotations && nextSpanAnnotations.length < spanAnnotations.length || !nextSpanSharesSomeAnnotations) {
|
|
3495
|
+
Transforms.insertNodes(editor, {
|
|
3496
|
+
_type: "span",
|
|
3497
|
+
_key: editorActor.getSnapshot().context.keyGenerator(),
|
|
3498
|
+
text: op.text,
|
|
3499
|
+
marks: nextSpan?.marks ?? []
|
|
3500
|
+
});
|
|
3501
|
+
return;
|
|
3502
|
+
}
|
|
3503
|
+
if (!nextSpan) {
|
|
3504
|
+
Transforms.insertNodes(editor, {
|
|
3505
|
+
_type: "span",
|
|
3506
|
+
_key: editorActor.getSnapshot().context.keyGenerator(),
|
|
3507
|
+
text: op.text,
|
|
3508
|
+
marks: []
|
|
3509
|
+
});
|
|
3510
|
+
return;
|
|
3511
|
+
}
|
|
3461
3512
|
}
|
|
3462
3513
|
}
|
|
3463
3514
|
}
|
|
3464
3515
|
}
|
|
3465
3516
|
if (op.type === "remove_text") {
|
|
3466
|
-
const
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
)
|
|
3478
|
-
if (
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
}
|
|
3499
|
-
return;
|
|
3500
|
-
}
|
|
3501
|
-
if (node.marks !== void 0 && node.marks.length > 0 && deletingAllText) {
|
|
3502
|
-
Editor.withoutNormalizing(editor, () => {
|
|
3503
|
-
apply2(op), Transforms.setNodes(editor, { marks: [] }, { at: op.path });
|
|
3504
|
-
}), editor.onChange();
|
|
3505
|
-
return;
|
|
3517
|
+
const { selection } = editor;
|
|
3518
|
+
if (selection && Range.isExpanded(selection)) {
|
|
3519
|
+
const [block, blockPath] = Editor.node(editor, selection, {
|
|
3520
|
+
depth: 1
|
|
3521
|
+
}), [span, spanPath] = Array.from(
|
|
3522
|
+
Editor.nodes(editor, {
|
|
3523
|
+
mode: "lowest",
|
|
3524
|
+
at: { path: op.path, offset: op.offset },
|
|
3525
|
+
match: (n) => editor.isTextSpan(n),
|
|
3526
|
+
voids: !1
|
|
3527
|
+
})
|
|
3528
|
+
)[0] ?? [void 0, void 0];
|
|
3529
|
+
if (span && block && isPortableTextBlock(block)) {
|
|
3530
|
+
const markDefs = block.markDefs ?? [], marks = span.marks ?? [], spanHasAnnotations = marks.some(
|
|
3531
|
+
(mark) => markDefs.find((markDef) => markDef._key === mark)
|
|
3532
|
+
), deletingFromTheEnd = op.offset + op.text.length === span.text.length, deletingAllText = op.offset === 0 && deletingFromTheEnd, previousSpan = getPreviousSpan({ editor, blockPath, spanPath }), nextSpan = getNextSpan({ editor, blockPath, spanPath }), previousSpanHasSameAnnotation = previousSpan ? previousSpan.marks?.some(
|
|
3533
|
+
(mark) => !decorators.includes(mark) && marks.includes(mark)
|
|
3534
|
+
) : !1, nextSpanHasSameAnnotation = nextSpan ? nextSpan.marks?.some(
|
|
3535
|
+
(mark) => !decorators.includes(mark) && marks.includes(mark)
|
|
3536
|
+
) : !1;
|
|
3537
|
+
if (spanHasAnnotations && deletingAllText && !previousSpanHasSameAnnotation && !nextSpanHasSameAnnotation) {
|
|
3538
|
+
const marksWithoutAnnotationMarks = ({
|
|
3539
|
+
...Editor.marks(editor) || {}
|
|
3540
|
+
}.marks || []).filter((mark) => decorators.includes(mark));
|
|
3541
|
+
Editor.withoutNormalizing(editor, () => {
|
|
3542
|
+
apply2(op), Transforms.setNodes(
|
|
3543
|
+
editor,
|
|
3544
|
+
{ marks: marksWithoutAnnotationMarks },
|
|
3545
|
+
{ at: op.path }
|
|
3546
|
+
);
|
|
3547
|
+
}), editor.onChange();
|
|
3548
|
+
return;
|
|
3549
|
+
}
|
|
3506
3550
|
}
|
|
3507
3551
|
}
|
|
3508
3552
|
}
|
|
@@ -3686,17 +3730,16 @@ function createWithPortableTextSelections(editorActor, types) {
|
|
|
3686
3730
|
const debug$a = debugWithName("plugin:withSchemaTypes");
|
|
3687
3731
|
function createWithSchemaTypes({
|
|
3688
3732
|
editorActor,
|
|
3689
|
-
schemaTypes
|
|
3690
|
-
keyGenerator
|
|
3733
|
+
schemaTypes
|
|
3691
3734
|
}) {
|
|
3692
3735
|
return function(editor) {
|
|
3693
|
-
editor.isTextBlock = (value) => isPortableTextTextBlock(value) && value._type === schemaTypes.block.name, editor.isTextSpan = (value) => isPortableTextSpan
|
|
3736
|
+
editor.isTextBlock = (value) => isPortableTextTextBlock(value) && value._type === schemaTypes.block.name, editor.isTextSpan = (value) => isPortableTextSpan(value) && value._type === schemaTypes.span.name, editor.isListBlock = (value) => isPortableTextListBlock(value) && value._type === schemaTypes.block.name, editor.isVoid = (element) => schemaTypes.block.name !== element._type && (schemaTypes.blockObjects.map((obj) => obj.name).includes(element._type) || schemaTypes.inlineObjects.map((obj) => obj.name).includes(element._type)), editor.isInline = (element) => schemaTypes.inlineObjects.map((obj) => obj.name).includes(element._type) && "__inline" in element && element.__inline === !0;
|
|
3694
3737
|
const { normalizeNode } = editor;
|
|
3695
3738
|
return editor.normalizeNode = (entry) => {
|
|
3696
3739
|
const [node, path] = entry;
|
|
3697
3740
|
if (node._type === void 0 && path.length === 2) {
|
|
3698
3741
|
debug$a("Setting span type on text node without a type");
|
|
3699
|
-
const span = node, key = span._key || keyGenerator();
|
|
3742
|
+
const span = node, key = span._key || editorActor.getSnapshot().context.keyGenerator();
|
|
3700
3743
|
editorActor.send({ type: "normalizing" }), Transforms.setNodes(
|
|
3701
3744
|
editor,
|
|
3702
3745
|
{ ...span, _type: schemaTypes.span.name, _key: key },
|
|
@@ -3706,7 +3749,7 @@ function createWithSchemaTypes({
|
|
|
3706
3749
|
}
|
|
3707
3750
|
if (node._key === void 0 && (path.length === 1 || path.length === 2)) {
|
|
3708
3751
|
debug$a("Setting missing key on child node without a key");
|
|
3709
|
-
const key = keyGenerator();
|
|
3752
|
+
const key = editorActor.getSnapshot().context.keyGenerator();
|
|
3710
3753
|
editorActor.send({ type: "normalizing" }), Transforms.setNodes(editor, { _key: key }, { at: path }), editorActor.send({ type: "done normalizing" });
|
|
3711
3754
|
return;
|
|
3712
3755
|
}
|
|
@@ -3716,8 +3759,8 @@ function createWithSchemaTypes({
|
|
|
3716
3759
|
}
|
|
3717
3760
|
const debug$9 = debugWithName("plugin:withUtils");
|
|
3718
3761
|
function createWithUtils({
|
|
3762
|
+
editorActor,
|
|
3719
3763
|
schemaTypes,
|
|
3720
|
-
keyGenerator,
|
|
3721
3764
|
portableTextEditor
|
|
3722
3765
|
}) {
|
|
3723
3766
|
return function(editor) {
|
|
@@ -3743,13 +3786,13 @@ function createWithUtils({
|
|
|
3743
3786
|
[
|
|
3744
3787
|
{
|
|
3745
3788
|
_type: schemaTypes.block.name,
|
|
3746
|
-
_key: keyGenerator(),
|
|
3789
|
+
_key: editorActor.getSnapshot().context.keyGenerator(),
|
|
3747
3790
|
style: schemaTypes.styles[0].value || "normal",
|
|
3748
3791
|
markDefs: [],
|
|
3749
3792
|
children: [
|
|
3750
3793
|
{
|
|
3751
3794
|
_type: "span",
|
|
3752
|
-
_key: keyGenerator(),
|
|
3795
|
+
_key: editorActor.getSnapshot().context.keyGenerator(),
|
|
3753
3796
|
text: "",
|
|
3754
3797
|
marks: options.decorators.filter(
|
|
3755
3798
|
(decorator) => schemaTypes.decorators.find(({ value }) => value === decorator)
|
|
@@ -3817,7 +3860,7 @@ function createWithHotkeys(types, portableTextEditor, hotkeysFromOptions) {
|
|
|
3817
3860
|
{
|
|
3818
3861
|
at: nextPath
|
|
3819
3862
|
}
|
|
3820
|
-
), editor.onChange();
|
|
3863
|
+
), Transforms.select(editor, { path: [...nextPath, 0], offset: 0 }), editor.onChange();
|
|
3821
3864
|
return;
|
|
3822
3865
|
}
|
|
3823
3866
|
}
|
|
@@ -3841,10 +3884,10 @@ function createWithHotkeys(types, portableTextEditor, hotkeysFromOptions) {
|
|
|
3841
3884
|
if ((isTab || isShiftTab) && editor.selection) {
|
|
3842
3885
|
const [focusChild] = Editor.node(editor, editor.selection.focus, {
|
|
3843
3886
|
depth: 2
|
|
3844
|
-
}), [focusBlock] = isPortableTextSpan
|
|
3887
|
+
}), [focusBlock] = isPortableTextSpan(focusChild) ? Editor.node(editor, editor.selection.focus, { depth: 1 }) : [], hasAnnotationFocus = focusChild && isPortableTextTextBlock(focusBlock) && isPortableTextSpan(focusChild) && (focusChild.marks || []).filter(
|
|
3845
3888
|
(m) => (focusBlock.markDefs || []).map((def) => def._key).includes(m)
|
|
3846
3889
|
).length > 0, [start] = Range.edges(editor.selection), atStartOfNode = Editor.isStart(editor, start, start.path);
|
|
3847
|
-
focusChild && isPortableTextSpan
|
|
3890
|
+
focusChild && isPortableTextSpan(focusChild) && (!hasAnnotationFocus || atStartOfNode) && editor.pteIncrementBlockLevels(isShiftTab) && event.preventDefault();
|
|
3848
3891
|
}
|
|
3849
3892
|
if (isEnter && !isShiftEnter && editor.selection) {
|
|
3850
3893
|
const focusBlockPath = editor.selection.focus.path.slice(0, 1), focusBlock = Node.descendant(editor, focusBlockPath);
|
|
@@ -3862,22 +3905,7 @@ function createWithHotkeys(types, portableTextEditor, hotkeysFromOptions) {
|
|
|
3862
3905
|
return;
|
|
3863
3906
|
}
|
|
3864
3907
|
}
|
|
3865
|
-
if (focusBlock && Editor.isVoid(editor, focusBlock)) {
|
|
3866
|
-
Editor.insertNode(editor, editor.pteCreateTextBlock({ decorators: [] })), event.preventDefault(), editor.onChange();
|
|
3867
|
-
return;
|
|
3868
|
-
}
|
|
3869
|
-
event.preventDefault(), editor.insertBreak(), editor.onChange();
|
|
3870
|
-
}
|
|
3871
|
-
if (isShiftEnter) {
|
|
3872
|
-
event.preventDefault(), editor.insertText(`
|
|
3873
|
-
`);
|
|
3874
|
-
return;
|
|
3875
3908
|
}
|
|
3876
|
-
if (isHotkey("mod+z", event.nativeEvent)) {
|
|
3877
|
-
event.preventDefault(), editor.undo();
|
|
3878
|
-
return;
|
|
3879
|
-
}
|
|
3880
|
-
(isHotkey("mod+y", event.nativeEvent) || isHotkey("mod+shift+z", event.nativeEvent)) && (event.preventDefault(), editor.redo());
|
|
3881
3909
|
}, editor;
|
|
3882
3910
|
};
|
|
3883
3911
|
}
|
|
@@ -4160,7 +4188,7 @@ function validateValue(value, types, keyGenerator) {
|
|
|
4160
4188
|
}) && (valid = !1), { valid, resolution, value });
|
|
4161
4189
|
}
|
|
4162
4190
|
const debug$7 = debugWithName("plugin:withInsertData");
|
|
4163
|
-
function createWithInsertData(editorActor, schemaTypes
|
|
4191
|
+
function createWithInsertData(editorActor, schemaTypes) {
|
|
4164
4192
|
return function(editor) {
|
|
4165
4193
|
const blockTypeName = schemaTypes.block.name, spanTypeName = schemaTypes.span.name, whitespaceOnPasteMode = schemaTypes.block.options.unstable_whitespaceOnPasteMode, toPlainText = (blocks) => blocks.map((block) => editor.isTextBlock(block) ? block.children.map((child) => child._type === spanTypeName ? child.text : `[${schemaTypes.inlineObjects.find((t) => t.name === child._type)?.title || "Object"}]`).join("") : `[${schemaTypes.blockObjects.find((t) => t.name === block._type)?.title || "Object"}]`).join(`
|
|
4166
4194
|
|
|
@@ -4208,10 +4236,14 @@ function createWithInsertData(editorActor, schemaTypes, keyGenerator) {
|
|
|
4208
4236
|
const slateValue = _regenerateKeys(
|
|
4209
4237
|
editor,
|
|
4210
4238
|
toSlateValue(parsed, { schemaTypes }),
|
|
4211
|
-
keyGenerator,
|
|
4239
|
+
editorActor.getSnapshot().context.keyGenerator,
|
|
4212
4240
|
spanTypeName,
|
|
4213
4241
|
schemaTypes
|
|
4214
|
-
), validation = validateValue(
|
|
4242
|
+
), validation = validateValue(
|
|
4243
|
+
parsed,
|
|
4244
|
+
schemaTypes,
|
|
4245
|
+
editorActor.getSnapshot().context.keyGenerator
|
|
4246
|
+
);
|
|
4215
4247
|
if (!validation.valid && !validation.resolution?.autoResolve) {
|
|
4216
4248
|
const errorDescription = `${validation.resolution?.description}`;
|
|
4217
4249
|
return editorActor.send({
|
|
@@ -4252,7 +4284,7 @@ function createWithInsertData(editorActor, schemaTypes, keyGenerator) {
|
|
|
4252
4284
|
const validation = validateValue(
|
|
4253
4285
|
portableText,
|
|
4254
4286
|
schemaTypes,
|
|
4255
|
-
keyGenerator
|
|
4287
|
+
editorActor.getSnapshot().context.keyGenerator
|
|
4256
4288
|
);
|
|
4257
4289
|
if (!validation.valid) {
|
|
4258
4290
|
const errorDescription = `Could not validate the resulting portable text to insert.
|
|
@@ -4356,27 +4388,21 @@ function _insertFragment(editor, fragment, schemaTypes) {
|
|
|
4356
4388
|
}), editor.onChange();
|
|
4357
4389
|
}
|
|
4358
4390
|
const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, options) => {
|
|
4359
|
-
const e = editor, {
|
|
4391
|
+
const e = editor, { portableTextEditor, patches$, readOnly, maxBlocks } = options, { editorActor, schemaTypes } = portableTextEditor;
|
|
4360
4392
|
e.subscriptions = [], e.destroy ? e.destroy() : originalFnMap.set(e, {
|
|
4361
4393
|
apply: e.apply,
|
|
4362
4394
|
onChange: e.onChange,
|
|
4363
4395
|
normalizeNode: e.normalizeNode
|
|
4364
4396
|
});
|
|
4365
|
-
const operationToPatches = createOperationToPatches(schemaTypes), withObjectKeys = createWithObjectKeys(
|
|
4397
|
+
const operationToPatches = createOperationToPatches(schemaTypes), withObjectKeys = createWithObjectKeys(editorActor, schemaTypes), withSchemaTypes = createWithSchemaTypes({
|
|
4366
4398
|
editorActor,
|
|
4367
|
-
schemaTypes
|
|
4368
|
-
keyGenerator
|
|
4369
|
-
), withSchemaTypes = createWithSchemaTypes({
|
|
4370
|
-
editorActor,
|
|
4371
|
-
schemaTypes,
|
|
4372
|
-
keyGenerator
|
|
4399
|
+
schemaTypes
|
|
4373
4400
|
}), withEditableAPI = createWithEditableAPI(
|
|
4401
|
+
editorActor,
|
|
4374
4402
|
portableTextEditor,
|
|
4375
|
-
schemaTypes
|
|
4376
|
-
keyGenerator
|
|
4403
|
+
schemaTypes
|
|
4377
4404
|
), withPatches = createWithPatches({
|
|
4378
4405
|
editorActor,
|
|
4379
|
-
keyGenerator,
|
|
4380
4406
|
patches$,
|
|
4381
4407
|
patchFunctions: operationToPatches,
|
|
4382
4408
|
readOnly,
|
|
@@ -4387,13 +4413,12 @@ const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, opti
|
|
|
4387
4413
|
blockSchemaType: schemaTypes.block
|
|
4388
4414
|
}), withPortableTextMarkModel = createWithPortableTextMarkModel(
|
|
4389
4415
|
editorActor,
|
|
4390
|
-
schemaTypes
|
|
4391
|
-
keyGenerator
|
|
4416
|
+
schemaTypes
|
|
4392
4417
|
), withPortableTextBlockStyle = createWithPortableTextBlockStyle(
|
|
4393
4418
|
editorActor,
|
|
4394
4419
|
schemaTypes
|
|
4395
|
-
), withPlaceholderBlock = createWithPlaceholderBlock(), withInsertBreak = createWithInsertBreak(
|
|
4396
|
-
|
|
4420
|
+
), withPlaceholderBlock = createWithPlaceholderBlock(), withInsertBreak = createWithInsertBreak(editorActor, schemaTypes), withUtils = createWithUtils({
|
|
4421
|
+
editorActor,
|
|
4397
4422
|
schemaTypes,
|
|
4398
4423
|
portableTextEditor
|
|
4399
4424
|
}), withPortableTextSelections = createWithPortableTextSelections(
|
|
@@ -4461,10 +4486,9 @@ const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, opti
|
|
|
4461
4486
|
};
|
|
4462
4487
|
}, debug$6 = debugWithName("component:PortableTextEditor:SlateContainer");
|
|
4463
4488
|
function SlateContainer(props) {
|
|
4464
|
-
const { patches$, portableTextEditor, readOnly, maxBlocks
|
|
4489
|
+
const { patches$, portableTextEditor, readOnly, maxBlocks } = props, [[slateEditor, subscribe]] = useState(() => {
|
|
4465
4490
|
debug$6("Creating new Slate editor instance");
|
|
4466
4491
|
const { editor, subscribe: _sub } = withPlugins(withReact(createEditor()), {
|
|
4467
|
-
keyGenerator,
|
|
4468
4492
|
maxBlocks,
|
|
4469
4493
|
patches$,
|
|
4470
4494
|
portableTextEditor,
|
|
@@ -4479,33 +4503,18 @@ function SlateContainer(props) {
|
|
|
4479
4503
|
};
|
|
4480
4504
|
}, [subscribe]), useEffect(() => {
|
|
4481
4505
|
debug$6("Re-initializing plugin chain"), withPlugins(slateEditor, {
|
|
4482
|
-
keyGenerator,
|
|
4483
4506
|
maxBlocks,
|
|
4484
4507
|
patches$,
|
|
4485
4508
|
portableTextEditor,
|
|
4486
4509
|
readOnly
|
|
4487
4510
|
});
|
|
4488
|
-
}, [
|
|
4489
|
-
keyGenerator,
|
|
4490
|
-
portableTextEditor,
|
|
4491
|
-
maxBlocks,
|
|
4492
|
-
readOnly,
|
|
4493
|
-
patches$,
|
|
4494
|
-
slateEditor
|
|
4495
|
-
]);
|
|
4511
|
+
}, [portableTextEditor, maxBlocks, readOnly, patches$, slateEditor]);
|
|
4496
4512
|
const initialValue = useMemo(() => [slateEditor.pteCreateTextBlock({ decorators: [] })], [slateEditor]);
|
|
4497
4513
|
return useEffect(() => () => {
|
|
4498
4514
|
debug$6("Destroying Slate editor"), slateEditor.destroy();
|
|
4499
4515
|
}, [slateEditor]), /* @__PURE__ */ jsx(Slate, { editor: slateEditor, initialValue, children: props.children });
|
|
4500
4516
|
}
|
|
4501
|
-
const
|
|
4502
|
-
const keyGenerator = useContext(PortableTextEditorKeyGeneratorContext);
|
|
4503
|
-
if (keyGenerator === void 0)
|
|
4504
|
-
throw new Error(
|
|
4505
|
-
"The `usePortableTextEditorKeyGenerator` hook must be used inside the <PortableTextEditor> component's context."
|
|
4506
|
-
);
|
|
4507
|
-
return keyGenerator;
|
|
4508
|
-
}, PortableTextEditorReadOnlyContext = createContext(!1), usePortableTextEditorReadOnlyStatus = () => {
|
|
4517
|
+
const PortableTextEditorReadOnlyContext = createContext(!1), usePortableTextEditorReadOnlyStatus = () => {
|
|
4509
4518
|
const readOnly = useContext(PortableTextEditorReadOnlyContext);
|
|
4510
4519
|
if (readOnly === void 0)
|
|
4511
4520
|
throw new Error(
|
|
@@ -4514,7 +4523,7 @@ const defaultKeyGenerator = () => randomKey(12), PortableTextEditorKeyGeneratorC
|
|
|
4514
4523
|
return readOnly;
|
|
4515
4524
|
}, debug$5 = debugWithName("hook:useSyncValue"), CURRENT_VALUE = /* @__PURE__ */ new WeakMap();
|
|
4516
4525
|
function useSyncValue(props) {
|
|
4517
|
-
const { editorActor, portableTextEditor, readOnly
|
|
4526
|
+
const { editorActor, portableTextEditor, readOnly } = props, { schemaTypes } = portableTextEditor, previousValue = useRef(), slateEditor = useSlate(), updateValueFunctionRef = useRef(), updateFromCurrentValue = useCallback(() => {
|
|
4518
4527
|
const currentValue = CURRENT_VALUE.get(portableTextEditor);
|
|
4519
4528
|
if (previousValue.current === currentValue) {
|
|
4520
4529
|
debug$5("Value is the same object as previous, not need to sync");
|
|
@@ -4580,7 +4589,7 @@ function useSyncValue(props) {
|
|
|
4580
4589
|
const validationValue = [value[currentBlockIndex]], validation = validateValue(
|
|
4581
4590
|
validationValue,
|
|
4582
4591
|
schemaTypes,
|
|
4583
|
-
keyGenerator
|
|
4592
|
+
editorActor.getSnapshot().context.keyGenerator
|
|
4584
4593
|
);
|
|
4585
4594
|
!validation.valid && validation.resolution?.autoResolve && validation.resolution?.patches.length > 0 && !readOnly && previousValue.current && previousValue.current !== value && (console.warn(
|
|
4586
4595
|
`${validation.resolution.action} for block with _key '${validationValue[0]._key}'. ${validation.resolution?.description}`
|
|
@@ -4605,7 +4614,7 @@ function useSyncValue(props) {
|
|
|
4605
4614
|
const validationValue = [value[currentBlockIndex]], validation = validateValue(
|
|
4606
4615
|
validationValue,
|
|
4607
4616
|
schemaTypes,
|
|
4608
|
-
keyGenerator
|
|
4617
|
+
editorActor.getSnapshot().context.keyGenerator
|
|
4609
4618
|
);
|
|
4610
4619
|
debug$5.enabled && debug$5(
|
|
4611
4620
|
"Validating and inserting new block in the end of the value",
|
|
@@ -4652,7 +4661,6 @@ function useSyncValue(props) {
|
|
|
4652
4661
|
return updateValueFunctionRef.current = updateFunction, updateFunction;
|
|
4653
4662
|
}, [
|
|
4654
4663
|
editorActor,
|
|
4655
|
-
keyGenerator,
|
|
4656
4664
|
portableTextEditor,
|
|
4657
4665
|
readOnly,
|
|
4658
4666
|
schemaTypes,
|
|
@@ -4720,9 +4728,8 @@ function _updateBlock(slateEditor, currentBlock, oldBlock, currentBlockIndex) {
|
|
|
4720
4728
|
}
|
|
4721
4729
|
const debug$4 = debugWithName("component:PortableTextEditor:Synchronizer"), debugVerbose$1 = debug$4.enabled && !1, FLUSH_PATCHES_THROTTLED_MS = process.env.NODE_ENV === "test" ? 500 : 1e3;
|
|
4722
4730
|
function Synchronizer(props) {
|
|
4723
|
-
const portableTextEditor = usePortableTextEditor(),
|
|
4731
|
+
const portableTextEditor = usePortableTextEditor(), readOnly = usePortableTextEditorReadOnlyStatus(), { editorActor, getValue, onChange, value } = props, pendingPatches = useRef([]), syncValue = useSyncValue({
|
|
4724
4732
|
editorActor,
|
|
4725
|
-
keyGenerator,
|
|
4726
4733
|
portableTextEditor,
|
|
4727
4734
|
readOnly
|
|
4728
4735
|
}), slateEditor = useSlate();
|
|
@@ -4823,6 +4830,29 @@ ${JSON.stringify(pendingPatches.current, null, 2)}`);
|
|
|
4823
4830
|
debug$4("Value from props changed, syncing new value"), syncValue(value), isInitialValueFromProps.current && (editorActor.send({ type: "ready" }), isInitialValueFromProps.current = !1);
|
|
4824
4831
|
}, [editorActor, syncValue, value]), null;
|
|
4825
4832
|
}
|
|
4833
|
+
function inserText({
|
|
4834
|
+
event
|
|
4835
|
+
}) {
|
|
4836
|
+
Editor.insertText(event.editor, event.text);
|
|
4837
|
+
}
|
|
4838
|
+
function inserTextBlock({
|
|
4839
|
+
context,
|
|
4840
|
+
event
|
|
4841
|
+
}) {
|
|
4842
|
+
Editor.insertNode(event.editor, {
|
|
4843
|
+
_key: context.keyGenerator(),
|
|
4844
|
+
_type: context.schema.block.name,
|
|
4845
|
+
style: context.schema.styles[0].value ?? "normal",
|
|
4846
|
+
markDefs: [],
|
|
4847
|
+
children: [
|
|
4848
|
+
{
|
|
4849
|
+
_key: context.keyGenerator(),
|
|
4850
|
+
_type: "span",
|
|
4851
|
+
text: ""
|
|
4852
|
+
}
|
|
4853
|
+
]
|
|
4854
|
+
});
|
|
4855
|
+
}
|
|
4826
4856
|
const networkLogic = fromCallback(({ sendBack }) => {
|
|
4827
4857
|
const onlineHandler = () => {
|
|
4828
4858
|
sendBack({ type: "online" });
|
|
@@ -4836,9 +4866,19 @@ const networkLogic = fromCallback(({ sendBack }) => {
|
|
|
4836
4866
|
types: {
|
|
4837
4867
|
context: {},
|
|
4838
4868
|
events: {},
|
|
4839
|
-
emitted: {}
|
|
4869
|
+
emitted: {},
|
|
4870
|
+
input: {}
|
|
4840
4871
|
},
|
|
4841
4872
|
actions: {
|
|
4873
|
+
"apply:insert text": ({ context, event }) => {
|
|
4874
|
+
assertEvent(event, "insert text"), inserText({ context, event });
|
|
4875
|
+
},
|
|
4876
|
+
"apply:insert text block": ({ context, event }) => {
|
|
4877
|
+
assertEvent(event, "insert text block"), inserTextBlock({ context, event });
|
|
4878
|
+
},
|
|
4879
|
+
"assign schema": assign({
|
|
4880
|
+
schema: ({ event }) => (assertEvent(event, "update schema"), event.schema)
|
|
4881
|
+
}),
|
|
4842
4882
|
"emit patch event": emit(({ event }) => (assertEvent(event, "patch"), event)),
|
|
4843
4883
|
"emit mutation event": emit(({ event }) => (assertEvent(event, "mutation"), event)),
|
|
4844
4884
|
"defer event": assign({
|
|
@@ -4850,6 +4890,50 @@ const networkLogic = fromCallback(({ sendBack }) => {
|
|
|
4850
4890
|
}),
|
|
4851
4891
|
"clear pending events": assign({
|
|
4852
4892
|
pendingEvents: []
|
|
4893
|
+
}),
|
|
4894
|
+
"handle behavior event": enqueueActions(({ context, event, enqueue }) => {
|
|
4895
|
+
assertEvent(event, ["key down"]);
|
|
4896
|
+
const eventBehaviors = context.behaviors.filter(
|
|
4897
|
+
(behavior) => behavior.on === event.type
|
|
4898
|
+
);
|
|
4899
|
+
if (eventBehaviors.length === 0)
|
|
4900
|
+
return;
|
|
4901
|
+
const value = fromSlateValue(
|
|
4902
|
+
event.editor.children,
|
|
4903
|
+
context.schema.block.name,
|
|
4904
|
+
KEY_TO_VALUE_ELEMENT.get(event.editor)
|
|
4905
|
+
), selection = toPortableTextRange(
|
|
4906
|
+
value,
|
|
4907
|
+
event.editor.selection,
|
|
4908
|
+
context.schema
|
|
4909
|
+
);
|
|
4910
|
+
if (!selection) {
|
|
4911
|
+
console.warn(
|
|
4912
|
+
`Unable to handle event ${event.type} due to missing selection`
|
|
4913
|
+
);
|
|
4914
|
+
return;
|
|
4915
|
+
}
|
|
4916
|
+
const behaviorContext = {
|
|
4917
|
+
schema: context.schema,
|
|
4918
|
+
value,
|
|
4919
|
+
selection
|
|
4920
|
+
};
|
|
4921
|
+
for (const eventBehavior of eventBehaviors) {
|
|
4922
|
+
const shouldRun = eventBehavior.guard?.({
|
|
4923
|
+
context: behaviorContext,
|
|
4924
|
+
event
|
|
4925
|
+
}) ?? !0;
|
|
4926
|
+
if (!shouldRun)
|
|
4927
|
+
continue;
|
|
4928
|
+
const actions = eventBehavior.actions.map(
|
|
4929
|
+
(action) => action({ context: behaviorContext, event }, shouldRun)
|
|
4930
|
+
);
|
|
4931
|
+
for (const action of actions)
|
|
4932
|
+
typeof action == "object" && enqueue.raise({
|
|
4933
|
+
...action,
|
|
4934
|
+
editor: event.editor
|
|
4935
|
+
});
|
|
4936
|
+
}
|
|
4853
4937
|
})
|
|
4854
4938
|
},
|
|
4855
4939
|
actors: {
|
|
@@ -4857,9 +4941,12 @@ const networkLogic = fromCallback(({ sendBack }) => {
|
|
|
4857
4941
|
}
|
|
4858
4942
|
}).createMachine({
|
|
4859
4943
|
id: "editor",
|
|
4860
|
-
context: {
|
|
4861
|
-
|
|
4862
|
-
|
|
4944
|
+
context: ({ input }) => ({
|
|
4945
|
+
behaviors: input.behaviors,
|
|
4946
|
+
keyGenerator: input.keyGenerator,
|
|
4947
|
+
pendingEvents: [],
|
|
4948
|
+
schema: input.schema
|
|
4949
|
+
}),
|
|
4863
4950
|
invoke: {
|
|
4864
4951
|
id: "networkLogic",
|
|
4865
4952
|
src: "networkLogic"
|
|
@@ -4876,7 +4963,17 @@ const networkLogic = fromCallback(({ sendBack }) => {
|
|
|
4876
4963
|
online: { actions: emit({ type: "online" }) },
|
|
4877
4964
|
offline: { actions: emit({ type: "offline" }) },
|
|
4878
4965
|
loading: { actions: emit({ type: "loading" }) },
|
|
4879
|
-
"done loading": { actions: emit({ type: "done loading" }) }
|
|
4966
|
+
"done loading": { actions: emit({ type: "done loading" }) },
|
|
4967
|
+
"update schema": { actions: "assign schema" },
|
|
4968
|
+
"key down": {
|
|
4969
|
+
actions: ["handle behavior event"]
|
|
4970
|
+
},
|
|
4971
|
+
"insert text": {
|
|
4972
|
+
actions: ["apply:insert text"]
|
|
4973
|
+
},
|
|
4974
|
+
"insert text block": {
|
|
4975
|
+
actions: ["apply:insert text block"]
|
|
4976
|
+
}
|
|
4880
4977
|
},
|
|
4881
4978
|
initial: "pristine",
|
|
4882
4979
|
states: {
|
|
@@ -4947,7 +5044,7 @@ function PortableTextEditorSelectionProvider(props) {
|
|
|
4947
5044
|
};
|
|
4948
5045
|
}, [props.editorActor]), /* @__PURE__ */ jsx(PortableTextEditorSelectionContext.Provider, { value: selection, children: props.children });
|
|
4949
5046
|
}
|
|
4950
|
-
const debug$2 = debugWithName("component:PortableTextEditor");
|
|
5047
|
+
const defaultKeyGenerator = () => randomKey(12), debug$2 = debugWithName("component:PortableTextEditor");
|
|
4951
5048
|
class PortableTextEditor extends Component {
|
|
4952
5049
|
/**
|
|
4953
5050
|
* @internal
|
|
@@ -4971,14 +5068,23 @@ class PortableTextEditor extends Component {
|
|
|
4971
5068
|
throw new Error('PortableTextEditor: missing "schemaType" property');
|
|
4972
5069
|
props.incomingPatches$ && console.warn(
|
|
4973
5070
|
"The prop 'incomingPatches$' is deprecated and renamed to 'patches$'"
|
|
4974
|
-
), this.
|
|
5071
|
+
), this.schemaTypes = getPortableTextMemberSchemaTypes(
|
|
4975
5072
|
props.schemaType.hasOwnProperty("jsonType") ? props.schemaType : compileType(props.schemaType)
|
|
4976
|
-
)
|
|
5073
|
+
), this.editorActor = createActor(editorMachine, {
|
|
5074
|
+
input: {
|
|
5075
|
+
behaviors: coreBehaviors,
|
|
5076
|
+
keyGenerator: props.keyGenerator || defaultKeyGenerator,
|
|
5077
|
+
schema: this.schemaTypes
|
|
5078
|
+
}
|
|
5079
|
+
}), this.editorActor.start();
|
|
4977
5080
|
}
|
|
4978
5081
|
componentDidUpdate(prevProps) {
|
|
4979
5082
|
this.props.schemaType !== prevProps.schemaType && (this.schemaTypes = getPortableTextMemberSchemaTypes(
|
|
4980
5083
|
this.props.schemaType.hasOwnProperty("jsonType") ? this.props.schemaType : compileType(this.props.schemaType)
|
|
4981
|
-
)
|
|
5084
|
+
), this.editorActor.send({
|
|
5085
|
+
type: "update schema",
|
|
5086
|
+
schema: this.schemaTypes
|
|
5087
|
+
})), this.props.editorRef !== prevProps.editorRef && this.props.editorRef && (this.props.editorRef.current = this);
|
|
4982
5088
|
}
|
|
4983
5089
|
setEditable = (editable) => {
|
|
4984
5090
|
this.editable = { ...this.editable, ...editable };
|
|
@@ -4988,35 +5094,28 @@ class PortableTextEditor extends Component {
|
|
|
4988
5094
|
return this.editable.getValue();
|
|
4989
5095
|
};
|
|
4990
5096
|
render() {
|
|
4991
|
-
const { value, children, patches$, incomingPatches$ } = this.props, _patches$ = incomingPatches$ || patches$, maxBlocks = typeof this.props.maxBlocks > "u" ? void 0 : Number.parseInt(this.props.maxBlocks.toString(), 10) || void 0, readOnly = !!this.props.readOnly
|
|
5097
|
+
const { value, children, patches$, incomingPatches$ } = this.props, _patches$ = incomingPatches$ || patches$, maxBlocks = typeof this.props.maxBlocks > "u" ? void 0 : Number.parseInt(this.props.maxBlocks.toString(), 10) || void 0, readOnly = !!this.props.readOnly;
|
|
4992
5098
|
return /* @__PURE__ */ jsx(
|
|
4993
5099
|
SlateContainer,
|
|
4994
5100
|
{
|
|
4995
|
-
keyGenerator,
|
|
4996
5101
|
maxBlocks,
|
|
4997
5102
|
patches$: _patches$,
|
|
4998
5103
|
portableTextEditor: this,
|
|
4999
5104
|
readOnly,
|
|
5000
|
-
children: /* @__PURE__ */ jsx(
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
}
|
|
5015
|
-
),
|
|
5016
|
-
children
|
|
5017
|
-
]
|
|
5018
|
-
}
|
|
5019
|
-
) }) }) })
|
|
5105
|
+
children: /* @__PURE__ */ jsx(PortableTextEditorContext.Provider, { value: this, children: /* @__PURE__ */ jsx(PortableTextEditorReadOnlyContext.Provider, { value: readOnly, children: /* @__PURE__ */ jsxs(PortableTextEditorSelectionProvider, { editorActor: this.editorActor, children: [
|
|
5106
|
+
/* @__PURE__ */ jsx(
|
|
5107
|
+
Synchronizer,
|
|
5108
|
+
{
|
|
5109
|
+
editorActor: this.editorActor,
|
|
5110
|
+
getValue: this.getValue,
|
|
5111
|
+
onChange: (change) => {
|
|
5112
|
+
this.props.onChange(change), this.change$.next(change);
|
|
5113
|
+
},
|
|
5114
|
+
value
|
|
5115
|
+
}
|
|
5116
|
+
),
|
|
5117
|
+
children
|
|
5118
|
+
] }) }) })
|
|
5020
5119
|
}
|
|
5021
5120
|
);
|
|
5022
5121
|
}
|
|
@@ -5282,7 +5381,7 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
5282
5381
|
scrollSelectionIntoView,
|
|
5283
5382
|
spellCheck,
|
|
5284
5383
|
...restProps
|
|
5285
|
-
} = props, portableTextEditor = usePortableTextEditor(), readOnly = usePortableTextEditorReadOnlyStatus(),
|
|
5384
|
+
} = props, portableTextEditor = usePortableTextEditor(), readOnly = usePortableTextEditorReadOnlyStatus(), ref = useRef(null), [editableElement, setEditableElement] = useState(
|
|
5286
5385
|
null
|
|
5287
5386
|
), [hasInvalidValue, setHasInvalidValue] = useState(!1), [rangeDecorationState, setRangeDecorationsState] = useState([]);
|
|
5288
5387
|
useImperativeHandle(
|
|
@@ -5290,8 +5389,8 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
5290
5389
|
() => ref.current
|
|
5291
5390
|
);
|
|
5292
5391
|
const rangeDecorationsRef = useRef(rangeDecorations), { editorActor, schemaTypes } = portableTextEditor, slateEditor = useSlate(), blockTypeName = schemaTypes.block.name, withInsertData = useMemo(
|
|
5293
|
-
() => createWithInsertData(editorActor, schemaTypes
|
|
5294
|
-
[editorActor,
|
|
5392
|
+
() => createWithInsertData(editorActor, schemaTypes),
|
|
5393
|
+
[editorActor, schemaTypes]
|
|
5295
5394
|
), withHotKeys = useMemo(
|
|
5296
5395
|
() => createWithHotkeys(schemaTypes, portableTextEditor, hotkeys),
|
|
5297
5396
|
[hotkeys, portableTextEditor, schemaTypes]
|
|
@@ -5542,7 +5641,11 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
5542
5641
|
}, [validateSelection, editableElement]);
|
|
5543
5642
|
const handleKeyDown = useCallback(
|
|
5544
5643
|
(event) => {
|
|
5545
|
-
props.onKeyDown && props.onKeyDown(event), event.isDefaultPrevented() ||
|
|
5644
|
+
props.onKeyDown && props.onKeyDown(event), event.isDefaultPrevented() || (editorActor.send({
|
|
5645
|
+
type: "key down",
|
|
5646
|
+
nativeEvent: event.nativeEvent,
|
|
5647
|
+
editor: slateEditor
|
|
5648
|
+
}), slateEditor.pteWithHotKeys(event));
|
|
5546
5649
|
},
|
|
5547
5650
|
[props, slateEditor]
|
|
5548
5651
|
), scrollSelectionIntoViewToSlate = useMemo(() => {
|