@portabletext/editor 1.0.8 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.d.mts +18 -5
- package/lib/index.d.ts +18 -5
- package/lib/index.esm.js +188 -177
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +187 -176
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +188 -177
- package/lib/index.mjs.map +1 -1
- package/package.json +20 -22
- package/src/editor/Editable.tsx +4 -7
- package/src/editor/PortableTextEditor.tsx +31 -17
- package/src/editor/__tests__/RangeDecorations.test.tsx +4 -4
- package/src/editor/components/Synchronizer.tsx +15 -46
- package/src/editor/hooks/usePortableTextEditor.ts +1 -0
- package/src/editor/hooks/usePortableTextEditorKeyGenerator.ts +3 -0
- package/src/editor/hooks/usePortableTextEditorSelection.tsx +63 -0
- package/src/editor/plugins/createWithHotKeys.ts +5 -1
- package/src/types/editor.ts +7 -0
- package/src/types/options.ts +6 -0
- package/src/utils/withChanges.ts +0 -7
- package/src/editor/hooks/usePortableTextEditorSelection.ts +0 -22
- package/src/editor/hooks/usePortableTextEditorValue.ts +0 -16
- package/src/utils/bufferUntil.ts +0 -15
package/lib/index.esm.js
CHANGED
|
@@ -4,7 +4,7 @@ import noop from "lodash/noop.js";
|
|
|
4
4
|
import { useRef, useState, useMemo, useEffect, useCallback, createContext, useContext, startTransition, Component, forwardRef, useImperativeHandle } from "react";
|
|
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
|
-
import debug$
|
|
7
|
+
import debug$m from "debug";
|
|
8
8
|
import { isKeySegment, isPortableTextSpan, isPortableTextTextBlock, isPortableTextListBlock } from "@sanity/types";
|
|
9
9
|
import { styled } from "styled-components";
|
|
10
10
|
import uniq from "lodash/uniq.js";
|
|
@@ -22,10 +22,10 @@ import throttle from "lodash/throttle.js";
|
|
|
22
22
|
import { randomKey } from "@sanity/util/content";
|
|
23
23
|
import debounce from "lodash/debounce.js";
|
|
24
24
|
const rootName = "sanity-pte:";
|
|
25
|
-
debug$
|
|
25
|
+
debug$m(rootName);
|
|
26
26
|
function debugWithName(name) {
|
|
27
27
|
const namespace = `${rootName}${name}`;
|
|
28
|
-
return debug$
|
|
28
|
+
return debug$m && debug$m.enabled(namespace) ? debug$m(namespace) : debug$m(rootName);
|
|
29
29
|
}
|
|
30
30
|
function createKeyedPath(point, value, types) {
|
|
31
31
|
const blockPath = [point.path[0]];
|
|
@@ -348,7 +348,7 @@ function getCounterContentForListLevel(level) {
|
|
|
348
348
|
return "counter(listItemNumberNextNextNext) '. '";
|
|
349
349
|
}
|
|
350
350
|
}
|
|
351
|
-
const debug$
|
|
351
|
+
const debug$l = debugWithName("components:DraggableBlock"), DraggableBlock = ({ children, element, readOnly, blockRef }) => {
|
|
352
352
|
const editor = useSlateStatic(), dragGhostRef = useRef(), [isDragOver, setIsDragOver] = useState(!1), isVoid = useMemo(() => Editor.isVoid(editor, element), [editor, element]), isInline = useMemo(() => Editor.isInline(editor, element), [editor, element]), [blockElement, setBlockElement] = useState(null);
|
|
353
353
|
useEffect(
|
|
354
354
|
() => setBlockElement(blockRef ? blockRef.current : ReactEditor.toDOMNode(editor, element)),
|
|
@@ -375,18 +375,18 @@ const debug$k = debugWithName("components:DraggableBlock"), DraggableBlock = ({
|
|
|
375
375
|
(event) => {
|
|
376
376
|
const targetBlock = IS_DRAGGING_ELEMENT_TARGET.get(editor);
|
|
377
377
|
if (targetBlock) {
|
|
378
|
-
IS_DRAGGING.set(editor, !1), event.preventDefault(), event.stopPropagation(), IS_DRAGGING_ELEMENT_TARGET.delete(editor), dragGhostRef.current && (debug$
|
|
378
|
+
IS_DRAGGING.set(editor, !1), event.preventDefault(), event.stopPropagation(), IS_DRAGGING_ELEMENT_TARGET.delete(editor), dragGhostRef.current && (debug$l("Removing drag ghost"), document.body.removeChild(dragGhostRef.current));
|
|
379
379
|
const dragPosition2 = IS_DRAGGING_BLOCK_TARGET_POSITION.get(editor);
|
|
380
380
|
IS_DRAGGING_BLOCK_TARGET_POSITION.delete(editor);
|
|
381
381
|
let targetPath = ReactEditor.findPath(editor, targetBlock);
|
|
382
382
|
const myPath = ReactEditor.findPath(editor, element), isBefore = Path.isBefore(myPath, targetPath);
|
|
383
383
|
if (dragPosition2 === "bottom" && !isBefore) {
|
|
384
384
|
if (targetPath[0] >= editor.children.length - 1) {
|
|
385
|
-
debug$
|
|
385
|
+
debug$l("target is already at the bottom, not moving");
|
|
386
386
|
return;
|
|
387
387
|
}
|
|
388
388
|
const originalPath = targetPath;
|
|
389
|
-
targetPath = Path.next(targetPath), debug$
|
|
389
|
+
targetPath = Path.next(targetPath), debug$l(
|
|
390
390
|
`Adjusting targetPath from ${JSON.stringify(originalPath)} to ${JSON.stringify(
|
|
391
391
|
targetPath
|
|
392
392
|
)}`
|
|
@@ -394,29 +394,29 @@ const debug$k = debugWithName("components:DraggableBlock"), DraggableBlock = ({
|
|
|
394
394
|
}
|
|
395
395
|
if (dragPosition2 === "top" && isBefore && targetPath[0] !== editor.children.length - 1) {
|
|
396
396
|
const originalPath = targetPath;
|
|
397
|
-
targetPath = Path.previous(targetPath), debug$
|
|
397
|
+
targetPath = Path.previous(targetPath), debug$l(
|
|
398
398
|
`Adjusting targetPath from ${JSON.stringify(originalPath)} to ${JSON.stringify(
|
|
399
399
|
targetPath
|
|
400
400
|
)}`
|
|
401
401
|
);
|
|
402
402
|
}
|
|
403
403
|
if (Path.equals(targetPath, myPath)) {
|
|
404
|
-
event.preventDefault(), debug$
|
|
404
|
+
event.preventDefault(), debug$l("targetPath and myPath is the same, not moving");
|
|
405
405
|
return;
|
|
406
406
|
}
|
|
407
|
-
debug$
|
|
407
|
+
debug$l(
|
|
408
408
|
`Moving element ${element._key} from path ${JSON.stringify(myPath)} to ${JSON.stringify(
|
|
409
409
|
targetPath
|
|
410
410
|
)} (${dragPosition2})`
|
|
411
411
|
), Transforms.moveNodes(editor, { at: myPath, to: targetPath }), editor.onChange();
|
|
412
412
|
return;
|
|
413
413
|
}
|
|
414
|
-
debug$
|
|
414
|
+
debug$l("No target element, not doing anything");
|
|
415
415
|
},
|
|
416
416
|
[editor, element]
|
|
417
417
|
), handleDrop = useCallback(
|
|
418
418
|
(event) => {
|
|
419
|
-
IS_DRAGGING_BLOCK_ELEMENT.get(editor) && (debug$
|
|
419
|
+
IS_DRAGGING_BLOCK_ELEMENT.get(editor) && (debug$l("On drop (prevented)", element), event.preventDefault(), event.stopPropagation(), setIsDragOver(!1));
|
|
420
420
|
},
|
|
421
421
|
[editor, element]
|
|
422
422
|
), handleDrag = useCallback(
|
|
@@ -433,10 +433,10 @@ const debug$k = debugWithName("components:DraggableBlock"), DraggableBlock = ({
|
|
|
433
433
|
), handleDragStart = useCallback(
|
|
434
434
|
(event) => {
|
|
435
435
|
if (!isVoid || isInline) {
|
|
436
|
-
debug$
|
|
436
|
+
debug$l("Not dragging block"), IS_DRAGGING_BLOCK_ELEMENT.delete(editor), IS_DRAGGING.set(editor, !1);
|
|
437
437
|
return;
|
|
438
438
|
}
|
|
439
|
-
if (debug$
|
|
439
|
+
if (debug$l("Drag start"), IS_DRAGGING.set(editor, !0), event.dataTransfer && (event.dataTransfer.setData("application/portable-text", "something"), event.dataTransfer.effectAllowed = "move"), blockElement && blockElement instanceof HTMLElement) {
|
|
440
440
|
let dragGhost = blockElement.cloneNode(!0);
|
|
441
441
|
const customGhost = dragGhost.querySelector("[data-pt-drag-ghost-element]");
|
|
442
442
|
if (customGhost && (dragGhost = customGhost), dragGhost.setAttribute("data-dragged", ""), document.body) {
|
|
@@ -717,12 +717,12 @@ function compileType(rawType) {
|
|
|
717
717
|
types: [rawType]
|
|
718
718
|
}).get(rawType.name);
|
|
719
719
|
}
|
|
720
|
-
const debug$
|
|
721
|
-
debug$
|
|
720
|
+
const debug$k = debugWithName("operationToPatches");
|
|
721
|
+
debug$k.enabled = !1;
|
|
722
722
|
function createOperationToPatches(types) {
|
|
723
723
|
const textBlockName = types.block.name;
|
|
724
724
|
function insertTextPatch(editor, operation, beforeValue) {
|
|
725
|
-
debug$
|
|
725
|
+
debug$k.enabled && debug$k("Operation", JSON.stringify(operation, null, 2));
|
|
726
726
|
const block = editor.isTextBlock(editor.children[operation.path[0]]) && editor.children[operation.path[0]];
|
|
727
727
|
if (!block)
|
|
728
728
|
throw new Error("Could not find block");
|
|
@@ -813,7 +813,7 @@ function createOperationToPatches(types) {
|
|
|
813
813
|
])
|
|
814
814
|
];
|
|
815
815
|
}
|
|
816
|
-
return debug$
|
|
816
|
+
return debug$k("Something was inserted into a void block. Not producing editor patches."), [];
|
|
817
817
|
}
|
|
818
818
|
function splitNodePatch(editor, operation, beforeValue) {
|
|
819
819
|
const patches = [], splitBlock = editor.children[operation.path[0]];
|
|
@@ -876,9 +876,9 @@ function createOperationToPatches(types) {
|
|
|
876
876
|
throw new Error("Block not found");
|
|
877
877
|
} else if (editor.isTextBlock(block) && operation.path.length === 2) {
|
|
878
878
|
const spanToRemove = editor.isTextBlock(block) && block.children && block.children[operation.path[1]];
|
|
879
|
-
return spanToRemove ? [unset([{ _key: block._key }, "children", { _key: spanToRemove._key }])] : (debug$
|
|
879
|
+
return spanToRemove ? [unset([{ _key: block._key }, "children", { _key: spanToRemove._key }])] : (debug$k("Span not found in editor trying to remove node"), []);
|
|
880
880
|
} else
|
|
881
|
-
return debug$
|
|
881
|
+
return debug$k("Not creating patch inside object block"), [];
|
|
882
882
|
}
|
|
883
883
|
function mergeNodePatch(editor, operation, beforeValue) {
|
|
884
884
|
const patches = [], block = beforeValue[operation.path[0]], targetBlock = editor.children[operation.path[0]];
|
|
@@ -894,7 +894,7 @@ function createOperationToPatches(types) {
|
|
|
894
894
|
set(targetSpan.text, [{ _key: block._key }, "children", { _key: targetSpan._key }, "text"])
|
|
895
895
|
), mergedSpan && patches.push(unset([{ _key: block._key }, "children", { _key: mergedSpan._key }])));
|
|
896
896
|
} else
|
|
897
|
-
debug$
|
|
897
|
+
debug$k("Void nodes can't be merged, not creating any patches");
|
|
898
898
|
return patches;
|
|
899
899
|
}
|
|
900
900
|
function moveNodePatch(editor, operation, beforeValue) {
|
|
@@ -927,7 +927,7 @@ function createOperationToPatches(types) {
|
|
|
927
927
|
splitNodePatch
|
|
928
928
|
};
|
|
929
929
|
}
|
|
930
|
-
const debug$
|
|
930
|
+
const debug$j = debugWithName("API:editable");
|
|
931
931
|
function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
932
932
|
return function(editor) {
|
|
933
933
|
return portableTextEditor.setEditable({
|
|
@@ -1010,7 +1010,7 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1010
1010
|
],
|
|
1011
1011
|
portableTextEditor
|
|
1012
1012
|
)[0].children[0], focusChildPath = editor.selection.focus.path.slice(0, 2), isSpanNode = child._type === types.span.name, focusNode = Node.get(editor, focusChildPath);
|
|
1013
|
-
return isSpanNode && focusNode._type !== types.span.name && (debug$
|
|
1013
|
+
return isSpanNode && focusNode._type !== types.span.name && (debug$j("Inserting span child next to inline object child, moving selection + 1"), editor.move({ distance: 1, unit: "character" })), Transforms.insertNodes(editor, child, {
|
|
1014
1014
|
select: !0,
|
|
1015
1015
|
at: editor.selection
|
|
1016
1016
|
}), editor.onChange(), ((_a = toPortableTextRange(
|
|
@@ -1209,18 +1209,18 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1209
1209
|
throw new Error("Invalid range");
|
|
1210
1210
|
if (range) {
|
|
1211
1211
|
if (!(options != null && options.mode) || (options == null ? void 0 : options.mode) === "selected") {
|
|
1212
|
-
debug$
|
|
1212
|
+
debug$j("Deleting content in selection"), Transforms.delete(editor, {
|
|
1213
1213
|
at: range,
|
|
1214
1214
|
hanging: !0,
|
|
1215
1215
|
voids: !0
|
|
1216
1216
|
}), editor.onChange();
|
|
1217
1217
|
return;
|
|
1218
1218
|
}
|
|
1219
|
-
(options == null ? void 0 : options.mode) === "blocks" && (debug$
|
|
1219
|
+
(options == null ? void 0 : options.mode) === "blocks" && (debug$j("Deleting blocks touched by selection"), Transforms.removeNodes(editor, {
|
|
1220
1220
|
at: range,
|
|
1221
1221
|
voids: !0,
|
|
1222
1222
|
match: (node) => editor.isTextBlock(node) || !editor.isTextBlock(node) && Element$1.isElement(node)
|
|
1223
|
-
})), (options == null ? void 0 : options.mode) === "children" && (debug$
|
|
1223
|
+
})), (options == null ? void 0 : options.mode) === "children" && (debug$j("Deleting children touched by selection"), Transforms.removeNodes(editor, {
|
|
1224
1224
|
at: range,
|
|
1225
1225
|
voids: !0,
|
|
1226
1226
|
match: (node) => node._type === types.span.name || // Text children
|
|
@@ -1231,7 +1231,7 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1231
1231
|
},
|
|
1232
1232
|
removeAnnotation: (type) => {
|
|
1233
1233
|
let { selection } = editor;
|
|
1234
|
-
if (debug$
|
|
1234
|
+
if (debug$j("Removing annotation", type), selection) {
|
|
1235
1235
|
if (Range.isCollapsed(selection)) {
|
|
1236
1236
|
const [node, nodePath] = Editor.node(editor, selection, { depth: 2 });
|
|
1237
1237
|
Text.isText(node) && node.marks && typeof node.text == "string" && (Transforms.select(editor, nodePath), selection = editor.selection);
|
|
@@ -2051,14 +2051,14 @@ function parse(textline) {
|
|
|
2051
2051
|
function toInt(num) {
|
|
2052
2052
|
return parseInt(num, 10);
|
|
2053
2053
|
}
|
|
2054
|
-
const debug$
|
|
2054
|
+
const debug$i = debugWithName("applyPatches"), debugVerbose$4 = debug$i.enabled && !0;
|
|
2055
2055
|
function createApplyPatch(schemaTypes) {
|
|
2056
2056
|
let previousPatch;
|
|
2057
2057
|
return function(editor, patch) {
|
|
2058
2058
|
let changed = !1;
|
|
2059
|
-
debugVerbose$
|
|
2059
|
+
debugVerbose$4 && (debug$i(`
|
|
2060
2060
|
|
|
2061
|
-
NEW PATCH =============================================================`), debug$
|
|
2061
|
+
NEW PATCH =============================================================`), debug$i(JSON.stringify(patch, null, 2)));
|
|
2062
2062
|
try {
|
|
2063
2063
|
switch (patch.type) {
|
|
2064
2064
|
case "insert":
|
|
@@ -2074,7 +2074,7 @@ NEW PATCH =============================================================`), debug
|
|
|
2074
2074
|
changed = diffMatchPatch(editor, patch);
|
|
2075
2075
|
break;
|
|
2076
2076
|
default:
|
|
2077
|
-
debug$
|
|
2077
|
+
debug$i("Unhandled patch", patch.type);
|
|
2078
2078
|
}
|
|
2079
2079
|
} catch (err) {
|
|
2080
2080
|
console.error(err);
|
|
@@ -2085,9 +2085,9 @@ NEW PATCH =============================================================`), debug
|
|
|
2085
2085
|
function diffMatchPatch(editor, patch) {
|
|
2086
2086
|
const { block, child, childPath } = findBlockAndChildFromPath(editor, patch.path);
|
|
2087
2087
|
if (!block)
|
|
2088
|
-
return debug$
|
|
2088
|
+
return debug$i("Block not found"), !1;
|
|
2089
2089
|
if (!child || !childPath)
|
|
2090
|
-
return debug$
|
|
2090
|
+
return debug$i("Child not found"), !1;
|
|
2091
2091
|
if (!(block && editor.isTextBlock(block) && patch.path.length === 4 && patch.path[1] === "children" && patch.path[3] === "text") || !Text.isText(child))
|
|
2092
2092
|
return !1;
|
|
2093
2093
|
const patches = parse(patch.value), [newValue] = apply(patches, child.text, { allowExceedingIndices: !0 }), diff$1 = cleanupEfficiency(diff(child.text, newValue), 5);
|
|
@@ -2105,40 +2105,40 @@ function insertPatch(editor, patch, schemaTypes) {
|
|
|
2105
2105
|
childPath: targetChildPath
|
|
2106
2106
|
} = findBlockAndChildFromPath(editor, patch.path);
|
|
2107
2107
|
if (!targetBlock || !targetBlockPath)
|
|
2108
|
-
return debug$
|
|
2108
|
+
return debug$i("Block not found"), !1;
|
|
2109
2109
|
if (patch.path.length > 1 && patch.path[1] !== "children")
|
|
2110
|
-
return debug$
|
|
2110
|
+
return debug$i("Ignoring patch targeting void value"), !1;
|
|
2111
2111
|
if (patch.path.length === 1) {
|
|
2112
2112
|
const { items: items2, position: position2 } = patch, blocksToInsert = toSlateValue(
|
|
2113
2113
|
items2,
|
|
2114
2114
|
{ schemaTypes },
|
|
2115
2115
|
KEY_TO_SLATE_ELEMENT.get(editor)
|
|
2116
2116
|
), targetBlockIndex = targetBlockPath[0], normalizedIdx2 = position2 === "after" ? targetBlockIndex + 1 : targetBlockIndex;
|
|
2117
|
-
return debug$
|
|
2117
|
+
return debug$i(`Inserting blocks at path [${normalizedIdx2}]`), debugState(editor, "before"), Transforms.insertNodes(editor, blocksToInsert, { at: [normalizedIdx2] }), debugState(editor, "after"), !0;
|
|
2118
2118
|
}
|
|
2119
2119
|
const { items, position } = patch;
|
|
2120
2120
|
if (!targetChild || !targetChildPath)
|
|
2121
|
-
return debug$
|
|
2121
|
+
return debug$i("Child not found"), !1;
|
|
2122
2122
|
const childrenToInsert = targetBlock && toSlateValue(
|
|
2123
2123
|
[{ ...targetBlock, children: items }],
|
|
2124
2124
|
{ schemaTypes },
|
|
2125
2125
|
KEY_TO_SLATE_ELEMENT.get(editor)
|
|
2126
2126
|
), targetChildIndex = targetChildPath[1], normalizedIdx = position === "after" ? targetChildIndex + 1 : targetChildIndex, childInsertPath = [targetChildPath[0], normalizedIdx];
|
|
2127
|
-
return debug$
|
|
2127
|
+
return debug$i(`Inserting children at path ${childInsertPath}`), debugState(editor, "before"), childrenToInsert && Element$1.isElement(childrenToInsert[0]) && Transforms.insertNodes(editor, childrenToInsert[0].children, { at: childInsertPath }), debugState(editor, "after"), !0;
|
|
2128
2128
|
}
|
|
2129
2129
|
function setPatch(editor, patch) {
|
|
2130
2130
|
let value = patch.value;
|
|
2131
2131
|
typeof patch.path[3] == "string" && (value = {}, value[patch.path[3]] = patch.value);
|
|
2132
2132
|
const { block, blockPath, child, childPath } = findBlockAndChildFromPath(editor, patch.path);
|
|
2133
2133
|
if (!block)
|
|
2134
|
-
return debug$
|
|
2134
|
+
return debug$i("Block not found"), !1;
|
|
2135
2135
|
const isTextBlock = editor.isTextBlock(block);
|
|
2136
2136
|
if (isTextBlock && patch.path.length > 1 && patch.path[1] !== "children")
|
|
2137
|
-
return debug$
|
|
2137
|
+
return debug$i("Ignoring setting void value"), !1;
|
|
2138
2138
|
if (debugState(editor, "before"), isTextBlock && child && childPath) {
|
|
2139
2139
|
if (Text.isText(value) && Text.isText(child)) {
|
|
2140
2140
|
const newText = child.text;
|
|
2141
|
-
value.text !== newText && (debug$
|
|
2141
|
+
value.text !== newText && (debug$i("Setting text property"), editor.apply({
|
|
2142
2142
|
type: "remove_text",
|
|
2143
2143
|
path: childPath,
|
|
2144
2144
|
offset: 0,
|
|
@@ -2150,7 +2150,7 @@ function setPatch(editor, patch) {
|
|
|
2150
2150
|
text: value.text
|
|
2151
2151
|
}), editor.onChange());
|
|
2152
2152
|
} else
|
|
2153
|
-
debug$
|
|
2153
|
+
debug$i("Setting non-text property"), editor.apply({
|
|
2154
2154
|
type: "set_node",
|
|
2155
2155
|
path: childPath,
|
|
2156
2156
|
properties: {},
|
|
@@ -2158,14 +2158,14 @@ function setPatch(editor, patch) {
|
|
|
2158
2158
|
});
|
|
2159
2159
|
return !0;
|
|
2160
2160
|
} else if (Element$1.isElement(block) && patch.path.length === 1 && blockPath) {
|
|
2161
|
-
debug$
|
|
2161
|
+
debug$i("Setting block property");
|
|
2162
2162
|
const { children, ...nextRest } = value, { children: prevChildren, ...prevRest } = block || { children: void 0 };
|
|
2163
2163
|
editor.apply({
|
|
2164
2164
|
type: "set_node",
|
|
2165
2165
|
path: blockPath,
|
|
2166
2166
|
properties: { ...prevRest },
|
|
2167
2167
|
newProperties: nextRest
|
|
2168
|
-
}), debug$
|
|
2168
|
+
}), debug$i("Setting children"), block.children.forEach((c, cIndex) => {
|
|
2169
2169
|
editor.apply({
|
|
2170
2170
|
type: "remove_node",
|
|
2171
2171
|
path: blockPath.concat(block.children.length - 1 - cIndex),
|
|
@@ -2186,7 +2186,7 @@ function setPatch(editor, patch) {
|
|
|
2186
2186
|
}
|
|
2187
2187
|
function unsetPatch(editor, patch, previousPatch) {
|
|
2188
2188
|
if (patch.path.length === 0) {
|
|
2189
|
-
debug$
|
|
2189
|
+
debug$i("Removing everything"), debugState(editor, "before");
|
|
2190
2190
|
const previousSelection = editor.selection;
|
|
2191
2191
|
return Transforms.deselect(editor), editor.children.forEach((c, i) => {
|
|
2192
2192
|
Transforms.removeNodes(editor, { at: [i] });
|
|
@@ -2198,17 +2198,17 @@ function unsetPatch(editor, patch, previousPatch) {
|
|
|
2198
2198
|
const { block, blockPath, child, childPath } = findBlockAndChildFromPath(editor, patch.path);
|
|
2199
2199
|
if (patch.path.length === 1) {
|
|
2200
2200
|
if (!block || !blockPath)
|
|
2201
|
-
return debug$
|
|
2201
|
+
return debug$i("Block not found"), !1;
|
|
2202
2202
|
const blockIndex = blockPath[0];
|
|
2203
|
-
return debug$
|
|
2203
|
+
return debug$i(`Removing block at path [${blockIndex}]`), debugState(editor, "before"), Transforms.removeNodes(editor, { at: [blockIndex] }), debugState(editor, "after"), !0;
|
|
2204
2204
|
}
|
|
2205
|
-
return editor.isTextBlock(block) && patch.path[1] === "children" && patch.path.length === 3 ? !child || !childPath ? (debug$
|
|
2205
|
+
return editor.isTextBlock(block) && patch.path[1] === "children" && patch.path.length === 3 ? !child || !childPath ? (debug$i("Child not found"), !1) : (debug$i(`Unsetting child at path ${JSON.stringify(childPath)}`), debugState(editor, "before"), debugVerbose$4 && debug$i(`Removing child at path ${JSON.stringify(childPath)}`), Transforms.removeNodes(editor, { at: childPath }), debugState(editor, "after"), !0) : !1;
|
|
2206
2206
|
}
|
|
2207
2207
|
function isKeyedSegment(segment) {
|
|
2208
2208
|
return typeof segment == "object" && "_key" in segment;
|
|
2209
2209
|
}
|
|
2210
2210
|
function debugState(editor, stateName) {
|
|
2211
|
-
debugVerbose$
|
|
2211
|
+
debugVerbose$4 && (debug$i(`Children ${stateName}:`, JSON.stringify(editor.children, null, 2)), debug$i(`Selection ${stateName}: `, JSON.stringify(editor.selection, null, 2)));
|
|
2212
2212
|
}
|
|
2213
2213
|
function findBlockFromPath(editor, path) {
|
|
2214
2214
|
let blockIndex = -1;
|
|
@@ -2247,7 +2247,7 @@ function withoutPatching(editor, fn) {
|
|
|
2247
2247
|
function isPatching(editor) {
|
|
2248
2248
|
return PATCHING.get(editor);
|
|
2249
2249
|
}
|
|
2250
|
-
const debug$
|
|
2250
|
+
const debug$h = debugWithName("plugin:withUndoRedo"), debugVerbose$3 = debug$h.enabled && !1, SAVING = /* @__PURE__ */ new WeakMap(), REMOTE_PATCHES = /* @__PURE__ */ new WeakMap(), UNDO_STEP_LIMIT = 1e3, isSaving = (editor) => {
|
|
2251
2251
|
const state = SAVING.get(editor);
|
|
2252
2252
|
return state === void 0 ? !0 : state;
|
|
2253
2253
|
}, getRemotePatches = (editor) => (REMOTE_PATCHES.get(editor) || REMOTE_PATCHES.set(editor, []), REMOTE_PATCHES.get(editor) || []);
|
|
@@ -2260,13 +2260,13 @@ function createWithUndoRedo(options) {
|
|
|
2260
2260
|
);
|
|
2261
2261
|
const remotePatches = getRemotePatches(editor);
|
|
2262
2262
|
patches$ && editor.subscriptions.push(() => {
|
|
2263
|
-
debug$
|
|
2263
|
+
debug$h("Subscribing to patches");
|
|
2264
2264
|
const sub = patches$.subscribe(({ patches, snapshot }) => {
|
|
2265
2265
|
let reset = !1;
|
|
2266
2266
|
patches.forEach((patch) => {
|
|
2267
2267
|
if (!reset && patch.origin !== "local" && remotePatches) {
|
|
2268
2268
|
if (patch.type === "unset" && patch.path.length === 0) {
|
|
2269
|
-
debug$
|
|
2269
|
+
debug$h("Someone else cleared the content, resetting undo/redo history"), editor.history = { undos: [], redos: [] }, remotePatches.splice(0, remotePatches.length), SAVING.set(editor, !0), reset = !0;
|
|
2270
2270
|
return;
|
|
2271
2271
|
}
|
|
2272
2272
|
remotePatches.push({ patch, time: /* @__PURE__ */ new Date(), snapshot, previousSnapshot });
|
|
@@ -2274,7 +2274,7 @@ function createWithUndoRedo(options) {
|
|
|
2274
2274
|
}), previousSnapshot = snapshot;
|
|
2275
2275
|
});
|
|
2276
2276
|
return () => {
|
|
2277
|
-
debug$
|
|
2277
|
+
debug$h("Unsubscribing to patches"), sub.unsubscribe();
|
|
2278
2278
|
};
|
|
2279
2279
|
}), editor.history = { undos: [], redos: [] };
|
|
2280
2280
|
const { apply: apply2 } = editor;
|
|
@@ -2293,7 +2293,7 @@ function createWithUndoRedo(options) {
|
|
|
2293
2293
|
operations: [...editor.selection === null ? [] : [createSelectOperation(editor)], op],
|
|
2294
2294
|
timestamp: /* @__PURE__ */ new Date()
|
|
2295
2295
|
};
|
|
2296
|
-
undos.push(newStep), debug$
|
|
2296
|
+
undos.push(newStep), debug$h("Created new undo step", step);
|
|
2297
2297
|
}
|
|
2298
2298
|
for (; undos.length > UNDO_STEP_LIMIT; )
|
|
2299
2299
|
undos.shift();
|
|
@@ -2306,7 +2306,7 @@ function createWithUndoRedo(options) {
|
|
|
2306
2306
|
const { undos } = editor.history;
|
|
2307
2307
|
if (undos.length > 0) {
|
|
2308
2308
|
const step = undos[undos.length - 1];
|
|
2309
|
-
if (debug$
|
|
2309
|
+
if (debug$h("Undoing", step), step.operations.length > 0) {
|
|
2310
2310
|
const otherPatches = remotePatches.filter((item) => item.time >= step.timestamp);
|
|
2311
2311
|
let transformedOperations = step.operations;
|
|
2312
2312
|
otherPatches.forEach((item) => {
|
|
@@ -2327,7 +2327,7 @@ function createWithUndoRedo(options) {
|
|
|
2327
2327
|
});
|
|
2328
2328
|
}), editor.normalize(), editor.onChange();
|
|
2329
2329
|
} catch (err) {
|
|
2330
|
-
debug$
|
|
2330
|
+
debug$h("Could not perform undo step", err), remotePatches.splice(0, remotePatches.length), Transforms.deselect(editor), editor.history = { undos: [], redos: [] }, SAVING.set(editor, !0), editor.onChange();
|
|
2331
2331
|
return;
|
|
2332
2332
|
}
|
|
2333
2333
|
editor.history.redos.push(step), editor.history.undos.pop();
|
|
@@ -2339,7 +2339,7 @@ function createWithUndoRedo(options) {
|
|
|
2339
2339
|
const { redos } = editor.history;
|
|
2340
2340
|
if (redos.length > 0) {
|
|
2341
2341
|
const step = redos[redos.length - 1];
|
|
2342
|
-
if (debug$
|
|
2342
|
+
if (debug$h("Redoing", step), step.operations.length > 0) {
|
|
2343
2343
|
const otherPatches = remotePatches.filter((item) => item.time >= step.timestamp);
|
|
2344
2344
|
let transformedOperations = step.operations;
|
|
2345
2345
|
otherPatches.forEach((item) => {
|
|
@@ -2360,7 +2360,7 @@ function createWithUndoRedo(options) {
|
|
|
2360
2360
|
});
|
|
2361
2361
|
}), editor.normalize(), editor.onChange();
|
|
2362
2362
|
} catch (err) {
|
|
2363
|
-
debug$
|
|
2363
|
+
debug$h("Could not perform redo step", err), remotePatches.splice(0, remotePatches.length), Transforms.deselect(editor), editor.history = { undos: [], redos: [] }, SAVING.set(editor, !0), editor.onChange();
|
|
2364
2364
|
return;
|
|
2365
2365
|
}
|
|
2366
2366
|
editor.history.undos.push(step), editor.history.redos.pop();
|
|
@@ -2370,13 +2370,13 @@ function createWithUndoRedo(options) {
|
|
|
2370
2370
|
};
|
|
2371
2371
|
}
|
|
2372
2372
|
function transformOperation(editor, patch, operation, snapshot, previousSnapshot) {
|
|
2373
|
-
debugVerbose$
|
|
2373
|
+
debugVerbose$3 && (debug$h(`Adjusting '${operation.type}' operation paths for '${patch.type}' patch`), debug$h(`Operation ${JSON.stringify(operation)}`), debug$h(`Patch ${JSON.stringify(patch)}`));
|
|
2374
2374
|
const transformedOperation = { ...operation };
|
|
2375
2375
|
if (patch.type === "insert" && patch.path.length === 1) {
|
|
2376
2376
|
const insertBlockIndex = (snapshot || []).findIndex(
|
|
2377
2377
|
(blk) => isEqual({ _key: blk._key }, patch.path[0])
|
|
2378
2378
|
);
|
|
2379
|
-
return debug$
|
|
2379
|
+
return debug$h(
|
|
2380
2380
|
`Adjusting block path (+${patch.items.length}) for '${transformedOperation.type}' operation and patch '${patch.type}'`
|
|
2381
2381
|
), [adjustBlockPath(transformedOperation, patch.items.length, insertBlockIndex)];
|
|
2382
2382
|
}
|
|
@@ -2384,12 +2384,12 @@ function transformOperation(editor, patch, operation, snapshot, previousSnapshot
|
|
|
2384
2384
|
const unsetBlockIndex = (previousSnapshot || []).findIndex(
|
|
2385
2385
|
(blk) => isEqual({ _key: blk._key }, patch.path[0])
|
|
2386
2386
|
);
|
|
2387
|
-
return "path" in transformedOperation && Array.isArray(transformedOperation.path) && transformedOperation.path[0] === unsetBlockIndex ? (debug$
|
|
2387
|
+
return "path" in transformedOperation && Array.isArray(transformedOperation.path) && transformedOperation.path[0] === unsetBlockIndex ? (debug$h("Skipping transformation that targeted removed block"), []) : (debugVerbose$3 && (debug$h(`Selection ${JSON.stringify(editor.selection)}`), debug$h(
|
|
2388
2388
|
`Adjusting block path (-1) for '${transformedOperation.type}' operation and patch '${patch.type}'`
|
|
2389
2389
|
)), [adjustBlockPath(transformedOperation, -1, unsetBlockIndex)]);
|
|
2390
2390
|
}
|
|
2391
2391
|
if (patch.type === "unset" && patch.path.length === 0)
|
|
2392
|
-
return debug$
|
|
2392
|
+
return debug$h(`Adjusting selection for unset everything patch and ${operation.type} operation`), [];
|
|
2393
2393
|
if (patch.type === "diffMatchPatch") {
|
|
2394
2394
|
const operationTargetBlock = findOperationTargetBlock(editor, transformedOperation);
|
|
2395
2395
|
return !operationTargetBlock || !isEqual({ _key: operationTargetBlock._key }, patch.path[0]) ? [transformedOperation] : (parse(patch.value).forEach((diffPatch) => {
|
|
@@ -2452,7 +2452,7 @@ function findOperationTargetBlock(editor, operation) {
|
|
|
2452
2452
|
let block;
|
|
2453
2453
|
return operation.type === "set_selection" && editor.selection ? block = editor.children[editor.selection.focus.path[0]] : "path" in operation && (block = editor.children[operation.path[0]]), block;
|
|
2454
2454
|
}
|
|
2455
|
-
const debug$
|
|
2455
|
+
const debug$g = debugWithName("plugin:withPatches");
|
|
2456
2456
|
function createWithPatches({
|
|
2457
2457
|
change$,
|
|
2458
2458
|
patches$,
|
|
@@ -2478,7 +2478,7 @@ function createWithPatches({
|
|
|
2478
2478
|
withoutSaving(editor, () => {
|
|
2479
2479
|
withPreserveKeys(editor, () => {
|
|
2480
2480
|
patches.forEach((patch) => {
|
|
2481
|
-
debug$
|
|
2481
|
+
debug$g.enabled && debug$g(`Handling remote patch ${JSON.stringify(patch)}`), changed = applyPatch(editor, patch);
|
|
2482
2482
|
});
|
|
2483
2483
|
});
|
|
2484
2484
|
});
|
|
@@ -2490,10 +2490,10 @@ function createWithPatches({
|
|
|
2490
2490
|
remotePatches.length !== 0 && (bufferedPatches = bufferedPatches.concat(remotePatches), handleBufferedRemotePatches());
|
|
2491
2491
|
};
|
|
2492
2492
|
return patches$ && editor.subscriptions.push(() => {
|
|
2493
|
-
debug$
|
|
2493
|
+
debug$g("Subscribing to patches$");
|
|
2494
2494
|
const sub = patches$.subscribe(handlePatches);
|
|
2495
2495
|
return () => {
|
|
2496
|
-
debug$
|
|
2496
|
+
debug$g("Unsubscribing to patches$"), sub.unsubscribe();
|
|
2497
2497
|
};
|
|
2498
2498
|
}), editor.apply = (operation) => {
|
|
2499
2499
|
if (readOnly)
|
|
@@ -2571,7 +2571,7 @@ function createWithPatches({
|
|
|
2571
2571
|
}, editor;
|
|
2572
2572
|
};
|
|
2573
2573
|
}
|
|
2574
|
-
const debug$
|
|
2574
|
+
const debug$f = debugWithName("plugin:withPlaceholderBlock");
|
|
2575
2575
|
function createWithPlaceholderBlock() {
|
|
2576
2576
|
return function(editor) {
|
|
2577
2577
|
const { apply: apply2 } = editor;
|
|
@@ -2580,14 +2580,14 @@ function createWithPlaceholderBlock() {
|
|
|
2580
2580
|
const node = op.node;
|
|
2581
2581
|
if (op.path[0] === 0 && Editor.isVoid(editor, node)) {
|
|
2582
2582
|
const nextPath = Path.next(op.path);
|
|
2583
|
-
editor.children[nextPath[0]] || (debug$
|
|
2583
|
+
editor.children[nextPath[0]] || (debug$f("Adding placeholder block"), Editor.insertNode(editor, editor.pteCreateEmptyBlock()));
|
|
2584
2584
|
}
|
|
2585
2585
|
}
|
|
2586
2586
|
apply2(op);
|
|
2587
2587
|
}, editor;
|
|
2588
2588
|
};
|
|
2589
2589
|
}
|
|
2590
|
-
const debug$
|
|
2590
|
+
const debug$e = debugWithName("plugin:withPortableTextBlockStyle");
|
|
2591
2591
|
function createWithPortableTextBlockStyle(types) {
|
|
2592
2592
|
const defaultStyle = types.styles[0].value;
|
|
2593
2593
|
return function(editor) {
|
|
@@ -2599,7 +2599,7 @@ function createWithPortableTextBlockStyle(types) {
|
|
|
2599
2599
|
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)) {
|
|
2600
2600
|
const [child] = Editor.node(editor, [op.path[0] + 1, 0]);
|
|
2601
2601
|
if (Text.isText(child) && child.text === "") {
|
|
2602
|
-
debug$
|
|
2602
|
+
debug$e(`Normalizing split node to ${defaultStyle} style`, op), Transforms.setNodes(editor, { style: defaultStyle }, { at: [op.path[0] + 1], voids: !1 });
|
|
2603
2603
|
break;
|
|
2604
2604
|
}
|
|
2605
2605
|
}
|
|
@@ -2615,9 +2615,9 @@ function createWithPortableTextBlockStyle(types) {
|
|
|
2615
2615
|
match: (node) => editor.isTextBlock(node)
|
|
2616
2616
|
})
|
|
2617
2617
|
].forEach(([node, path]) => {
|
|
2618
|
-
editor.isTextBlock(node) && node.style === blockStyle ? (debug$
|
|
2618
|
+
editor.isTextBlock(node) && node.style === blockStyle ? (debug$e(`Unsetting block style '${blockStyle}'`), Transforms.setNodes(editor, { ...node, style: defaultStyle }, {
|
|
2619
2619
|
at: path
|
|
2620
|
-
})) : (blockStyle ? debug$
|
|
2620
|
+
})) : (blockStyle ? debug$e(`Setting style '${blockStyle}'`) : debug$e("Setting default style", defaultStyle), Transforms.setNodes(
|
|
2621
2621
|
editor,
|
|
2622
2622
|
{
|
|
2623
2623
|
...node,
|
|
@@ -2629,11 +2629,11 @@ function createWithPortableTextBlockStyle(types) {
|
|
|
2629
2629
|
}, editor;
|
|
2630
2630
|
};
|
|
2631
2631
|
}
|
|
2632
|
-
const debug$
|
|
2632
|
+
const debug$d = debugWithName("plugin:withPortableTextLists"), MAX_LIST_LEVEL = 10;
|
|
2633
2633
|
function createWithPortableTextLists(types) {
|
|
2634
2634
|
return function(editor) {
|
|
2635
2635
|
return editor.pteToggleListItem = (listItemStyle) => {
|
|
2636
|
-
editor.pteHasListStyle(listItemStyle) ? (debug$
|
|
2636
|
+
editor.pteHasListStyle(listItemStyle) ? (debug$d(`Remove list item '${listItemStyle}'`), editor.pteUnsetListItem(listItemStyle)) : (debug$d(`Add list item '${listItemStyle}'`), editor.pteSetListItem(listItemStyle));
|
|
2637
2637
|
}, editor.pteUnsetListItem = (listItemStyle) => {
|
|
2638
2638
|
editor.selection && [
|
|
2639
2639
|
...Editor.nodes(editor, {
|
|
@@ -2647,7 +2647,7 @@ function createWithPortableTextLists(types) {
|
|
|
2647
2647
|
listItem: void 0,
|
|
2648
2648
|
level: void 0
|
|
2649
2649
|
};
|
|
2650
|
-
debug$
|
|
2650
|
+
debug$d(`Unsetting list '${listItemStyle}'`), Transforms.setNodes(editor, newNode, { at: path });
|
|
2651
2651
|
}
|
|
2652
2652
|
});
|
|
2653
2653
|
}, editor.pteSetListItem = (listItemStyle) => {
|
|
@@ -2657,7 +2657,7 @@ function createWithPortableTextLists(types) {
|
|
|
2657
2657
|
match: (node) => editor.isTextBlock(node)
|
|
2658
2658
|
})
|
|
2659
2659
|
].forEach(([node, path]) => {
|
|
2660
|
-
debug$
|
|
2660
|
+
debug$d(`Setting list '${listItemStyle}'`), Transforms.setNodes(
|
|
2661
2661
|
editor,
|
|
2662
2662
|
{
|
|
2663
2663
|
...node,
|
|
@@ -2677,7 +2677,7 @@ function createWithPortableTextLists(types) {
|
|
|
2677
2677
|
})
|
|
2678
2678
|
];
|
|
2679
2679
|
return selectedBlocks.length === 0 ? !1 : (selectedBlocks.forEach(([node, path]) => {
|
|
2680
|
-
Element$1.isElement(node) && (debug$
|
|
2680
|
+
Element$1.isElement(node) && (debug$d("Unset list"), Transforms.setNodes(
|
|
2681
2681
|
editor,
|
|
2682
2682
|
{
|
|
2683
2683
|
...node,
|
|
@@ -2699,7 +2699,7 @@ function createWithPortableTextLists(types) {
|
|
|
2699
2699
|
return selectedBlocks.length === 0 ? !1 : (selectedBlocks.forEach(([node, path]) => {
|
|
2700
2700
|
if (editor.isListBlock(node)) {
|
|
2701
2701
|
let level = node.level || 1;
|
|
2702
|
-
reverse ? (level--, debug$
|
|
2702
|
+
reverse ? (level--, debug$d("Decrementing list level", Math.min(MAX_LIST_LEVEL, Math.max(1, level)))) : (level++, debug$d("Incrementing list level", Math.min(MAX_LIST_LEVEL, Math.max(1, level)))), Transforms.setNodes(
|
|
2703
2703
|
editor,
|
|
2704
2704
|
{ level: Math.min(MAX_LIST_LEVEL, Math.max(1, level)) },
|
|
2705
2705
|
{ at: path }
|
|
@@ -2721,7 +2721,7 @@ function createWithPortableTextLists(types) {
|
|
|
2721
2721
|
}, editor;
|
|
2722
2722
|
};
|
|
2723
2723
|
}
|
|
2724
|
-
const debug$
|
|
2724
|
+
const debug$c = debugWithName("plugin:withPortableTextMarkModel");
|
|
2725
2725
|
function createWithPortableTextMarkModel(types, change$) {
|
|
2726
2726
|
return function(editor) {
|
|
2727
2727
|
const { apply: apply2, normalizeNode } = editor, decorators = types.decorators.map((t) => t.value), forceNewSelection = () => {
|
|
@@ -2742,7 +2742,7 @@ function createWithPortableTextMarkModel(types, change$) {
|
|
|
2742
2742
|
) && mergeSpans(editor);
|
|
2743
2743
|
const [node, path] = nodeEntry, isSpan = Text.isText(node) && node._type === types.span.name, isTextBlock = editor.isTextBlock(node);
|
|
2744
2744
|
if (isSpan || isTextBlock) {
|
|
2745
|
-
if (isSpan && !Array.isArray(node.marks) && (debug$
|
|
2745
|
+
if (isSpan && !Array.isArray(node.marks) && (debug$c("Adding .marks to span node"), Transforms.setNodes(editor, { marks: [] }, { at: path }), editor.onChange()), isSpan && (node.marks || []).length > 0) {
|
|
2746
2746
|
const spanMarks = node.marks || EMPTY_MARKS$1, annotationMarks = spanMarks.filter(
|
|
2747
2747
|
(mark) => !types.decorators.map((dec) => dec.value).includes(mark)
|
|
2748
2748
|
);
|
|
@@ -2753,7 +2753,7 @@ function createWithPortableTextMarkModel(types, change$) {
|
|
|
2753
2753
|
return !((_a = block.markDefs) != null && _a.find((def) => def._key === mark));
|
|
2754
2754
|
}
|
|
2755
2755
|
) || [];
|
|
2756
|
-
orphanedMarks.length > 0 && (debug$
|
|
2756
|
+
orphanedMarks.length > 0 && (debug$c("Removing orphaned .marks from span node"), Transforms.setNodes(
|
|
2757
2757
|
editor,
|
|
2758
2758
|
{ marks: spanMarks.filter((mark) => !orphanedMarks.includes(mark)) },
|
|
2759
2759
|
{ at: path }
|
|
@@ -2763,14 +2763,14 @@ function createWithPortableTextMarkModel(types, change$) {
|
|
|
2763
2763
|
for (const op of editor.operations) {
|
|
2764
2764
|
if (op.type === "merge_node" && op.path.length === 1 && "markDefs" in op.properties && op.properties._type === types.block.name && Array.isArray(op.properties.markDefs) && op.properties.markDefs.length > 0 && op.path[0] - 1 >= 0) {
|
|
2765
2765
|
const [targetBlock, targetPath] = Editor.node(editor, [op.path[0] - 1]);
|
|
2766
|
-
if (debug$
|
|
2766
|
+
if (debug$c("Copying markDefs over to merged block", op), editor.isTextBlock(targetBlock)) {
|
|
2767
2767
|
const oldDefs = Array.isArray(targetBlock.markDefs) && targetBlock.markDefs || [], newMarkDefs = uniq([...oldDefs, ...op.properties.markDefs]);
|
|
2768
2768
|
isEqual(newMarkDefs, targetBlock.markDefs) || (Transforms.setNodes(editor, { markDefs: newMarkDefs }, { at: targetPath, voids: !1 }), editor.onChange());
|
|
2769
2769
|
}
|
|
2770
2770
|
}
|
|
2771
2771
|
if (op.type === "split_node" && op.path.length === 1 && Element$1.isElementProps(op.properties) && op.properties._type === types.block.name && "markDefs" in op.properties && Array.isArray(op.properties.markDefs) && op.properties.markDefs.length > 0 && op.path[0] + 1 < editor.children.length) {
|
|
2772
2772
|
const [targetBlock, targetPath] = Editor.node(editor, [op.path[0] + 1]);
|
|
2773
|
-
if (debug$
|
|
2773
|
+
if (debug$c("Copying markDefs over to split block", op), editor.isTextBlock(targetBlock)) {
|
|
2774
2774
|
const oldDefs = Array.isArray(targetBlock.markDefs) && targetBlock.markDefs || [];
|
|
2775
2775
|
Transforms.setNodes(
|
|
2776
2776
|
editor,
|
|
@@ -2794,7 +2794,7 @@ function createWithPortableTextMarkModel(types, change$) {
|
|
|
2794
2794
|
(op) => op.type === "merge_node" && "markDefs" in op.properties && op.path.length === 1
|
|
2795
2795
|
)) {
|
|
2796
2796
|
const newMarkDefs = (node.markDefs || []).filter((def) => node.children.find((child) => Text.isText(child) && Array.isArray(child.marks) && child.marks.includes(def._key)));
|
|
2797
|
-
node.markDefs && !isEqual(newMarkDefs, node.markDefs) && (debug$
|
|
2797
|
+
node.markDefs && !isEqual(newMarkDefs, node.markDefs) && (debug$c("Removing markDef not in use"), Transforms.setNodes(
|
|
2798
2798
|
editor,
|
|
2799
2799
|
{
|
|
2800
2800
|
markDefs: newMarkDefs
|
|
@@ -2827,7 +2827,7 @@ function createWithPortableTextMarkModel(types, change$) {
|
|
|
2827
2827
|
editor,
|
|
2828
2828
|
{ marks: marksWithoutAnnotationMarks },
|
|
2829
2829
|
{ at: Path.next(selection.focus.path) }
|
|
2830
|
-
), debug$
|
|
2830
|
+
), debug$c("Inserting text at end of annotation");
|
|
2831
2831
|
return;
|
|
2832
2832
|
}
|
|
2833
2833
|
}
|
|
@@ -2919,7 +2919,7 @@ function createWithPortableTextMarkModel(types, change$) {
|
|
|
2919
2919
|
...Editor.marks(editor) || {}
|
|
2920
2920
|
}.marks || []).includes(mark);
|
|
2921
2921
|
}, editor.pteToggleMark = (mark) => {
|
|
2922
|
-
editor.pteIsMarkActive(mark) ? (debug$
|
|
2922
|
+
editor.pteIsMarkActive(mark) ? (debug$c(`Remove mark '${mark}'`), Editor.removeMark(editor, mark)) : (debug$c(`Add mark '${mark}'`), Editor.addMark(editor, mark, !0));
|
|
2923
2923
|
}, editor;
|
|
2924
2924
|
};
|
|
2925
2925
|
function mergeSpans(editor) {
|
|
@@ -2933,12 +2933,12 @@ function createWithPortableTextMarkModel(types, change$) {
|
|
|
2933
2933
|
const [parent] = path.length > 1 ? Editor.node(editor, Path.parent(path)) : [void 0], nextPath = [path[0], path[1] + 1];
|
|
2934
2934
|
if (editor.isTextBlock(parent)) {
|
|
2935
2935
|
const nextNode = parent.children[nextPath[1]];
|
|
2936
|
-
Text.isText(node) && Text.isText(nextNode) && isEqual(nextNode.marks, node.marks) && (debug$
|
|
2936
|
+
Text.isText(node) && Text.isText(nextNode) && isEqual(nextNode.marks, node.marks) && (debug$c("Merging spans"), Transforms.mergeNodes(editor, { at: nextPath, voids: !0 }), editor.onChange());
|
|
2937
2937
|
}
|
|
2938
2938
|
}
|
|
2939
2939
|
}
|
|
2940
2940
|
}
|
|
2941
|
-
const debug$
|
|
2941
|
+
const debug$b = debugWithName("plugin:withPortableTextSelections"), debugVerbose$2 = debug$b.enabled && !1;
|
|
2942
2942
|
function createWithPortableTextSelections(change$, types) {
|
|
2943
2943
|
let prevSelection = null;
|
|
2944
2944
|
return function(editor) {
|
|
@@ -2954,7 +2954,7 @@ function createWithPortableTextSelections(change$, types) {
|
|
|
2954
2954
|
ptRange = toPortableTextRange(value, editor.selection, types), SLATE_TO_PORTABLE_TEXT_RANGE.set(editor.selection, ptRange);
|
|
2955
2955
|
}
|
|
2956
2956
|
}
|
|
2957
|
-
debugVerbose$
|
|
2957
|
+
debugVerbose$2 && debug$b(
|
|
2958
2958
|
`Emitting selection ${JSON.stringify(ptRange || null)} (${JSON.stringify(
|
|
2959
2959
|
editor.selection
|
|
2960
2960
|
)})`
|
|
@@ -2968,7 +2968,7 @@ function createWithPortableTextSelections(change$, types) {
|
|
|
2968
2968
|
}, editor;
|
|
2969
2969
|
};
|
|
2970
2970
|
}
|
|
2971
|
-
const debug$
|
|
2971
|
+
const debug$a = debugWithName("plugin:withSchemaTypes");
|
|
2972
2972
|
function createWithSchemaTypes({
|
|
2973
2973
|
schemaTypes,
|
|
2974
2974
|
keyGenerator
|
|
@@ -2979,12 +2979,12 @@ function createWithSchemaTypes({
|
|
|
2979
2979
|
return editor.normalizeNode = (entry) => {
|
|
2980
2980
|
const [node, path] = entry;
|
|
2981
2981
|
if (node._type === void 0 && path.length === 2) {
|
|
2982
|
-
debug$
|
|
2982
|
+
debug$a("Setting span type on text node without a type");
|
|
2983
2983
|
const span = node, key = span._key || keyGenerator();
|
|
2984
2984
|
Transforms.setNodes(editor, { ...span, _type: schemaTypes.span.name, _key: key }, { at: path });
|
|
2985
2985
|
}
|
|
2986
2986
|
if (node._key === void 0 && (path.length === 1 || path.length === 2)) {
|
|
2987
|
-
debug$
|
|
2987
|
+
debug$a("Setting missing key on child node without a key");
|
|
2988
2988
|
const key = keyGenerator();
|
|
2989
2989
|
Transforms.setNodes(editor, { _key: key }, { at: path });
|
|
2990
2990
|
}
|
|
@@ -2992,7 +2992,7 @@ function createWithSchemaTypes({
|
|
|
2992
2992
|
}, editor;
|
|
2993
2993
|
};
|
|
2994
2994
|
}
|
|
2995
|
-
const debug$
|
|
2995
|
+
const debug$9 = debugWithName("plugin:withUtils");
|
|
2996
2996
|
function createWithUtils({ schemaTypes, keyGenerator, portableTextEditor }) {
|
|
2997
2997
|
return function(editor) {
|
|
2998
2998
|
return editor.pteExpandToWord = () => {
|
|
@@ -3000,18 +3000,18 @@ function createWithUtils({ schemaTypes, keyGenerator, portableTextEditor }) {
|
|
|
3000
3000
|
if (selection && !Range.isExpanded(selection)) {
|
|
3001
3001
|
const [textNode] = Editor.node(editor, selection.focus, { depth: 2 });
|
|
3002
3002
|
if (!textNode || !Text.isText(textNode) || textNode.text.length === 0) {
|
|
3003
|
-
debug$
|
|
3003
|
+
debug$9("pteExpandToWord: Can't expand to word here");
|
|
3004
3004
|
return;
|
|
3005
3005
|
}
|
|
3006
3006
|
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);
|
|
3007
3007
|
if (!(newStartOffset === newEndOffset || isNaN(newStartOffset) || isNaN(newEndOffset))) {
|
|
3008
|
-
debug$
|
|
3008
|
+
debug$9("pteExpandToWord: Expanding to focused word"), Transforms.setSelection(editor, {
|
|
3009
3009
|
anchor: { ...selection.anchor, offset: newStartOffset },
|
|
3010
3010
|
focus: { ...selection.focus, offset: newEndOffset }
|
|
3011
3011
|
});
|
|
3012
3012
|
return;
|
|
3013
3013
|
}
|
|
3014
|
-
debug$
|
|
3014
|
+
debug$9("pteExpandToWord: Can't expand to word here");
|
|
3015
3015
|
}
|
|
3016
3016
|
}, editor.pteCreateEmptyBlock = () => toSlateValue(
|
|
3017
3017
|
[
|
|
@@ -3034,7 +3034,7 @@ function createWithUtils({ schemaTypes, keyGenerator, portableTextEditor }) {
|
|
|
3034
3034
|
)[0], editor;
|
|
3035
3035
|
};
|
|
3036
3036
|
}
|
|
3037
|
-
const debug$
|
|
3037
|
+
const debug$8 = debugWithName("plugin:withHotKeys"), DEFAULT_HOTKEYS = {
|
|
3038
3038
|
marks: {
|
|
3039
3039
|
"mod+b": "strong",
|
|
3040
3040
|
"mod+i": "em",
|
|
@@ -3047,7 +3047,7 @@ function createWithHotkeys(types, portableTextEditor, hotkeysFromOptions) {
|
|
|
3047
3047
|
const reservedHotkeys = ["enter", "tab", "shift", "delete", "end"], activeHotkeys = hotkeysFromOptions || DEFAULT_HOTKEYS;
|
|
3048
3048
|
return function(editor) {
|
|
3049
3049
|
return editor.pteWithHotKeys = (event) => {
|
|
3050
|
-
var _a, _b, _c, _d;
|
|
3050
|
+
var _a, _b, _c, _d, _e, _f;
|
|
3051
3051
|
Object.keys(activeHotkeys).forEach((cat) => {
|
|
3052
3052
|
if (cat === "marks")
|
|
3053
3053
|
for (const hotkey in activeHotkeys[cat]) {
|
|
@@ -3058,7 +3058,7 @@ function createWithHotkeys(types, portableTextEditor, hotkeysFromOptions) {
|
|
|
3058
3058
|
const possibleMark = activeHotkeys[cat];
|
|
3059
3059
|
if (possibleMark) {
|
|
3060
3060
|
const mark = possibleMark[hotkey];
|
|
3061
|
-
debug$
|
|
3061
|
+
debug$8(`HotKey ${hotkey} to toggle ${mark}`), editor.pteToggleMark(mark);
|
|
3062
3062
|
}
|
|
3063
3063
|
}
|
|
3064
3064
|
}
|
|
@@ -3103,7 +3103,7 @@ function createWithHotkeys(types, portableTextEditor, hotkeysFromOptions) {
|
|
|
3103
3103
|
if (isBackspace && editor.selection && editor.selection.focus.path[0] > 0 && Range.isCollapsed(editor.selection)) {
|
|
3104
3104
|
const prevPath = Path.previous(editor.selection.focus.path.slice(0, 1)), prevBlock = Node.descendant(editor, prevPath), focusBlock = Node.descendant(editor, editor.selection.focus.path.slice(0, 1));
|
|
3105
3105
|
if (prevBlock && focusBlock && Editor.isVoid(editor, prevBlock) && editor.selection.focus.offset === 0) {
|
|
3106
|
-
debug$
|
|
3106
|
+
debug$8("Preventing deleting void block above"), event.preventDefault(), event.stopPropagation();
|
|
3107
3107
|
const isTextBlock = isPortableTextTextBlock(focusBlock), isEmptyFocusBlock = isTextBlock && focusBlock.children.length === 1 && ((_d = (_c = focusBlock.children) == null ? void 0 : _c[0]) == null ? void 0 : _d.text) === "";
|
|
3108
3108
|
if (!isTextBlock || isEmptyFocusBlock) {
|
|
3109
3109
|
Transforms.removeNodes(editor, { match: (n) => n === focusBlock }), Transforms.select(editor, prevPath), editor.onChange();
|
|
@@ -3120,9 +3120,9 @@ function createWithHotkeys(types, portableTextEditor, hotkeysFromOptions) {
|
|
|
3120
3120
|
const nextBlock = Node.descendant(
|
|
3121
3121
|
editor,
|
|
3122
3122
|
Path.next(editor.selection.focus.path.slice(0, 1))
|
|
3123
|
-
), focusBlockPath = editor.selection.focus.path.slice(0, 1), focusBlock = Node.descendant(editor, focusBlockPath);
|
|
3124
|
-
if (nextBlock && focusBlock && !Editor.isVoid(editor, focusBlock) && Editor.isVoid(editor, nextBlock)) {
|
|
3125
|
-
debug$
|
|
3123
|
+
), focusBlockPath = editor.selection.focus.path.slice(0, 1), focusBlock = Node.descendant(editor, focusBlockPath), isEmptyFocusBlock = isPortableTextTextBlock(focusBlock) && focusBlock.children.length === 1 && ((_f = (_e = focusBlock.children) == null ? void 0 : _e[0]) == null ? void 0 : _f.text) === "";
|
|
3124
|
+
if (nextBlock && focusBlock && !Editor.isVoid(editor, focusBlock) && Editor.isVoid(editor, nextBlock) && isEmptyFocusBlock) {
|
|
3125
|
+
debug$8("Preventing deleting void block below"), event.preventDefault(), event.stopPropagation(), Transforms.removeNodes(editor, { match: (n) => n === focusBlock }), Transforms.select(editor, focusBlockPath), editor.onChange();
|
|
3126
3126
|
return;
|
|
3127
3127
|
}
|
|
3128
3128
|
}
|
|
@@ -3422,7 +3422,7 @@ function validateValue(value, types, keyGenerator) {
|
|
|
3422
3422
|
return !1;
|
|
3423
3423
|
}) && (valid = !1), { valid, resolution, value });
|
|
3424
3424
|
}
|
|
3425
|
-
const debug$
|
|
3425
|
+
const debug$7 = debugWithName("plugin:withInsertData");
|
|
3426
3426
|
function createWithInsertData(change$, schemaTypes, keyGenerator) {
|
|
3427
3427
|
return function(editor) {
|
|
3428
3428
|
const blockTypeName = schemaTypes.block.name, spanTypeName = schemaTypes.span.name, whitespaceOnPasteMode = schemaTypes.block.options.unstable_whitespaceOnPasteMode, toPlainText = (blocks) => blocks.map((block) => {
|
|
@@ -3461,13 +3461,13 @@ function createWithInsertData(change$, schemaTypes, keyGenerator) {
|
|
|
3461
3461
|
const asHTML = div.innerHTML;
|
|
3462
3462
|
contents.ownerDocument.body.removeChild(div);
|
|
3463
3463
|
const fragment = editor.getFragment(), portableText = fromSlateValue(fragment, blockTypeName), asJSON = JSON.stringify(portableText), asPlainText = toPlainText(portableText);
|
|
3464
|
-
data.clearData(), data.setData("text/plain", asPlainText), data.setData("text/html", asHTML), data.setData("application/json", asJSON), data.setData("application/x-portable-text", asJSON), debug$
|
|
3464
|
+
data.clearData(), data.setData("text/plain", asPlainText), data.setData("text/html", asHTML), data.setData("application/json", asJSON), data.setData("application/x-portable-text", asJSON), debug$7("text", asPlainText), data.setData("application/x-portable-text-event-origin", originEvent || "external"), debug$7("Set fragment data", asJSON, asHTML);
|
|
3465
3465
|
}, editor.insertPortableTextData = (data) => {
|
|
3466
3466
|
var _a, _b;
|
|
3467
3467
|
if (!editor.selection)
|
|
3468
3468
|
return !1;
|
|
3469
3469
|
const pText = data.getData("application/x-portable-text"), origin = data.getData("application/x-portable-text-event-origin");
|
|
3470
|
-
if (debug$
|
|
3470
|
+
if (debug$7(`Inserting portable text from ${origin} event`, pText), pText) {
|
|
3471
3471
|
const parsed = JSON.parse(pText);
|
|
3472
3472
|
if (Array.isArray(parsed) && parsed.length > 0) {
|
|
3473
3473
|
const slateValue = _regenerateKeys(
|
|
@@ -3485,7 +3485,7 @@ function createWithInsertData(change$, schemaTypes, keyGenerator) {
|
|
|
3485
3485
|
name: "pasteError",
|
|
3486
3486
|
description: errorDescription,
|
|
3487
3487
|
data: validation
|
|
3488
|
-
}), debug$
|
|
3488
|
+
}), debug$7("Invalid insert result", validation), !1;
|
|
3489
3489
|
}
|
|
3490
3490
|
return _insertFragment(editor, slateValue, schemaTypes), !0;
|
|
3491
3491
|
}
|
|
@@ -3494,11 +3494,11 @@ function createWithInsertData(change$, schemaTypes, keyGenerator) {
|
|
|
3494
3494
|
}, editor.insertTextOrHTMLData = (data) => {
|
|
3495
3495
|
var _a;
|
|
3496
3496
|
if (!editor.selection)
|
|
3497
|
-
return debug$
|
|
3497
|
+
return debug$7("No selection, not inserting"), !1;
|
|
3498
3498
|
change$.next({ type: "loading", isLoading: !0 });
|
|
3499
3499
|
const html = data.getData("text/html"), text = data.getData("text/plain");
|
|
3500
3500
|
if (html || text) {
|
|
3501
|
-
debug$
|
|
3501
|
+
debug$7("Inserting data", data);
|
|
3502
3502
|
let portableText, fragment, insertedType;
|
|
3503
3503
|
if (html) {
|
|
3504
3504
|
if (portableText = htmlToBlocks(html, schemaTypes.portableText, {
|
|
@@ -3526,9 +3526,9 @@ Try to insert as plain text (shift-paste) instead.`;
|
|
|
3526
3526
|
name: "pasteError",
|
|
3527
3527
|
description: errorDescription,
|
|
3528
3528
|
data: validation
|
|
3529
|
-
}), debug$
|
|
3529
|
+
}), debug$7("Invalid insert result", validation), !1;
|
|
3530
3530
|
}
|
|
3531
|
-
return debug$
|
|
3531
|
+
return debug$7(`Inserting ${insertedType} fragment at ${JSON.stringify(editor.selection)}`), _insertFragment(editor, fragment, schemaTypes), change$.next({ type: "loading", isLoading: !1 }), !0;
|
|
3532
3532
|
}
|
|
3533
3533
|
return change$.next({ type: "loading", isLoading: !1 }), !1;
|
|
3534
3534
|
}, editor.insertData = (data) => {
|
|
@@ -3596,7 +3596,7 @@ function _insertFragment(editor, fragment, schemaTypes) {
|
|
|
3596
3596
|
const [focusBlock, focusPath] = Editor.node(editor, editor.selection, { depth: 1 });
|
|
3597
3597
|
if (editor.isTextBlock(focusBlock) && editor.isTextBlock(fragment[0])) {
|
|
3598
3598
|
const { markDefs } = focusBlock;
|
|
3599
|
-
debug$
|
|
3599
|
+
debug$7("Mixing markDefs of focusBlock and fragments[0] block", markDefs, fragment[0].markDefs), isEqual(markDefs, fragment[0].markDefs) || Transforms.setNodes(
|
|
3600
3600
|
editor,
|
|
3601
3601
|
{
|
|
3602
3602
|
markDefs: uniq([...fragment[0].markDefs || [], ...markDefs || []])
|
|
@@ -3679,10 +3679,10 @@ const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, opti
|
|
|
3679
3679
|
};
|
|
3680
3680
|
}
|
|
3681
3681
|
};
|
|
3682
|
-
}, debug$
|
|
3682
|
+
}, debug$6 = debugWithName("component:PortableTextEditor:SlateContainer");
|
|
3683
3683
|
function SlateContainer(props) {
|
|
3684
3684
|
const { patches$, portableTextEditor, readOnly, maxBlocks, keyGenerator } = props, [[slateEditor, subscribe]] = useState(() => {
|
|
3685
|
-
debug$
|
|
3685
|
+
debug$6("Creating new Slate editor instance");
|
|
3686
3686
|
const { editor, subscribe: _sub } = withPlugins(withReact(createEditor()), {
|
|
3687
3687
|
keyGenerator,
|
|
3688
3688
|
maxBlocks,
|
|
@@ -3698,7 +3698,7 @@ function SlateContainer(props) {
|
|
|
3698
3698
|
unsubscribe();
|
|
3699
3699
|
};
|
|
3700
3700
|
}, [subscribe]), useEffect(() => {
|
|
3701
|
-
debug$
|
|
3701
|
+
debug$6("Re-initializing plugin chain"), withPlugins(slateEditor, {
|
|
3702
3702
|
keyGenerator,
|
|
3703
3703
|
maxBlocks,
|
|
3704
3704
|
patches$,
|
|
@@ -3708,7 +3708,7 @@ function SlateContainer(props) {
|
|
|
3708
3708
|
}, [keyGenerator, portableTextEditor, maxBlocks, readOnly, patches$, slateEditor]);
|
|
3709
3709
|
const initialValue = useMemo(() => [slateEditor.pteCreateEmptyBlock()], [slateEditor]);
|
|
3710
3710
|
return useEffect(() => () => {
|
|
3711
|
-
debug$
|
|
3711
|
+
debug$6("Destroying Slate editor"), slateEditor.destroy();
|
|
3712
3712
|
}, [slateEditor]), /* @__PURE__ */ jsx(Slate, { editor: slateEditor, initialValue, children: props.children });
|
|
3713
3713
|
}
|
|
3714
3714
|
const defaultKeyGenerator = () => randomKey(12), PortableTextEditorKeyGeneratorContext = createContext(defaultKeyGenerator), usePortableTextEditorKeyGenerator = () => {
|
|
@@ -3718,31 +3718,22 @@ const defaultKeyGenerator = () => randomKey(12), PortableTextEditorKeyGeneratorC
|
|
|
3718
3718
|
"The `usePortableTextEditorKeyGenerator` hook must be used inside the <PortableTextEditor> component's context."
|
|
3719
3719
|
);
|
|
3720
3720
|
return keyGenerator;
|
|
3721
|
-
},
|
|
3722
|
-
const selection = useContext(PortableTextEditorSelectionContext);
|
|
3723
|
-
if (selection === void 0)
|
|
3724
|
-
throw new Error(
|
|
3725
|
-
"The `usePortableTextEditorSelection` hook must be used inside the <PortableTextEditor> component's context."
|
|
3726
|
-
);
|
|
3727
|
-
return selection;
|
|
3728
|
-
}, PortableTextEditorValueContext = createContext(
|
|
3729
|
-
void 0
|
|
3730
|
-
), PortableTextEditorReadOnlyContext = createContext(!1), usePortableTextEditorReadOnlyStatus = () => {
|
|
3721
|
+
}, PortableTextEditorReadOnlyContext = createContext(!1), usePortableTextEditorReadOnlyStatus = () => {
|
|
3731
3722
|
const readOnly = useContext(PortableTextEditorReadOnlyContext);
|
|
3732
3723
|
if (readOnly === void 0)
|
|
3733
3724
|
throw new Error(
|
|
3734
3725
|
"The `usePortableTextEditorReadOnly` hook must be used inside the <PortableTextEditor> component's context."
|
|
3735
3726
|
);
|
|
3736
3727
|
return readOnly;
|
|
3737
|
-
}, debug$
|
|
3728
|
+
}, debug$5 = debugWithName("hook:useSyncValue"), CURRENT_VALUE = /* @__PURE__ */ new WeakMap();
|
|
3738
3729
|
function useSyncValue(props) {
|
|
3739
3730
|
const { portableTextEditor, readOnly, keyGenerator } = props, { change$, schemaTypes } = portableTextEditor, previousValue = useRef(), slateEditor = useSlate(), updateValueFunctionRef = useRef(), updateFromCurrentValue = useCallback(() => {
|
|
3740
3731
|
const currentValue = CURRENT_VALUE.get(portableTextEditor);
|
|
3741
3732
|
if (previousValue.current === currentValue) {
|
|
3742
|
-
debug$
|
|
3733
|
+
debug$5("Value is the same object as previous, not need to sync");
|
|
3743
3734
|
return;
|
|
3744
3735
|
}
|
|
3745
|
-
updateValueFunctionRef.current && currentValue && (debug$
|
|
3736
|
+
updateValueFunctionRef.current && currentValue && (debug$5("Updating the value debounced"), updateValueFunctionRef.current(currentValue));
|
|
3746
3737
|
}, [portableTextEditor]), updateValueDebounced = useMemo(
|
|
3747
3738
|
() => debounce(updateFromCurrentValue, 1e3, { trailing: !0, leading: !1 }),
|
|
3748
3739
|
[updateFromCurrentValue]
|
|
@@ -3753,17 +3744,17 @@ function useSyncValue(props) {
|
|
|
3753
3744
|
const isProcessingLocalChanges = isChangingLocally(slateEditor), isProcessingRemoteChanges = isChangingRemotely(slateEditor);
|
|
3754
3745
|
if (!readOnly) {
|
|
3755
3746
|
if (isProcessingLocalChanges) {
|
|
3756
|
-
debug$
|
|
3747
|
+
debug$5("Has local changes, not syncing value right now"), updateValueDebounced();
|
|
3757
3748
|
return;
|
|
3758
3749
|
}
|
|
3759
3750
|
if (isProcessingRemoteChanges) {
|
|
3760
|
-
debug$
|
|
3751
|
+
debug$5("Has remote changes, not syncing value right now"), updateValueDebounced();
|
|
3761
3752
|
return;
|
|
3762
3753
|
}
|
|
3763
3754
|
}
|
|
3764
3755
|
let isChanged = !1, isValid = !0;
|
|
3765
3756
|
const hadSelection = !!slateEditor.selection;
|
|
3766
|
-
if ((!value || value.length === 0) && (debug$
|
|
3757
|
+
if ((!value || value.length === 0) && (debug$5("Value is empty"), Editor.withoutNormalizing(slateEditor, () => {
|
|
3767
3758
|
withoutSaving(slateEditor, () => {
|
|
3768
3759
|
withoutPatching(slateEditor, () => {
|
|
3769
3760
|
hadSelection && Transforms.deselect(slateEditor);
|
|
@@ -3800,7 +3791,7 @@ function useSyncValue(props) {
|
|
|
3800
3791
|
`${validation.resolution.action} for block with _key '${validationValue[0]._key}'. ${(_c = validation.resolution) == null ? void 0 : _c.description}`
|
|
3801
3792
|
), validation.resolution.patches.forEach((patch) => {
|
|
3802
3793
|
change$.next({ type: "patch", patch });
|
|
3803
|
-
})), validation.valid || (_d = validation.resolution) != null && _d.autoResolve ? (oldBlock._key === currentBlock._key ? (debug$
|
|
3794
|
+
})), validation.valid || (_d = validation.resolution) != null && _d.autoResolve ? (oldBlock._key === currentBlock._key ? (debug$5.enabled && debug$5("Updating block", oldBlock, currentBlock), _updateBlock(slateEditor, currentBlock, oldBlock, currentBlockIndex)) : (debug$5.enabled && debug$5("Replacing block", oldBlock, currentBlock), _replaceBlock(slateEditor, currentBlock, currentBlockIndex)), isChanged = !0) : (change$.next({
|
|
3804
3795
|
type: "invalidValue",
|
|
3805
3796
|
resolution: validation.resolution,
|
|
3806
3797
|
value
|
|
@@ -3808,14 +3799,14 @@ function useSyncValue(props) {
|
|
|
3808
3799
|
}
|
|
3809
3800
|
if (!oldBlock && isValid) {
|
|
3810
3801
|
const validationValue = [value[currentBlockIndex]], validation = validateValue(validationValue, schemaTypes, keyGenerator);
|
|
3811
|
-
debug$
|
|
3802
|
+
debug$5.enabled && debug$5(
|
|
3812
3803
|
"Validating and inserting new block in the end of the value",
|
|
3813
3804
|
currentBlock
|
|
3814
3805
|
), validation.valid || (_e = validation.resolution) != null && _e.autoResolve ? withPreserveKeys(slateEditor, () => {
|
|
3815
3806
|
Transforms.insertNodes(slateEditor, currentBlock, {
|
|
3816
3807
|
at: [currentBlockIndex]
|
|
3817
3808
|
});
|
|
3818
|
-
}) : (debug$
|
|
3809
|
+
}) : (debug$5("Invalid", validation), change$.next({
|
|
3819
3810
|
type: "invalidValue",
|
|
3820
3811
|
resolution: validation.resolution,
|
|
3821
3812
|
value
|
|
@@ -3828,11 +3819,11 @@ function useSyncValue(props) {
|
|
|
3828
3819
|
});
|
|
3829
3820
|
}
|
|
3830
3821
|
if (!isValid) {
|
|
3831
|
-
debug$
|
|
3822
|
+
debug$5("Invalid value, returning");
|
|
3832
3823
|
return;
|
|
3833
3824
|
}
|
|
3834
3825
|
if (isChanged) {
|
|
3835
|
-
debug$
|
|
3826
|
+
debug$5("Server value changed, syncing editor");
|
|
3836
3827
|
try {
|
|
3837
3828
|
slateEditor.onChange();
|
|
3838
3829
|
} catch (err) {
|
|
@@ -3848,7 +3839,7 @@ function useSyncValue(props) {
|
|
|
3848
3839
|
focus: { path: [0, 0], offset: 0 }
|
|
3849
3840
|
}), slateEditor.onChange()), change$.next({ type: "value", value });
|
|
3850
3841
|
} else
|
|
3851
|
-
debug$
|
|
3842
|
+
debug$5("Server value and editor value is equal, no need to sync.");
|
|
3852
3843
|
previousValue.current = value;
|
|
3853
3844
|
};
|
|
3854
3845
|
return updateValueFunctionRef.current = updateFunction, updateFunction;
|
|
@@ -3876,7 +3867,7 @@ function _updateBlock(slateEditor, currentBlock, oldBlock, currentBlockIndex) {
|
|
|
3876
3867
|
currentBlock.children.length < oldBlockChildrenLength && Array.from(Array(oldBlockChildrenLength - currentBlock.children.length)).forEach(
|
|
3877
3868
|
(_, index) => {
|
|
3878
3869
|
const childIndex = oldBlockChildrenLength - 1 - index;
|
|
3879
|
-
childIndex > 0 && (debug$
|
|
3870
|
+
childIndex > 0 && (debug$5("Removing child"), Transforms.removeNodes(slateEditor, {
|
|
3880
3871
|
at: [currentBlockIndex, childIndex]
|
|
3881
3872
|
}));
|
|
3882
3873
|
}
|
|
@@ -3884,7 +3875,7 @@ function _updateBlock(slateEditor, currentBlock, oldBlock, currentBlockIndex) {
|
|
|
3884
3875
|
const oldBlockChild = oldBlock.children[currentBlockChildIndex], isChildChanged = !isEqual(currentBlockChild, oldBlockChild), isTextChanged = !isEqual(currentBlockChild.text, oldBlockChild == null ? void 0 : oldBlockChild.text), path = [currentBlockIndex, currentBlockChildIndex];
|
|
3885
3876
|
if (isChildChanged)
|
|
3886
3877
|
if (currentBlockChild._key === (oldBlockChild == null ? void 0 : oldBlockChild._key)) {
|
|
3887
|
-
debug$
|
|
3878
|
+
debug$5("Updating changed child", currentBlockChild, oldBlockChild), Transforms.setNodes(slateEditor, currentBlockChild, {
|
|
3888
3879
|
at: path
|
|
3889
3880
|
});
|
|
3890
3881
|
const isSpanNode = Text.isText(currentBlockChild) && currentBlockChild._type === "span" && Text.isText(oldBlockChild) && oldBlockChild._type === "span";
|
|
@@ -3892,7 +3883,7 @@ function _updateBlock(slateEditor, currentBlock, oldBlock, currentBlockIndex) {
|
|
|
3892
3883
|
at: { focus: { path, offset: 0 }, anchor: { path, offset: oldBlockChild.text.length } }
|
|
3893
3884
|
}), Transforms.insertText(slateEditor, currentBlockChild.text, {
|
|
3894
3885
|
at: path
|
|
3895
|
-
}), slateEditor.onChange()) : isSpanNode || (debug$
|
|
3886
|
+
}), slateEditor.onChange()) : isSpanNode || (debug$5("Updating changed inline object child", currentBlockChild), Transforms.setNodes(
|
|
3896
3887
|
slateEditor,
|
|
3897
3888
|
{ _key: VOID_CHILD_KEY },
|
|
3898
3889
|
{
|
|
@@ -3900,13 +3891,13 @@ function _updateBlock(slateEditor, currentBlock, oldBlock, currentBlockIndex) {
|
|
|
3900
3891
|
voids: !0
|
|
3901
3892
|
}
|
|
3902
3893
|
));
|
|
3903
|
-
} else oldBlockChild ? (debug$
|
|
3894
|
+
} else oldBlockChild ? (debug$5("Replacing child", currentBlockChild), Transforms.removeNodes(slateEditor, {
|
|
3904
3895
|
at: [currentBlockIndex, currentBlockChildIndex]
|
|
3905
3896
|
}), withPreserveKeys(slateEditor, () => {
|
|
3906
3897
|
Transforms.insertNodes(slateEditor, currentBlockChild, {
|
|
3907
3898
|
at: [currentBlockIndex, currentBlockChildIndex]
|
|
3908
3899
|
});
|
|
3909
|
-
}), slateEditor.onChange()) : oldBlockChild || (debug$
|
|
3900
|
+
}), slateEditor.onChange()) : oldBlockChild || (debug$5("Inserting new child", currentBlockChild), withPreserveKeys(slateEditor, () => {
|
|
3910
3901
|
Transforms.insertNodes(slateEditor, currentBlockChild, {
|
|
3911
3902
|
at: [currentBlockIndex, currentBlockChildIndex]
|
|
3912
3903
|
}), slateEditor.onChange();
|
|
@@ -3914,9 +3905,9 @@ function _updateBlock(slateEditor, currentBlock, oldBlock, currentBlockIndex) {
|
|
|
3914
3905
|
});
|
|
3915
3906
|
}
|
|
3916
3907
|
}
|
|
3917
|
-
const debug$
|
|
3908
|
+
const debug$4 = debugWithName("component:PortableTextEditor:Synchronizer"), debugVerbose$1 = debug$4.enabled && !1, FLUSH_PATCHES_THROTTLED_MS = process.env.NODE_ENV === "test" ? 500 : 1e3;
|
|
3918
3909
|
function Synchronizer(props) {
|
|
3919
|
-
const
|
|
3910
|
+
const portableTextEditor = usePortableTextEditor(), keyGenerator = usePortableTextEditorKeyGenerator(), readOnly = usePortableTextEditorReadOnlyStatus(), { change$, getValue, onChange, value } = props, pendingPatches = useRef([]), syncValue = useSyncValue({
|
|
3920
3911
|
keyGenerator,
|
|
3921
3912
|
onChange,
|
|
3922
3913
|
portableTextEditor,
|
|
@@ -3927,13 +3918,13 @@ function Synchronizer(props) {
|
|
|
3927
3918
|
}, [slateEditor]);
|
|
3928
3919
|
const onFlushPendingPatches = useCallback(() => {
|
|
3929
3920
|
if (pendingPatches.current.length > 0) {
|
|
3930
|
-
debug$
|
|
3921
|
+
debug$4("Flushing pending patches"), debugVerbose$1 && debug$4(`Patches:
|
|
3931
3922
|
${JSON.stringify(pendingPatches.current, null, 2)}`);
|
|
3932
|
-
const snapshot =
|
|
3923
|
+
const snapshot = getValue();
|
|
3933
3924
|
change$.next({ type: "mutation", patches: pendingPatches.current, snapshot }), pendingPatches.current = [];
|
|
3934
3925
|
}
|
|
3935
3926
|
IS_PROCESSING_LOCAL_CHANGES.set(slateEditor, !1);
|
|
3936
|
-
}, [slateEditor,
|
|
3927
|
+
}, [slateEditor, getValue, change$]), onFlushPendingPatchesThrottled = useMemo(() => throttle(
|
|
3937
3928
|
() => {
|
|
3938
3929
|
if (Editor.isNormalizing(slateEditor)) {
|
|
3939
3930
|
onFlushPendingPatches();
|
|
@@ -3950,37 +3941,54 @@ ${JSON.stringify(pendingPatches.current, null, 2)}`);
|
|
|
3950
3941
|
useEffect(() => () => {
|
|
3951
3942
|
onFlushPendingPatches();
|
|
3952
3943
|
}, [onFlushPendingPatches]), useEffect(() => {
|
|
3953
|
-
debug$
|
|
3944
|
+
debug$4("Subscribing to editor changes$");
|
|
3954
3945
|
const sub = change$.subscribe((next) => {
|
|
3955
3946
|
switch (next.type) {
|
|
3956
3947
|
case "patch":
|
|
3957
3948
|
IS_PROCESSING_LOCAL_CHANGES.set(slateEditor, !0), pendingPatches.current.push(next.patch), onFlushPendingPatchesThrottled(), onChange(next);
|
|
3958
3949
|
break;
|
|
3959
|
-
case "selection":
|
|
3960
|
-
startTransition(() => {
|
|
3961
|
-
debugVerbose && debug$3("Setting selection"), setSelection(next.selection);
|
|
3962
|
-
}), onChange(next);
|
|
3963
|
-
break;
|
|
3964
3950
|
default:
|
|
3965
3951
|
onChange(next);
|
|
3966
3952
|
}
|
|
3967
3953
|
});
|
|
3968
3954
|
return () => {
|
|
3969
|
-
debug$
|
|
3955
|
+
debug$4("Unsubscribing to changes$"), sub.unsubscribe();
|
|
3970
3956
|
};
|
|
3971
3957
|
}, [change$, onChange, onFlushPendingPatchesThrottled, slateEditor]);
|
|
3972
3958
|
const handleOnline = useCallback(() => {
|
|
3973
|
-
debug$
|
|
3959
|
+
debug$4("Editor is online, syncing from props.value"), change$.next({ type: "connection", value: "online" }), syncValue(value);
|
|
3974
3960
|
}, [change$, syncValue, value]), handleOffline = useCallback(() => {
|
|
3975
|
-
debug$
|
|
3961
|
+
debug$4("Editor is offline"), change$.next({ type: "connection", value: "offline" });
|
|
3976
3962
|
}, [change$]);
|
|
3977
3963
|
useEffect(() => (portableTextEditor.props.patches$ && (window.addEventListener("online", handleOnline), window.addEventListener("offline", handleOffline)), () => {
|
|
3978
3964
|
portableTextEditor.props.patches$ && (window.removeEventListener("online", handleOnline), window.removeEventListener("offline", handleOffline));
|
|
3979
3965
|
}));
|
|
3980
3966
|
const isInitialValueFromProps = useRef(!0);
|
|
3981
3967
|
return useEffect(() => {
|
|
3982
|
-
debug$
|
|
3983
|
-
}, [change$, syncValue, value]),
|
|
3968
|
+
debug$4("Value from props changed, syncing new value"), syncValue(value), isInitialValueFromProps.current && (change$.next({ type: "loading", isLoading: !1 }), change$.next({ type: "ready" }), isInitialValueFromProps.current = !1);
|
|
3969
|
+
}, [change$, syncValue, value]), null;
|
|
3970
|
+
}
|
|
3971
|
+
const PortableTextEditorSelectionContext = createContext(null), usePortableTextEditorSelection = () => {
|
|
3972
|
+
const selection = useContext(PortableTextEditorSelectionContext);
|
|
3973
|
+
if (selection === void 0)
|
|
3974
|
+
throw new Error(
|
|
3975
|
+
"The `usePortableTextEditorSelection` hook must be used inside the <PortableTextEditor> component's context."
|
|
3976
|
+
);
|
|
3977
|
+
return selection;
|
|
3978
|
+
}, debug$3 = debugWithName("component:PortableTextEditor:SelectionProvider"), debugVerbose = debug$3.enabled && !1;
|
|
3979
|
+
function PortableTextEditorSelectionProvider(props) {
|
|
3980
|
+
const { change$ } = props, [selection, setSelection] = useState(null);
|
|
3981
|
+
return useEffect(() => {
|
|
3982
|
+
debug$3("Subscribing to selection changes$");
|
|
3983
|
+
const subscription = change$.subscribe((next) => {
|
|
3984
|
+
next.type === "selection" && startTransition(() => {
|
|
3985
|
+
debugVerbose && debug$3("Setting selection"), setSelection(next.selection);
|
|
3986
|
+
});
|
|
3987
|
+
});
|
|
3988
|
+
return () => {
|
|
3989
|
+
debug$3("Unsubscribing to selection changes$"), subscription.unsubscribe();
|
|
3990
|
+
};
|
|
3991
|
+
}, [change$]), /* @__PURE__ */ jsx(PortableTextEditorSelectionContext.Provider, { value: selection, children: props.children });
|
|
3984
3992
|
}
|
|
3985
3993
|
var __defProp = Object.defineProperty, __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __publicField = (obj, key, value) => __defNormalProp(obj, typeof key != "symbol" ? key + "" : key, value);
|
|
3986
3994
|
const debug$2 = debugWithName("component:PortableTextEditor");
|
|
@@ -3988,8 +3996,11 @@ class PortableTextEditor extends Component {
|
|
|
3988
3996
|
constructor(props) {
|
|
3989
3997
|
if (super(props), __publicField(this, "change$", new Subject()), __publicField(this, "schemaTypes"), __publicField(this, "editable"), __publicField(this, "setEditable", (editable) => {
|
|
3990
3998
|
this.editable = { ...this.editable, ...editable };
|
|
3999
|
+
}), __publicField(this, "getValue", () => {
|
|
4000
|
+
if (this.editable)
|
|
4001
|
+
return this.editable.getValue();
|
|
3991
4002
|
}), !props.schemaType)
|
|
3992
|
-
throw new Error('PortableTextEditor: missing "
|
|
4003
|
+
throw new Error('PortableTextEditor: missing "schemaType" property');
|
|
3993
4004
|
props.incomingPatches$ && console.warn("The prop 'incomingPatches$' is deprecated and renamed to 'patches$'"), this.change$.next({ type: "loading", isLoading: !0 }), this.schemaTypes = getPortableTextMemberSchemaTypes(
|
|
3994
4005
|
props.schemaType.hasOwnProperty("jsonType") ? props.schemaType : compileType(props.schemaType)
|
|
3995
4006
|
);
|
|
@@ -4009,18 +4020,18 @@ class PortableTextEditor extends Component {
|
|
|
4009
4020
|
patches$: _patches$,
|
|
4010
4021
|
portableTextEditor: this,
|
|
4011
4022
|
readOnly,
|
|
4012
|
-
children: /* @__PURE__ */ jsx(
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
)
|
|
4023
|
+
children: /* @__PURE__ */ jsx(PortableTextEditorKeyGeneratorContext.Provider, { value: keyGenerator, children: /* @__PURE__ */ jsx(PortableTextEditorContext.Provider, { value: this, children: /* @__PURE__ */ jsx(PortableTextEditorReadOnlyContext.Provider, { value: readOnly, children: /* @__PURE__ */ jsxs(PortableTextEditorSelectionProvider, { change$, children: [
|
|
4024
|
+
/* @__PURE__ */ jsx(
|
|
4025
|
+
Synchronizer,
|
|
4026
|
+
{
|
|
4027
|
+
change$,
|
|
4028
|
+
getValue: this.getValue,
|
|
4029
|
+
onChange,
|
|
4030
|
+
value
|
|
4031
|
+
}
|
|
4032
|
+
),
|
|
4033
|
+
children
|
|
4034
|
+
] }) }) }) })
|
|
4024
4035
|
}
|
|
4025
4036
|
);
|
|
4026
4037
|
}
|
|
@@ -4280,7 +4291,7 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4280
4291
|
pointerEvents: "none",
|
|
4281
4292
|
left: 0,
|
|
4282
4293
|
right: 0
|
|
4283
|
-
},
|
|
4294
|
+
}, PortableTextEditable = forwardRef(function(props, forwardedRef) {
|
|
4284
4295
|
const {
|
|
4285
4296
|
hotkeys,
|
|
4286
4297
|
onBlur,
|
|
@@ -4301,7 +4312,7 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4301
4312
|
scrollSelectionIntoView,
|
|
4302
4313
|
spellCheck,
|
|
4303
4314
|
...restProps
|
|
4304
|
-
} = props, portableTextEditor = usePortableTextEditor(), readOnly = usePortableTextEditorReadOnlyStatus(), keyGenerator = usePortableTextEditorKeyGenerator(), ref = useRef(null), [editableElement, setEditableElement] = useState(null), [hasInvalidValue, setHasInvalidValue] = useState(!1), [rangeDecorationState, setRangeDecorationsState] = useState(
|
|
4315
|
+
} = props, portableTextEditor = usePortableTextEditor(), readOnly = usePortableTextEditorReadOnlyStatus(), keyGenerator = usePortableTextEditorKeyGenerator(), ref = useRef(null), [editableElement, setEditableElement] = useState(null), [hasInvalidValue, setHasInvalidValue] = useState(!1), [rangeDecorationState, setRangeDecorationsState] = useState([]);
|
|
4305
4316
|
useImperativeHandle(forwardedRef, () => ref.current);
|
|
4306
4317
|
const rangeDecorationsRef = useRef(rangeDecorations), { change$, schemaTypes } = portableTextEditor, slateEditor = useSlate(), blockTypeName = schemaTypes.block.name, withInsertData = useMemo(
|
|
4307
4318
|
() => createWithInsertData(change$, schemaTypes, keyGenerator),
|
|
@@ -4393,7 +4404,7 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4393
4404
|
return;
|
|
4394
4405
|
}
|
|
4395
4406
|
}
|
|
4396
|
-
setRangeDecorationsState(
|
|
4407
|
+
setRangeDecorationsState([]);
|
|
4397
4408
|
},
|
|
4398
4409
|
[portableTextEditor, rangeDecorations, schemaTypes, slateEditor]
|
|
4399
4410
|
);
|
|
@@ -4542,9 +4553,9 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4542
4553
|
}
|
|
4543
4554
|
];
|
|
4544
4555
|
if (path.length === 0)
|
|
4545
|
-
return
|
|
4556
|
+
return [];
|
|
4546
4557
|
const result = rangeDecorationState.filter((item) => Range.isCollapsed(item) ? path.length !== 2 ? !1 : Path.equals(item.focus.path, path) && Path.equals(item.anchor.path, path) : Range.intersection(item, { anchor: { path, offset: 0 }, focus: { path, offset: 0 } }) || Range.includes(item, path));
|
|
4547
|
-
return result.length > 0 ? result :
|
|
4558
|
+
return result.length > 0 ? result : [];
|
|
4548
4559
|
},
|
|
4549
4560
|
[slateEditor, schemaTypes, rangeDecorationState]
|
|
4550
4561
|
);
|