@portabletext/editor 1.1.0 → 1.1.2
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 +3 -0
- package/lib/index.d.mts +1680 -12
- package/lib/index.d.ts +1680 -12
- package/lib/index.esm.js +310 -162
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +310 -163
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +310 -162
- package/lib/index.mjs.map +1 -1
- package/package.json +25 -38
- package/src/editor/Editable.tsx +51 -50
- package/src/editor/PortableTextEditor.tsx +42 -26
- package/src/editor/__tests__/PortableTextEditor.test.tsx +11 -12
- package/src/editor/__tests__/PortableTextEditorTester.tsx +2 -5
- package/src/editor/__tests__/RangeDecorations.test.tsx +6 -7
- package/src/editor/__tests__/handleClick.test.tsx +27 -7
- package/src/editor/__tests__/insert-block.test.tsx +6 -6
- package/src/editor/__tests__/pteWarningsSelfSolving.test.tsx +8 -8
- package/src/editor/__tests__/self-solving.test.tsx +176 -0
- package/src/editor/components/Element.tsx +15 -17
- package/src/editor/components/Leaf.tsx +40 -35
- package/src/editor/components/SlateContainer.tsx +2 -2
- package/src/editor/components/Synchronizer.tsx +62 -34
- package/src/editor/editor-machine.ts +195 -0
- package/src/editor/hooks/usePortableTextEditor.ts +1 -1
- package/src/editor/hooks/usePortableTextEditorSelection.tsx +12 -14
- package/src/editor/hooks/useSyncValue.test.tsx +9 -9
- package/src/editor/hooks/useSyncValue.ts +16 -19
- package/src/editor/nodes/DefaultAnnotation.tsx +1 -2
- package/src/editor/nodes/DefaultObject.tsx +1 -1
- package/src/editor/plugins/__tests__/createWithInsertData.test.tsx +2 -5
- package/src/editor/plugins/__tests__/withEditableAPIDelete.test.tsx +28 -28
- package/src/editor/plugins/__tests__/withEditableAPIGetFragment.test.tsx +17 -17
- package/src/editor/plugins/__tests__/withEditableAPIInsert.test.tsx +8 -8
- package/src/editor/plugins/__tests__/withEditableAPISelectionsOverlapping.test.tsx +6 -6
- package/src/editor/plugins/__tests__/withPortableTextLists.test.tsx +2 -2
- package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +47 -49
- package/src/editor/plugins/__tests__/withPortableTextSelections.test.tsx +22 -11
- package/src/editor/plugins/__tests__/withUndoRedo.test.tsx +9 -9
- package/src/editor/plugins/createWithEditableAPI.ts +8 -8
- package/src/editor/plugins/createWithHotKeys.ts +8 -12
- package/src/editor/plugins/createWithInsertBreak.ts +4 -4
- package/src/editor/plugins/createWithInsertData.ts +11 -16
- package/src/editor/plugins/createWithMaxBlocks.ts +1 -1
- package/src/editor/plugins/createWithObjectKeys.ts +10 -3
- package/src/editor/plugins/createWithPatches.ts +9 -12
- package/src/editor/plugins/createWithPlaceholderBlock.ts +2 -2
- package/src/editor/plugins/createWithPortableTextBlockStyle.ts +13 -5
- package/src/editor/plugins/createWithPortableTextLists.ts +3 -4
- package/src/editor/plugins/createWithPortableTextMarkModel.ts +24 -10
- package/src/editor/plugins/createWithPortableTextSelections.ts +9 -10
- package/src/editor/plugins/createWithSchemaTypes.ts +13 -4
- package/src/editor/plugins/createWithUndoRedo.ts +3 -7
- package/src/editor/plugins/createWithUtils.ts +6 -6
- package/src/editor/plugins/index.ts +21 -11
- package/src/index.ts +9 -3
- package/src/types/editor.ts +33 -33
- package/src/types/options.ts +3 -3
- package/src/types/slate.ts +4 -4
- package/src/utils/__tests__/dmpToOperations.test.ts +4 -4
- package/src/utils/__tests__/operationToPatches.test.ts +62 -62
- package/src/utils/__tests__/patchToOperations.test.ts +40 -40
- package/src/utils/__tests__/ranges.test.ts +2 -2
- package/src/utils/__tests__/valueNormalization.test.tsx +14 -2
- package/src/utils/__tests__/values.test.ts +17 -17
- package/src/utils/applyPatch.ts +10 -12
- package/src/utils/getPortableTextMemberSchemaTypes.ts +8 -8
- package/src/utils/operationToPatches.ts +5 -9
- package/src/utils/paths.ts +5 -5
- package/src/utils/ranges.ts +4 -5
- package/src/utils/selection.ts +2 -2
- package/src/utils/ucs2Indices.ts +2 -2
- package/src/utils/validateValue.ts +3 -25
- package/src/utils/values.ts +7 -8
- package/src/utils/weakMaps.ts +2 -2
- package/src/utils/withChanges.ts +1 -1
- package/src/utils/withUndoRedo.ts +1 -1
- package/src/utils/withoutPatching.ts +1 -1
- package/src/editor/__tests__/utils.ts +0 -45
package/lib/index.mjs
CHANGED
|
@@ -9,6 +9,7 @@ import { isKeySegment, isPortableTextSpan as isPortableTextSpan$1, isPortableTex
|
|
|
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, emit, assertEvent, assign, enqueueActions, createActor } from "xstate";
|
|
12
13
|
import { Schema } from "@sanity/schema";
|
|
13
14
|
import { diffMatchPatch as diffMatchPatch$1, set, insert, setIfMissing, unset, applyAll } from "@portabletext/patches";
|
|
14
15
|
import get from "lodash/get.js";
|
|
@@ -126,7 +127,7 @@ function normalizeSelection(selection, value) {
|
|
|
126
127
|
const { anchor, focus } = selection;
|
|
127
128
|
return anchor && value.find((blk) => isEqual({ _key: blk._key }, anchor.path[0])) && (newAnchor = normalizePoint(anchor, value)), focus && value.find((blk) => isEqual({ _key: blk._key }, focus.path[0])) && (newFocus = normalizePoint(focus, value)), newAnchor && newFocus ? { anchor: newAnchor, focus: newFocus, backward: selection.backward } : null;
|
|
128
129
|
}
|
|
129
|
-
const
|
|
130
|
+
const VOID_CHILD_KEY = "void-child";
|
|
130
131
|
function keepObjectEquality(object, keyMap) {
|
|
131
132
|
const value = keyMap[object._key];
|
|
132
133
|
return value && isEqual(object, value) ? value : (keyMap[object._key] = object, object);
|
|
@@ -724,7 +725,6 @@ const EMPTY_ANNOTATIONS = [], inlineBlockStyle = { display: "inline-block" }, El
|
|
|
724
725
|
};
|
|
725
726
|
function DefaultAnnotation(props) {
|
|
726
727
|
const handleClick = useCallback(
|
|
727
|
-
// eslint-disable-next-line no-alert
|
|
728
728
|
() => alert(JSON.stringify(props.annotation)),
|
|
729
729
|
[props.annotation]
|
|
730
730
|
);
|
|
@@ -1711,7 +1711,7 @@ function createWithMaxBlocks(maxBlocks) {
|
|
|
1711
1711
|
}, editor;
|
|
1712
1712
|
};
|
|
1713
1713
|
}
|
|
1714
|
-
function createWithObjectKeys(schemaTypes, keyGenerator) {
|
|
1714
|
+
function createWithObjectKeys(editorActor, schemaTypes, keyGenerator) {
|
|
1715
1715
|
return function(editor) {
|
|
1716
1716
|
const { apply: apply2, normalizeNode } = editor;
|
|
1717
1717
|
return editor.apply = (operation) => {
|
|
@@ -1747,10 +1747,13 @@ function createWithObjectKeys(schemaTypes, keyGenerator) {
|
|
|
1747
1747
|
}, editor.normalizeNode = (entry) => {
|
|
1748
1748
|
const [node, path] = entry;
|
|
1749
1749
|
if (Element$1.isElement(node) && node._type === schemaTypes.block.name) {
|
|
1750
|
-
node._key
|
|
1750
|
+
if (!node._key) {
|
|
1751
|
+
editorActor.send({ type: "normalizing" }), Transforms.setNodes(editor, { _key: keyGenerator() }, { at: path }), editorActor.send({ type: "done normalizing" });
|
|
1752
|
+
return;
|
|
1753
|
+
}
|
|
1751
1754
|
for (const [child, childPath] of Node.children(editor, path))
|
|
1752
1755
|
if (!child._key) {
|
|
1753
|
-
Transforms.setNodes(editor, { _key: keyGenerator() }, { at: childPath });
|
|
1756
|
+
editorActor.send({ type: "normalizing" }), Transforms.setNodes(editor, { _key: keyGenerator() }, { at: childPath }), editorActor.send({ type: "done normalizing" });
|
|
1754
1757
|
return;
|
|
1755
1758
|
}
|
|
1756
1759
|
}
|
|
@@ -2456,7 +2459,7 @@ function toInt(num) {
|
|
|
2456
2459
|
const debug$i = debugWithName("applyPatches"), debugVerbose$4 = debug$i.enabled && !0;
|
|
2457
2460
|
function createApplyPatch(schemaTypes) {
|
|
2458
2461
|
let previousPatch;
|
|
2459
|
-
return
|
|
2462
|
+
return (editor, patch) => {
|
|
2460
2463
|
let changed = !1;
|
|
2461
2464
|
debugVerbose$4 && (debug$i(
|
|
2462
2465
|
`
|
|
@@ -2907,7 +2910,7 @@ function findOperationTargetBlock(editor, operation) {
|
|
|
2907
2910
|
}
|
|
2908
2911
|
const debug$g = debugWithName("plugin:withPatches");
|
|
2909
2912
|
function createWithPatches({
|
|
2910
|
-
|
|
2913
|
+
editorActor,
|
|
2911
2914
|
patches$,
|
|
2912
2915
|
patchFunctions,
|
|
2913
2916
|
readOnly,
|
|
@@ -3036,7 +3039,7 @@ function createWithPatches({
|
|
|
3036
3039
|
}
|
|
3037
3040
|
return !editorWasEmpty && editorIsEmpty && ["merge_node", "set_node", "remove_text", "remove_node"].includes(
|
|
3038
3041
|
operation.type
|
|
3039
|
-
) && (patches = [...patches, unset([])],
|
|
3042
|
+
) && (patches = [...patches, unset([])], editorActor.send({
|
|
3040
3043
|
type: "unset",
|
|
3041
3044
|
previousValue: fromSlateValue(
|
|
3042
3045
|
previousChildren,
|
|
@@ -3044,7 +3047,7 @@ function createWithPatches({
|
|
|
3044
3047
|
KEY_TO_VALUE_ELEMENT.get(editor)
|
|
3045
3048
|
)
|
|
3046
3049
|
})), editorWasEmpty && patches.length > 0 && (patches = [setIfMissing([], []), ...patches]), patches.length > 0 && patches.forEach((patch) => {
|
|
3047
|
-
|
|
3050
|
+
editorActor.send({
|
|
3048
3051
|
type: "patch",
|
|
3049
3052
|
patch: { ...patch, origin: "local" }
|
|
3050
3053
|
});
|
|
@@ -3080,25 +3083,25 @@ function createWithPlaceholderBlock() {
|
|
|
3080
3083
|
};
|
|
3081
3084
|
}
|
|
3082
3085
|
const debug$e = debugWithName("plugin:withPortableTextBlockStyle");
|
|
3083
|
-
function createWithPortableTextBlockStyle(types) {
|
|
3086
|
+
function createWithPortableTextBlockStyle(editorActor, types) {
|
|
3084
3087
|
const defaultStyle = types.styles[0].value;
|
|
3085
3088
|
return function(editor) {
|
|
3086
3089
|
const { normalizeNode } = editor;
|
|
3087
3090
|
return editor.normalizeNode = (nodeEntry) => {
|
|
3088
|
-
normalizeNode(nodeEntry);
|
|
3089
3091
|
const [, path] = nodeEntry;
|
|
3090
3092
|
for (const op of editor.operations)
|
|
3091
3093
|
if (op.type === "split_node" && op.path.length === 1 && editor.isTextBlock(op.properties) && op.properties.style !== defaultStyle && op.path[0] === path[0] && !Path.equals(path, op.path)) {
|
|
3092
3094
|
const [child] = Editor.node(editor, [op.path[0] + 1, 0]);
|
|
3093
3095
|
if (Text.isText(child) && child.text === "") {
|
|
3094
|
-
debug$e(`Normalizing split node to ${defaultStyle} style`, op), Transforms.setNodes(
|
|
3096
|
+
debug$e(`Normalizing split node to ${defaultStyle} style`, op), editorActor.send({ type: "normalizing" }), Transforms.setNodes(
|
|
3095
3097
|
editor,
|
|
3096
3098
|
{ style: defaultStyle },
|
|
3097
3099
|
{ at: [op.path[0] + 1], voids: !1 }
|
|
3098
|
-
);
|
|
3099
|
-
|
|
3100
|
+
), editorActor.send({ type: "done normalizing" });
|
|
3101
|
+
return;
|
|
3100
3102
|
}
|
|
3101
3103
|
}
|
|
3104
|
+
normalizeNode(nodeEntry);
|
|
3102
3105
|
}, editor.pteHasBlockStyle = (style) => editor.selection ? [
|
|
3103
3106
|
...Editor.nodes(editor, {
|
|
3104
3107
|
at: editor.selection,
|
|
@@ -3243,7 +3246,7 @@ function isPortableTextBlock(node) {
|
|
|
3243
3246
|
);
|
|
3244
3247
|
}
|
|
3245
3248
|
const debug$c = debugWithName("plugin:withPortableTextMarkModel");
|
|
3246
|
-
function createWithPortableTextMarkModel(types,
|
|
3249
|
+
function createWithPortableTextMarkModel(editorActor, types, keyGenerator) {
|
|
3247
3250
|
return function(editor) {
|
|
3248
3251
|
const { apply: apply2, normalizeNode } = editor, decorators = types.decorators.map((t) => t.value), forceNewSelection = () => {
|
|
3249
3252
|
editor.selection && (Transforms.select(editor, { ...editor.selection }), editor.selection = { ...editor.selection });
|
|
@@ -3252,7 +3255,7 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
3252
3255
|
editor.selection,
|
|
3253
3256
|
types
|
|
3254
3257
|
);
|
|
3255
|
-
|
|
3258
|
+
editorActor.send({ type: "selection", selection: ptRange });
|
|
3256
3259
|
};
|
|
3257
3260
|
return editor.normalizeNode = (nodeEntry) => {
|
|
3258
3261
|
const [node, path] = nodeEntry;
|
|
@@ -3265,20 +3268,20 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
3265
3268
|
"Merging spans",
|
|
3266
3269
|
JSON.stringify(child, null, 2),
|
|
3267
3270
|
JSON.stringify(nextNode, null, 2)
|
|
3268
|
-
), Transforms.mergeNodes(editor, {
|
|
3271
|
+
), editorActor.send({ type: "normalizing" }), Transforms.mergeNodes(editor, {
|
|
3269
3272
|
at: [childPath[0], childPath[1] + 1],
|
|
3270
3273
|
voids: !0
|
|
3271
|
-
});
|
|
3274
|
+
}), editorActor.send({ type: "done normalizing" });
|
|
3272
3275
|
return;
|
|
3273
3276
|
}
|
|
3274
3277
|
}
|
|
3275
3278
|
}
|
|
3276
3279
|
if (editor.isTextBlock(node) && !Array.isArray(node.markDefs)) {
|
|
3277
|
-
debug$c("Adding .markDefs to block node"), Transforms.setNodes(editor, { markDefs: [] }, { at: path });
|
|
3280
|
+
debug$c("Adding .markDefs to block node"), editorActor.send({ type: "normalizing" }), Transforms.setNodes(editor, { markDefs: [] }, { at: path }), editorActor.send({ type: "done normalizing" });
|
|
3278
3281
|
return;
|
|
3279
3282
|
}
|
|
3280
3283
|
if (editor.isTextSpan(node) && !Array.isArray(node.marks)) {
|
|
3281
|
-
debug$c("Adding .marks to span node"), Transforms.setNodes(editor, { marks: [] }, { at: path });
|
|
3284
|
+
debug$c("Adding .marks to span node"), editorActor.send({ type: "normalizing" }), Transforms.setNodes(editor, { marks: [] }, { at: path }), editorActor.send({ type: "done normalizing" });
|
|
3282
3285
|
return;
|
|
3283
3286
|
}
|
|
3284
3287
|
if (editor.isTextSpan(node)) {
|
|
@@ -3286,11 +3289,11 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
3286
3289
|
(mark) => !decorators2.includes(mark)
|
|
3287
3290
|
);
|
|
3288
3291
|
if (editor.isTextBlock(block) && node.text === "" && annotations && annotations.length > 0) {
|
|
3289
|
-
debug$c("Removing annotations from empty span node"), Transforms.setNodes(
|
|
3292
|
+
debug$c("Removing annotations from empty span node"), editorActor.send({ type: "normalizing" }), Transforms.setNodes(
|
|
3290
3293
|
editor,
|
|
3291
3294
|
{ marks: node.marks?.filter((mark) => decorators2.includes(mark)) },
|
|
3292
3295
|
{ at: path }
|
|
3293
|
-
);
|
|
3296
|
+
), editorActor.send({ type: "done normalizing" });
|
|
3294
3297
|
return;
|
|
3295
3298
|
}
|
|
3296
3299
|
}
|
|
@@ -3300,7 +3303,7 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
3300
3303
|
if (editor.isTextSpan(child)) {
|
|
3301
3304
|
const marks = child.marks ?? [], orphanedAnnotations = marks.filter((mark) => !decorators2.includes(mark) && !node.markDefs?.find((def) => def._key === mark));
|
|
3302
3305
|
if (orphanedAnnotations.length > 0) {
|
|
3303
|
-
debug$c("Removing orphaned annotations from span node"), Transforms.setNodes(
|
|
3306
|
+
debug$c("Removing orphaned annotations from span node"), editorActor.send({ type: "normalizing" }), Transforms.setNodes(
|
|
3304
3307
|
editor,
|
|
3305
3308
|
{
|
|
3306
3309
|
marks: marks.filter(
|
|
@@ -3308,7 +3311,7 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
3308
3311
|
)
|
|
3309
3312
|
},
|
|
3310
3313
|
{ at: childPath }
|
|
3311
|
-
);
|
|
3314
|
+
), editorActor.send({ type: "done normalizing" });
|
|
3312
3315
|
return;
|
|
3313
3316
|
}
|
|
3314
3317
|
}
|
|
@@ -3320,7 +3323,7 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
3320
3323
|
(decorator) => decorator.value
|
|
3321
3324
|
), marks = node.marks ?? [], orphanedAnnotations = marks.filter((mark) => !decorators2.includes(mark) && !block.markDefs?.find((def) => def._key === mark));
|
|
3322
3325
|
if (orphanedAnnotations.length > 0) {
|
|
3323
|
-
debug$c("Removing orphaned annotations from span node"), Transforms.setNodes(
|
|
3326
|
+
debug$c("Removing orphaned annotations from span node"), editorActor.send({ type: "normalizing" }), Transforms.setNodes(
|
|
3324
3327
|
editor,
|
|
3325
3328
|
{
|
|
3326
3329
|
marks: marks.filter(
|
|
@@ -3328,7 +3331,7 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
3328
3331
|
)
|
|
3329
3332
|
},
|
|
3330
3333
|
{ at: path }
|
|
3331
|
-
);
|
|
3334
|
+
), editorActor.send({ type: "done normalizing" });
|
|
3332
3335
|
return;
|
|
3333
3336
|
}
|
|
3334
3337
|
}
|
|
@@ -3337,20 +3340,23 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
3337
3340
|
const markDefs = node.markDefs ?? [], markDefKeys = /* @__PURE__ */ new Set(), newMarkDefs = [];
|
|
3338
3341
|
for (const markDef of markDefs)
|
|
3339
3342
|
markDefKeys.has(markDef._key) || (markDefKeys.add(markDef._key), newMarkDefs.push(markDef));
|
|
3340
|
-
markDefs.length !== newMarkDefs.length
|
|
3343
|
+
if (markDefs.length !== newMarkDefs.length) {
|
|
3344
|
+
debug$c("Removing duplicate markDefs"), editorActor.send({ type: "normalizing" }), Transforms.setNodes(editor, { markDefs: newMarkDefs }, { at: path }), editorActor.send({ type: "done normalizing" });
|
|
3345
|
+
return;
|
|
3346
|
+
}
|
|
3341
3347
|
}
|
|
3342
3348
|
if (editor.isTextBlock(node) && !editor.operations.some(
|
|
3343
3349
|
(op) => op.type === "merge_node" && "markDefs" in op.properties && op.path.length === 1
|
|
3344
3350
|
)) {
|
|
3345
3351
|
const newMarkDefs = (node.markDefs || []).filter((def) => node.children.find((child) => Text.isText(child) && Array.isArray(child.marks) && child.marks.includes(def._key)));
|
|
3346
3352
|
if (node.markDefs && !isEqual(newMarkDefs, node.markDefs)) {
|
|
3347
|
-
debug$c("Removing markDef not in use"), Transforms.setNodes(
|
|
3353
|
+
debug$c("Removing markDef not in use"), editorActor.send({ type: "normalizing" }), Transforms.setNodes(
|
|
3348
3354
|
editor,
|
|
3349
3355
|
{
|
|
3350
3356
|
markDefs: newMarkDefs
|
|
3351
3357
|
},
|
|
3352
3358
|
{ at: path }
|
|
3353
|
-
);
|
|
3359
|
+
), editorActor.send({ type: "done normalizing" });
|
|
3354
3360
|
return;
|
|
3355
3361
|
}
|
|
3356
3362
|
}
|
|
@@ -3583,7 +3589,7 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
3583
3589
|
};
|
|
3584
3590
|
}
|
|
3585
3591
|
const debug$b = debugWithName("plugin:withPortableTextSelections"), debugVerbose$2 = debug$b.enabled && !1;
|
|
3586
|
-
function createWithPortableTextSelections(
|
|
3592
|
+
function createWithPortableTextSelections(editorActor, types) {
|
|
3587
3593
|
let prevSelection = null;
|
|
3588
3594
|
return function(editor) {
|
|
3589
3595
|
const emitPortableTextSelection = () => {
|
|
@@ -3602,7 +3608,7 @@ function createWithPortableTextSelections(change$, types) {
|
|
|
3602
3608
|
`Emitting selection ${JSON.stringify(ptRange || null)} (${JSON.stringify(
|
|
3603
3609
|
editor.selection
|
|
3604
3610
|
)})`
|
|
3605
|
-
), ptRange ?
|
|
3611
|
+
), ptRange ? editorActor.send({ type: "selection", selection: ptRange }) : editorActor.send({ type: "selection", selection: null });
|
|
3606
3612
|
}
|
|
3607
3613
|
prevSelection = editor.selection;
|
|
3608
3614
|
}, { onChange } = editor;
|
|
@@ -3614,27 +3620,30 @@ function createWithPortableTextSelections(change$, types) {
|
|
|
3614
3620
|
}
|
|
3615
3621
|
const debug$a = debugWithName("plugin:withSchemaTypes");
|
|
3616
3622
|
function createWithSchemaTypes({
|
|
3623
|
+
editorActor,
|
|
3617
3624
|
schemaTypes,
|
|
3618
3625
|
keyGenerator
|
|
3619
3626
|
}) {
|
|
3620
3627
|
return function(editor) {
|
|
3621
|
-
editor.isTextBlock = (value) => isPortableTextTextBlock(value) && value._type === schemaTypes.block.name, editor.isTextSpan = (value) => isPortableTextSpan$1(value) && value._type
|
|
3628
|
+
editor.isTextBlock = (value) => isPortableTextTextBlock(value) && value._type === schemaTypes.block.name, editor.isTextSpan = (value) => isPortableTextSpan$1(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;
|
|
3622
3629
|
const { normalizeNode } = editor;
|
|
3623
3630
|
return editor.normalizeNode = (entry) => {
|
|
3624
3631
|
const [node, path] = entry;
|
|
3625
3632
|
if (node._type === void 0 && path.length === 2) {
|
|
3626
3633
|
debug$a("Setting span type on text node without a type");
|
|
3627
3634
|
const span = node, key = span._key || keyGenerator();
|
|
3628
|
-
Transforms.setNodes(
|
|
3635
|
+
editorActor.send({ type: "normalizing" }), Transforms.setNodes(
|
|
3629
3636
|
editor,
|
|
3630
3637
|
{ ...span, _type: schemaTypes.span.name, _key: key },
|
|
3631
3638
|
{ at: path }
|
|
3632
|
-
);
|
|
3639
|
+
), editorActor.send({ type: "done normalizing" });
|
|
3640
|
+
return;
|
|
3633
3641
|
}
|
|
3634
3642
|
if (node._key === void 0 && (path.length === 1 || path.length === 2)) {
|
|
3635
3643
|
debug$a("Setting missing key on child node without a key");
|
|
3636
3644
|
const key = keyGenerator();
|
|
3637
|
-
Transforms.setNodes(editor, { _key: key }, { at: path });
|
|
3645
|
+
editorActor.send({ type: "normalizing" }), Transforms.setNodes(editor, { _key: key }, { at: path }), editorActor.send({ type: "done normalizing" });
|
|
3646
|
+
return;
|
|
3638
3647
|
}
|
|
3639
3648
|
normalizeNode(entry);
|
|
3640
3649
|
}, editor;
|
|
@@ -3656,7 +3665,7 @@ function createWithUtils({
|
|
|
3656
3665
|
return;
|
|
3657
3666
|
}
|
|
3658
3667
|
const { focus } = selection, focusOffset = focus.offset, charsBefore = textNode.text.slice(0, focusOffset), charsAfter = textNode.text.slice(focusOffset, -1), isEmpty = (str) => str.match(/\s/g), whiteSpaceBeforeIndex = charsBefore.split("").reverse().findIndex((str) => isEmpty(str)), newStartOffset = whiteSpaceBeforeIndex > -1 ? charsBefore.length - whiteSpaceBeforeIndex : 0, whiteSpaceAfterIndex = charsAfter.split("").findIndex((obj) => isEmpty(obj)), newEndOffset = charsBefore.length + (whiteSpaceAfterIndex > -1 ? whiteSpaceAfterIndex : charsAfter.length + 1);
|
|
3659
|
-
if (!(newStartOffset === newEndOffset || isNaN(newStartOffset) || isNaN(newEndOffset))) {
|
|
3668
|
+
if (!(newStartOffset === newEndOffset || Number.isNaN(newStartOffset) || Number.isNaN(newEndOffset))) {
|
|
3660
3669
|
debug$9("pteExpandToWord: Expanding to focused word"), Transforms.setSelection(editor, {
|
|
3661
3670
|
anchor: { ...selection.anchor, offset: newStartOffset },
|
|
3662
3671
|
focus: { ...selection.focus, offset: newEndOffset }
|
|
@@ -3942,22 +3951,6 @@ function validateValue(value, types, keyGenerator) {
|
|
|
3942
3951
|
}
|
|
3943
3952
|
}, !0;
|
|
3944
3953
|
}
|
|
3945
|
-
if (blk.markDefs && !Array.isArray(blk.markDefs))
|
|
3946
|
-
return resolution = {
|
|
3947
|
-
patches: [
|
|
3948
|
-
set({ ...textBlock, markDefs: EMPTY_MARKDEFS }, [
|
|
3949
|
-
{ _key: textBlock._key }
|
|
3950
|
-
])
|
|
3951
|
-
],
|
|
3952
|
-
description: "Block has invalid required property 'markDefs'.",
|
|
3953
|
-
action: "Add empty markDefs array",
|
|
3954
|
-
item: textBlock,
|
|
3955
|
-
i18n: {
|
|
3956
|
-
description: "inputs.portable-text.invalid-value.missing-or-invalid-markdefs.description",
|
|
3957
|
-
action: "inputs.portable-text.invalid-value.missing-or-invalid-markdefs.action",
|
|
3958
|
-
values: { key: textBlock._key }
|
|
3959
|
-
}
|
|
3960
|
-
}, !0;
|
|
3961
3954
|
const allUsedMarks = uniq(
|
|
3962
3955
|
flatten(
|
|
3963
3956
|
textBlock.children.filter((cld) => cld._type === types.span.name).map((cld) => cld.marks || [])
|
|
@@ -4102,7 +4095,7 @@ function validateValue(value, types, keyGenerator) {
|
|
|
4102
4095
|
}) && (valid = !1), { valid, resolution, value });
|
|
4103
4096
|
}
|
|
4104
4097
|
const debug$7 = debugWithName("plugin:withInsertData");
|
|
4105
|
-
function createWithInsertData(
|
|
4098
|
+
function createWithInsertData(editorActor, schemaTypes, keyGenerator) {
|
|
4106
4099
|
return function(editor) {
|
|
4107
4100
|
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(`
|
|
4108
4101
|
|
|
@@ -4156,9 +4149,8 @@ function createWithInsertData(change$, schemaTypes, keyGenerator) {
|
|
|
4156
4149
|
), validation = validateValue(parsed, schemaTypes, keyGenerator);
|
|
4157
4150
|
if (!validation.valid && !validation.resolution?.autoResolve) {
|
|
4158
4151
|
const errorDescription = `${validation.resolution?.description}`;
|
|
4159
|
-
return
|
|
4152
|
+
return editorActor.send({
|
|
4160
4153
|
type: "error",
|
|
4161
|
-
level: "warning",
|
|
4162
4154
|
name: "pasteError",
|
|
4163
4155
|
description: errorDescription,
|
|
4164
4156
|
data: validation
|
|
@@ -4171,7 +4163,6 @@ function createWithInsertData(change$, schemaTypes, keyGenerator) {
|
|
|
4171
4163
|
}, editor.insertTextOrHTMLData = (data) => {
|
|
4172
4164
|
if (!editor.selection)
|
|
4173
4165
|
return debug$7("No selection, not inserting"), !1;
|
|
4174
|
-
change$.next({ type: "loading", isLoading: !0 });
|
|
4175
4166
|
const html = data.getData("text/html"), text = data.getData("text/plain");
|
|
4176
4167
|
if (html || text) {
|
|
4177
4168
|
debug$7("Inserting data", data);
|
|
@@ -4202,9 +4193,8 @@ function createWithInsertData(change$, schemaTypes, keyGenerator) {
|
|
|
4202
4193
|
const errorDescription = `Could not validate the resulting portable text to insert.
|
|
4203
4194
|
${validation.resolution?.description}
|
|
4204
4195
|
Try to insert as plain text (shift-paste) instead.`;
|
|
4205
|
-
return
|
|
4196
|
+
return editorActor.send({
|
|
4206
4197
|
type: "error",
|
|
4207
|
-
level: "warning",
|
|
4208
4198
|
name: "pasteError",
|
|
4209
4199
|
description: errorDescription,
|
|
4210
4200
|
data: validation
|
|
@@ -4212,9 +4202,9 @@ Try to insert as plain text (shift-paste) instead.`;
|
|
|
4212
4202
|
}
|
|
4213
4203
|
return debug$7(
|
|
4214
4204
|
`Inserting ${insertedType} fragment at ${JSON.stringify(editor.selection)}`
|
|
4215
|
-
), _insertFragment(editor, fragment, schemaTypes),
|
|
4205
|
+
), _insertFragment(editor, fragment, schemaTypes), !0;
|
|
4216
4206
|
}
|
|
4217
|
-
return
|
|
4207
|
+
return !1;
|
|
4218
4208
|
}, editor.insertData = (data) => {
|
|
4219
4209
|
editor.insertPortableTextData(data) || editor.insertTextOrHTMLData(data);
|
|
4220
4210
|
}, editor.insertFragmentData = (data) => {
|
|
@@ -4258,10 +4248,7 @@ function _regenerateKeys(editor, fragment, keyGenerator, spanTypeName, editorTyp
|
|
|
4258
4248
|
return newNode.children = newNode.children.map(
|
|
4259
4249
|
(child) => child._type === spanTypeName && editor.isTextSpan(child) ? {
|
|
4260
4250
|
...child,
|
|
4261
|
-
marks: child.marks && child.marks.includes(oldKey) ? (
|
|
4262
|
-
// eslint-disable-next-line max-nested-callbacks
|
|
4263
|
-
[...child.marks].filter((mark) => mark !== oldKey).concat(newKey)
|
|
4264
|
-
) : child.marks
|
|
4251
|
+
marks: child.marks && child.marks.includes(oldKey) ? [...child.marks].filter((mark) => mark !== oldKey).concat(newKey) : child.marks
|
|
4265
4252
|
} : child
|
|
4266
4253
|
), { ...def, _key: newKey };
|
|
4267
4254
|
});
|
|
@@ -4304,18 +4291,26 @@ function _insertFragment(editor, fragment, schemaTypes) {
|
|
|
4304
4291
|
}), editor.onChange();
|
|
4305
4292
|
}
|
|
4306
4293
|
const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, options) => {
|
|
4307
|
-
const e = editor, { keyGenerator, portableTextEditor, patches$, readOnly, maxBlocks } = options, {
|
|
4294
|
+
const e = editor, { keyGenerator, portableTextEditor, patches$, readOnly, maxBlocks } = options, { editorActor, schemaTypes } = portableTextEditor;
|
|
4308
4295
|
e.subscriptions = [], e.destroy ? e.destroy() : originalFnMap.set(e, {
|
|
4309
4296
|
apply: e.apply,
|
|
4310
4297
|
onChange: e.onChange,
|
|
4311
4298
|
normalizeNode: e.normalizeNode
|
|
4312
4299
|
});
|
|
4313
|
-
const operationToPatches = createOperationToPatches(schemaTypes), withObjectKeys = createWithObjectKeys(
|
|
4300
|
+
const operationToPatches = createOperationToPatches(schemaTypes), withObjectKeys = createWithObjectKeys(
|
|
4301
|
+
editorActor,
|
|
4302
|
+
schemaTypes,
|
|
4303
|
+
keyGenerator
|
|
4304
|
+
), withSchemaTypes = createWithSchemaTypes({
|
|
4305
|
+
editorActor,
|
|
4306
|
+
schemaTypes,
|
|
4307
|
+
keyGenerator
|
|
4308
|
+
}), withEditableAPI = createWithEditableAPI(
|
|
4314
4309
|
portableTextEditor,
|
|
4315
4310
|
schemaTypes,
|
|
4316
4311
|
keyGenerator
|
|
4317
4312
|
), withPatches = createWithPatches({
|
|
4318
|
-
|
|
4313
|
+
editorActor,
|
|
4319
4314
|
keyGenerator,
|
|
4320
4315
|
patches$,
|
|
4321
4316
|
patchFunctions: operationToPatches,
|
|
@@ -4326,15 +4321,18 @@ const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, opti
|
|
|
4326
4321
|
patches$,
|
|
4327
4322
|
blockSchemaType: schemaTypes.block
|
|
4328
4323
|
}), withPortableTextMarkModel = createWithPortableTextMarkModel(
|
|
4324
|
+
editorActor,
|
|
4329
4325
|
schemaTypes,
|
|
4330
|
-
change$,
|
|
4331
4326
|
keyGenerator
|
|
4332
|
-
), withPortableTextBlockStyle = createWithPortableTextBlockStyle(
|
|
4327
|
+
), withPortableTextBlockStyle = createWithPortableTextBlockStyle(
|
|
4328
|
+
editorActor,
|
|
4329
|
+
schemaTypes
|
|
4330
|
+
), withPlaceholderBlock = createWithPlaceholderBlock(), withInsertBreak = createWithInsertBreak(schemaTypes, keyGenerator), withUtils = createWithUtils({
|
|
4333
4331
|
keyGenerator,
|
|
4334
4332
|
schemaTypes,
|
|
4335
4333
|
portableTextEditor
|
|
4336
4334
|
}), withPortableTextSelections = createWithPortableTextSelections(
|
|
4337
|
-
|
|
4335
|
+
editorActor,
|
|
4338
4336
|
schemaTypes
|
|
4339
4337
|
);
|
|
4340
4338
|
return e.destroy = () => {
|
|
@@ -4451,7 +4449,7 @@ const defaultKeyGenerator = () => randomKey(12), PortableTextEditorKeyGeneratorC
|
|
|
4451
4449
|
return readOnly;
|
|
4452
4450
|
}, debug$5 = debugWithName("hook:useSyncValue"), CURRENT_VALUE = /* @__PURE__ */ new WeakMap();
|
|
4453
4451
|
function useSyncValue(props) {
|
|
4454
|
-
const { portableTextEditor, readOnly, keyGenerator } = props, {
|
|
4452
|
+
const { editorActor, portableTextEditor, readOnly, keyGenerator } = props, { schemaTypes } = portableTextEditor, previousValue = useRef(), slateEditor = useSlate(), updateValueFunctionRef = useRef(), updateFromCurrentValue = useCallback(() => {
|
|
4455
4453
|
const currentValue = CURRENT_VALUE.get(portableTextEditor);
|
|
4456
4454
|
if (previousValue.current === currentValue) {
|
|
4457
4455
|
debug$5("Value is the same object as previous, not need to sync");
|
|
@@ -4522,7 +4520,7 @@ function useSyncValue(props) {
|
|
|
4522
4520
|
!validation.valid && validation.resolution?.autoResolve && validation.resolution?.patches.length > 0 && !readOnly && previousValue.current && previousValue.current !== value && (console.warn(
|
|
4523
4521
|
`${validation.resolution.action} for block with _key '${validationValue[0]._key}'. ${validation.resolution?.description}`
|
|
4524
4522
|
), validation.resolution.patches.forEach((patch) => {
|
|
4525
|
-
|
|
4523
|
+
editorActor.send({ type: "patch", patch });
|
|
4526
4524
|
})), validation.valid || validation.resolution?.autoResolve ? (oldBlock._key === currentBlock._key ? (debug$5.enabled && debug$5("Updating block", oldBlock, currentBlock), _updateBlock(
|
|
4527
4525
|
slateEditor,
|
|
4528
4526
|
currentBlock,
|
|
@@ -4532,8 +4530,8 @@ function useSyncValue(props) {
|
|
|
4532
4530
|
slateEditor,
|
|
4533
4531
|
currentBlock,
|
|
4534
4532
|
currentBlockIndex
|
|
4535
|
-
)), isChanged = !0) : (
|
|
4536
|
-
type: "
|
|
4533
|
+
)), isChanged = !0) : (editorActor.send({
|
|
4534
|
+
type: "invalid value",
|
|
4537
4535
|
resolution: validation.resolution,
|
|
4538
4536
|
value
|
|
4539
4537
|
}), isValid = !1);
|
|
@@ -4549,8 +4547,8 @@ function useSyncValue(props) {
|
|
|
4549
4547
|
currentBlock
|
|
4550
4548
|
), validation.valid || validation.resolution?.autoResolve ? Transforms.insertNodes(slateEditor, currentBlock, {
|
|
4551
4549
|
at: [currentBlockIndex]
|
|
4552
|
-
}) : (debug$5("Invalid", validation),
|
|
4553
|
-
type: "
|
|
4550
|
+
}) : (debug$5("Invalid", validation), editorActor.send({
|
|
4551
|
+
type: "invalid value",
|
|
4554
4552
|
resolution: validation.resolution,
|
|
4555
4553
|
value
|
|
4556
4554
|
}), isValid = !1);
|
|
@@ -4571,8 +4569,8 @@ function useSyncValue(props) {
|
|
|
4571
4569
|
try {
|
|
4572
4570
|
slateEditor.onChange();
|
|
4573
4571
|
} catch (err) {
|
|
4574
|
-
console.error(err),
|
|
4575
|
-
type: "
|
|
4572
|
+
console.error(err), editorActor.send({
|
|
4573
|
+
type: "invalid value",
|
|
4576
4574
|
resolution: null,
|
|
4577
4575
|
value
|
|
4578
4576
|
});
|
|
@@ -4581,14 +4579,14 @@ function useSyncValue(props) {
|
|
|
4581
4579
|
hadSelection && !slateEditor.selection && (Transforms.select(slateEditor, {
|
|
4582
4580
|
anchor: { path: [0, 0], offset: 0 },
|
|
4583
4581
|
focus: { path: [0, 0], offset: 0 }
|
|
4584
|
-
}), slateEditor.onChange()),
|
|
4582
|
+
}), slateEditor.onChange()), editorActor.send({ type: "value changed", value });
|
|
4585
4583
|
} else
|
|
4586
4584
|
debug$5("Server value and editor value is equal, no need to sync.");
|
|
4587
4585
|
previousValue.current = value;
|
|
4588
4586
|
};
|
|
4589
4587
|
return updateValueFunctionRef.current = updateFunction, updateFunction;
|
|
4590
4588
|
}, [
|
|
4591
|
-
|
|
4589
|
+
editorActor,
|
|
4592
4590
|
keyGenerator,
|
|
4593
4591
|
portableTextEditor,
|
|
4594
4592
|
readOnly,
|
|
@@ -4657,9 +4655,9 @@ function _updateBlock(slateEditor, currentBlock, oldBlock, currentBlockIndex) {
|
|
|
4657
4655
|
}
|
|
4658
4656
|
const debug$4 = debugWithName("component:PortableTextEditor:Synchronizer"), debugVerbose$1 = debug$4.enabled && !1, FLUSH_PATCHES_THROTTLED_MS = process.env.NODE_ENV === "test" ? 500 : 1e3;
|
|
4659
4657
|
function Synchronizer(props) {
|
|
4660
|
-
const portableTextEditor = usePortableTextEditor(), keyGenerator = usePortableTextEditorKeyGenerator(), readOnly = usePortableTextEditorReadOnlyStatus(), {
|
|
4658
|
+
const portableTextEditor = usePortableTextEditor(), keyGenerator = usePortableTextEditorKeyGenerator(), readOnly = usePortableTextEditorReadOnlyStatus(), { editorActor, getValue, onChange, value } = props, pendingPatches = useRef([]), syncValue = useSyncValue({
|
|
4659
|
+
editorActor,
|
|
4661
4660
|
keyGenerator,
|
|
4662
|
-
onChange,
|
|
4663
4661
|
portableTextEditor,
|
|
4664
4662
|
readOnly
|
|
4665
4663
|
}), slateEditor = useSlate();
|
|
@@ -4671,14 +4669,14 @@ function Synchronizer(props) {
|
|
|
4671
4669
|
debug$4("Flushing pending patches"), debugVerbose$1 && debug$4(`Patches:
|
|
4672
4670
|
${JSON.stringify(pendingPatches.current, null, 2)}`);
|
|
4673
4671
|
const snapshot = getValue();
|
|
4674
|
-
|
|
4672
|
+
editorActor.send({
|
|
4675
4673
|
type: "mutation",
|
|
4676
4674
|
patches: pendingPatches.current,
|
|
4677
4675
|
snapshot
|
|
4678
4676
|
}), pendingPatches.current = [];
|
|
4679
4677
|
}
|
|
4680
4678
|
IS_PROCESSING_LOCAL_CHANGES.set(slateEditor, !1);
|
|
4681
|
-
}, [slateEditor, getValue
|
|
4679
|
+
}, [editorActor, slateEditor, getValue]), onFlushPendingPatchesThrottled = useMemo(() => throttle(
|
|
4682
4680
|
() => {
|
|
4683
4681
|
if (Editor.isNormalizing(slateEditor)) {
|
|
4684
4682
|
onFlushPendingPatches();
|
|
@@ -4695,34 +4693,174 @@ ${JSON.stringify(pendingPatches.current, null, 2)}`);
|
|
|
4695
4693
|
useEffect(() => () => {
|
|
4696
4694
|
onFlushPendingPatches();
|
|
4697
4695
|
}, [onFlushPendingPatches]), useEffect(() => {
|
|
4698
|
-
debug$4("Subscribing to editor changes
|
|
4699
|
-
const sub =
|
|
4700
|
-
switch (
|
|
4696
|
+
debug$4("Subscribing to editor changes");
|
|
4697
|
+
const sub = editorActor.on("*", (event) => {
|
|
4698
|
+
switch (event.type) {
|
|
4701
4699
|
case "patch":
|
|
4702
|
-
IS_PROCESSING_LOCAL_CHANGES.set(slateEditor, !0), pendingPatches.current.push(
|
|
4700
|
+
IS_PROCESSING_LOCAL_CHANGES.set(slateEditor, !0), pendingPatches.current.push(event.patch), onFlushPendingPatchesThrottled(), onChange(event);
|
|
4701
|
+
break;
|
|
4702
|
+
case "loading": {
|
|
4703
|
+
onChange({ type: "loading", isLoading: !0 });
|
|
4704
|
+
break;
|
|
4705
|
+
}
|
|
4706
|
+
case "done loading": {
|
|
4707
|
+
onChange({ type: "loading", isLoading: !1 });
|
|
4708
|
+
break;
|
|
4709
|
+
}
|
|
4710
|
+
case "offline": {
|
|
4711
|
+
onChange({ type: "connection", value: "offline" });
|
|
4712
|
+
break;
|
|
4713
|
+
}
|
|
4714
|
+
case "online": {
|
|
4715
|
+
onChange({ type: "connection", value: "online" });
|
|
4716
|
+
break;
|
|
4717
|
+
}
|
|
4718
|
+
case "value changed": {
|
|
4719
|
+
onChange({ type: "value", value: event.value });
|
|
4720
|
+
break;
|
|
4721
|
+
}
|
|
4722
|
+
case "invalid value": {
|
|
4723
|
+
onChange({
|
|
4724
|
+
type: "invalidValue",
|
|
4725
|
+
resolution: event.resolution,
|
|
4726
|
+
value: event.value
|
|
4727
|
+
});
|
|
4703
4728
|
break;
|
|
4729
|
+
}
|
|
4730
|
+
case "error": {
|
|
4731
|
+
onChange({
|
|
4732
|
+
...event,
|
|
4733
|
+
level: "warning"
|
|
4734
|
+
});
|
|
4735
|
+
break;
|
|
4736
|
+
}
|
|
4704
4737
|
default:
|
|
4705
|
-
onChange(
|
|
4738
|
+
onChange(event);
|
|
4706
4739
|
}
|
|
4707
4740
|
});
|
|
4708
4741
|
return () => {
|
|
4709
|
-
debug$4("Unsubscribing to changes
|
|
4742
|
+
debug$4("Unsubscribing to changes"), sub.unsubscribe();
|
|
4710
4743
|
};
|
|
4711
|
-
}, [
|
|
4744
|
+
}, [editorActor, onFlushPendingPatchesThrottled, slateEditor]);
|
|
4712
4745
|
const handleOnline = useCallback(() => {
|
|
4713
|
-
debug$4("Editor is online, syncing from props.value"),
|
|
4714
|
-
}, [
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4746
|
+
debug$4("Editor is online, syncing from props.value"), syncValue(value);
|
|
4747
|
+
}, [syncValue, value]);
|
|
4748
|
+
useEffect(() => {
|
|
4749
|
+
const subscription = editorActor.on("online", () => {
|
|
4750
|
+
portableTextEditor.props.patches$ && handleOnline();
|
|
4751
|
+
});
|
|
4752
|
+
return () => {
|
|
4753
|
+
subscription.unsubscribe();
|
|
4754
|
+
};
|
|
4755
|
+
}, [editorActor]);
|
|
4720
4756
|
const isInitialValueFromProps = useRef(!0);
|
|
4721
4757
|
return useEffect(() => {
|
|
4722
|
-
debug$4("Value from props changed, syncing new value"), syncValue(value), isInitialValueFromProps.current && (
|
|
4723
|
-
}, [
|
|
4758
|
+
debug$4("Value from props changed, syncing new value"), syncValue(value), isInitialValueFromProps.current && (editorActor.send({ type: "ready" }), isInitialValueFromProps.current = !1);
|
|
4759
|
+
}, [editorActor, syncValue, value]), null;
|
|
4724
4760
|
}
|
|
4725
|
-
const
|
|
4761
|
+
const networkLogic = fromCallback(({ sendBack }) => {
|
|
4762
|
+
const onlineHandler = () => {
|
|
4763
|
+
sendBack({ type: "online" });
|
|
4764
|
+
}, offlineHandler = () => {
|
|
4765
|
+
sendBack({ type: "offline" });
|
|
4766
|
+
};
|
|
4767
|
+
return window.addEventListener("online", onlineHandler), window.addEventListener("offline", offlineHandler), () => {
|
|
4768
|
+
window.removeEventListener("online", onlineHandler), window.removeEventListener("offline", offlineHandler);
|
|
4769
|
+
};
|
|
4770
|
+
}), editorMachine = setup({
|
|
4771
|
+
types: {
|
|
4772
|
+
context: {},
|
|
4773
|
+
events: {},
|
|
4774
|
+
emitted: {}
|
|
4775
|
+
},
|
|
4776
|
+
actions: {
|
|
4777
|
+
"emit patch event": emit(({ event }) => (assertEvent(event, "patch"), event)),
|
|
4778
|
+
"emit mutation event": emit(({ event }) => (assertEvent(event, "mutation"), event)),
|
|
4779
|
+
"defer event": assign({
|
|
4780
|
+
pendingEvents: ({ context, event }) => (assertEvent(event, ["patch", "mutation"]), [...context.pendingEvents, event])
|
|
4781
|
+
}),
|
|
4782
|
+
"emit pending events": enqueueActions(({ context, enqueue }) => {
|
|
4783
|
+
for (const event of context.pendingEvents)
|
|
4784
|
+
enqueue(emit(event));
|
|
4785
|
+
}),
|
|
4786
|
+
"clear pending events": assign({
|
|
4787
|
+
pendingEvents: []
|
|
4788
|
+
})
|
|
4789
|
+
},
|
|
4790
|
+
actors: {
|
|
4791
|
+
networkLogic
|
|
4792
|
+
}
|
|
4793
|
+
}).createMachine({
|
|
4794
|
+
id: "editor",
|
|
4795
|
+
context: {
|
|
4796
|
+
pendingEvents: []
|
|
4797
|
+
},
|
|
4798
|
+
invoke: {
|
|
4799
|
+
id: "networkLogic",
|
|
4800
|
+
src: "networkLogic"
|
|
4801
|
+
},
|
|
4802
|
+
on: {
|
|
4803
|
+
ready: { actions: emit(({ event }) => event) },
|
|
4804
|
+
unset: { actions: emit(({ event }) => event) },
|
|
4805
|
+
"value changed": { actions: emit(({ event }) => event) },
|
|
4806
|
+
"invalid value": { actions: emit(({ event }) => event) },
|
|
4807
|
+
error: { actions: emit(({ event }) => event) },
|
|
4808
|
+
selection: { actions: emit(({ event }) => event) },
|
|
4809
|
+
blur: { actions: emit(({ event }) => event) },
|
|
4810
|
+
focus: { actions: emit(({ event }) => event) },
|
|
4811
|
+
online: { actions: emit({ type: "online" }) },
|
|
4812
|
+
offline: { actions: emit({ type: "offline" }) },
|
|
4813
|
+
loading: { actions: emit({ type: "loading" }) },
|
|
4814
|
+
"done loading": { actions: emit({ type: "done loading" }) }
|
|
4815
|
+
},
|
|
4816
|
+
initial: "pristine",
|
|
4817
|
+
states: {
|
|
4818
|
+
pristine: {
|
|
4819
|
+
initial: "idle",
|
|
4820
|
+
states: {
|
|
4821
|
+
idle: {
|
|
4822
|
+
on: {
|
|
4823
|
+
normalizing: {
|
|
4824
|
+
target: "normalizing"
|
|
4825
|
+
},
|
|
4826
|
+
patch: {
|
|
4827
|
+
actions: "defer event",
|
|
4828
|
+
target: "#editor.dirty"
|
|
4829
|
+
},
|
|
4830
|
+
mutation: {
|
|
4831
|
+
actions: "defer event",
|
|
4832
|
+
target: "#editor.dirty"
|
|
4833
|
+
}
|
|
4834
|
+
}
|
|
4835
|
+
},
|
|
4836
|
+
normalizing: {
|
|
4837
|
+
on: {
|
|
4838
|
+
"done normalizing": {
|
|
4839
|
+
target: "idle"
|
|
4840
|
+
},
|
|
4841
|
+
patch: {
|
|
4842
|
+
actions: "defer event"
|
|
4843
|
+
},
|
|
4844
|
+
mutation: {
|
|
4845
|
+
actions: "defer event"
|
|
4846
|
+
}
|
|
4847
|
+
}
|
|
4848
|
+
}
|
|
4849
|
+
}
|
|
4850
|
+
},
|
|
4851
|
+
dirty: {
|
|
4852
|
+
entry: ["emit pending events", "clear pending events"],
|
|
4853
|
+
on: {
|
|
4854
|
+
patch: {
|
|
4855
|
+
actions: "emit patch event"
|
|
4856
|
+
},
|
|
4857
|
+
mutation: {
|
|
4858
|
+
actions: "emit mutation event"
|
|
4859
|
+
}
|
|
4860
|
+
}
|
|
4861
|
+
}
|
|
4862
|
+
}
|
|
4863
|
+
}), PortableTextEditorSelectionContext = createContext(null), usePortableTextEditorSelection = () => {
|
|
4726
4864
|
const selection = useContext(PortableTextEditorSelectionContext);
|
|
4727
4865
|
if (selection === void 0)
|
|
4728
4866
|
throw new Error(
|
|
@@ -4731,21 +4869,26 @@ const PortableTextEditorSelectionContext = createContext(null), usePortableTextE
|
|
|
4731
4869
|
return selection;
|
|
4732
4870
|
}, debug$3 = debugWithName("component:PortableTextEditor:SelectionProvider"), debugVerbose = debug$3.enabled && !1;
|
|
4733
4871
|
function PortableTextEditorSelectionProvider(props) {
|
|
4734
|
-
const
|
|
4872
|
+
const [selection, setSelection] = useState(null);
|
|
4735
4873
|
return useEffect(() => {
|
|
4736
|
-
debug$3("Subscribing to selection changes
|
|
4737
|
-
const subscription =
|
|
4738
|
-
|
|
4739
|
-
debugVerbose && debug$3("Setting selection"), setSelection(
|
|
4874
|
+
debug$3("Subscribing to selection changes");
|
|
4875
|
+
const subscription = props.editorActor.on("selection", (event) => {
|
|
4876
|
+
startTransition(() => {
|
|
4877
|
+
debugVerbose && debug$3("Setting selection"), setSelection(event.selection);
|
|
4740
4878
|
});
|
|
4741
4879
|
});
|
|
4742
4880
|
return () => {
|
|
4743
|
-
debug$3("Unsubscribing to selection changes
|
|
4881
|
+
debug$3("Unsubscribing to selection changes"), subscription.unsubscribe();
|
|
4744
4882
|
};
|
|
4745
|
-
}, [
|
|
4883
|
+
}, [props.editorActor]), /* @__PURE__ */ jsx(PortableTextEditorSelectionContext.Provider, { value: selection, children: props.children });
|
|
4746
4884
|
}
|
|
4747
4885
|
const debug$2 = debugWithName("component:PortableTextEditor");
|
|
4748
4886
|
class PortableTextEditor extends Component {
|
|
4887
|
+
/**
|
|
4888
|
+
* @internal
|
|
4889
|
+
* Don't use this API directly. It's subject to change.
|
|
4890
|
+
*/
|
|
4891
|
+
editorActor;
|
|
4749
4892
|
/**
|
|
4750
4893
|
* An observable of all the editor changes.
|
|
4751
4894
|
*/
|
|
@@ -4763,7 +4906,7 @@ class PortableTextEditor extends Component {
|
|
|
4763
4906
|
throw new Error('PortableTextEditor: missing "schemaType" property');
|
|
4764
4907
|
props.incomingPatches$ && console.warn(
|
|
4765
4908
|
"The prop 'incomingPatches$' is deprecated and renamed to 'patches$'"
|
|
4766
|
-
), this.
|
|
4909
|
+
), this.editorActor = createActor(editorMachine), this.editorActor.start(), this.schemaTypes = getPortableTextMemberSchemaTypes(
|
|
4767
4910
|
props.schemaType.hasOwnProperty("jsonType") ? props.schemaType : compileType(props.schemaType)
|
|
4768
4911
|
);
|
|
4769
4912
|
}
|
|
@@ -4780,7 +4923,7 @@ class PortableTextEditor extends Component {
|
|
|
4780
4923
|
return this.editable.getValue();
|
|
4781
4924
|
};
|
|
4782
4925
|
render() {
|
|
4783
|
-
const {
|
|
4926
|
+
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, keyGenerator = this.props.keyGenerator || defaultKeyGenerator;
|
|
4784
4927
|
return /* @__PURE__ */ jsx(
|
|
4785
4928
|
SlateContainer,
|
|
4786
4929
|
{
|
|
@@ -4789,18 +4932,26 @@ class PortableTextEditor extends Component {
|
|
|
4789
4932
|
patches$: _patches$,
|
|
4790
4933
|
portableTextEditor: this,
|
|
4791
4934
|
readOnly,
|
|
4792
|
-
children: /* @__PURE__ */ jsx(PortableTextEditorKeyGeneratorContext.Provider, { value: keyGenerator, children: /* @__PURE__ */ jsx(PortableTextEditorContext.Provider, { value: this, children: /* @__PURE__ */ jsx(PortableTextEditorReadOnlyContext.Provider, { value: readOnly, children: /* @__PURE__ */ jsxs(
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4935
|
+
children: /* @__PURE__ */ jsx(PortableTextEditorKeyGeneratorContext.Provider, { value: keyGenerator, children: /* @__PURE__ */ jsx(PortableTextEditorContext.Provider, { value: this, children: /* @__PURE__ */ jsx(PortableTextEditorReadOnlyContext.Provider, { value: readOnly, children: /* @__PURE__ */ jsxs(
|
|
4936
|
+
PortableTextEditorSelectionProvider,
|
|
4937
|
+
{
|
|
4938
|
+
editorActor: this.editorActor,
|
|
4939
|
+
children: [
|
|
4940
|
+
/* @__PURE__ */ jsx(
|
|
4941
|
+
Synchronizer,
|
|
4942
|
+
{
|
|
4943
|
+
editorActor: this.editorActor,
|
|
4944
|
+
getValue: this.getValue,
|
|
4945
|
+
onChange: (change) => {
|
|
4946
|
+
this.props.onChange(change), this.change$.next(change);
|
|
4947
|
+
},
|
|
4948
|
+
value
|
|
4949
|
+
}
|
|
4950
|
+
),
|
|
4951
|
+
children
|
|
4952
|
+
]
|
|
4953
|
+
}
|
|
4954
|
+
) }) }) })
|
|
4804
4955
|
}
|
|
4805
4956
|
);
|
|
4806
4957
|
}
|
|
@@ -4910,20 +5061,19 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4910
5061
|
useEffect(() => {
|
|
4911
5062
|
if (!shouldTrackSelectionAndFocus)
|
|
4912
5063
|
return;
|
|
4913
|
-
const
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
|
|
5064
|
+
const onBlur = portableTextEditor.editorActor.on("blur", () => {
|
|
5065
|
+
setFocused(!1), setSelected(!1);
|
|
5066
|
+
}), onFocus = portableTextEditor.editorActor.on("focus", () => {
|
|
5067
|
+
const sel = PortableTextEditor.getSelection(portableTextEditor);
|
|
5068
|
+
sel && isEqual(sel.focus.path, path) && PortableTextEditor.isCollapsedSelection(portableTextEditor) && setFocused(!0), setSelectedFromRange();
|
|
5069
|
+
}), onSelection = portableTextEditor.editorActor.on(
|
|
5070
|
+
"selection",
|
|
5071
|
+
(event) => {
|
|
5072
|
+
event.selection && isEqual(event.selection.focus.path, path) && PortableTextEditor.isCollapsedSelection(portableTextEditor) ? setFocused(!0) : setFocused(!1), setSelectedFromRange();
|
|
4917
5073
|
}
|
|
4918
|
-
|
|
4919
|
-
const sel = PortableTextEditor.getSelection(portableTextEditor);
|
|
4920
|
-
sel && isEqual(sel.focus.path, path) && PortableTextEditor.isCollapsedSelection(portableTextEditor) && setFocused(!0), setSelectedFromRange();
|
|
4921
|
-
return;
|
|
4922
|
-
}
|
|
4923
|
-
next.type === "selection" && (next.selection && isEqual(next.selection.focus.path, path) && PortableTextEditor.isCollapsedSelection(portableTextEditor) ? setFocused(!0) : setFocused(!1), setSelectedFromRange());
|
|
4924
|
-
});
|
|
5074
|
+
);
|
|
4925
5075
|
return () => {
|
|
4926
|
-
|
|
5076
|
+
onBlur.unsubscribe(), onFocus.unsubscribe(), onSelection.unsubscribe();
|
|
4927
5077
|
};
|
|
4928
5078
|
}, [
|
|
4929
5079
|
path,
|
|
@@ -5074,9 +5224,9 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
5074
5224
|
forwardedRef,
|
|
5075
5225
|
() => ref.current
|
|
5076
5226
|
);
|
|
5077
|
-
const rangeDecorationsRef = useRef(rangeDecorations), {
|
|
5078
|
-
() => createWithInsertData(
|
|
5079
|
-
[
|
|
5227
|
+
const rangeDecorationsRef = useRef(rangeDecorations), { editorActor, schemaTypes } = portableTextEditor, slateEditor = useSlate(), blockTypeName = schemaTypes.block.name, withInsertData = useMemo(
|
|
5228
|
+
() => createWithInsertData(editorActor, schemaTypes, keyGenerator),
|
|
5229
|
+
[editorActor, keyGenerator, schemaTypes]
|
|
5080
5230
|
), withHotKeys = useMemo(
|
|
5081
5231
|
() => createWithHotkeys(schemaTypes, portableTextEditor, hotkeys),
|
|
5082
5232
|
[hotkeys, portableTextEditor, schemaTypes]
|
|
@@ -5149,10 +5299,13 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
5149
5299
|
`Normalized selection from props ${JSON.stringify(normalizedSelection)}`
|
|
5150
5300
|
);
|
|
5151
5301
|
const slateRange = toSlateRange(normalizedSelection, slateEditor);
|
|
5152
|
-
slateRange && (Transforms.select(slateEditor, slateRange), slateEditor.operations.some((o) => o.type === "set_selection") ||
|
|
5302
|
+
slateRange && (Transforms.select(slateEditor, slateRange), slateEditor.operations.some((o) => o.type === "set_selection") || editorActor.send({
|
|
5303
|
+
type: "selection",
|
|
5304
|
+
selection: normalizedSelection
|
|
5305
|
+
}), slateEditor.onChange());
|
|
5153
5306
|
}
|
|
5154
5307
|
}
|
|
5155
|
-
}, [propsSelection, slateEditor
|
|
5308
|
+
}, [editorActor, propsSelection, slateEditor]), syncRangeDecorations = useCallback(
|
|
5156
5309
|
(operation) => {
|
|
5157
5310
|
if (rangeDecorations && rangeDecorations.length > 0) {
|
|
5158
5311
|
const newSlateRanges = [];
|
|
@@ -5191,28 +5344,22 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
5191
5344
|
return;
|
|
5192
5345
|
}
|
|
5193
5346
|
}
|
|
5194
|
-
setRangeDecorationsState([]);
|
|
5347
|
+
rangeDecorationState.length > 0 && setRangeDecorationsState([]);
|
|
5195
5348
|
},
|
|
5196
5349
|
[portableTextEditor, rangeDecorations, schemaTypes, slateEditor]
|
|
5197
5350
|
);
|
|
5198
5351
|
useEffect(() => {
|
|
5199
|
-
const
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
setHasInvalidValue(!0);
|
|
5206
|
-
break;
|
|
5207
|
-
case "value":
|
|
5208
|
-
setHasInvalidValue(!1);
|
|
5209
|
-
break;
|
|
5210
|
-
}
|
|
5352
|
+
const onReady = editorActor.on("ready", () => {
|
|
5353
|
+
restoreSelectionFromProps();
|
|
5354
|
+
}), onInvalidValue = editorActor.on("invalid value", () => {
|
|
5355
|
+
setHasInvalidValue(!0);
|
|
5356
|
+
}), onValueChanged = editorActor.on("value changed", () => {
|
|
5357
|
+
setHasInvalidValue(!1);
|
|
5211
5358
|
});
|
|
5212
5359
|
return () => {
|
|
5213
|
-
|
|
5360
|
+
onReady.unsubscribe(), onInvalidValue.unsubscribe(), onValueChanged.unsubscribe();
|
|
5214
5361
|
};
|
|
5215
|
-
}, [
|
|
5362
|
+
}, [editorActor, restoreSelectionFromProps]), useEffect(() => {
|
|
5216
5363
|
propsSelection && !hasInvalidValue && restoreSelectionFromProps();
|
|
5217
5364
|
}, [hasInvalidValue, propsSelection, restoreSelectionFromProps]);
|
|
5218
5365
|
const originalApply = useMemo(() => slateEditor.apply, [slateEditor]), [syncedRangeDecorations, setSyncedRangeDecorations] = useState(!1);
|
|
@@ -5243,7 +5390,7 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
5243
5390
|
slateEditor.selection,
|
|
5244
5391
|
schemaTypes
|
|
5245
5392
|
)?.focus.path || [], onPasteResult = onPaste({ event, value, path, schemaTypes });
|
|
5246
|
-
onPasteResult === void 0 ? (debug("No result from custom paste handler, pasting normally"), slateEditor.insertData(event.clipboardData)) : (
|
|
5393
|
+
onPasteResult === void 0 ? (debug("No result from custom paste handler, pasting normally"), slateEditor.insertData(event.clipboardData)) : (editorActor.send({ type: "loading" }), Promise.resolve(onPasteResult).then((result) => {
|
|
5247
5394
|
debug("Custom paste function from client resolved", result), !result || !result.insert ? (debug("No result from custom paste handler, pasting normally"), slateEditor.insertData(event.clipboardData)) : result.insert ? slateEditor.insertFragment(
|
|
5248
5395
|
toSlateValue(result.insert, {
|
|
5249
5396
|
schemaTypes
|
|
@@ -5253,23 +5400,23 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
5253
5400
|
result
|
|
5254
5401
|
);
|
|
5255
5402
|
}).catch((error) => (console.error(error), error)).finally(() => {
|
|
5256
|
-
|
|
5403
|
+
editorActor.send({ type: "done loading" });
|
|
5257
5404
|
}));
|
|
5258
5405
|
},
|
|
5259
|
-
[
|
|
5406
|
+
[onPaste, portableTextEditor, schemaTypes, slateEditor]
|
|
5260
5407
|
), handleOnFocus = useCallback(
|
|
5261
5408
|
(event) => {
|
|
5262
5409
|
if (onFocus && onFocus(event), !event.isDefaultPrevented()) {
|
|
5263
5410
|
const selection = PortableTextEditor.getSelection(portableTextEditor);
|
|
5264
|
-
selection === null && (Transforms.select(slateEditor, Editor.start(slateEditor, [])), slateEditor.onChange()),
|
|
5411
|
+
selection === null && (Transforms.select(slateEditor, Editor.start(slateEditor, [])), slateEditor.onChange()), editorActor.send({ type: "focus", event });
|
|
5265
5412
|
const newSelection = PortableTextEditor.getSelection(portableTextEditor);
|
|
5266
|
-
selection === newSelection &&
|
|
5413
|
+
selection === newSelection && editorActor.send({
|
|
5267
5414
|
type: "selection",
|
|
5268
5415
|
selection
|
|
5269
5416
|
});
|
|
5270
5417
|
}
|
|
5271
5418
|
},
|
|
5272
|
-
[onFocus, portableTextEditor,
|
|
5419
|
+
[editorActor, onFocus, portableTextEditor, slateEditor]
|
|
5273
5420
|
), handleClick = useCallback(
|
|
5274
5421
|
(event) => {
|
|
5275
5422
|
if (onClick && onClick(event), slateEditor.selection && event.target === event.currentTarget) {
|
|
@@ -5286,9 +5433,9 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
5286
5433
|
[onClick, slateEditor]
|
|
5287
5434
|
), handleOnBlur = useCallback(
|
|
5288
5435
|
(event) => {
|
|
5289
|
-
onBlur && onBlur(event), event.isPropagationStopped() ||
|
|
5436
|
+
onBlur && onBlur(event), event.isPropagationStopped() || editorActor.send({ type: "blur", event });
|
|
5290
5437
|
},
|
|
5291
|
-
[
|
|
5438
|
+
[editorActor, onBlur]
|
|
5292
5439
|
), handleOnBeforeInput = useCallback(
|
|
5293
5440
|
(event) => {
|
|
5294
5441
|
onBeforeInput && onBeforeInput(event);
|
|
@@ -5394,6 +5541,7 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
5394
5541
|
export {
|
|
5395
5542
|
PortableTextEditable,
|
|
5396
5543
|
PortableTextEditor,
|
|
5544
|
+
editorMachine,
|
|
5397
5545
|
defaultKeyGenerator as keyGenerator,
|
|
5398
5546
|
usePortableTextEditor,
|
|
5399
5547
|
usePortableTextEditorSelection
|