@portabletext/editor 1.50.2 → 1.50.3
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.cjs +259 -235
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +13 -2
- package/lib/index.d.ts +13 -2
- package/lib/index.js +264 -240
- package/lib/index.js.map +1 -1
- package/lib/plugins/index.d.cts +6 -0
- package/lib/plugins/index.d.ts +6 -0
- package/package.json +13 -13
- package/src/editor/plugins/createWithPatches.ts +37 -75
- package/src/editor/plugins/with-plugins.ts +0 -3
- package/src/editor/relay-machine.ts +9 -0
- package/src/internal-utils/{__tests__/operationToPatches.test.ts → operation-to-patches.test.ts} +44 -39
- package/src/internal-utils/operation-to-patches.ts +467 -0
- package/src/types/editor.ts +7 -2
- package/src/internal-utils/operationToPatches.ts +0 -489
package/lib/index.d.cts
CHANGED
|
@@ -824,6 +824,9 @@ export declare type EditorEmittedEvent =
|
|
|
824
824
|
event: FocusEvent_2<HTMLDivElement, Element>
|
|
825
825
|
}
|
|
826
826
|
| {
|
|
827
|
+
/**
|
|
828
|
+
* @deprecated
|
|
829
|
+
*/
|
|
827
830
|
type: 'done loading'
|
|
828
831
|
}
|
|
829
832
|
| {
|
|
@@ -840,6 +843,9 @@ export declare type EditorEmittedEvent =
|
|
|
840
843
|
value: Array<PortableTextBlock> | undefined
|
|
841
844
|
}
|
|
842
845
|
| {
|
|
846
|
+
/**
|
|
847
|
+
* @deprecated
|
|
848
|
+
*/
|
|
843
849
|
type: 'loading'
|
|
844
850
|
}
|
|
845
851
|
| MutationEvent
|
|
@@ -2977,7 +2983,9 @@ export declare const keyGenerator: () => string
|
|
|
2977
2983
|
/**
|
|
2978
2984
|
* The editor is currently loading something
|
|
2979
2985
|
* Could be used to show a spinner etc.
|
|
2980
|
-
* @beta
|
|
2986
|
+
* @beta
|
|
2987
|
+
* @deprecated
|
|
2988
|
+
*/
|
|
2981
2989
|
export declare type LoadingChange = {
|
|
2982
2990
|
type: 'loading'
|
|
2983
2991
|
isLoading: boolean
|
|
@@ -4100,7 +4108,10 @@ export declare type UndoChange = {
|
|
|
4100
4108
|
timestamp: Date
|
|
4101
4109
|
}
|
|
4102
4110
|
|
|
4103
|
-
/**
|
|
4111
|
+
/**
|
|
4112
|
+
* @beta
|
|
4113
|
+
* @deprecated Use `'patch'` changes instead
|
|
4114
|
+
*/
|
|
4104
4115
|
export declare type UnsetChange = {
|
|
4105
4116
|
type: 'unset'
|
|
4106
4117
|
previousValue: PortableTextBlock[]
|
package/lib/index.d.ts
CHANGED
|
@@ -824,6 +824,9 @@ export declare type EditorEmittedEvent =
|
|
|
824
824
|
event: FocusEvent_2<HTMLDivElement, Element>
|
|
825
825
|
}
|
|
826
826
|
| {
|
|
827
|
+
/**
|
|
828
|
+
* @deprecated
|
|
829
|
+
*/
|
|
827
830
|
type: 'done loading'
|
|
828
831
|
}
|
|
829
832
|
| {
|
|
@@ -840,6 +843,9 @@ export declare type EditorEmittedEvent =
|
|
|
840
843
|
value: Array<PortableTextBlock> | undefined
|
|
841
844
|
}
|
|
842
845
|
| {
|
|
846
|
+
/**
|
|
847
|
+
* @deprecated
|
|
848
|
+
*/
|
|
843
849
|
type: 'loading'
|
|
844
850
|
}
|
|
845
851
|
| MutationEvent
|
|
@@ -2977,7 +2983,9 @@ export declare const keyGenerator: () => string
|
|
|
2977
2983
|
/**
|
|
2978
2984
|
* The editor is currently loading something
|
|
2979
2985
|
* Could be used to show a spinner etc.
|
|
2980
|
-
* @beta
|
|
2986
|
+
* @beta
|
|
2987
|
+
* @deprecated
|
|
2988
|
+
*/
|
|
2981
2989
|
export declare type LoadingChange = {
|
|
2982
2990
|
type: 'loading'
|
|
2983
2991
|
isLoading: boolean
|
|
@@ -4100,7 +4108,10 @@ export declare type UndoChange = {
|
|
|
4100
4108
|
timestamp: Date
|
|
4101
4109
|
}
|
|
4102
4110
|
|
|
4103
|
-
/**
|
|
4111
|
+
/**
|
|
4112
|
+
* @beta
|
|
4113
|
+
* @deprecated Use `'patch'` changes instead
|
|
4114
|
+
*/
|
|
4104
4115
|
export declare type UnsetChange = {
|
|
4105
4116
|
type: 'unset'
|
|
4106
4117
|
previousValue: PortableTextBlock[]
|
package/lib/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { useSelector, useActorRef } from "@xstate/react";
|
|
|
7
7
|
import noop from "lodash/noop.js";
|
|
8
8
|
import { Element as Element$1, Text, Range, Editor, Node, Point, Transforms, Path, Operation, deleteBackward, deleteForward, createEditor } from "slate";
|
|
9
9
|
import { useSlateStatic, useSelected, withReact, ReactEditor, Slate, useSlate, Editable } from "slate-react";
|
|
10
|
-
import debug$
|
|
10
|
+
import debug$i from "debug";
|
|
11
11
|
import { getBlockEndPoint, isEmptyTextBlock, isEqualSelectionPoints } from "./_chunks-es/util.is-equal-selection-points.js";
|
|
12
12
|
import { getBlockStartPoint, isKeyedSegment as isKeyedSegment$1, parseInlineObject, parseTextBlock, parseBlockObject, parseBlock, sliceBlocks, isTextBlock, parseAnnotation, blockOffsetToSpanSelectionPoint, isSpan$1 as isSpan, isListBlock, getTextBlockText, parseBlocks } from "./_chunks-es/util.slice-blocks.js";
|
|
13
13
|
import { isSelectionCollapsed, getFocusTextBlock, getFocusSpan, getSelectedBlocks, isSelectionExpanded, getSelectionStartBlock as getSelectionStartBlock$1, getSelectionEndBlock as getSelectionEndBlock$1, getFocusBlock as getFocusBlock$1, getFocusBlockObject, getPreviousBlock, getNextBlock, getFirstBlock as getFirstBlock$1, getLastBlock as getLastBlock$1, getFocusListBlock } from "./_chunks-es/selector.is-selection-expanded.js";
|
|
@@ -24,13 +24,13 @@ import { setup, assign, enqueueActions, emit, assertEvent, stateIn, fromCallback
|
|
|
24
24
|
import { htmlToBlocks } from "@portabletext/block-tools";
|
|
25
25
|
import { toHTML } from "@portabletext/to-html";
|
|
26
26
|
import { Schema } from "@sanity/schema";
|
|
27
|
-
import { insert, unset, set, diffMatchPatch as diffMatchPatch$1, setIfMissing, applyAll } from "@portabletext/patches";
|
|
28
|
-
import get from "lodash/get.js";
|
|
29
|
-
import isUndefined from "lodash/isUndefined.js";
|
|
30
|
-
import omitBy from "lodash/omitBy.js";
|
|
31
27
|
import flatten from "lodash/flatten.js";
|
|
32
28
|
import omit from "lodash/omit.js";
|
|
33
29
|
import { blockOffsetsToSelection } from "./_chunks-es/util.child-selection-point-to-block-offset.js";
|
|
30
|
+
import { applyAll, unset, insert, set, setIfMissing, diffMatchPatch as diffMatchPatch$1 } from "@portabletext/patches";
|
|
31
|
+
import get from "lodash/get.js";
|
|
32
|
+
import isUndefined from "lodash/isUndefined.js";
|
|
33
|
+
import omitBy from "lodash/omitBy.js";
|
|
34
34
|
import startCase from "lodash.startcase";
|
|
35
35
|
import isPlainObject from "lodash/isPlainObject.js";
|
|
36
36
|
function EditorEventListener(props) {
|
|
@@ -59,10 +59,10 @@ function getCompoundClientRect(nodes) {
|
|
|
59
59
|
return new DOMRect(left, top, right - left, bottom - top);
|
|
60
60
|
}
|
|
61
61
|
const rootName = "sanity-pte:";
|
|
62
|
-
debug$
|
|
62
|
+
debug$i(rootName);
|
|
63
63
|
function debugWithName(name) {
|
|
64
64
|
const namespace = `${rootName}${name}`;
|
|
65
|
-
return debug$
|
|
65
|
+
return debug$i && debug$i.enabled(namespace) ? debug$i(namespace) : debug$i(rootName);
|
|
66
66
|
}
|
|
67
67
|
function getDragSelection({
|
|
68
68
|
eventSelection,
|
|
@@ -1376,228 +1376,6 @@ function compileType(rawType) {
|
|
|
1376
1376
|
types: [rawType]
|
|
1377
1377
|
}).get(rawType.name);
|
|
1378
1378
|
}
|
|
1379
|
-
const debug$i = debugWithName("operationToPatches");
|
|
1380
|
-
function createOperationToPatches(editorActor) {
|
|
1381
|
-
const textBlockName = editorActor.getSnapshot().context.schema.block.name;
|
|
1382
|
-
function insertTextPatch(editor, operation, beforeValue) {
|
|
1383
|
-
debug$i.enabled && debug$i("Operation", JSON.stringify(operation, null, 2));
|
|
1384
|
-
const block = editor.isTextBlock(editor.children[operation.path[0]]) && editor.children[operation.path[0]];
|
|
1385
|
-
if (!block)
|
|
1386
|
-
throw new Error("Could not find block");
|
|
1387
|
-
const textChild = editor.isTextBlock(block) && editor.isTextSpan(block.children[operation.path[1]]) && block.children[operation.path[1]];
|
|
1388
|
-
if (!textChild)
|
|
1389
|
-
throw new Error("Could not find child");
|
|
1390
|
-
const path = [{
|
|
1391
|
-
_key: block._key
|
|
1392
|
-
}, "children", {
|
|
1393
|
-
_key: textChild._key
|
|
1394
|
-
}, "text"], prevBlock = beforeValue[operation.path[0]], prevChild = editor.isTextBlock(prevBlock) && prevBlock.children[operation.path[1]], prevText = editor.isTextSpan(prevChild) ? prevChild.text : "", patch = diffMatchPatch$1(prevText, textChild.text, path);
|
|
1395
|
-
return patch.value.length ? [patch] : [];
|
|
1396
|
-
}
|
|
1397
|
-
function removeTextPatch(editor, operation, beforeValue) {
|
|
1398
|
-
const block = editor && editor.children[operation.path[0]];
|
|
1399
|
-
if (!block)
|
|
1400
|
-
throw new Error("Could not find block");
|
|
1401
|
-
const child = editor.isTextBlock(block) && block.children[operation.path[1]] || void 0, textChild = editor.isTextSpan(child) ? child : void 0;
|
|
1402
|
-
if (child && !textChild)
|
|
1403
|
-
throw new Error("Expected span");
|
|
1404
|
-
if (!textChild)
|
|
1405
|
-
throw new Error("Could not find child");
|
|
1406
|
-
const path = [{
|
|
1407
|
-
_key: block._key
|
|
1408
|
-
}, "children", {
|
|
1409
|
-
_key: textChild._key
|
|
1410
|
-
}, "text"], beforeBlock = beforeValue[operation.path[0]], prevTextChild = editor.isTextBlock(beforeBlock) && beforeBlock.children[operation.path[1]], prevText = editor.isTextSpan(prevTextChild) && prevTextChild.text, patch = diffMatchPatch$1(prevText || "", textChild.text, path);
|
|
1411
|
-
return patch.value ? [patch] : [];
|
|
1412
|
-
}
|
|
1413
|
-
function setNodePatch(editor, operation) {
|
|
1414
|
-
if (operation.path.length === 1) {
|
|
1415
|
-
const block = editor.children[operation.path[0]];
|
|
1416
|
-
if (typeof block._key != "string")
|
|
1417
|
-
throw new Error("Expected block to have a _key");
|
|
1418
|
-
const setNode = omitBy({
|
|
1419
|
-
...editor.children[operation.path[0]],
|
|
1420
|
-
...operation.newProperties
|
|
1421
|
-
}, isUndefined);
|
|
1422
|
-
return [set(fromSlateValue([setNode], textBlockName)[0], [{
|
|
1423
|
-
_key: block._key
|
|
1424
|
-
}])];
|
|
1425
|
-
} else if (operation.path.length === 2) {
|
|
1426
|
-
const block = editor.children[operation.path[0]];
|
|
1427
|
-
if (editor.isTextBlock(block)) {
|
|
1428
|
-
const child = block.children[operation.path[1]];
|
|
1429
|
-
if (child) {
|
|
1430
|
-
const blockKey = block._key, childKey = child._key, patches = [], keys = Object.keys(operation.newProperties);
|
|
1431
|
-
return keys.forEach((keyName) => {
|
|
1432
|
-
if (keys.length === 1 && keyName === "_key") {
|
|
1433
|
-
const val = get(operation.newProperties, keyName);
|
|
1434
|
-
patches.push(set(val, [{
|
|
1435
|
-
_key: blockKey
|
|
1436
|
-
}, "children", block.children.indexOf(child), keyName]));
|
|
1437
|
-
} else {
|
|
1438
|
-
const val = get(operation.newProperties, keyName);
|
|
1439
|
-
patches.push(set(val, [{
|
|
1440
|
-
_key: blockKey
|
|
1441
|
-
}, "children", {
|
|
1442
|
-
_key: childKey
|
|
1443
|
-
}, keyName]));
|
|
1444
|
-
}
|
|
1445
|
-
}), patches;
|
|
1446
|
-
}
|
|
1447
|
-
throw new Error("Could not find a valid child");
|
|
1448
|
-
}
|
|
1449
|
-
throw new Error("Could not find a valid block");
|
|
1450
|
-
} else
|
|
1451
|
-
throw new Error(`Unexpected path encountered: ${JSON.stringify(operation.path)}`);
|
|
1452
|
-
}
|
|
1453
|
-
function insertNodePatch(editor, operation, beforeValue) {
|
|
1454
|
-
const block = beforeValue[operation.path[0]], isTextBlock2 = editor.isTextBlock(block);
|
|
1455
|
-
if (operation.path.length === 1) {
|
|
1456
|
-
const position = operation.path[0] === 0 ? "before" : "after", beforeBlock = beforeValue[operation.path[0] - 1], targetKey = operation.path[0] === 0 ? block?._key : beforeBlock?._key;
|
|
1457
|
-
return targetKey ? [insert([fromSlateValue([operation.node], textBlockName)[0]], position, [{
|
|
1458
|
-
_key: targetKey
|
|
1459
|
-
}])] : [setIfMissing(beforeValue, []), insert([fromSlateValue([operation.node], textBlockName)[0]], "before", [operation.path[0]])];
|
|
1460
|
-
} else if (isTextBlock2 && operation.path.length === 2 && editor.children[operation.path[0]]) {
|
|
1461
|
-
const position = block.children.length === 0 || !block.children[operation.path[1] - 1] ? "before" : "after", node = {
|
|
1462
|
-
...operation.node
|
|
1463
|
-
};
|
|
1464
|
-
!node._type && Text.isText(node) && (node._type = "span", node.marks = []);
|
|
1465
|
-
const child = fromSlateValue([{
|
|
1466
|
-
_key: "bogus",
|
|
1467
|
-
_type: textBlockName,
|
|
1468
|
-
children: [node]
|
|
1469
|
-
}], textBlockName)[0].children[0];
|
|
1470
|
-
return [insert([child], position, [{
|
|
1471
|
-
_key: block._key
|
|
1472
|
-
}, "children", block.children.length <= 1 || !block.children[operation.path[1] - 1] ? 0 : {
|
|
1473
|
-
_key: block.children[operation.path[1] - 1]._key
|
|
1474
|
-
}])];
|
|
1475
|
-
}
|
|
1476
|
-
return debug$i("Something was inserted into a void block. Not producing editor patches."), [];
|
|
1477
|
-
}
|
|
1478
|
-
function splitNodePatch(editor, operation, beforeValue) {
|
|
1479
|
-
const patches = [], splitBlock = editor.children[operation.path[0]];
|
|
1480
|
-
if (!editor.isTextBlock(splitBlock))
|
|
1481
|
-
throw new Error(`Block with path ${JSON.stringify(operation.path[0])} is not a text block and can't be split`);
|
|
1482
|
-
if (operation.path.length === 1) {
|
|
1483
|
-
const oldBlock = beforeValue[operation.path[0]];
|
|
1484
|
-
if (editor.isTextBlock(oldBlock)) {
|
|
1485
|
-
const targetValue = fromSlateValue([editor.children[operation.path[0] + 1]], textBlockName)[0];
|
|
1486
|
-
targetValue && (patches.push(insert([targetValue], "after", [{
|
|
1487
|
-
_key: splitBlock._key
|
|
1488
|
-
}])), oldBlock.children.slice(operation.position).forEach((span) => {
|
|
1489
|
-
const path = [{
|
|
1490
|
-
_key: oldBlock._key
|
|
1491
|
-
}, "children", {
|
|
1492
|
-
_key: span._key
|
|
1493
|
-
}];
|
|
1494
|
-
patches.push(unset(path));
|
|
1495
|
-
}));
|
|
1496
|
-
}
|
|
1497
|
-
return patches;
|
|
1498
|
-
}
|
|
1499
|
-
if (operation.path.length === 2) {
|
|
1500
|
-
const splitSpan = splitBlock.children[operation.path[1]];
|
|
1501
|
-
if (editor.isTextSpan(splitSpan)) {
|
|
1502
|
-
const targetSpans = fromSlateValue([{
|
|
1503
|
-
...splitBlock,
|
|
1504
|
-
children: splitBlock.children.slice(operation.path[1] + 1, operation.path[1] + 2)
|
|
1505
|
-
}], textBlockName)[0].children;
|
|
1506
|
-
patches.push(insert(targetSpans, "after", [{
|
|
1507
|
-
_key: splitBlock._key
|
|
1508
|
-
}, "children", {
|
|
1509
|
-
_key: splitSpan._key
|
|
1510
|
-
}])), patches.push(set(splitSpan.text, [{
|
|
1511
|
-
_key: splitBlock._key
|
|
1512
|
-
}, "children", {
|
|
1513
|
-
_key: splitSpan._key
|
|
1514
|
-
}, "text"]));
|
|
1515
|
-
}
|
|
1516
|
-
return patches;
|
|
1517
|
-
}
|
|
1518
|
-
return patches;
|
|
1519
|
-
}
|
|
1520
|
-
function removeNodePatch(editor, operation, beforeValue) {
|
|
1521
|
-
const block = beforeValue[operation.path[0]];
|
|
1522
|
-
if (operation.path.length === 1) {
|
|
1523
|
-
if (block && block._key)
|
|
1524
|
-
return [unset([{
|
|
1525
|
-
_key: block._key
|
|
1526
|
-
}])];
|
|
1527
|
-
throw new Error("Block not found");
|
|
1528
|
-
} else if (editor.isTextBlock(block) && operation.path.length === 2) {
|
|
1529
|
-
const spanToRemove = block.children[operation.path[1]];
|
|
1530
|
-
return spanToRemove ? block.children.filter((span) => span._key === operation.node._key).length > 1 ? (console.warn(`Multiple spans have \`_key\` ${operation.node._key}. It's ambiguous which one to remove.`, JSON.stringify(block, null, 2)), []) : [unset([{
|
|
1531
|
-
_key: block._key
|
|
1532
|
-
}, "children", {
|
|
1533
|
-
_key: spanToRemove._key
|
|
1534
|
-
}])] : (debug$i("Span not found in editor trying to remove node"), []);
|
|
1535
|
-
} else
|
|
1536
|
-
return debug$i("Not creating patch inside object block"), [];
|
|
1537
|
-
}
|
|
1538
|
-
function mergeNodePatch(editor, operation, beforeValue) {
|
|
1539
|
-
const patches = [], block = beforeValue[operation.path[0]], updatedBlock = editor.children[operation.path[0]];
|
|
1540
|
-
if (operation.path.length === 1)
|
|
1541
|
-
if (block?._key) {
|
|
1542
|
-
const newBlock = fromSlateValue([editor.children[operation.path[0] - 1]], textBlockName)[0];
|
|
1543
|
-
patches.push(set(newBlock, [{
|
|
1544
|
-
_key: newBlock._key
|
|
1545
|
-
}])), patches.push(unset([{
|
|
1546
|
-
_key: block._key
|
|
1547
|
-
}]));
|
|
1548
|
-
} else
|
|
1549
|
-
throw new Error("Target key not found!");
|
|
1550
|
-
else if (editor.isTextBlock(block) && editor.isTextBlock(updatedBlock) && operation.path.length === 2) {
|
|
1551
|
-
const updatedSpan = updatedBlock.children[operation.path[1] - 1] && editor.isTextSpan(updatedBlock.children[operation.path[1] - 1]) ? updatedBlock.children[operation.path[1] - 1] : void 0, removedSpan = block.children[operation.path[1]] && editor.isTextSpan(block.children[operation.path[1]]) ? block.children[operation.path[1]] : void 0;
|
|
1552
|
-
updatedSpan && (block.children.filter((span) => span._key === updatedSpan._key).length === 1 ? patches.push(set(updatedSpan.text, [{
|
|
1553
|
-
_key: block._key
|
|
1554
|
-
}, "children", {
|
|
1555
|
-
_key: updatedSpan._key
|
|
1556
|
-
}, "text"])) : console.warn(`Multiple spans have \`_key\` ${updatedSpan._key}. It's ambiguous which one to update.`, JSON.stringify(block, null, 2))), removedSpan && (block.children.filter((span) => span._key === removedSpan._key).length === 1 ? patches.push(unset([{
|
|
1557
|
-
_key: block._key
|
|
1558
|
-
}, "children", {
|
|
1559
|
-
_key: removedSpan._key
|
|
1560
|
-
}])) : console.warn(`Multiple spans have \`_key\` ${removedSpan._key}. It's ambiguous which one to remove.`, JSON.stringify(block, null, 2)));
|
|
1561
|
-
} else
|
|
1562
|
-
debug$i("Void nodes can't be merged, not creating any patches");
|
|
1563
|
-
return patches;
|
|
1564
|
-
}
|
|
1565
|
-
function moveNodePatch(editor, operation, beforeValue) {
|
|
1566
|
-
const patches = [], block = beforeValue[operation.path[0]], targetBlock = beforeValue[operation.newPath[0]];
|
|
1567
|
-
if (!targetBlock)
|
|
1568
|
-
return patches;
|
|
1569
|
-
if (operation.path.length === 1) {
|
|
1570
|
-
const position = operation.path[0] > operation.newPath[0] ? "before" : "after";
|
|
1571
|
-
patches.push(unset([{
|
|
1572
|
-
_key: block._key
|
|
1573
|
-
}])), patches.push(insert([fromSlateValue([block], textBlockName)[0]], position, [{
|
|
1574
|
-
_key: targetBlock._key
|
|
1575
|
-
}]));
|
|
1576
|
-
} else if (operation.path.length === 2 && editor.isTextBlock(block) && editor.isTextBlock(targetBlock)) {
|
|
1577
|
-
const child = block.children[operation.path[1]], targetChild = targetBlock.children[operation.newPath[1]], position = operation.newPath[1] === targetBlock.children.length ? "after" : "before", childToInsert = fromSlateValue([block], textBlockName)[0].children[operation.path[1]];
|
|
1578
|
-
patches.push(unset([{
|
|
1579
|
-
_key: block._key
|
|
1580
|
-
}, "children", {
|
|
1581
|
-
_key: child._key
|
|
1582
|
-
}])), patches.push(insert([childToInsert], position, [{
|
|
1583
|
-
_key: targetBlock._key
|
|
1584
|
-
}, "children", {
|
|
1585
|
-
_key: targetChild._key
|
|
1586
|
-
}]));
|
|
1587
|
-
}
|
|
1588
|
-
return patches;
|
|
1589
|
-
}
|
|
1590
|
-
return {
|
|
1591
|
-
insertNodePatch,
|
|
1592
|
-
insertTextPatch,
|
|
1593
|
-
mergeNodePatch,
|
|
1594
|
-
moveNodePatch,
|
|
1595
|
-
removeNodePatch,
|
|
1596
|
-
removeTextPatch,
|
|
1597
|
-
setNodePatch,
|
|
1598
|
-
splitNodePatch
|
|
1599
|
-
};
|
|
1600
|
-
}
|
|
1601
1379
|
const insertTextOperationImplementation = ({
|
|
1602
1380
|
operation
|
|
1603
1381
|
}) => {
|
|
@@ -4439,6 +4217,254 @@ function findBlockAndChildFromPath(editor, path) {
|
|
|
4439
4217
|
childPath: void 0
|
|
4440
4218
|
};
|
|
4441
4219
|
}
|
|
4220
|
+
function insertTextPatch(schema, children, operation, beforeValue) {
|
|
4221
|
+
const block = isTextBlock({
|
|
4222
|
+
schema
|
|
4223
|
+
}, children[operation.path[0]]) && children[operation.path[0]];
|
|
4224
|
+
if (!block)
|
|
4225
|
+
throw new Error("Could not find block");
|
|
4226
|
+
const textChild = isTextBlock({
|
|
4227
|
+
schema
|
|
4228
|
+
}, block) && isSpan({
|
|
4229
|
+
schema
|
|
4230
|
+
}, block.children[operation.path[1]]) && block.children[operation.path[1]];
|
|
4231
|
+
if (!textChild)
|
|
4232
|
+
throw new Error("Could not find child");
|
|
4233
|
+
const path = [{
|
|
4234
|
+
_key: block._key
|
|
4235
|
+
}, "children", {
|
|
4236
|
+
_key: textChild._key
|
|
4237
|
+
}, "text"], prevBlock = beforeValue[operation.path[0]], prevChild = isTextBlock({
|
|
4238
|
+
schema
|
|
4239
|
+
}, prevBlock) && prevBlock.children[operation.path[1]], prevText = isSpan({
|
|
4240
|
+
schema
|
|
4241
|
+
}, prevChild) ? prevChild.text : "", patch = diffMatchPatch$1(prevText, textChild.text, path);
|
|
4242
|
+
return patch.value.length ? [patch] : [];
|
|
4243
|
+
}
|
|
4244
|
+
function removeTextPatch(schema, children, operation, beforeValue) {
|
|
4245
|
+
const block = children[operation.path[0]];
|
|
4246
|
+
if (!block)
|
|
4247
|
+
throw new Error("Could not find block");
|
|
4248
|
+
const child = isTextBlock({
|
|
4249
|
+
schema
|
|
4250
|
+
}, block) && block.children[operation.path[1]] || void 0, textChild = isSpan({
|
|
4251
|
+
schema
|
|
4252
|
+
}, child) ? child : void 0;
|
|
4253
|
+
if (child && !textChild)
|
|
4254
|
+
throw new Error("Expected span");
|
|
4255
|
+
if (!textChild)
|
|
4256
|
+
throw new Error("Could not find child");
|
|
4257
|
+
const path = [{
|
|
4258
|
+
_key: block._key
|
|
4259
|
+
}, "children", {
|
|
4260
|
+
_key: textChild._key
|
|
4261
|
+
}, "text"], beforeBlock = beforeValue[operation.path[0]], prevTextChild = isTextBlock({
|
|
4262
|
+
schema
|
|
4263
|
+
}, beforeBlock) && beforeBlock.children[operation.path[1]], prevText = isSpan({
|
|
4264
|
+
schema
|
|
4265
|
+
}, prevTextChild) && prevTextChild.text, patch = diffMatchPatch$1(prevText || "", textChild.text, path);
|
|
4266
|
+
return patch.value ? [patch] : [];
|
|
4267
|
+
}
|
|
4268
|
+
function setNodePatch(schema, children, operation) {
|
|
4269
|
+
if (operation.path.length === 1) {
|
|
4270
|
+
const block = children[operation.path[0]];
|
|
4271
|
+
if (typeof block._key != "string")
|
|
4272
|
+
throw new Error("Expected block to have a _key");
|
|
4273
|
+
const setNode = omitBy({
|
|
4274
|
+
...children[operation.path[0]],
|
|
4275
|
+
...operation.newProperties
|
|
4276
|
+
}, isUndefined);
|
|
4277
|
+
return [set(fromSlateValue([setNode], schema.block.name)[0], [{
|
|
4278
|
+
_key: block._key
|
|
4279
|
+
}])];
|
|
4280
|
+
} else if (operation.path.length === 2) {
|
|
4281
|
+
const block = children[operation.path[0]];
|
|
4282
|
+
if (isTextBlock({
|
|
4283
|
+
schema
|
|
4284
|
+
}, block)) {
|
|
4285
|
+
const child = block.children[operation.path[1]];
|
|
4286
|
+
if (child) {
|
|
4287
|
+
const blockKey = block._key, childKey = child._key, patches = [], keys = Object.keys(operation.newProperties);
|
|
4288
|
+
return keys.forEach((keyName) => {
|
|
4289
|
+
if (keys.length === 1 && keyName === "_key") {
|
|
4290
|
+
const val = get(operation.newProperties, keyName);
|
|
4291
|
+
patches.push(set(val, [{
|
|
4292
|
+
_key: blockKey
|
|
4293
|
+
}, "children", block.children.indexOf(child), keyName]));
|
|
4294
|
+
} else {
|
|
4295
|
+
const val = get(operation.newProperties, keyName);
|
|
4296
|
+
patches.push(set(val, [{
|
|
4297
|
+
_key: blockKey
|
|
4298
|
+
}, "children", {
|
|
4299
|
+
_key: childKey
|
|
4300
|
+
}, keyName]));
|
|
4301
|
+
}
|
|
4302
|
+
}), patches;
|
|
4303
|
+
}
|
|
4304
|
+
throw new Error("Could not find a valid child");
|
|
4305
|
+
}
|
|
4306
|
+
throw new Error("Could not find a valid block");
|
|
4307
|
+
} else
|
|
4308
|
+
throw new Error(`Unexpected path encountered: ${JSON.stringify(operation.path)}`);
|
|
4309
|
+
}
|
|
4310
|
+
function insertNodePatch(schema, children, operation, beforeValue) {
|
|
4311
|
+
const block = beforeValue[operation.path[0]];
|
|
4312
|
+
if (operation.path.length === 1) {
|
|
4313
|
+
const position = operation.path[0] === 0 ? "before" : "after", beforeBlock = beforeValue[operation.path[0] - 1], targetKey = operation.path[0] === 0 ? block?._key : beforeBlock?._key;
|
|
4314
|
+
return targetKey ? [insert([fromSlateValue([operation.node], schema.block.name)[0]], position, [{
|
|
4315
|
+
_key: targetKey
|
|
4316
|
+
}])] : [setIfMissing(beforeValue, []), insert([fromSlateValue([operation.node], schema.block.name)[0]], "before", [operation.path[0]])];
|
|
4317
|
+
} else if (isTextBlock({
|
|
4318
|
+
schema
|
|
4319
|
+
}, block) && operation.path.length === 2 && children[operation.path[0]]) {
|
|
4320
|
+
const position = block.children.length === 0 || !block.children[operation.path[1] - 1] ? "before" : "after", node = {
|
|
4321
|
+
...operation.node
|
|
4322
|
+
};
|
|
4323
|
+
!node._type && Text.isText(node) && (node._type = "span", node.marks = []);
|
|
4324
|
+
const child = fromSlateValue([{
|
|
4325
|
+
_key: "bogus",
|
|
4326
|
+
_type: schema.block.name,
|
|
4327
|
+
children: [node]
|
|
4328
|
+
}], schema.block.name)[0].children[0];
|
|
4329
|
+
return [insert([child], position, [{
|
|
4330
|
+
_key: block._key
|
|
4331
|
+
}, "children", block.children.length <= 1 || !block.children[operation.path[1] - 1] ? 0 : {
|
|
4332
|
+
_key: block.children[operation.path[1] - 1]._key
|
|
4333
|
+
}])];
|
|
4334
|
+
}
|
|
4335
|
+
return [];
|
|
4336
|
+
}
|
|
4337
|
+
function splitNodePatch(schema, children, operation, beforeValue) {
|
|
4338
|
+
const patches = [], splitBlock = children[operation.path[0]];
|
|
4339
|
+
if (!isTextBlock({
|
|
4340
|
+
schema
|
|
4341
|
+
}, splitBlock))
|
|
4342
|
+
throw new Error(`Block with path ${JSON.stringify(operation.path[0])} is not a text block and can't be split`);
|
|
4343
|
+
if (operation.path.length === 1) {
|
|
4344
|
+
const oldBlock = beforeValue[operation.path[0]];
|
|
4345
|
+
if (isTextBlock({
|
|
4346
|
+
schema
|
|
4347
|
+
}, oldBlock)) {
|
|
4348
|
+
const targetValue = fromSlateValue([children[operation.path[0] + 1]], schema.block.name)[0];
|
|
4349
|
+
targetValue && (patches.push(insert([targetValue], "after", [{
|
|
4350
|
+
_key: splitBlock._key
|
|
4351
|
+
}])), oldBlock.children.slice(operation.position).forEach((span) => {
|
|
4352
|
+
const path = [{
|
|
4353
|
+
_key: oldBlock._key
|
|
4354
|
+
}, "children", {
|
|
4355
|
+
_key: span._key
|
|
4356
|
+
}];
|
|
4357
|
+
patches.push(unset(path));
|
|
4358
|
+
}));
|
|
4359
|
+
}
|
|
4360
|
+
return patches;
|
|
4361
|
+
}
|
|
4362
|
+
if (operation.path.length === 2) {
|
|
4363
|
+
const splitSpan = splitBlock.children[operation.path[1]];
|
|
4364
|
+
if (isSpan({
|
|
4365
|
+
schema
|
|
4366
|
+
}, splitSpan)) {
|
|
4367
|
+
const targetSpans = fromSlateValue([{
|
|
4368
|
+
...splitBlock,
|
|
4369
|
+
children: splitBlock.children.slice(operation.path[1] + 1, operation.path[1] + 2)
|
|
4370
|
+
}], schema.block.name)[0].children;
|
|
4371
|
+
patches.push(insert(targetSpans, "after", [{
|
|
4372
|
+
_key: splitBlock._key
|
|
4373
|
+
}, "children", {
|
|
4374
|
+
_key: splitSpan._key
|
|
4375
|
+
}])), patches.push(set(splitSpan.text, [{
|
|
4376
|
+
_key: splitBlock._key
|
|
4377
|
+
}, "children", {
|
|
4378
|
+
_key: splitSpan._key
|
|
4379
|
+
}, "text"]));
|
|
4380
|
+
}
|
|
4381
|
+
return patches;
|
|
4382
|
+
}
|
|
4383
|
+
return patches;
|
|
4384
|
+
}
|
|
4385
|
+
function removeNodePatch(schema, beforeValue, operation) {
|
|
4386
|
+
const block = beforeValue[operation.path[0]];
|
|
4387
|
+
if (operation.path.length === 1) {
|
|
4388
|
+
if (block && block._key)
|
|
4389
|
+
return [unset([{
|
|
4390
|
+
_key: block._key
|
|
4391
|
+
}])];
|
|
4392
|
+
throw new Error("Block not found");
|
|
4393
|
+
} else if (isTextBlock({
|
|
4394
|
+
schema
|
|
4395
|
+
}, block) && operation.path.length === 2) {
|
|
4396
|
+
const spanToRemove = block.children[operation.path[1]];
|
|
4397
|
+
return spanToRemove ? block.children.filter((span) => span._key === operation.node._key).length > 1 ? (console.warn(`Multiple spans have \`_key\` ${operation.node._key}. It's ambiguous which one to remove.`, JSON.stringify(block, null, 2)), []) : [unset([{
|
|
4398
|
+
_key: block._key
|
|
4399
|
+
}, "children", {
|
|
4400
|
+
_key: spanToRemove._key
|
|
4401
|
+
}])] : [];
|
|
4402
|
+
} else
|
|
4403
|
+
return [];
|
|
4404
|
+
}
|
|
4405
|
+
function mergeNodePatch(schema, children, operation, beforeValue) {
|
|
4406
|
+
const patches = [], block = beforeValue[operation.path[0]], updatedBlock = children[operation.path[0]];
|
|
4407
|
+
if (operation.path.length === 1)
|
|
4408
|
+
if (block?._key) {
|
|
4409
|
+
const newBlock = fromSlateValue([children[operation.path[0] - 1]], schema.block.name)[0];
|
|
4410
|
+
patches.push(set(newBlock, [{
|
|
4411
|
+
_key: newBlock._key
|
|
4412
|
+
}])), patches.push(unset([{
|
|
4413
|
+
_key: block._key
|
|
4414
|
+
}]));
|
|
4415
|
+
} else
|
|
4416
|
+
throw new Error("Target key not found!");
|
|
4417
|
+
else if (isTextBlock({
|
|
4418
|
+
schema
|
|
4419
|
+
}, block) && isTextBlock({
|
|
4420
|
+
schema
|
|
4421
|
+
}, updatedBlock) && operation.path.length === 2) {
|
|
4422
|
+
const updatedSpan = updatedBlock.children[operation.path[1] - 1] && isSpan({
|
|
4423
|
+
schema
|
|
4424
|
+
}, updatedBlock.children[operation.path[1] - 1]) ? updatedBlock.children[operation.path[1] - 1] : void 0, removedSpan = block.children[operation.path[1]] && isSpan({
|
|
4425
|
+
schema
|
|
4426
|
+
}, block.children[operation.path[1]]) ? block.children[operation.path[1]] : void 0;
|
|
4427
|
+
updatedSpan && (block.children.filter((span) => span._key === updatedSpan._key).length === 1 ? patches.push(set(updatedSpan.text, [{
|
|
4428
|
+
_key: block._key
|
|
4429
|
+
}, "children", {
|
|
4430
|
+
_key: updatedSpan._key
|
|
4431
|
+
}, "text"])) : console.warn(`Multiple spans have \`_key\` ${updatedSpan._key}. It's ambiguous which one to update.`, JSON.stringify(block, null, 2))), removedSpan && (block.children.filter((span) => span._key === removedSpan._key).length === 1 ? patches.push(unset([{
|
|
4432
|
+
_key: block._key
|
|
4433
|
+
}, "children", {
|
|
4434
|
+
_key: removedSpan._key
|
|
4435
|
+
}])) : console.warn(`Multiple spans have \`_key\` ${removedSpan._key}. It's ambiguous which one to remove.`, JSON.stringify(block, null, 2)));
|
|
4436
|
+
}
|
|
4437
|
+
return patches;
|
|
4438
|
+
}
|
|
4439
|
+
function moveNodePatch(schema, beforeValue, operation) {
|
|
4440
|
+
const patches = [], block = beforeValue[operation.path[0]], targetBlock = beforeValue[operation.newPath[0]];
|
|
4441
|
+
if (!targetBlock)
|
|
4442
|
+
return patches;
|
|
4443
|
+
if (operation.path.length === 1) {
|
|
4444
|
+
const position = operation.path[0] > operation.newPath[0] ? "before" : "after";
|
|
4445
|
+
patches.push(unset([{
|
|
4446
|
+
_key: block._key
|
|
4447
|
+
}])), patches.push(insert([fromSlateValue([block], schema.block.name)[0]], position, [{
|
|
4448
|
+
_key: targetBlock._key
|
|
4449
|
+
}]));
|
|
4450
|
+
} else if (operation.path.length === 2 && isTextBlock({
|
|
4451
|
+
schema
|
|
4452
|
+
}, block) && isTextBlock({
|
|
4453
|
+
schema
|
|
4454
|
+
}, targetBlock)) {
|
|
4455
|
+
const child = block.children[operation.path[1]], targetChild = targetBlock.children[operation.newPath[1]], position = operation.newPath[1] === targetBlock.children.length ? "after" : "before", childToInsert = fromSlateValue([block], schema.block.name)[0].children[operation.path[1]];
|
|
4456
|
+
patches.push(unset([{
|
|
4457
|
+
_key: block._key
|
|
4458
|
+
}, "children", {
|
|
4459
|
+
_key: child._key
|
|
4460
|
+
}])), patches.push(insert([childToInsert], position, [{
|
|
4461
|
+
_key: targetBlock._key
|
|
4462
|
+
}, "children", {
|
|
4463
|
+
_key: targetChild._key
|
|
4464
|
+
}]));
|
|
4465
|
+
}
|
|
4466
|
+
return patches;
|
|
4467
|
+
}
|
|
4442
4468
|
const PATCHING = /* @__PURE__ */ new WeakMap();
|
|
4443
4469
|
function withoutPatching(editor, fn) {
|
|
4444
4470
|
const prev = isPatching(editor);
|
|
@@ -4451,7 +4477,6 @@ const debug$e = debugWithName("plugin:withPatches");
|
|
|
4451
4477
|
function createWithPatches({
|
|
4452
4478
|
editorActor,
|
|
4453
4479
|
relayActor,
|
|
4454
|
-
patchFunctions,
|
|
4455
4480
|
subscriptions
|
|
4456
4481
|
}) {
|
|
4457
4482
|
let previousChildren;
|
|
@@ -4506,28 +4531,28 @@ function createWithPatches({
|
|
|
4506
4531
|
return editor;
|
|
4507
4532
|
switch (editorWasEmpty && !editorIsEmpty && operation.type !== "set_selection" && patches.push(insert(previousChildren, "before", [0])), operation.type) {
|
|
4508
4533
|
case "insert_text":
|
|
4509
|
-
patches = [...patches, ...
|
|
4534
|
+
patches = [...patches, ...insertTextPatch(editorActor.getSnapshot().context.schema, editor.children, operation, previousChildren)];
|
|
4510
4535
|
break;
|
|
4511
4536
|
case "remove_text":
|
|
4512
|
-
patches = [...patches, ...
|
|
4537
|
+
patches = [...patches, ...removeTextPatch(editorActor.getSnapshot().context.schema, editor.children, operation, previousChildren)];
|
|
4513
4538
|
break;
|
|
4514
4539
|
case "remove_node":
|
|
4515
|
-
patches = [...patches, ...
|
|
4540
|
+
patches = [...patches, ...removeNodePatch(editorActor.getSnapshot().context.schema, previousChildren, operation)];
|
|
4516
4541
|
break;
|
|
4517
4542
|
case "split_node":
|
|
4518
|
-
patches = [...patches, ...
|
|
4543
|
+
patches = [...patches, ...splitNodePatch(editorActor.getSnapshot().context.schema, editor.children, operation, previousChildren)];
|
|
4519
4544
|
break;
|
|
4520
4545
|
case "insert_node":
|
|
4521
|
-
patches = [...patches, ...
|
|
4546
|
+
patches = [...patches, ...insertNodePatch(editorActor.getSnapshot().context.schema, editor.children, operation, previousChildren)];
|
|
4522
4547
|
break;
|
|
4523
4548
|
case "set_node":
|
|
4524
|
-
patches = [...patches, ...
|
|
4549
|
+
patches = [...patches, ...setNodePatch(editorActor.getSnapshot().context.schema, editor.children, operation)];
|
|
4525
4550
|
break;
|
|
4526
4551
|
case "merge_node":
|
|
4527
|
-
patches = [...patches, ...
|
|
4552
|
+
patches = [...patches, ...mergeNodePatch(editorActor.getSnapshot().context.schema, editor.children, operation, previousChildren)];
|
|
4528
4553
|
break;
|
|
4529
4554
|
case "move_node":
|
|
4530
|
-
patches = [...patches, ...
|
|
4555
|
+
patches = [...patches, ...moveNodePatch(editorActor.getSnapshot().context.schema, previousChildren, operation)];
|
|
4531
4556
|
break;
|
|
4532
4557
|
}
|
|
4533
4558
|
if (!editorWasEmpty && editorIsEmpty && ["merge_node", "set_node", "remove_text", "remove_node"].includes(operation.type) && (patches = [...patches, unset([])], relayActor.send({
|
|
@@ -4723,12 +4748,11 @@ const withPlugins = (editor, options) => {
|
|
|
4723
4748
|
const e = editor, {
|
|
4724
4749
|
editorActor,
|
|
4725
4750
|
relayActor
|
|
4726
|
-
} = options,
|
|
4751
|
+
} = options, withObjectKeys = createWithObjectKeys(editorActor), withSchemaTypes = createWithSchemaTypes({
|
|
4727
4752
|
editorActor
|
|
4728
4753
|
}), withPatches = createWithPatches({
|
|
4729
4754
|
editorActor,
|
|
4730
4755
|
relayActor,
|
|
4731
|
-
patchFunctions: operationToPatches,
|
|
4732
4756
|
subscriptions: options.subscriptions
|
|
4733
4757
|
}), withMaxBlocks = createWithMaxBlocks(editorActor), withUndoRedo = createWithUndoRedo({
|
|
4734
4758
|
editorActor,
|