@portabletext/editor 1.0.18 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.d.mts +140 -66
- package/lib/index.d.ts +140 -66
- package/lib/index.esm.js +1164 -410
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +1164 -410
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +1164 -410
- package/lib/index.mjs.map +1 -1
- package/package.json +8 -4
- package/src/editor/Editable.tsx +107 -36
- package/src/editor/PortableTextEditor.tsx +47 -12
- package/src/editor/__tests__/PortableTextEditor.test.tsx +42 -15
- package/src/editor/__tests__/PortableTextEditorTester.tsx +50 -38
- package/src/editor/__tests__/RangeDecorations.test.tsx +0 -1
- package/src/editor/__tests__/handleClick.test.tsx +28 -9
- package/src/editor/__tests__/insert-block.test.tsx +22 -6
- package/src/editor/__tests__/pteWarningsSelfSolving.test.tsx +30 -62
- package/src/editor/__tests__/utils.ts +10 -3
- package/src/editor/components/DraggableBlock.tsx +36 -13
- package/src/editor/components/Element.tsx +59 -17
- package/src/editor/components/Leaf.tsx +106 -68
- package/src/editor/components/SlateContainer.tsx +12 -5
- package/src/editor/components/Synchronizer.tsx +5 -2
- package/src/editor/hooks/usePortableTextEditor.ts +2 -2
- package/src/editor/hooks/usePortableTextEditorSelection.tsx +9 -3
- package/src/editor/hooks/useSyncValue.test.tsx +9 -4
- package/src/editor/hooks/useSyncValue.ts +199 -130
- package/src/editor/nodes/DefaultAnnotation.tsx +6 -3
- package/src/editor/plugins/__tests__/createWithInsertData.test.tsx +25 -7
- package/src/editor/plugins/__tests__/withEditableAPIDelete.test.tsx +26 -9
- package/src/editor/plugins/__tests__/withEditableAPIGetFragment.test.tsx +15 -5
- package/src/editor/plugins/__tests__/withEditableAPIInsert.test.tsx +60 -19
- package/src/editor/plugins/__tests__/withEditableAPISelectionsOverlapping.test.tsx +4 -2
- package/src/editor/plugins/__tests__/withPortableTextLists.test.tsx +4 -2
- package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +61 -550
- package/src/editor/plugins/__tests__/withPortableTextSelections.test.tsx +6 -3
- package/src/editor/plugins/__tests__/withUndoRedo.test.tsx +30 -13
- package/src/editor/plugins/createWithEditableAPI.ts +354 -115
- package/src/editor/plugins/createWithHotKeys.ts +41 -121
- package/src/editor/plugins/createWithInsertBreak.ts +166 -27
- package/src/editor/plugins/createWithInsertData.ts +60 -23
- package/src/editor/plugins/createWithMaxBlocks.ts +5 -2
- package/src/editor/plugins/createWithObjectKeys.ts +7 -3
- package/src/editor/plugins/createWithPatches.ts +60 -16
- package/src/editor/plugins/createWithPlaceholderBlock.ts +7 -3
- package/src/editor/plugins/createWithPortableTextBlockStyle.ts +17 -7
- package/src/editor/plugins/createWithPortableTextLists.ts +21 -8
- package/src/editor/plugins/createWithPortableTextMarkModel.ts +301 -155
- package/src/editor/plugins/createWithPortableTextSelections.ts +4 -2
- package/src/editor/plugins/createWithSchemaTypes.ts +25 -9
- package/src/editor/plugins/createWithUndoRedo.ts +107 -24
- package/src/editor/plugins/createWithUtils.ts +32 -10
- package/src/editor/plugins/index.ts +31 -10
- package/src/types/editor.ts +44 -15
- package/src/types/options.ts +4 -2
- package/src/types/slate.ts +2 -2
- package/src/utils/__tests__/dmpToOperations.test.ts +38 -13
- package/src/utils/__tests__/operationToPatches.test.ts +3 -2
- package/src/utils/__tests__/patchToOperations.test.ts +15 -4
- package/src/utils/__tests__/ranges.test.ts +8 -3
- package/src/utils/__tests__/valueNormalization.test.tsx +12 -4
- package/src/utils/__tests__/values.test.ts +0 -1
- package/src/utils/applyPatch.ts +71 -20
- package/src/utils/getPortableTextMemberSchemaTypes.ts +30 -15
- package/src/utils/operationToPatches.ts +126 -43
- package/src/utils/paths.ts +24 -7
- package/src/utils/ranges.ts +12 -5
- package/src/utils/selection.ts +19 -7
- package/src/utils/validateValue.ts +118 -45
- package/src/utils/values.ts +31 -10
- package/src/utils/weakMaps.ts +18 -8
- package/src/utils/withChanges.ts +4 -2
- package/src/editor/plugins/__tests__/withHotkeys.test.tsx +0 -212
- package/src/editor/plugins/__tests__/withInsertBreak.test.tsx +0 -220
- package/src/editor/plugins/__tests__/withPlaceholderBlock.test.tsx +0 -133
package/lib/index.esm.js
CHANGED
|
@@ -54,7 +54,9 @@ function createArrayedPath(point, editor) {
|
|
|
54
54
|
return [];
|
|
55
55
|
if (editor.isVoid(block))
|
|
56
56
|
return [blockPath[0], 0];
|
|
57
|
-
const childPath = [point.path[2]], childIndex = block.children.findIndex(
|
|
57
|
+
const childPath = [point.path[2]], childIndex = block.children.findIndex(
|
|
58
|
+
(child) => isEqual([{ _key: child._key }], childPath)
|
|
59
|
+
);
|
|
58
60
|
if (childIndex >= 0 && block.children[childIndex]) {
|
|
59
61
|
const child = block.children[childIndex];
|
|
60
62
|
return Element$1.isElement(child) && editor.isVoid(child) ? blockPath.concat(childIndex).concat(0) : blockPath.concat(childIndex);
|
|
@@ -99,7 +101,9 @@ function normalizePoint(point, value) {
|
|
|
99
101
|
return null;
|
|
100
102
|
const newPath = [];
|
|
101
103
|
let newOffset = point.offset || 0;
|
|
102
|
-
const blockKey = typeof point.path[0] == "object" && "_key" in point.path[0] && point.path[0]._key, childKey = typeof point.path[2] == "object" && "_key" in point.path[2] && point.path[2]._key, block = value.find(
|
|
104
|
+
const blockKey = typeof point.path[0] == "object" && "_key" in point.path[0] && point.path[0]._key, childKey = typeof point.path[2] == "object" && "_key" in point.path[2] && point.path[2]._key, block = value.find(
|
|
105
|
+
(blk) => blk._key === blockKey
|
|
106
|
+
);
|
|
103
107
|
if (block)
|
|
104
108
|
newPath.push({ _key: block._key });
|
|
105
109
|
else
|
|
@@ -122,14 +126,16 @@ function normalizeSelection(selection, value) {
|
|
|
122
126
|
const { anchor, focus } = selection;
|
|
123
127
|
return anchor && value.find((blk) => isEqual({ _key: blk._key }, anchor.path[0])) && (newAnchor = normalizePoint(anchor, value)), focus && value.find((blk) => isEqual({ _key: blk._key }, focus.path[0])) && (newFocus = normalizePoint(focus, value)), newAnchor && newFocus ? { anchor: newAnchor, focus: newFocus, backward: selection.backward } : null;
|
|
124
128
|
}
|
|
125
|
-
const EMPTY_MARKDEFS = [],
|
|
129
|
+
const EMPTY_MARKDEFS = [], VOID_CHILD_KEY = "void-child";
|
|
126
130
|
function keepObjectEquality(object, keyMap) {
|
|
127
131
|
const value = keyMap[object._key];
|
|
128
132
|
return value && isEqual(object, value) ? value : (keyMap[object._key] = object, object);
|
|
129
133
|
}
|
|
130
134
|
function toSlateValue(value, { schemaTypes }, keyMap = {}) {
|
|
131
135
|
return value && Array.isArray(value) ? value.map((block) => {
|
|
132
|
-
const { _type, _key, ...rest } = block, voidChildren = [
|
|
136
|
+
const { _type, _key, ...rest } = block, voidChildren = [
|
|
137
|
+
{ _key: VOID_CHILD_KEY, _type: "span", text: "", marks: [] }
|
|
138
|
+
];
|
|
133
139
|
if (block && block._type === schemaTypes.block.name) {
|
|
134
140
|
const textBlock = block;
|
|
135
141
|
let hasInlines = !1;
|
|
@@ -170,12 +176,25 @@ function fromSlateValue(value, textBlockType, keyMap = {}) {
|
|
|
170
176
|
const { _type: _cType } = child;
|
|
171
177
|
if ("value" in child && _cType !== "span") {
|
|
172
178
|
hasInlines = !0;
|
|
173
|
-
const {
|
|
174
|
-
|
|
179
|
+
const {
|
|
180
|
+
value: v,
|
|
181
|
+
_key: k,
|
|
182
|
+
_type: t,
|
|
183
|
+
__inline: _i,
|
|
184
|
+
children: _c,
|
|
185
|
+
...rest
|
|
186
|
+
} = child;
|
|
187
|
+
return keepObjectEquality(
|
|
188
|
+
{ ...rest, ...v, _key: k, _type: t },
|
|
189
|
+
keyMap
|
|
190
|
+
);
|
|
175
191
|
}
|
|
176
192
|
return child;
|
|
177
193
|
});
|
|
178
|
-
return hasInlines ? keepObjectEquality(
|
|
194
|
+
return hasInlines ? keepObjectEquality(
|
|
195
|
+
{ ...block, children, _key, _type },
|
|
196
|
+
keyMap
|
|
197
|
+
) : block;
|
|
179
198
|
}
|
|
180
199
|
const blockValue = "value" in block && block.value;
|
|
181
200
|
return keepObjectEquality(
|
|
@@ -347,10 +366,23 @@ function getCounterContentForListLevel(level) {
|
|
|
347
366
|
return "counter(listItemNumberNextNextNext) '. '";
|
|
348
367
|
}
|
|
349
368
|
}
|
|
350
|
-
const debug$l = debugWithName("components:DraggableBlock"), DraggableBlock = ({
|
|
351
|
-
|
|
369
|
+
const debug$l = debugWithName("components:DraggableBlock"), DraggableBlock = ({
|
|
370
|
+
children,
|
|
371
|
+
element,
|
|
372
|
+
readOnly,
|
|
373
|
+
blockRef
|
|
374
|
+
}) => {
|
|
375
|
+
const editor = useSlateStatic(), dragGhostRef = useRef(), [isDragOver, setIsDragOver] = useState(!1), isVoid = useMemo(
|
|
376
|
+
() => Editor.isVoid(editor, element),
|
|
377
|
+
[editor, element]
|
|
378
|
+
), isInline = useMemo(
|
|
379
|
+
() => Editor.isInline(editor, element),
|
|
380
|
+
[editor, element]
|
|
381
|
+
), [blockElement, setBlockElement] = useState(null);
|
|
352
382
|
useEffect(
|
|
353
|
-
() => setBlockElement(
|
|
383
|
+
() => setBlockElement(
|
|
384
|
+
blockRef ? blockRef.current : ReactEditor.toDOMNode(editor, element)
|
|
385
|
+
),
|
|
354
386
|
[editor, element, blockRef]
|
|
355
387
|
);
|
|
356
388
|
const handleDragOver = useCallback(
|
|
@@ -437,7 +469,9 @@ const debug$l = debugWithName("components:DraggableBlock"), DraggableBlock = ({
|
|
|
437
469
|
}
|
|
438
470
|
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) {
|
|
439
471
|
let dragGhost = blockElement.cloneNode(!0);
|
|
440
|
-
const customGhost = dragGhost.querySelector(
|
|
472
|
+
const customGhost = dragGhost.querySelector(
|
|
473
|
+
"[data-pt-drag-ghost-element]"
|
|
474
|
+
);
|
|
441
475
|
if (customGhost && (dragGhost = customGhost), dragGhost.setAttribute("data-dragged", ""), document.body) {
|
|
442
476
|
dragGhostRef.current = dragGhost, dragGhost.style.position = "absolute", dragGhost.style.left = "-99999px", dragGhost.style.boxSizing = "border-box", document.body.appendChild(dragGhost);
|
|
443
477
|
const rect = blockElement.getBoundingClientRect(), x = event.clientX - rect.left, y = event.clientY - rect.top;
|
|
@@ -495,7 +529,11 @@ const EMPTY_ANNOTATIONS = [], inlineBlockStyle = { display: "inline-block" }, El
|
|
|
495
529
|
spellCheck
|
|
496
530
|
}) => {
|
|
497
531
|
const editor = useSlateStatic(), selected = useSelected(), blockRef = useRef(null), inlineBlockObjectRef = useRef(null), focused = selected && editor.selection && Range.isCollapsed(editor.selection) || !1, value = useMemo(
|
|
498
|
-
() => fromSlateValue(
|
|
532
|
+
() => fromSlateValue(
|
|
533
|
+
[element],
|
|
534
|
+
schemaTypes.block.name,
|
|
535
|
+
KEY_TO_VALUE_ELEMENT.get(editor)
|
|
536
|
+
)[0],
|
|
499
537
|
[editor, element, schemaTypes.block.name]
|
|
500
538
|
);
|
|
501
539
|
let renderedBlock = children, className;
|
|
@@ -505,11 +543,17 @@ const EMPTY_ANNOTATIONS = [], inlineBlockStyle = { display: "inline-block" }, El
|
|
|
505
543
|
if (typeof element._key != "string")
|
|
506
544
|
throw new Error("Expected element to have a _key property");
|
|
507
545
|
if (editor.isInline(element)) {
|
|
508
|
-
const path = ReactEditor.findPath(editor, element), [block2] = Editor.node(editor, path, { depth: 1 }), schemaType2 = schemaTypes.inlineObjects.find(
|
|
546
|
+
const path = ReactEditor.findPath(editor, element), [block2] = Editor.node(editor, path, { depth: 1 }), schemaType2 = schemaTypes.inlineObjects.find(
|
|
547
|
+
(_type) => _type.name === element._type
|
|
548
|
+
);
|
|
509
549
|
if (!schemaType2)
|
|
510
550
|
throw new Error("Could not find type for inline block element");
|
|
511
551
|
if (Element$1.isElement(block2)) {
|
|
512
|
-
const elmPath = [
|
|
552
|
+
const elmPath = [
|
|
553
|
+
{ _key: block2._key },
|
|
554
|
+
"children",
|
|
555
|
+
{ _key: element._key }
|
|
556
|
+
];
|
|
513
557
|
return /* @__PURE__ */ jsxs("span", { ...attributes, children: [
|
|
514
558
|
children,
|
|
515
559
|
/* @__PURE__ */ jsxs(
|
|
@@ -547,7 +591,9 @@ const EMPTY_ANNOTATIONS = [], inlineBlockStyle = { display: "inline-block" }, El
|
|
|
547
591
|
className = "pt-block pt-text-block";
|
|
548
592
|
const isListItem = "listItem" in element, style = "style" in element && element.style || "normal";
|
|
549
593
|
className = `pt-block pt-text-block pt-text-block-style-${style}`;
|
|
550
|
-
const blockStyleType = schemaTypes.styles.find(
|
|
594
|
+
const blockStyleType = schemaTypes.styles.find(
|
|
595
|
+
(item) => item.value === style
|
|
596
|
+
);
|
|
551
597
|
renderStyle && blockStyleType && (renderedBlock = renderStyle({
|
|
552
598
|
block: element,
|
|
553
599
|
children,
|
|
@@ -560,7 +606,9 @@ const EMPTY_ANNOTATIONS = [], inlineBlockStyle = { display: "inline-block" }, El
|
|
|
560
606
|
}));
|
|
561
607
|
let level;
|
|
562
608
|
if (isListItem && (typeof element.level == "number" && (level = element.level), className += ` pt-list-item pt-list-item-${element.listItem} pt-list-item-level-${level || 1}`), editor.isListBlock(value) && isListItem && element.listItem) {
|
|
563
|
-
const listType = schemaTypes.lists.find(
|
|
609
|
+
const listType = schemaTypes.lists.find(
|
|
610
|
+
(item) => item.value === element.listItem
|
|
611
|
+
);
|
|
564
612
|
renderListItem && listType ? renderedBlock = renderListItem({
|
|
565
613
|
block: value,
|
|
566
614
|
children: renderedBlock,
|
|
@@ -597,15 +645,38 @@ const EMPTY_ANNOTATIONS = [], inlineBlockStyle = { display: "inline-block" }, El
|
|
|
597
645
|
{
|
|
598
646
|
enumerable: !1,
|
|
599
647
|
get() {
|
|
600
|
-
return console.warn(
|
|
648
|
+
return console.warn(
|
|
649
|
+
"Property 'type' is deprecated, use 'schemaType' instead."
|
|
650
|
+
), schemaTypes.block;
|
|
601
651
|
}
|
|
602
652
|
}
|
|
603
653
|
), propsOrDefaultRendered = renderBlock ? renderBlock(renderProps) : children;
|
|
604
|
-
return /* @__PURE__ */ jsx(
|
|
654
|
+
return /* @__PURE__ */ jsx(
|
|
655
|
+
"div",
|
|
656
|
+
{
|
|
657
|
+
...attributes,
|
|
658
|
+
className,
|
|
659
|
+
spellCheck,
|
|
660
|
+
children: /* @__PURE__ */ jsx(
|
|
661
|
+
DraggableBlock,
|
|
662
|
+
{
|
|
663
|
+
element,
|
|
664
|
+
readOnly,
|
|
665
|
+
blockRef,
|
|
666
|
+
children: /* @__PURE__ */ jsx("div", { ref: blockRef, children: propsOrDefaultRendered })
|
|
667
|
+
}
|
|
668
|
+
)
|
|
669
|
+
},
|
|
670
|
+
element._key
|
|
671
|
+
);
|
|
605
672
|
}
|
|
606
|
-
const schemaType = schemaTypes.blockObjects.find(
|
|
673
|
+
const schemaType = schemaTypes.blockObjects.find(
|
|
674
|
+
(_type) => _type.name === element._type
|
|
675
|
+
);
|
|
607
676
|
if (!schemaType)
|
|
608
|
-
throw new Error(
|
|
677
|
+
throw new Error(
|
|
678
|
+
`Could not find schema type for block element of _type ${element._type}`
|
|
679
|
+
);
|
|
609
680
|
className = "pt-block pt-object-block";
|
|
610
681
|
const block = fromSlateValue(
|
|
611
682
|
[element],
|
|
@@ -628,7 +699,9 @@ const EMPTY_ANNOTATIONS = [], inlineBlockStyle = { display: "inline-block" }, El
|
|
|
628
699
|
{
|
|
629
700
|
enumerable: !1,
|
|
630
701
|
get() {
|
|
631
|
-
return console.warn(
|
|
702
|
+
return console.warn(
|
|
703
|
+
"Property 'type' is deprecated, use 'schemaType' instead."
|
|
704
|
+
), schemaType;
|
|
632
705
|
}
|
|
633
706
|
}
|
|
634
707
|
);
|
|
@@ -650,7 +723,11 @@ const EMPTY_ANNOTATIONS = [], inlineBlockStyle = { display: "inline-block" }, El
|
|
|
650
723
|
return editor;
|
|
651
724
|
};
|
|
652
725
|
function DefaultAnnotation(props) {
|
|
653
|
-
const handleClick = useCallback(
|
|
726
|
+
const handleClick = useCallback(
|
|
727
|
+
// eslint-disable-next-line no-alert
|
|
728
|
+
() => alert(JSON.stringify(props.annotation)),
|
|
729
|
+
[props.annotation]
|
|
730
|
+
);
|
|
654
731
|
return /* @__PURE__ */ jsx("span", { style: { color: "blue" }, onClick: handleClick, children: props.children });
|
|
655
732
|
}
|
|
656
733
|
function getPortableTextMemberSchemaTypes(portableTextType) {
|
|
@@ -659,16 +736,24 @@ function getPortableTextMemberSchemaTypes(portableTextType) {
|
|
|
659
736
|
const blockType = portableTextType.of?.find(findBlockType);
|
|
660
737
|
if (!blockType)
|
|
661
738
|
throw new Error("Block type is not defined in this schema (required)");
|
|
662
|
-
const childrenField = blockType.fields?.find(
|
|
739
|
+
const childrenField = blockType.fields?.find(
|
|
740
|
+
(field) => field.name === "children"
|
|
741
|
+
);
|
|
663
742
|
if (!childrenField)
|
|
664
743
|
throw new Error("Children field for block type found in schema (required)");
|
|
665
744
|
const ofType = childrenField.type.of;
|
|
666
745
|
if (!ofType)
|
|
667
|
-
throw new Error(
|
|
746
|
+
throw new Error(
|
|
747
|
+
"Valid types for block children not found in schema (required)"
|
|
748
|
+
);
|
|
668
749
|
const spanType = ofType.find((memberType) => memberType.name === "span");
|
|
669
750
|
if (!spanType)
|
|
670
751
|
throw new Error("Span type not found in schema (required)");
|
|
671
|
-
const inlineObjectTypes = ofType.filter(
|
|
752
|
+
const inlineObjectTypes = ofType.filter(
|
|
753
|
+
(memberType) => memberType.name !== "span"
|
|
754
|
+
) || [], blockObjectTypes = portableTextType.of?.filter(
|
|
755
|
+
(field) => field.name !== blockType.name
|
|
756
|
+
) || [];
|
|
672
757
|
return {
|
|
673
758
|
styles: resolveEnabledStyles(blockType),
|
|
674
759
|
decorators: resolveEnabledDecorators(spanType),
|
|
@@ -682,10 +767,16 @@ function getPortableTextMemberSchemaTypes(portableTextType) {
|
|
|
682
767
|
};
|
|
683
768
|
}
|
|
684
769
|
function resolveEnabledStyles(blockType) {
|
|
685
|
-
const styleField = blockType.fields?.find(
|
|
770
|
+
const styleField = blockType.fields?.find(
|
|
771
|
+
(btField) => btField.name === "style"
|
|
772
|
+
);
|
|
686
773
|
if (!styleField)
|
|
687
|
-
throw new Error(
|
|
688
|
-
|
|
774
|
+
throw new Error(
|
|
775
|
+
"A field with name 'style' is not defined in the block type (required)."
|
|
776
|
+
);
|
|
777
|
+
const textStyles = styleField.type.options?.list && styleField.type.options.list?.filter(
|
|
778
|
+
(style) => style.value
|
|
779
|
+
);
|
|
689
780
|
if (!textStyles || textStyles.length === 0)
|
|
690
781
|
throw new Error(
|
|
691
782
|
"The style fields need at least one style defined. I.e: {title: 'Normal', value: 'normal'}."
|
|
@@ -696,9 +787,13 @@ function resolveEnabledDecorators(spanType) {
|
|
|
696
787
|
return spanType.decorators;
|
|
697
788
|
}
|
|
698
789
|
function resolveEnabledListItems(blockType) {
|
|
699
|
-
const listField = blockType.fields?.find(
|
|
790
|
+
const listField = blockType.fields?.find(
|
|
791
|
+
(btField) => btField.name === "listItem"
|
|
792
|
+
);
|
|
700
793
|
if (!listField)
|
|
701
|
-
throw new Error(
|
|
794
|
+
throw new Error(
|
|
795
|
+
"A field with name 'listItem' is not defined in the block type (required)."
|
|
796
|
+
);
|
|
702
797
|
const listItems = listField.type.options?.list && listField.type.options.list.filter((list) => list.value);
|
|
703
798
|
if (!listItems)
|
|
704
799
|
throw new Error("The list field need at least to be an empty array");
|
|
@@ -724,7 +819,12 @@ function createOperationToPatches(types) {
|
|
|
724
819
|
const textChild = editor.isTextBlock(block) && editor.isTextSpan(block.children[operation.path[1]]) && block.children[operation.path[1]];
|
|
725
820
|
if (!textChild)
|
|
726
821
|
throw new Error("Could not find child");
|
|
727
|
-
const path = [
|
|
822
|
+
const path = [
|
|
823
|
+
{ _key: block._key },
|
|
824
|
+
"children",
|
|
825
|
+
{ _key: textChild._key },
|
|
826
|
+
"text"
|
|
827
|
+
], 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);
|
|
728
828
|
return patch.value.length ? [patch] : [];
|
|
729
829
|
}
|
|
730
830
|
function removeTextPatch(editor, operation, beforeValue) {
|
|
@@ -736,7 +836,12 @@ function createOperationToPatches(types) {
|
|
|
736
836
|
throw new Error("Expected span");
|
|
737
837
|
if (!textChild)
|
|
738
838
|
throw new Error("Could not find child");
|
|
739
|
-
const path = [
|
|
839
|
+
const path = [
|
|
840
|
+
{ _key: block._key },
|
|
841
|
+
"children",
|
|
842
|
+
{ _key: textChild._key },
|
|
843
|
+
"text"
|
|
844
|
+
], 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);
|
|
740
845
|
return patch.value ? [patch] : [];
|
|
741
846
|
}
|
|
742
847
|
function setNodePatch(editor, operation) {
|
|
@@ -748,7 +853,9 @@ function createOperationToPatches(types) {
|
|
|
748
853
|
{ ...editor.children[operation.path[0]], ...operation.newProperties },
|
|
749
854
|
isUndefined
|
|
750
855
|
);
|
|
751
|
-
return [
|
|
856
|
+
return [
|
|
857
|
+
set(fromSlateValue([setNode], textBlockName)[0], [{ _key: block._key }])
|
|
858
|
+
];
|
|
752
859
|
} else if (operation.path.length === 2) {
|
|
753
860
|
const block = editor.children[operation.path[0]];
|
|
754
861
|
if (editor.isTextBlock(block)) {
|
|
@@ -759,11 +866,23 @@ function createOperationToPatches(types) {
|
|
|
759
866
|
if (keys.length === 1 && keyName === "_key") {
|
|
760
867
|
const val = get(operation.newProperties, keyName);
|
|
761
868
|
patches.push(
|
|
762
|
-
set(val, [
|
|
869
|
+
set(val, [
|
|
870
|
+
{ _key: blockKey },
|
|
871
|
+
"children",
|
|
872
|
+
block.children.indexOf(child),
|
|
873
|
+
keyName
|
|
874
|
+
])
|
|
763
875
|
);
|
|
764
876
|
} else {
|
|
765
877
|
const val = get(operation.newProperties, keyName);
|
|
766
|
-
patches.push(
|
|
878
|
+
patches.push(
|
|
879
|
+
set(val, [
|
|
880
|
+
{ _key: blockKey },
|
|
881
|
+
"children",
|
|
882
|
+
{ _key: childKey },
|
|
883
|
+
keyName
|
|
884
|
+
])
|
|
885
|
+
);
|
|
767
886
|
}
|
|
768
887
|
}), patches;
|
|
769
888
|
}
|
|
@@ -771,21 +890,27 @@ function createOperationToPatches(types) {
|
|
|
771
890
|
}
|
|
772
891
|
throw new Error("Could not find a valid block");
|
|
773
892
|
} else
|
|
774
|
-
throw new Error(
|
|
893
|
+
throw new Error(
|
|
894
|
+
`Unexpected path encountered: ${JSON.stringify(operation.path)}`
|
|
895
|
+
);
|
|
775
896
|
}
|
|
776
897
|
function insertNodePatch(editor, operation, beforeValue) {
|
|
777
898
|
const block = beforeValue[operation.path[0]], isTextBlock = editor.isTextBlock(block);
|
|
778
899
|
if (operation.path.length === 1) {
|
|
779
900
|
const position = operation.path[0] === 0 ? "before" : "after", beforeBlock = beforeValue[operation.path[0] - 1], targetKey = operation.path[0] === 0 ? block?._key : beforeBlock?._key;
|
|
780
901
|
return targetKey ? [
|
|
781
|
-
insert(
|
|
782
|
-
|
|
783
|
-
|
|
902
|
+
insert(
|
|
903
|
+
[fromSlateValue([operation.node], textBlockName)[0]],
|
|
904
|
+
position,
|
|
905
|
+
[{ _key: targetKey }]
|
|
906
|
+
)
|
|
784
907
|
] : [
|
|
785
908
|
setIfMissing(beforeValue, []),
|
|
786
|
-
insert(
|
|
787
|
-
operation.
|
|
788
|
-
|
|
909
|
+
insert(
|
|
910
|
+
[fromSlateValue([operation.node], textBlockName)[0]],
|
|
911
|
+
"before",
|
|
912
|
+
[operation.path[0]]
|
|
913
|
+
)
|
|
789
914
|
];
|
|
790
915
|
} else if (isTextBlock && operation.path.length === 2 && editor.children[operation.path[0]]) {
|
|
791
916
|
const position = block.children.length === 0 || !block.children[operation.path[1] - 1] ? "before" : "after", node = { ...operation.node };
|
|
@@ -808,7 +933,9 @@ function createOperationToPatches(types) {
|
|
|
808
933
|
])
|
|
809
934
|
];
|
|
810
935
|
}
|
|
811
|
-
return debug$k(
|
|
936
|
+
return debug$k(
|
|
937
|
+
"Something was inserted into a void block. Not producing editor patches."
|
|
938
|
+
), [];
|
|
812
939
|
}
|
|
813
940
|
function splitNodePatch(editor, operation, beforeValue) {
|
|
814
941
|
const patches = [], splitBlock = editor.children[operation.path[0]];
|
|
@@ -825,7 +952,9 @@ function createOperationToPatches(types) {
|
|
|
825
952
|
[editor.children[operation.path[0] + 1]],
|
|
826
953
|
textBlockName
|
|
827
954
|
)[0];
|
|
828
|
-
targetValue && (patches.push(
|
|
955
|
+
targetValue && (patches.push(
|
|
956
|
+
insert([targetValue], "after", [{ _key: splitBlock._key }])
|
|
957
|
+
), oldBlock.children.slice(operation.position).forEach((span) => {
|
|
829
958
|
const path = [{ _key: oldBlock._key }, "children", { _key: span._key }];
|
|
830
959
|
patches.push(unset(path));
|
|
831
960
|
}));
|
|
@@ -839,7 +968,10 @@ function createOperationToPatches(types) {
|
|
|
839
968
|
[
|
|
840
969
|
{
|
|
841
970
|
...splitBlock,
|
|
842
|
-
children: splitBlock.children.slice(
|
|
971
|
+
children: splitBlock.children.slice(
|
|
972
|
+
operation.path[1] + 1,
|
|
973
|
+
operation.path[1] + 2
|
|
974
|
+
)
|
|
843
975
|
}
|
|
844
976
|
],
|
|
845
977
|
textBlockName
|
|
@@ -871,10 +1003,14 @@ function createOperationToPatches(types) {
|
|
|
871
1003
|
throw new Error("Block not found");
|
|
872
1004
|
} else if (editor.isTextBlock(block) && operation.path.length === 2) {
|
|
873
1005
|
const spanToRemove = block.children[operation.path[1]];
|
|
874
|
-
return spanToRemove ? block.children.filter(
|
|
1006
|
+
return spanToRemove ? block.children.filter(
|
|
1007
|
+
(span) => span._key === operation.node._key
|
|
1008
|
+
).length > 1 ? (console.warn(
|
|
875
1009
|
`Multiple spans have \`_key\` ${operation.node._key}. It's ambiguous which one to remove.`,
|
|
876
1010
|
JSON.stringify(block, null, 2)
|
|
877
|
-
), []) : [
|
|
1011
|
+
), []) : [
|
|
1012
|
+
unset([{ _key: block._key }, "children", { _key: spanToRemove._key }])
|
|
1013
|
+
] : (debug$k("Span not found in editor trying to remove node"), []);
|
|
878
1014
|
} else
|
|
879
1015
|
return debug$k("Not creating patch inside object block"), [];
|
|
880
1016
|
}
|
|
@@ -882,13 +1018,18 @@ function createOperationToPatches(types) {
|
|
|
882
1018
|
const patches = [], block = beforeValue[operation.path[0]], updatedBlock = editor.children[operation.path[0]];
|
|
883
1019
|
if (operation.path.length === 1)
|
|
884
1020
|
if (block?._key) {
|
|
885
|
-
const newBlock = fromSlateValue(
|
|
1021
|
+
const newBlock = fromSlateValue(
|
|
1022
|
+
[editor.children[operation.path[0] - 1]],
|
|
1023
|
+
textBlockName
|
|
1024
|
+
)[0];
|
|
886
1025
|
patches.push(set(newBlock, [{ _key: newBlock._key }])), patches.push(unset([{ _key: block._key }]));
|
|
887
1026
|
} else
|
|
888
1027
|
throw new Error("Target key not found!");
|
|
889
1028
|
else if (editor.isTextBlock(block) && editor.isTextBlock(updatedBlock) && operation.path.length === 2) {
|
|
890
1029
|
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;
|
|
891
|
-
updatedSpan && (block.children.filter(
|
|
1030
|
+
updatedSpan && (block.children.filter(
|
|
1031
|
+
(span) => span._key === updatedSpan._key
|
|
1032
|
+
).length === 1 ? patches.push(
|
|
892
1033
|
set(updatedSpan.text, [
|
|
893
1034
|
{ _key: block._key },
|
|
894
1035
|
"children",
|
|
@@ -898,7 +1039,11 @@ function createOperationToPatches(types) {
|
|
|
898
1039
|
) : console.warn(
|
|
899
1040
|
`Multiple spans have \`_key\` ${updatedSpan._key}. It's ambiguous which one to update.`,
|
|
900
1041
|
JSON.stringify(block, null, 2)
|
|
901
|
-
)), removedSpan && (block.children.filter(
|
|
1042
|
+
)), removedSpan && (block.children.filter(
|
|
1043
|
+
(span) => span._key === removedSpan._key
|
|
1044
|
+
).length === 1 ? patches.push(
|
|
1045
|
+
unset([{ _key: block._key }, "children", { _key: removedSpan._key }])
|
|
1046
|
+
) : console.warn(
|
|
902
1047
|
`Multiple spans have \`_key\` ${removedSpan._key}. It's ambiguous which one to remove.`,
|
|
903
1048
|
JSON.stringify(block, null, 2)
|
|
904
1049
|
));
|
|
@@ -911,7 +1056,9 @@ function createOperationToPatches(types) {
|
|
|
911
1056
|
if (operation.path.length === 1) {
|
|
912
1057
|
const position = operation.path[0] > operation.newPath[0] ? "before" : "after";
|
|
913
1058
|
patches.push(unset([{ _key: block._key }])), patches.push(
|
|
914
|
-
insert([fromSlateValue([block], textBlockName)[0]], position, [
|
|
1059
|
+
insert([fromSlateValue([block], textBlockName)[0]], position, [
|
|
1060
|
+
{ _key: targetBlock._key }
|
|
1061
|
+
])
|
|
915
1062
|
);
|
|
916
1063
|
} else if (operation.path.length === 2 && editor.isTextBlock(block) && editor.isTextBlock(targetBlock)) {
|
|
917
1064
|
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]];
|
|
@@ -973,14 +1120,24 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
973
1120
|
},
|
|
974
1121
|
focusBlock: () => {
|
|
975
1122
|
if (editor.selection) {
|
|
976
|
-
const block = Node.descendant(
|
|
1123
|
+
const block = Node.descendant(
|
|
1124
|
+
editor,
|
|
1125
|
+
editor.selection.focus.path.slice(0, 1)
|
|
1126
|
+
);
|
|
977
1127
|
if (block)
|
|
978
|
-
return fromSlateValue(
|
|
1128
|
+
return fromSlateValue(
|
|
1129
|
+
[block],
|
|
1130
|
+
types.block.name,
|
|
1131
|
+
KEY_TO_VALUE_ELEMENT.get(editor)
|
|
1132
|
+
)[0];
|
|
979
1133
|
}
|
|
980
1134
|
},
|
|
981
1135
|
focusChild: () => {
|
|
982
1136
|
if (editor.selection) {
|
|
983
|
-
const block = Node.descendant(
|
|
1137
|
+
const block = Node.descendant(
|
|
1138
|
+
editor,
|
|
1139
|
+
editor.selection.focus.path.slice(0, 1)
|
|
1140
|
+
);
|
|
984
1141
|
if (block && editor.isTextBlock(block))
|
|
985
1142
|
return fromSlateValue(
|
|
986
1143
|
[block],
|
|
@@ -1001,7 +1158,9 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1001
1158
|
if (!focusBlock)
|
|
1002
1159
|
throw new Error("No focused text block");
|
|
1003
1160
|
if (type.name !== types.span.name && !types.inlineObjects.some((t) => t.name === type.name))
|
|
1004
|
-
throw new Error(
|
|
1161
|
+
throw new Error(
|
|
1162
|
+
"This type cannot be inserted as a child to a text block"
|
|
1163
|
+
);
|
|
1005
1164
|
const child = toSlateValue(
|
|
1006
1165
|
[
|
|
1007
1166
|
{
|
|
@@ -1018,11 +1177,17 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1018
1177
|
],
|
|
1019
1178
|
portableTextEditor
|
|
1020
1179
|
)[0].children[0], focusChildPath = editor.selection.focus.path.slice(0, 2), isSpanNode = child._type === types.span.name, focusNode = Node.get(editor, focusChildPath);
|
|
1021
|
-
return isSpanNode && focusNode._type !== types.span.name && (debug$j(
|
|
1180
|
+
return isSpanNode && focusNode._type !== types.span.name && (debug$j(
|
|
1181
|
+
"Inserting span child next to inline object child, moving selection + 1"
|
|
1182
|
+
), editor.move({ distance: 1, unit: "character" })), Transforms.insertNodes(editor, child, {
|
|
1022
1183
|
select: !0,
|
|
1023
1184
|
at: editor.selection
|
|
1024
1185
|
}), editor.onChange(), toPortableTextRange(
|
|
1025
|
-
fromSlateValue(
|
|
1186
|
+
fromSlateValue(
|
|
1187
|
+
editor.children,
|
|
1188
|
+
types.block.name,
|
|
1189
|
+
KEY_TO_VALUE_ELEMENT.get(editor)
|
|
1190
|
+
),
|
|
1026
1191
|
editor.selection,
|
|
1027
1192
|
types
|
|
1028
1193
|
)?.focus.path || [];
|
|
@@ -1047,7 +1212,11 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1047
1212
|
})
|
|
1048
1213
|
)[0];
|
|
1049
1214
|
return Editor.insertNode(editor, block), lastBlock && isEqualToEmptyEditor([lastBlock[0]], types) && Transforms.removeNodes(editor, { at: lastBlock[1] }), editor.onChange(), toPortableTextRange(
|
|
1050
|
-
fromSlateValue(
|
|
1215
|
+
fromSlateValue(
|
|
1216
|
+
editor.children,
|
|
1217
|
+
types.block.name,
|
|
1218
|
+
KEY_TO_VALUE_ELEMENT.get(editor)
|
|
1219
|
+
),
|
|
1051
1220
|
editor.selection,
|
|
1052
1221
|
types
|
|
1053
1222
|
)?.focus.path ?? [];
|
|
@@ -1059,7 +1228,11 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1059
1228
|
})
|
|
1060
1229
|
)[0];
|
|
1061
1230
|
return Editor.insertNode(editor, block), focusBlock && isEqualToEmptyEditor([focusBlock[0]], types) && Transforms.removeNodes(editor, { at: focusBlock[1] }), editor.onChange(), toPortableTextRange(
|
|
1062
|
-
fromSlateValue(
|
|
1231
|
+
fromSlateValue(
|
|
1232
|
+
editor.children,
|
|
1233
|
+
types.block.name,
|
|
1234
|
+
KEY_TO_VALUE_ELEMENT.get(editor)
|
|
1235
|
+
),
|
|
1063
1236
|
editor.selection,
|
|
1064
1237
|
types
|
|
1065
1238
|
)?.focus.path || [];
|
|
@@ -1085,10 +1258,16 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1085
1258
|
editor
|
|
1086
1259
|
);
|
|
1087
1260
|
if (slatePath) {
|
|
1088
|
-
const [block, blockPath] = Editor.node(
|
|
1261
|
+
const [block, blockPath] = Editor.node(
|
|
1262
|
+
editor,
|
|
1263
|
+
slatePath.focus.path.slice(0, 1)
|
|
1264
|
+
);
|
|
1089
1265
|
if (block && blockPath && typeof block._key == "string") {
|
|
1090
1266
|
if (path.length === 1 && slatePath.focus.path.length === 1)
|
|
1091
|
-
return [
|
|
1267
|
+
return [
|
|
1268
|
+
fromSlateValue([block], types.block.name)[0],
|
|
1269
|
+
[{ _key: block._key }]
|
|
1270
|
+
];
|
|
1092
1271
|
const ptBlock = fromSlateValue(
|
|
1093
1272
|
[block],
|
|
1094
1273
|
types.block.name,
|
|
@@ -1097,7 +1276,10 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1097
1276
|
if (editor.isTextBlock(ptBlock)) {
|
|
1098
1277
|
const ptChild = ptBlock.children[slatePath.focus.path[1]];
|
|
1099
1278
|
if (ptChild)
|
|
1100
|
-
return [
|
|
1279
|
+
return [
|
|
1280
|
+
ptChild,
|
|
1281
|
+
[{ _key: block._key }, "children", { _key: ptChild._key }]
|
|
1282
|
+
];
|
|
1101
1283
|
}
|
|
1102
1284
|
}
|
|
1103
1285
|
}
|
|
@@ -1164,43 +1346,74 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1164
1346
|
addAnnotation: (type, value) => {
|
|
1165
1347
|
const { selection: originalSelection } = editor;
|
|
1166
1348
|
let returnValue;
|
|
1167
|
-
if (originalSelection) {
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
editor
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1349
|
+
if (originalSelection && (Range.isCollapsed(originalSelection) && (editor.pteExpandToWord(), editor.onChange()), editor.selection)) {
|
|
1350
|
+
let spanPath, markDefPath;
|
|
1351
|
+
const markDefPaths = [];
|
|
1352
|
+
Editor.withoutNormalizing(editor, () => {
|
|
1353
|
+
if (!editor.selection)
|
|
1354
|
+
return;
|
|
1355
|
+
const selectedBlocks = Editor.nodes(editor, {
|
|
1356
|
+
at: editor.selection,
|
|
1357
|
+
match: (node) => editor.isTextBlock(node),
|
|
1358
|
+
reverse: Range.isBackward(editor.selection)
|
|
1359
|
+
});
|
|
1360
|
+
for (const [block, blockPath] of selectedBlocks) {
|
|
1361
|
+
if (block.children.length === 0 || block.children.length === 1 && block.children[0].text === "")
|
|
1362
|
+
continue;
|
|
1363
|
+
const annotationKey = keyGenerator(), markDefs = block.markDefs ?? [];
|
|
1364
|
+
markDefs.find(
|
|
1365
|
+
(markDef) => markDef._type === type.name && markDef._key === annotationKey
|
|
1366
|
+
) === void 0 && (Transforms.setNodes(
|
|
1367
|
+
editor,
|
|
1368
|
+
{
|
|
1369
|
+
markDefs: [
|
|
1370
|
+
...markDefs,
|
|
1371
|
+
{
|
|
1372
|
+
_type: type.name,
|
|
1373
|
+
_key: annotationKey,
|
|
1374
|
+
...value
|
|
1375
|
+
}
|
|
1376
|
+
]
|
|
1377
|
+
},
|
|
1378
|
+
{ at: blockPath }
|
|
1379
|
+
), markDefPath = [
|
|
1380
|
+
{ _key: block._key },
|
|
1381
|
+
"markDefs",
|
|
1382
|
+
{ _key: annotationKey }
|
|
1383
|
+
], Range.isBackward(editor.selection) ? markDefPaths.unshift(markDefPath) : markDefPaths.push(markDefPath)), Transforms.setNodes(
|
|
1384
|
+
editor,
|
|
1385
|
+
{},
|
|
1386
|
+
{ match: Text.isText, split: !0 }
|
|
1387
|
+
);
|
|
1388
|
+
const children = Node.children(editor, blockPath);
|
|
1389
|
+
for (const [span, path] of children) {
|
|
1390
|
+
if (!editor.isTextSpan(span) || !Range.includes(editor.selection, path))
|
|
1391
|
+
continue;
|
|
1392
|
+
const marks = span.marks ?? [], existingSameTypeAnnotations = marks.filter(
|
|
1393
|
+
(mark) => markDefs.some(
|
|
1394
|
+
(markDef) => markDef._key === mark && markDef._type === type.name
|
|
1395
|
+
)
|
|
1396
|
+
);
|
|
1397
|
+
Transforms.setNodes(
|
|
1398
|
+
editor,
|
|
1399
|
+
{
|
|
1400
|
+
marks: [
|
|
1401
|
+
...marks.filter(
|
|
1402
|
+
(mark) => !existingSameTypeAnnotations.includes(mark)
|
|
1403
|
+
),
|
|
1404
|
+
annotationKey
|
|
1405
|
+
]
|
|
1406
|
+
},
|
|
1407
|
+
{ at: path }
|
|
1408
|
+
), spanPath = [{ _key: block._key }, "children", { _key: span._key }];
|
|
1192
1409
|
}
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
);
|
|
1199
|
-
newPortableTextEditorSelection && (returnValue = {
|
|
1200
|
-
spanPath: newPortableTextEditorSelection.focus.path,
|
|
1201
|
-
markDefPath: [{ _key: block._key }, "markDefs", { _key: annotationKey }]
|
|
1410
|
+
}
|
|
1411
|
+
markDefPath && spanPath && (returnValue = {
|
|
1412
|
+
markDefPath,
|
|
1413
|
+
markDefPaths,
|
|
1414
|
+
spanPath
|
|
1202
1415
|
});
|
|
1203
|
-
}),
|
|
1416
|
+
}), editor.onChange();
|
|
1204
1417
|
}
|
|
1205
1418
|
return returnValue;
|
|
1206
1419
|
},
|
|
@@ -1227,34 +1440,98 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1227
1440
|
voids: !0,
|
|
1228
1441
|
match: (node) => node._type === types.span.name || // Text children
|
|
1229
1442
|
!editor.isTextBlock(node) && Element$1.isElement(node)
|
|
1230
|
-
})), editor.children.length === 0 && (editor.children = [editor.
|
|
1443
|
+
})), editor.children.length === 0 && (editor.children = [editor.pteCreateTextBlock({ decorators: [] })]), editor.onChange();
|
|
1231
1444
|
}
|
|
1232
1445
|
}
|
|
1233
1446
|
},
|
|
1234
1447
|
removeAnnotation: (type) => {
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
if (selection && Range.isExpanded(selection)) {
|
|
1243
|
-
if (selection = editor.selection, !selection)
|
|
1448
|
+
debug$j("Removing annotation", type), Editor.withoutNormalizing(editor, () => {
|
|
1449
|
+
if (editor.selection)
|
|
1450
|
+
if (Range.isCollapsed(editor.selection)) {
|
|
1451
|
+
const [block, blockPath] = Editor.node(editor, editor.selection, {
|
|
1452
|
+
depth: 1
|
|
1453
|
+
});
|
|
1454
|
+
if (!editor.isTextBlock(block))
|
|
1244
1455
|
return;
|
|
1245
|
-
[
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1456
|
+
const potentialAnnotations = (block.markDefs ?? []).filter(
|
|
1457
|
+
(markDef) => markDef._type === type.name
|
|
1458
|
+
), [selectedChild, selectedChildPath] = Editor.node(
|
|
1459
|
+
editor,
|
|
1460
|
+
editor.selection,
|
|
1461
|
+
{
|
|
1462
|
+
depth: 2
|
|
1463
|
+
}
|
|
1464
|
+
);
|
|
1465
|
+
if (!editor.isTextSpan(selectedChild))
|
|
1466
|
+
return;
|
|
1467
|
+
const annotationToRemove = selectedChild.marks?.find(
|
|
1468
|
+
(mark) => potentialAnnotations.some((markDef) => markDef._key === mark)
|
|
1469
|
+
);
|
|
1470
|
+
if (!annotationToRemove)
|
|
1471
|
+
return;
|
|
1472
|
+
const previousSpansWithSameAnnotation = [];
|
|
1473
|
+
for (const [child, childPath] of Node.children(editor, blockPath, {
|
|
1474
|
+
reverse: !0
|
|
1475
|
+
}))
|
|
1476
|
+
if (editor.isTextSpan(child) && Path.isBefore(childPath, selectedChildPath))
|
|
1477
|
+
if (child.marks?.includes(annotationToRemove))
|
|
1478
|
+
previousSpansWithSameAnnotation.push([child, childPath]);
|
|
1479
|
+
else
|
|
1480
|
+
break;
|
|
1481
|
+
const nextSpansWithSameAnnotation = [];
|
|
1482
|
+
for (const [child, childPath] of Node.children(editor, blockPath))
|
|
1483
|
+
if (editor.isTextSpan(child) && Path.isAfter(childPath, selectedChildPath))
|
|
1484
|
+
if (child.marks?.includes(annotationToRemove))
|
|
1485
|
+
nextSpansWithSameAnnotation.push([child, childPath]);
|
|
1486
|
+
else
|
|
1487
|
+
break;
|
|
1488
|
+
for (const [child, childPath] of [
|
|
1489
|
+
...previousSpansWithSameAnnotation,
|
|
1490
|
+
[selectedChild, selectedChildPath],
|
|
1491
|
+
...nextSpansWithSameAnnotation
|
|
1492
|
+
])
|
|
1493
|
+
Transforms.setNodes(
|
|
1494
|
+
editor,
|
|
1495
|
+
{
|
|
1496
|
+
marks: child.marks?.filter(
|
|
1497
|
+
(mark) => mark !== annotationToRemove
|
|
1498
|
+
)
|
|
1499
|
+
},
|
|
1500
|
+
{ at: childPath }
|
|
1501
|
+
);
|
|
1502
|
+
} else {
|
|
1503
|
+
Transforms.setNodes(
|
|
1504
|
+
editor,
|
|
1505
|
+
{},
|
|
1506
|
+
{
|
|
1507
|
+
match: (node) => editor.isTextSpan(node),
|
|
1508
|
+
split: !0,
|
|
1509
|
+
hanging: !0
|
|
1510
|
+
}
|
|
1511
|
+
);
|
|
1512
|
+
const blocks = Editor.nodes(editor, {
|
|
1513
|
+
at: editor.selection,
|
|
1514
|
+
match: (node) => editor.isTextBlock(node)
|
|
1254
1515
|
});
|
|
1516
|
+
for (const [block, blockPath] of blocks) {
|
|
1517
|
+
const children = Node.children(editor, blockPath);
|
|
1518
|
+
for (const [child, childPath] of children) {
|
|
1519
|
+
if (!editor.isTextSpan(child) || !Range.includes(editor.selection, childPath))
|
|
1520
|
+
continue;
|
|
1521
|
+
const markDefs = block.markDefs ?? [], marks = child.marks ?? [], marksWithoutAnnotation = marks.filter((mark) => markDefs.find(
|
|
1522
|
+
(markDef2) => markDef2._key === mark
|
|
1523
|
+
)?._type !== type.name);
|
|
1524
|
+
marksWithoutAnnotation.length !== marks.length && Transforms.setNodes(
|
|
1525
|
+
editor,
|
|
1526
|
+
{
|
|
1527
|
+
marks: marksWithoutAnnotation
|
|
1528
|
+
},
|
|
1529
|
+
{ at: childPath }
|
|
1530
|
+
);
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1255
1533
|
}
|
|
1256
|
-
|
|
1257
|
-
}
|
|
1534
|
+
}), editor.onChange();
|
|
1258
1535
|
},
|
|
1259
1536
|
getSelection: () => {
|
|
1260
1537
|
let ptRange = null;
|
|
@@ -1263,14 +1540,22 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1263
1540
|
if (existing)
|
|
1264
1541
|
return existing;
|
|
1265
1542
|
ptRange = toPortableTextRange(
|
|
1266
|
-
fromSlateValue(
|
|
1543
|
+
fromSlateValue(
|
|
1544
|
+
editor.children,
|
|
1545
|
+
types.block.name,
|
|
1546
|
+
KEY_TO_VALUE_ELEMENT.get(editor)
|
|
1547
|
+
),
|
|
1267
1548
|
editor.selection,
|
|
1268
1549
|
types
|
|
1269
1550
|
), SLATE_TO_PORTABLE_TEXT_RANGE.set(editor.selection, ptRange);
|
|
1270
1551
|
}
|
|
1271
1552
|
return ptRange;
|
|
1272
1553
|
},
|
|
1273
|
-
getValue: () => fromSlateValue(
|
|
1554
|
+
getValue: () => fromSlateValue(
|
|
1555
|
+
editor.children,
|
|
1556
|
+
types.block.name,
|
|
1557
|
+
KEY_TO_VALUE_ELEMENT.get(editor)
|
|
1558
|
+
),
|
|
1274
1559
|
isCollapsedSelection: () => !!editor.selection && Range.isCollapsed(editor.selection),
|
|
1275
1560
|
isExpandedSelection: () => !!editor.selection && Range.isExpanded(editor.selection),
|
|
1276
1561
|
insertBreak: () => {
|
|
@@ -1284,23 +1569,94 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1284
1569
|
}), editor;
|
|
1285
1570
|
};
|
|
1286
1571
|
}
|
|
1287
|
-
function createWithInsertBreak(types) {
|
|
1572
|
+
function createWithInsertBreak(types, keyGenerator) {
|
|
1288
1573
|
return function(editor) {
|
|
1289
1574
|
const { insertBreak } = editor;
|
|
1290
1575
|
return editor.insertBreak = () => {
|
|
1291
|
-
if (editor.selection) {
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1576
|
+
if (!editor.selection) {
|
|
1577
|
+
insertBreak();
|
|
1578
|
+
return;
|
|
1579
|
+
}
|
|
1580
|
+
const focusBlockPath = editor.selection.focus.path.slice(0, 1), focusBlock = Node.descendant(editor, focusBlockPath);
|
|
1581
|
+
if (editor.isTextBlock(focusBlock)) {
|
|
1582
|
+
const [start, end] = Range.edges(editor.selection), isEndAtStartOfBlock = isEqual(end, {
|
|
1583
|
+
path: [...focusBlockPath, 0],
|
|
1584
|
+
offset: 0
|
|
1585
|
+
});
|
|
1586
|
+
if (isEndAtStartOfBlock && Range.isCollapsed(editor.selection)) {
|
|
1587
|
+
const focusDecorators = editor.isTextSpan(focusBlock.children[0]) ? (focusBlock.children[0].marks ?? []).filter(
|
|
1588
|
+
(mark) => types.decorators.some((decorator) => decorator.value === mark)
|
|
1589
|
+
) : [];
|
|
1590
|
+
Editor.insertNode(
|
|
1591
|
+
editor,
|
|
1592
|
+
editor.pteCreateTextBlock({ decorators: focusDecorators })
|
|
1593
|
+
);
|
|
1594
|
+
const [nextBlockPath] = Path.next(focusBlockPath);
|
|
1595
|
+
Transforms.select(editor, {
|
|
1596
|
+
anchor: { path: [nextBlockPath, 0], offset: 0 },
|
|
1597
|
+
focus: { path: [nextBlockPath, 0], offset: 0 }
|
|
1598
|
+
}), editor.onChange();
|
|
1599
|
+
return;
|
|
1600
|
+
}
|
|
1601
|
+
const lastFocusBlockChild = focusBlock.children[focusBlock.children.length - 1], isStartAtEndOfBlock = isEqual(start, {
|
|
1602
|
+
path: [...focusBlockPath, focusBlock.children.length - 1],
|
|
1603
|
+
offset: editor.isTextSpan(lastFocusBlockChild) ? lastFocusBlockChild.text.length : 0
|
|
1604
|
+
});
|
|
1605
|
+
if (!isEndAtStartOfBlock && !isStartAtEndOfBlock) {
|
|
1606
|
+
Editor.withoutNormalizing(editor, () => {
|
|
1607
|
+
if (!editor.selection)
|
|
1608
|
+
return;
|
|
1609
|
+
Transforms.splitNodes(editor, {
|
|
1610
|
+
at: editor.selection
|
|
1611
|
+
});
|
|
1612
|
+
const [nextNode, nextNodePath] = Editor.node(
|
|
1613
|
+
editor,
|
|
1614
|
+
Path.next(focusBlockPath),
|
|
1615
|
+
{ depth: 1 }
|
|
1616
|
+
);
|
|
1617
|
+
if (Transforms.setSelection(editor, {
|
|
1618
|
+
anchor: { path: [...nextNodePath, 0], offset: 0 },
|
|
1619
|
+
focus: { path: [...nextNodePath, 0], offset: 0 }
|
|
1620
|
+
}), editor.isTextBlock(nextNode) && nextNode.markDefs && nextNode.markDefs.length > 0) {
|
|
1621
|
+
const newMarkDefKeys = /* @__PURE__ */ new Map(), prevNodeSpans = Array.from(
|
|
1622
|
+
Node.children(editor, focusBlockPath)
|
|
1623
|
+
).map((entry) => entry[0]).filter((node) => editor.isTextSpan(node)), children = Node.children(editor, nextNodePath);
|
|
1624
|
+
for (const [child, childPath] of children) {
|
|
1625
|
+
if (!editor.isTextSpan(child))
|
|
1626
|
+
continue;
|
|
1627
|
+
const marks = child.marks ?? [];
|
|
1628
|
+
for (const mark of marks)
|
|
1629
|
+
types.decorators.some(
|
|
1630
|
+
(decorator) => decorator.value === mark
|
|
1631
|
+
) || prevNodeSpans.some(
|
|
1632
|
+
(prevNodeSpan) => prevNodeSpan.marks?.includes(mark)
|
|
1633
|
+
) && !newMarkDefKeys.has(mark) && newMarkDefKeys.set(mark, keyGenerator());
|
|
1634
|
+
const newMarks = marks.map(
|
|
1635
|
+
(mark) => newMarkDefKeys.get(mark) ?? mark
|
|
1636
|
+
);
|
|
1637
|
+
isEqual(marks, newMarks) || Transforms.setNodes(
|
|
1638
|
+
editor,
|
|
1639
|
+
{ marks: newMarks },
|
|
1640
|
+
{
|
|
1641
|
+
at: childPath
|
|
1642
|
+
}
|
|
1643
|
+
);
|
|
1644
|
+
}
|
|
1645
|
+
const newMarkDefs = nextNode.markDefs.map((markDef) => ({
|
|
1646
|
+
...markDef,
|
|
1647
|
+
_key: newMarkDefKeys.get(markDef._key) ?? markDef._key
|
|
1648
|
+
}));
|
|
1649
|
+
isEqual(nextNode.markDefs, newMarkDefs) || Transforms.setNodes(
|
|
1650
|
+
editor,
|
|
1651
|
+
{ markDefs: newMarkDefs },
|
|
1652
|
+
{
|
|
1653
|
+
at: nextNodePath,
|
|
1654
|
+
match: (node) => editor.isTextBlock(node)
|
|
1655
|
+
}
|
|
1656
|
+
);
|
|
1657
|
+
}
|
|
1658
|
+
}), editor.onChange();
|
|
1659
|
+
return;
|
|
1304
1660
|
}
|
|
1305
1661
|
}
|
|
1306
1662
|
insertBreak();
|
|
@@ -2102,9 +2458,11 @@ function createApplyPatch(schemaTypes) {
|
|
|
2102
2458
|
let previousPatch;
|
|
2103
2459
|
return function(editor, patch) {
|
|
2104
2460
|
let changed = !1;
|
|
2105
|
-
debugVerbose$4 && (debug$i(
|
|
2461
|
+
debugVerbose$4 && (debug$i(
|
|
2462
|
+
`
|
|
2106
2463
|
|
|
2107
|
-
NEW PATCH =============================================================`
|
|
2464
|
+
NEW PATCH =============================================================`
|
|
2465
|
+
), debug$i(JSON.stringify(patch, null, 2)));
|
|
2108
2466
|
try {
|
|
2109
2467
|
switch (patch.type) {
|
|
2110
2468
|
case "insert":
|
|
@@ -2129,14 +2487,19 @@ NEW PATCH =============================================================`), debug
|
|
|
2129
2487
|
};
|
|
2130
2488
|
}
|
|
2131
2489
|
function diffMatchPatch(editor, patch) {
|
|
2132
|
-
const { block, child, childPath } = findBlockAndChildFromPath(
|
|
2490
|
+
const { block, child, childPath } = findBlockAndChildFromPath(
|
|
2491
|
+
editor,
|
|
2492
|
+
patch.path
|
|
2493
|
+
);
|
|
2133
2494
|
if (!block)
|
|
2134
2495
|
return debug$i("Block not found"), !1;
|
|
2135
2496
|
if (!child || !childPath)
|
|
2136
2497
|
return debug$i("Child not found"), !1;
|
|
2137
2498
|
if (!(block && editor.isTextBlock(block) && patch.path.length === 4 && patch.path[1] === "children" && patch.path[3] === "text") || !Text.isText(child))
|
|
2138
2499
|
return !1;
|
|
2139
|
-
const patches = parse(patch.value), [newValue] = apply(patches, child.text, {
|
|
2500
|
+
const patches = parse(patch.value), [newValue] = apply(patches, child.text, {
|
|
2501
|
+
allowExceedingIndices: !0
|
|
2502
|
+
}), diff$1 = cleanupEfficiency(diff(child.text, newValue), 5);
|
|
2140
2503
|
debugState(editor, "before");
|
|
2141
2504
|
let offset = 0;
|
|
2142
2505
|
for (const [op, text] of diff$1)
|
|
@@ -2170,12 +2533,17 @@ function insertPatch(editor, patch, schemaTypes) {
|
|
|
2170
2533
|
{ schemaTypes },
|
|
2171
2534
|
KEY_TO_SLATE_ELEMENT.get(editor)
|
|
2172
2535
|
), targetChildIndex = targetChildPath[1], normalizedIdx = position === "after" ? targetChildIndex + 1 : targetChildIndex, childInsertPath = [targetChildPath[0], normalizedIdx];
|
|
2173
|
-
return debug$i(`Inserting children at path ${childInsertPath}`), debugState(editor, "before"), childrenToInsert && Element$1.isElement(childrenToInsert[0]) && Transforms.insertNodes(editor, childrenToInsert[0].children, {
|
|
2536
|
+
return debug$i(`Inserting children at path ${childInsertPath}`), debugState(editor, "before"), childrenToInsert && Element$1.isElement(childrenToInsert[0]) && Transforms.insertNodes(editor, childrenToInsert[0].children, {
|
|
2537
|
+
at: childInsertPath
|
|
2538
|
+
}), debugState(editor, "after"), !0;
|
|
2174
2539
|
}
|
|
2175
2540
|
function setPatch(editor, patch) {
|
|
2176
2541
|
let value = patch.value;
|
|
2177
2542
|
typeof patch.path[3] == "string" && (value = {}, value[patch.path[3]] = patch.value);
|
|
2178
|
-
const { block, blockPath, child, childPath } = findBlockAndChildFromPath(
|
|
2543
|
+
const { block, blockPath, child, childPath } = findBlockAndChildFromPath(
|
|
2544
|
+
editor,
|
|
2545
|
+
patch.path
|
|
2546
|
+
);
|
|
2179
2547
|
if (!block)
|
|
2180
2548
|
return debug$i("Block not found"), !1;
|
|
2181
2549
|
const isTextBlock = editor.isTextBlock(block);
|
|
@@ -2236,12 +2604,15 @@ function unsetPatch(editor, patch, previousPatch) {
|
|
|
2236
2604
|
const previousSelection = editor.selection;
|
|
2237
2605
|
return Transforms.deselect(editor), editor.children.forEach((c, i) => {
|
|
2238
2606
|
Transforms.removeNodes(editor, { at: [i] });
|
|
2239
|
-
}), Transforms.insertNodes(editor, editor.
|
|
2607
|
+
}), Transforms.insertNodes(editor, editor.pteCreateTextBlock({ decorators: [] })), previousSelection && Transforms.select(editor, {
|
|
2240
2608
|
anchor: { path: [0, 0], offset: 0 },
|
|
2241
2609
|
focus: { path: [0, 0], offset: 0 }
|
|
2242
2610
|
}), editor.onChange(), debugState(editor, "after"), !0;
|
|
2243
2611
|
}
|
|
2244
|
-
const { block, blockPath, child, childPath } = findBlockAndChildFromPath(
|
|
2612
|
+
const { block, blockPath, child, childPath } = findBlockAndChildFromPath(
|
|
2613
|
+
editor,
|
|
2614
|
+
patch.path
|
|
2615
|
+
);
|
|
2245
2616
|
if (patch.path.length === 1) {
|
|
2246
2617
|
if (!block || !blockPath)
|
|
2247
2618
|
return debug$i("Block not found"), !1;
|
|
@@ -2273,7 +2644,12 @@ function findBlockAndChildFromPath(editor, path) {
|
|
|
2273
2644
|
const isMatch = isKeyedSegment(path[2]) ? node._key === path[2]._key : index === path[2];
|
|
2274
2645
|
return isMatch && (childIndex = index), isMatch;
|
|
2275
2646
|
});
|
|
2276
|
-
return child ? {
|
|
2647
|
+
return child ? {
|
|
2648
|
+
block,
|
|
2649
|
+
child,
|
|
2650
|
+
blockPath,
|
|
2651
|
+
childPath: blockPath?.concat(childIndex)
|
|
2652
|
+
} : { block, blockPath, child: void 0, childPath: void 0 };
|
|
2277
2653
|
}
|
|
2278
2654
|
const PATCHING = /* @__PURE__ */ new WeakMap();
|
|
2279
2655
|
function withoutPatching(editor, fn) {
|
|
@@ -2302,10 +2678,17 @@ function createWithUndoRedo(options) {
|
|
|
2302
2678
|
patches.forEach((patch) => {
|
|
2303
2679
|
if (!reset && patch.origin !== "local" && remotePatches) {
|
|
2304
2680
|
if (patch.type === "unset" && patch.path.length === 0) {
|
|
2305
|
-
debug$h(
|
|
2681
|
+
debug$h(
|
|
2682
|
+
"Someone else cleared the content, resetting undo/redo history"
|
|
2683
|
+
), editor.history = { undos: [], redos: [] }, remotePatches.splice(0, remotePatches.length), SAVING.set(editor, !0), reset = !0;
|
|
2306
2684
|
return;
|
|
2307
2685
|
}
|
|
2308
|
-
remotePatches.push({
|
|
2686
|
+
remotePatches.push({
|
|
2687
|
+
patch,
|
|
2688
|
+
time: /* @__PURE__ */ new Date(),
|
|
2689
|
+
snapshot,
|
|
2690
|
+
previousSnapshot
|
|
2691
|
+
});
|
|
2309
2692
|
}
|
|
2310
2693
|
}), previousSnapshot = snapshot;
|
|
2311
2694
|
});
|
|
@@ -2326,7 +2709,10 @@ function createWithUndoRedo(options) {
|
|
|
2326
2709
|
step.operations.push(op);
|
|
2327
2710
|
else {
|
|
2328
2711
|
const newStep = {
|
|
2329
|
-
operations: [
|
|
2712
|
+
operations: [
|
|
2713
|
+
...editor.selection === null ? [] : [createSelectOperation(editor)],
|
|
2714
|
+
op
|
|
2715
|
+
],
|
|
2330
2716
|
timestamp: /* @__PURE__ */ new Date()
|
|
2331
2717
|
};
|
|
2332
2718
|
undos.push(newStep), debug$h("Created new undo step", step);
|
|
@@ -2343,12 +2729,20 @@ function createWithUndoRedo(options) {
|
|
|
2343
2729
|
if (undos.length > 0) {
|
|
2344
2730
|
const step = undos[undos.length - 1];
|
|
2345
2731
|
if (debug$h("Undoing", step), step.operations.length > 0) {
|
|
2346
|
-
const otherPatches = remotePatches.filter(
|
|
2732
|
+
const otherPatches = remotePatches.filter(
|
|
2733
|
+
(item) => item.time >= step.timestamp
|
|
2734
|
+
);
|
|
2347
2735
|
let transformedOperations = step.operations;
|
|
2348
2736
|
otherPatches.forEach((item) => {
|
|
2349
2737
|
transformedOperations = flatten(
|
|
2350
2738
|
transformedOperations.map(
|
|
2351
|
-
(op) => transformOperation(
|
|
2739
|
+
(op) => transformOperation(
|
|
2740
|
+
editor,
|
|
2741
|
+
item.patch,
|
|
2742
|
+
op,
|
|
2743
|
+
item.snapshot,
|
|
2744
|
+
item.previousSnapshot
|
|
2745
|
+
)
|
|
2352
2746
|
)
|
|
2353
2747
|
);
|
|
2354
2748
|
});
|
|
@@ -2377,12 +2771,20 @@ function createWithUndoRedo(options) {
|
|
|
2377
2771
|
if (redos.length > 0) {
|
|
2378
2772
|
const step = redos[redos.length - 1];
|
|
2379
2773
|
if (debug$h("Redoing", step), step.operations.length > 0) {
|
|
2380
|
-
const otherPatches = remotePatches.filter(
|
|
2774
|
+
const otherPatches = remotePatches.filter(
|
|
2775
|
+
(item) => item.time >= step.timestamp
|
|
2776
|
+
);
|
|
2381
2777
|
let transformedOperations = step.operations;
|
|
2382
2778
|
otherPatches.forEach((item) => {
|
|
2383
2779
|
transformedOperations = flatten(
|
|
2384
2780
|
transformedOperations.map(
|
|
2385
|
-
(op) => transformOperation(
|
|
2781
|
+
(op) => transformOperation(
|
|
2782
|
+
editor,
|
|
2783
|
+
item.patch,
|
|
2784
|
+
op,
|
|
2785
|
+
item.snapshot,
|
|
2786
|
+
item.previousSnapshot
|
|
2787
|
+
)
|
|
2386
2788
|
)
|
|
2387
2789
|
);
|
|
2388
2790
|
});
|
|
@@ -2407,7 +2809,9 @@ function createWithUndoRedo(options) {
|
|
|
2407
2809
|
};
|
|
2408
2810
|
}
|
|
2409
2811
|
function transformOperation(editor, patch, operation, snapshot, previousSnapshot) {
|
|
2410
|
-
debugVerbose$3 && (debug$h(
|
|
2812
|
+
debugVerbose$3 && (debug$h(
|
|
2813
|
+
`Adjusting '${operation.type}' operation paths for '${patch.type}' patch`
|
|
2814
|
+
), debug$h(`Operation ${JSON.stringify(operation)}`), debug$h(`Patch ${JSON.stringify(patch)}`));
|
|
2411
2815
|
const transformedOperation = { ...operation };
|
|
2412
2816
|
if (patch.type === "insert" && patch.path.length === 1) {
|
|
2413
2817
|
const insertBlockIndex = (snapshot || []).findIndex(
|
|
@@ -2415,7 +2819,13 @@ function transformOperation(editor, patch, operation, snapshot, previousSnapshot
|
|
|
2415
2819
|
);
|
|
2416
2820
|
return debug$h(
|
|
2417
2821
|
`Adjusting block path (+${patch.items.length}) for '${transformedOperation.type}' operation and patch '${patch.type}'`
|
|
2418
|
-
), [
|
|
2822
|
+
), [
|
|
2823
|
+
adjustBlockPath(
|
|
2824
|
+
transformedOperation,
|
|
2825
|
+
patch.items.length,
|
|
2826
|
+
insertBlockIndex
|
|
2827
|
+
)
|
|
2828
|
+
];
|
|
2419
2829
|
}
|
|
2420
2830
|
if (patch.type === "unset" && patch.path.length === 1) {
|
|
2421
2831
|
const unsetBlockIndex = (previousSnapshot || []).findIndex(
|
|
@@ -2426,9 +2836,14 @@ function transformOperation(editor, patch, operation, snapshot, previousSnapshot
|
|
|
2426
2836
|
)), [adjustBlockPath(transformedOperation, -1, unsetBlockIndex)]);
|
|
2427
2837
|
}
|
|
2428
2838
|
if (patch.type === "unset" && patch.path.length === 0)
|
|
2429
|
-
return debug$h(
|
|
2839
|
+
return debug$h(
|
|
2840
|
+
`Adjusting selection for unset everything patch and ${operation.type} operation`
|
|
2841
|
+
), [];
|
|
2430
2842
|
if (patch.type === "diffMatchPatch") {
|
|
2431
|
-
const operationTargetBlock = findOperationTargetBlock(
|
|
2843
|
+
const operationTargetBlock = findOperationTargetBlock(
|
|
2844
|
+
editor,
|
|
2845
|
+
transformedOperation
|
|
2846
|
+
);
|
|
2432
2847
|
return !operationTargetBlock || !isEqual({ _key: operationTargetBlock._key }, patch.path[0]) ? [transformedOperation] : (parse(patch.value).forEach((diffPatch) => {
|
|
2433
2848
|
let adjustOffsetBy = 0, changedOffset = diffPatch.utf8Start1;
|
|
2434
2849
|
const { diffs } = diffPatch;
|
|
@@ -2454,7 +2869,10 @@ function transformOperation(editor, patch, operation, snapshot, previousSnapshot
|
|
|
2454
2869
|
function adjustBlockPath(operation, level, blockIndex) {
|
|
2455
2870
|
const transformedOperation = { ...operation };
|
|
2456
2871
|
if (blockIndex >= 0 && transformedOperation.type !== "set_selection" && Array.isArray(transformedOperation.path) && transformedOperation.path[0] >= blockIndex + level && transformedOperation.path[0] + level > -1) {
|
|
2457
|
-
const newPath = [
|
|
2872
|
+
const newPath = [
|
|
2873
|
+
transformedOperation.path[0] + level,
|
|
2874
|
+
...transformedOperation.path.slice(1)
|
|
2875
|
+
];
|
|
2458
2876
|
transformedOperation.path = newPath;
|
|
2459
2877
|
}
|
|
2460
2878
|
if (transformedOperation.type === "set_selection") {
|
|
@@ -2542,31 +2960,51 @@ function createWithPatches({
|
|
|
2542
2960
|
case "insert_text":
|
|
2543
2961
|
patches = [
|
|
2544
2962
|
...patches,
|
|
2545
|
-
...patchFunctions.insertTextPatch(
|
|
2963
|
+
...patchFunctions.insertTextPatch(
|
|
2964
|
+
editor,
|
|
2965
|
+
operation,
|
|
2966
|
+
previousChildren
|
|
2967
|
+
)
|
|
2546
2968
|
];
|
|
2547
2969
|
break;
|
|
2548
2970
|
case "remove_text":
|
|
2549
2971
|
patches = [
|
|
2550
2972
|
...patches,
|
|
2551
|
-
...patchFunctions.removeTextPatch(
|
|
2973
|
+
...patchFunctions.removeTextPatch(
|
|
2974
|
+
editor,
|
|
2975
|
+
operation,
|
|
2976
|
+
previousChildren
|
|
2977
|
+
)
|
|
2552
2978
|
];
|
|
2553
2979
|
break;
|
|
2554
2980
|
case "remove_node":
|
|
2555
2981
|
patches = [
|
|
2556
2982
|
...patches,
|
|
2557
|
-
...patchFunctions.removeNodePatch(
|
|
2983
|
+
...patchFunctions.removeNodePatch(
|
|
2984
|
+
editor,
|
|
2985
|
+
operation,
|
|
2986
|
+
previousChildren
|
|
2987
|
+
)
|
|
2558
2988
|
];
|
|
2559
2989
|
break;
|
|
2560
2990
|
case "split_node":
|
|
2561
2991
|
patches = [
|
|
2562
2992
|
...patches,
|
|
2563
|
-
...patchFunctions.splitNodePatch(
|
|
2993
|
+
...patchFunctions.splitNodePatch(
|
|
2994
|
+
editor,
|
|
2995
|
+
operation,
|
|
2996
|
+
previousChildren
|
|
2997
|
+
)
|
|
2564
2998
|
];
|
|
2565
2999
|
break;
|
|
2566
3000
|
case "insert_node":
|
|
2567
3001
|
patches = [
|
|
2568
3002
|
...patches,
|
|
2569
|
-
...patchFunctions.insertNodePatch(
|
|
3003
|
+
...patchFunctions.insertNodePatch(
|
|
3004
|
+
editor,
|
|
3005
|
+
operation,
|
|
3006
|
+
previousChildren
|
|
3007
|
+
)
|
|
2570
3008
|
];
|
|
2571
3009
|
break;
|
|
2572
3010
|
case "set_node":
|
|
@@ -2578,17 +3016,27 @@ function createWithPatches({
|
|
|
2578
3016
|
case "merge_node":
|
|
2579
3017
|
patches = [
|
|
2580
3018
|
...patches,
|
|
2581
|
-
...patchFunctions.mergeNodePatch(
|
|
3019
|
+
...patchFunctions.mergeNodePatch(
|
|
3020
|
+
editor,
|
|
3021
|
+
operation,
|
|
3022
|
+
previousChildren
|
|
3023
|
+
)
|
|
2582
3024
|
];
|
|
2583
3025
|
break;
|
|
2584
3026
|
case "move_node":
|
|
2585
3027
|
patches = [
|
|
2586
3028
|
...patches,
|
|
2587
|
-
...patchFunctions.moveNodePatch(
|
|
3029
|
+
...patchFunctions.moveNodePatch(
|
|
3030
|
+
editor,
|
|
3031
|
+
operation,
|
|
3032
|
+
previousChildren
|
|
3033
|
+
)
|
|
2588
3034
|
];
|
|
2589
3035
|
break;
|
|
2590
3036
|
}
|
|
2591
|
-
return !editorWasEmpty && editorIsEmpty && ["merge_node", "set_node", "remove_text", "remove_node"].includes(
|
|
3037
|
+
return !editorWasEmpty && editorIsEmpty && ["merge_node", "set_node", "remove_text", "remove_node"].includes(
|
|
3038
|
+
operation.type
|
|
3039
|
+
) && (patches = [...patches, unset([])], change$.next({
|
|
2592
3040
|
type: "unset",
|
|
2593
3041
|
previousValue: fromSlateValue(
|
|
2594
3042
|
previousChildren,
|
|
@@ -2621,7 +3069,10 @@ function createWithPlaceholderBlock() {
|
|
|
2621
3069
|
const node = op.node;
|
|
2622
3070
|
if (op.path[0] === 0 && Editor.isVoid(editor, node)) {
|
|
2623
3071
|
const nextPath = Path.next(op.path);
|
|
2624
|
-
editor.children[nextPath[0]] || (debug$f("Adding placeholder block"), Editor.insertNode(
|
|
3072
|
+
editor.children[nextPath[0]] || (debug$f("Adding placeholder block"), Editor.insertNode(
|
|
3073
|
+
editor,
|
|
3074
|
+
editor.pteCreateTextBlock({ decorators: [] })
|
|
3075
|
+
));
|
|
2625
3076
|
}
|
|
2626
3077
|
}
|
|
2627
3078
|
apply2(op);
|
|
@@ -2640,7 +3091,11 @@ function createWithPortableTextBlockStyle(types) {
|
|
|
2640
3091
|
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)) {
|
|
2641
3092
|
const [child] = Editor.node(editor, [op.path[0] + 1, 0]);
|
|
2642
3093
|
if (Text.isText(child) && child.text === "") {
|
|
2643
|
-
debug$e(`Normalizing split node to ${defaultStyle} style`, op), Transforms.setNodes(
|
|
3094
|
+
debug$e(`Normalizing split node to ${defaultStyle} style`, op), Transforms.setNodes(
|
|
3095
|
+
editor,
|
|
3096
|
+
{ style: defaultStyle },
|
|
3097
|
+
{ at: [op.path[0] + 1], voids: !1 }
|
|
3098
|
+
);
|
|
2644
3099
|
break;
|
|
2645
3100
|
}
|
|
2646
3101
|
}
|
|
@@ -2656,9 +3111,13 @@ function createWithPortableTextBlockStyle(types) {
|
|
|
2656
3111
|
match: (node) => editor.isTextBlock(node)
|
|
2657
3112
|
})
|
|
2658
3113
|
].forEach(([node, path]) => {
|
|
2659
|
-
editor.isTextBlock(node) && node.style === blockStyle ? (debug$e(`Unsetting block style '${blockStyle}'`), Transforms.setNodes(
|
|
2660
|
-
|
|
2661
|
-
|
|
3114
|
+
editor.isTextBlock(node) && node.style === blockStyle ? (debug$e(`Unsetting block style '${blockStyle}'`), Transforms.setNodes(
|
|
3115
|
+
editor,
|
|
3116
|
+
{ ...node, style: defaultStyle },
|
|
3117
|
+
{
|
|
3118
|
+
at: path
|
|
3119
|
+
}
|
|
3120
|
+
)) : (blockStyle ? debug$e(`Setting style '${blockStyle}'`) : debug$e("Setting default style", defaultStyle), Transforms.setNodes(
|
|
2662
3121
|
editor,
|
|
2663
3122
|
{
|
|
2664
3123
|
...node,
|
|
@@ -2740,7 +3199,13 @@ function createWithPortableTextLists(types) {
|
|
|
2740
3199
|
return selectedBlocks.length === 0 ? !1 : (selectedBlocks.forEach(([node, path]) => {
|
|
2741
3200
|
if (editor.isListBlock(node)) {
|
|
2742
3201
|
let level = node.level || 1;
|
|
2743
|
-
reverse ? (level--, debug$d(
|
|
3202
|
+
reverse ? (level--, debug$d(
|
|
3203
|
+
"Decrementing list level",
|
|
3204
|
+
Math.min(MAX_LIST_LEVEL, Math.max(1, level))
|
|
3205
|
+
)) : (level++, debug$d(
|
|
3206
|
+
"Incrementing list level",
|
|
3207
|
+
Math.min(MAX_LIST_LEVEL, Math.max(1, level))
|
|
3208
|
+
)), Transforms.setNodes(
|
|
2744
3209
|
editor,
|
|
2745
3210
|
{ level: Math.min(MAX_LIST_LEVEL, Math.max(1, level)) },
|
|
2746
3211
|
{ at: path }
|
|
@@ -2782,11 +3247,15 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
2782
3247
|
return function(editor) {
|
|
2783
3248
|
const { apply: apply2, normalizeNode } = editor, decorators = types.decorators.map((t) => t.value), forceNewSelection = () => {
|
|
2784
3249
|
editor.selection && (Transforms.select(editor, { ...editor.selection }), editor.selection = { ...editor.selection });
|
|
2785
|
-
const ptRange = toPortableTextRange(
|
|
3250
|
+
const ptRange = toPortableTextRange(
|
|
3251
|
+
editor.children,
|
|
3252
|
+
editor.selection,
|
|
3253
|
+
types
|
|
3254
|
+
);
|
|
2786
3255
|
change$.next({ type: "selection", selection: ptRange });
|
|
2787
3256
|
};
|
|
2788
3257
|
return editor.normalizeNode = (nodeEntry) => {
|
|
2789
|
-
const [node, path] = nodeEntry
|
|
3258
|
+
const [node, path] = nodeEntry;
|
|
2790
3259
|
if (editor.isTextBlock(node)) {
|
|
2791
3260
|
const children = Node.children(editor, path);
|
|
2792
3261
|
for (const [child, childPath] of children) {
|
|
@@ -2796,73 +3265,80 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
2796
3265
|
"Merging spans",
|
|
2797
3266
|
JSON.stringify(child, null, 2),
|
|
2798
3267
|
JSON.stringify(nextNode, null, 2)
|
|
2799
|
-
), Transforms.mergeNodes(editor, {
|
|
3268
|
+
), Transforms.mergeNodes(editor, {
|
|
3269
|
+
at: [childPath[0], childPath[1] + 1],
|
|
3270
|
+
voids: !0
|
|
3271
|
+
});
|
|
2800
3272
|
return;
|
|
2801
3273
|
}
|
|
2802
3274
|
}
|
|
2803
3275
|
}
|
|
2804
|
-
if (
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
3276
|
+
if (editor.isTextBlock(node) && !Array.isArray(node.markDefs)) {
|
|
3277
|
+
debug$c("Adding .markDefs to block node"), Transforms.setNodes(editor, { markDefs: [] }, { at: path });
|
|
3278
|
+
return;
|
|
3279
|
+
}
|
|
3280
|
+
if (editor.isTextSpan(node) && !Array.isArray(node.marks)) {
|
|
3281
|
+
debug$c("Adding .marks to span node"), Transforms.setNodes(editor, { marks: [] }, { at: path });
|
|
3282
|
+
return;
|
|
3283
|
+
}
|
|
3284
|
+
if (editor.isTextSpan(node)) {
|
|
3285
|
+
const blockPath = Path.parent(path), [block] = Editor.node(editor, blockPath), decorators2 = types.decorators.map((decorator) => decorator.value), annotations = node.marks?.filter(
|
|
3286
|
+
(mark) => !decorators2.includes(mark)
|
|
3287
|
+
);
|
|
3288
|
+
if (editor.isTextBlock(block) && node.text === "" && annotations && annotations.length > 0) {
|
|
3289
|
+
debug$c("Removing annotations from empty span node"), Transforms.setNodes(
|
|
3290
|
+
editor,
|
|
3291
|
+
{ marks: node.marks?.filter((mark) => decorators2.includes(mark)) },
|
|
3292
|
+
{ at: path }
|
|
2812
3293
|
);
|
|
2813
|
-
|
|
2814
|
-
const [block] = Editor.node(editor, Path.parent(path)), orphanedMarks = editor.isTextBlock(block) && annotationMarks.filter(
|
|
2815
|
-
(mark) => !block.markDefs?.find((def) => def._key === mark)
|
|
2816
|
-
) || [];
|
|
2817
|
-
if (orphanedMarks.length > 0) {
|
|
2818
|
-
debug$c("Removing orphaned .marks from span node"), Transforms.setNodes(
|
|
2819
|
-
editor,
|
|
2820
|
-
{ marks: spanMarks.filter((mark) => !orphanedMarks.includes(mark)) },
|
|
2821
|
-
{ at: path }
|
|
2822
|
-
);
|
|
2823
|
-
return;
|
|
2824
|
-
}
|
|
2825
|
-
}
|
|
3294
|
+
return;
|
|
2826
3295
|
}
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
}
|
|
2836
|
-
}
|
|
2837
|
-
}
|
|
2838
|
-
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) {
|
|
2839
|
-
const [targetBlock, targetPath] = Editor.node(editor, [op.path[0] + 1]);
|
|
2840
|
-
if (debug$c("Copying markDefs over to split block", op), editor.isTextBlock(targetBlock)) {
|
|
2841
|
-
const oldDefs = Array.isArray(targetBlock.markDefs) && targetBlock.markDefs || [];
|
|
2842
|
-
Transforms.setNodes(
|
|
3296
|
+
}
|
|
3297
|
+
if (editor.isTextBlock(node)) {
|
|
3298
|
+
const decorators2 = types.decorators.map((decorator) => decorator.value);
|
|
3299
|
+
for (const [child, childPath] of Node.children(editor, path))
|
|
3300
|
+
if (editor.isTextSpan(child)) {
|
|
3301
|
+
const marks = child.marks ?? [], orphanedAnnotations = marks.filter((mark) => !decorators2.includes(mark) && !node.markDefs?.find((def) => def._key === mark));
|
|
3302
|
+
if (orphanedAnnotations.length > 0) {
|
|
3303
|
+
debug$c("Removing orphaned annotations from span node"), Transforms.setNodes(
|
|
2843
3304
|
editor,
|
|
2844
|
-
{
|
|
2845
|
-
|
|
3305
|
+
{
|
|
3306
|
+
marks: marks.filter(
|
|
3307
|
+
(mark) => !orphanedAnnotations.includes(mark)
|
|
3308
|
+
)
|
|
3309
|
+
},
|
|
3310
|
+
{ at: childPath }
|
|
2846
3311
|
);
|
|
2847
3312
|
return;
|
|
2848
3313
|
}
|
|
2849
3314
|
}
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
if (
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
3315
|
+
}
|
|
3316
|
+
if (editor.isTextSpan(node)) {
|
|
3317
|
+
const blockPath = Path.parent(path), [block] = Editor.node(editor, blockPath);
|
|
3318
|
+
if (editor.isTextBlock(block)) {
|
|
3319
|
+
const decorators2 = types.decorators.map(
|
|
3320
|
+
(decorator) => decorator.value
|
|
3321
|
+
), marks = node.marks ?? [], orphanedAnnotations = marks.filter((mark) => !decorators2.includes(mark) && !block.markDefs?.find((def) => def._key === mark));
|
|
3322
|
+
if (orphanedAnnotations.length > 0) {
|
|
3323
|
+
debug$c("Removing orphaned annotations from span node"), Transforms.setNodes(
|
|
3324
|
+
editor,
|
|
3325
|
+
{
|
|
3326
|
+
marks: marks.filter(
|
|
3327
|
+
(mark) => !orphanedAnnotations.includes(mark)
|
|
3328
|
+
)
|
|
3329
|
+
},
|
|
3330
|
+
{ at: path }
|
|
3331
|
+
);
|
|
3332
|
+
return;
|
|
2863
3333
|
}
|
|
2864
3334
|
}
|
|
2865
3335
|
}
|
|
3336
|
+
if (editor.isTextBlock(node)) {
|
|
3337
|
+
const markDefs = node.markDefs ?? [], markDefKeys = /* @__PURE__ */ new Set(), newMarkDefs = [];
|
|
3338
|
+
for (const markDef of markDefs)
|
|
3339
|
+
markDefKeys.has(markDef._key) || (markDefKeys.add(markDef._key), newMarkDefs.push(markDef));
|
|
3340
|
+
markDefs.length !== newMarkDefs.length && (debug$c("Removing duplicate markDefs"), Transforms.setNodes(editor, { markDefs: newMarkDefs }, { at: path }));
|
|
3341
|
+
}
|
|
2866
3342
|
if (editor.isTextBlock(node) && !editor.operations.some(
|
|
2867
3343
|
(op) => op.type === "merge_node" && "markDefs" in op.properties && op.path.length === 1
|
|
2868
3344
|
)) {
|
|
@@ -2890,7 +3366,9 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
2890
3366
|
}
|
|
2891
3367
|
if (op.type === "insert_text") {
|
|
2892
3368
|
const { selection } = editor;
|
|
2893
|
-
if (selection && Range.isCollapsed(selection) && Editor.marks(editor)?.marks?.some(
|
|
3369
|
+
if (selection && Range.isCollapsed(selection) && Editor.marks(editor)?.marks?.some(
|
|
3370
|
+
(mark) => !decorators.includes(mark)
|
|
3371
|
+
)) {
|
|
2894
3372
|
const [node] = Array.from(
|
|
2895
3373
|
Editor.nodes(editor, {
|
|
2896
3374
|
mode: "lowest",
|
|
@@ -2941,7 +3419,11 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
2941
3419
|
...Editor.marks(editor) || {}
|
|
2942
3420
|
}.marks || []).filter((mark) => decorators.includes(mark));
|
|
2943
3421
|
Editor.withoutNormalizing(editor, () => {
|
|
2944
|
-
apply2(op), Transforms.setNodes(
|
|
3422
|
+
apply2(op), Transforms.setNodes(
|
|
3423
|
+
editor,
|
|
3424
|
+
{ marks: marksWithoutAnnotationMarks },
|
|
3425
|
+
{ at: op.path }
|
|
3426
|
+
);
|
|
2945
3427
|
}), editor.onChange();
|
|
2946
3428
|
return;
|
|
2947
3429
|
}
|
|
@@ -2953,13 +3435,34 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
2953
3435
|
}
|
|
2954
3436
|
}
|
|
2955
3437
|
}
|
|
3438
|
+
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) {
|
|
3439
|
+
const [targetBlock, targetPath] = Editor.node(editor, [op.path[0] - 1]);
|
|
3440
|
+
if (editor.isTextBlock(targetBlock)) {
|
|
3441
|
+
const oldDefs = Array.isArray(targetBlock.markDefs) && targetBlock.markDefs || [], newMarkDefs = uniq([...oldDefs, ...op.properties.markDefs]);
|
|
3442
|
+
debug$c("Copying markDefs over to merged block", op), Transforms.setNodes(
|
|
3443
|
+
editor,
|
|
3444
|
+
{ markDefs: newMarkDefs },
|
|
3445
|
+
{ at: targetPath, voids: !1 }
|
|
3446
|
+
), apply2(op);
|
|
3447
|
+
return;
|
|
3448
|
+
}
|
|
3449
|
+
}
|
|
2956
3450
|
apply2(op);
|
|
2957
3451
|
}, editor.addMark = (mark) => {
|
|
2958
3452
|
if (editor.selection) {
|
|
2959
3453
|
if (Range.isExpanded(editor.selection))
|
|
2960
3454
|
Editor.withoutNormalizing(editor, () => {
|
|
2961
|
-
Transforms.setNodes(
|
|
2962
|
-
|
|
3455
|
+
Transforms.setNodes(
|
|
3456
|
+
editor,
|
|
3457
|
+
{},
|
|
3458
|
+
{ match: Text.isText, split: !0, hanging: !0 }
|
|
3459
|
+
);
|
|
3460
|
+
const splitTextNodes = Range.isRange(editor.selection) ? [
|
|
3461
|
+
...Editor.nodes(editor, {
|
|
3462
|
+
at: editor.selection,
|
|
3463
|
+
match: Text.isText
|
|
3464
|
+
})
|
|
3465
|
+
] : [];
|
|
2963
3466
|
splitTextNodes.length > 1 && splitTextNodes.every((node) => node[0].marks?.includes(mark)) ? editor.removeMark(mark) : splitTextNodes.forEach(([node, path]) => {
|
|
2964
3467
|
const marks = [
|
|
2965
3468
|
...(Array.isArray(node.marks) ? node.marks : []).filter(
|
|
@@ -2975,13 +3478,32 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
2975
3478
|
});
|
|
2976
3479
|
});
|
|
2977
3480
|
else {
|
|
2978
|
-
const
|
|
2979
|
-
|
|
2980
|
-
}.
|
|
2981
|
-
|
|
2982
|
-
marks
|
|
2983
|
-
|
|
2984
|
-
|
|
3481
|
+
const [block, blockPath] = Editor.node(editor, editor.selection, {
|
|
3482
|
+
depth: 1
|
|
3483
|
+
}), lonelyEmptySpan = editor.isTextBlock(block) && block.children.length === 1 && editor.isTextSpan(block.children[0]) && block.children[0].text === "" ? block.children[0] : void 0;
|
|
3484
|
+
if (lonelyEmptySpan) {
|
|
3485
|
+
const existingMarks = lonelyEmptySpan.marks ?? [], existingMarksWithoutDecorator = existingMarks.filter(
|
|
3486
|
+
(existingMark) => existingMark !== mark
|
|
3487
|
+
);
|
|
3488
|
+
Transforms.setNodes(
|
|
3489
|
+
editor,
|
|
3490
|
+
{
|
|
3491
|
+
marks: existingMarks.length === existingMarksWithoutDecorator.length ? [...existingMarks, mark] : existingMarksWithoutDecorator
|
|
3492
|
+
},
|
|
3493
|
+
{
|
|
3494
|
+
at: blockPath,
|
|
3495
|
+
match: (node) => editor.isTextSpan(node)
|
|
3496
|
+
}
|
|
3497
|
+
);
|
|
3498
|
+
} else {
|
|
3499
|
+
const existingMarks = {
|
|
3500
|
+
...Editor.marks(editor) || {}
|
|
3501
|
+
}.marks || [], marks = {
|
|
3502
|
+
...Editor.marks(editor) || {},
|
|
3503
|
+
marks: [...existingMarks, mark]
|
|
3504
|
+
};
|
|
3505
|
+
return editor.marks = marks, forceNewSelection(), editor;
|
|
3506
|
+
}
|
|
2985
3507
|
}
|
|
2986
3508
|
editor.onChange(), forceNewSelection();
|
|
2987
3509
|
}
|
|
@@ -2991,16 +3513,21 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
2991
3513
|
if (selection) {
|
|
2992
3514
|
if (Range.isExpanded(selection))
|
|
2993
3515
|
Editor.withoutNormalizing(editor, () => {
|
|
2994
|
-
Transforms.setNodes(
|
|
2995
|
-
|
|
3516
|
+
Transforms.setNodes(
|
|
3517
|
+
editor,
|
|
3518
|
+
{},
|
|
3519
|
+
{ match: Text.isText, split: !0, hanging: !0 }
|
|
3520
|
+
), editor.selection && [
|
|
3521
|
+
...Editor.nodes(editor, {
|
|
3522
|
+
at: editor.selection,
|
|
3523
|
+
match: Text.isText
|
|
3524
|
+
})
|
|
2996
3525
|
].forEach(([node, path]) => {
|
|
2997
3526
|
const block = editor.children[path[0]];
|
|
2998
3527
|
Element$1.isElement(block) && block.children.includes(node) && Transforms.setNodes(
|
|
2999
3528
|
editor,
|
|
3000
3529
|
{
|
|
3001
|
-
marks: (Array.isArray(node.marks) ? node.marks : []).filter(
|
|
3002
|
-
(eMark) => eMark !== mark
|
|
3003
|
-
),
|
|
3530
|
+
marks: (Array.isArray(node.marks) ? node.marks : []).filter((eMark) => eMark !== mark),
|
|
3004
3531
|
_type: "span"
|
|
3005
3532
|
},
|
|
3006
3533
|
{ at: path }
|
|
@@ -3008,13 +3535,32 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
3008
3535
|
});
|
|
3009
3536
|
}), Editor.normalize(editor);
|
|
3010
3537
|
else {
|
|
3011
|
-
const
|
|
3012
|
-
|
|
3013
|
-
}.
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3538
|
+
const [block, blockPath] = Editor.node(editor, selection, {
|
|
3539
|
+
depth: 1
|
|
3540
|
+
}), lonelyEmptySpan = editor.isTextBlock(block) && block.children.length === 1 && editor.isTextSpan(block.children[0]) && block.children[0].text === "" ? block.children[0] : void 0;
|
|
3541
|
+
if (lonelyEmptySpan) {
|
|
3542
|
+
const existingMarksWithoutDecorator = (lonelyEmptySpan.marks ?? []).filter(
|
|
3543
|
+
(existingMark) => existingMark !== mark
|
|
3544
|
+
);
|
|
3545
|
+
Transforms.setNodes(
|
|
3546
|
+
editor,
|
|
3547
|
+
{
|
|
3548
|
+
marks: existingMarksWithoutDecorator
|
|
3549
|
+
},
|
|
3550
|
+
{
|
|
3551
|
+
at: blockPath,
|
|
3552
|
+
match: (node) => editor.isTextSpan(node)
|
|
3553
|
+
}
|
|
3554
|
+
);
|
|
3555
|
+
} else {
|
|
3556
|
+
const existingMarks = {
|
|
3557
|
+
...Editor.marks(editor) || {}
|
|
3558
|
+
}.marks || [], marks = {
|
|
3559
|
+
...Editor.marks(editor) || {},
|
|
3560
|
+
marks: existingMarks.filter((eMark) => eMark !== mark)
|
|
3561
|
+
};
|
|
3562
|
+
return editor.marks = { marks: marks.marks, _type: "span" }, forceNewSelection(), editor;
|
|
3563
|
+
}
|
|
3018
3564
|
}
|
|
3019
3565
|
editor.onChange(), forceNewSelection();
|
|
3020
3566
|
}
|
|
@@ -3079,7 +3625,11 @@ function createWithSchemaTypes({
|
|
|
3079
3625
|
if (node._type === void 0 && path.length === 2) {
|
|
3080
3626
|
debug$a("Setting span type on text node without a type");
|
|
3081
3627
|
const span = node, key = span._key || keyGenerator();
|
|
3082
|
-
Transforms.setNodes(
|
|
3628
|
+
Transforms.setNodes(
|
|
3629
|
+
editor,
|
|
3630
|
+
{ ...span, _type: schemaTypes.span.name, _key: key },
|
|
3631
|
+
{ at: path }
|
|
3632
|
+
);
|
|
3083
3633
|
}
|
|
3084
3634
|
if (node._key === void 0 && (path.length === 1 || path.length === 2)) {
|
|
3085
3635
|
debug$a("Setting missing key on child node without a key");
|
|
@@ -3091,7 +3641,11 @@ function createWithSchemaTypes({
|
|
|
3091
3641
|
};
|
|
3092
3642
|
}
|
|
3093
3643
|
const debug$9 = debugWithName("plugin:withUtils");
|
|
3094
|
-
function createWithUtils({
|
|
3644
|
+
function createWithUtils({
|
|
3645
|
+
schemaTypes,
|
|
3646
|
+
keyGenerator,
|
|
3647
|
+
portableTextEditor
|
|
3648
|
+
}) {
|
|
3095
3649
|
return function(editor) {
|
|
3096
3650
|
return editor.pteExpandToWord = () => {
|
|
3097
3651
|
const { selection } = editor;
|
|
@@ -3111,7 +3665,7 @@ function createWithUtils({ schemaTypes, keyGenerator, portableTextEditor }) {
|
|
|
3111
3665
|
}
|
|
3112
3666
|
debug$9("pteExpandToWord: Can't expand to word here");
|
|
3113
3667
|
}
|
|
3114
|
-
}, editor.
|
|
3668
|
+
}, editor.pteCreateTextBlock = (options) => toSlateValue(
|
|
3115
3669
|
[
|
|
3116
3670
|
{
|
|
3117
3671
|
_type: schemaTypes.block.name,
|
|
@@ -3123,7 +3677,9 @@ function createWithUtils({ schemaTypes, keyGenerator, portableTextEditor }) {
|
|
|
3123
3677
|
_type: "span",
|
|
3124
3678
|
_key: keyGenerator(),
|
|
3125
3679
|
text: "",
|
|
3126
|
-
marks:
|
|
3680
|
+
marks: options.decorators.filter(
|
|
3681
|
+
(decorator) => schemaTypes.decorators.find(({ value }) => value === decorator)
|
|
3682
|
+
)
|
|
3127
3683
|
}
|
|
3128
3684
|
]
|
|
3129
3685
|
}
|
|
@@ -3172,59 +3728,46 @@ function createWithHotkeys(types, portableTextEditor, hotkeysFromOptions) {
|
|
|
3172
3728
|
}
|
|
3173
3729
|
}
|
|
3174
3730
|
});
|
|
3175
|
-
const isEnter = isHotkey("enter", event.nativeEvent), isTab = isHotkey("tab", event.nativeEvent), isShiftEnter = isHotkey("shift+enter", event.nativeEvent), isShiftTab = isHotkey("shift+tab", event.nativeEvent),
|
|
3731
|
+
const isEnter = isHotkey("enter", event.nativeEvent), isTab = isHotkey("tab", event.nativeEvent), isShiftEnter = isHotkey("shift+enter", event.nativeEvent), isShiftTab = isHotkey("shift+tab", event.nativeEvent), isArrowDown = isHotkey("down", event.nativeEvent), isArrowUp = isHotkey("up", event.nativeEvent);
|
|
3176
3732
|
if (isArrowDown && editor.selection) {
|
|
3177
|
-
const focusBlock = Node.descendant(
|
|
3733
|
+
const focusBlock = Node.descendant(
|
|
3734
|
+
editor,
|
|
3735
|
+
editor.selection.focus.path.slice(0, 1)
|
|
3736
|
+
);
|
|
3178
3737
|
if (focusBlock && Editor.isVoid(editor, focusBlock)) {
|
|
3179
3738
|
const nextPath = Path.next(editor.selection.focus.path.slice(0, 1));
|
|
3180
3739
|
if (!Node.has(editor, nextPath)) {
|
|
3181
|
-
Transforms.insertNodes(
|
|
3740
|
+
Transforms.insertNodes(
|
|
3741
|
+
editor,
|
|
3742
|
+
editor.pteCreateTextBlock({ decorators: [] }),
|
|
3743
|
+
{
|
|
3744
|
+
at: nextPath
|
|
3745
|
+
}
|
|
3746
|
+
), editor.onChange();
|
|
3182
3747
|
return;
|
|
3183
3748
|
}
|
|
3184
3749
|
}
|
|
3185
3750
|
}
|
|
3186
3751
|
if (isArrowUp && editor.selection) {
|
|
3187
|
-
const isFirstBlock = editor.selection.focus.path[0] === 0, focusBlock = Node.descendant(
|
|
3188
|
-
if (isFirstBlock && focusBlock && Editor.isVoid(editor, focusBlock)) {
|
|
3189
|
-
Transforms.insertNodes(editor, editor.pteCreateEmptyBlock(), { at: [0] }), Transforms.select(editor, { path: [0, 0], offset: 0 }), editor.onChange();
|
|
3190
|
-
return;
|
|
3191
|
-
}
|
|
3192
|
-
}
|
|
3193
|
-
if (isBackspace && editor.selection && editor.selection.focus.path[0] === 0 && Range.isCollapsed(editor.selection)) {
|
|
3194
|
-
const focusBlock = Node.descendant(editor, editor.selection.focus.path.slice(0, 1)), nextPath = Path.next(editor.selection.focus.path.slice(0, 1)), nextBlock = Node.has(editor, nextPath), isTextBlock = isPortableTextTextBlock(focusBlock), isEmptyFocusBlock = isTextBlock && focusBlock.children.length === 1 && focusBlock.children?.[0]?.text === "";
|
|
3195
|
-
if (nextBlock && isTextBlock && isEmptyFocusBlock) {
|
|
3196
|
-
event.preventDefault(), event.stopPropagation(), Transforms.removeNodes(editor, { match: (n) => n === focusBlock }), editor.onChange();
|
|
3197
|
-
return;
|
|
3198
|
-
}
|
|
3199
|
-
}
|
|
3200
|
-
if (isBackspace && editor.selection && editor.selection.focus.path[0] > 0 && Range.isCollapsed(editor.selection)) {
|
|
3201
|
-
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));
|
|
3202
|
-
if (prevBlock && focusBlock && Editor.isVoid(editor, prevBlock) && editor.selection.focus.offset === 0) {
|
|
3203
|
-
debug$8("Preventing deleting void block above"), event.preventDefault(), event.stopPropagation();
|
|
3204
|
-
const isTextBlock = isPortableTextTextBlock(focusBlock), isEmptyFocusBlock = isTextBlock && focusBlock.children.length === 1 && focusBlock.children?.[0]?.text === "";
|
|
3205
|
-
if (!isTextBlock || isEmptyFocusBlock) {
|
|
3206
|
-
Transforms.removeNodes(editor, { match: (n) => n === focusBlock }), Transforms.select(editor, prevPath), editor.onChange();
|
|
3207
|
-
return;
|
|
3208
|
-
}
|
|
3209
|
-
if (isTextBlock && !isEmptyFocusBlock) {
|
|
3210
|
-
Transforms.select(editor, prevPath), editor.onChange();
|
|
3211
|
-
return;
|
|
3212
|
-
}
|
|
3213
|
-
return;
|
|
3214
|
-
}
|
|
3215
|
-
}
|
|
3216
|
-
if (isDelete && editor.selection && editor.selection.focus.offset === 0 && Range.isCollapsed(editor.selection) && editor.children[editor.selection.focus.path[0] + 1]) {
|
|
3217
|
-
const nextBlock = Node.descendant(
|
|
3752
|
+
const isFirstBlock = editor.selection.focus.path[0] === 0, focusBlock = Node.descendant(
|
|
3218
3753
|
editor,
|
|
3219
|
-
|
|
3220
|
-
)
|
|
3221
|
-
if (
|
|
3222
|
-
|
|
3754
|
+
editor.selection.focus.path.slice(0, 1)
|
|
3755
|
+
);
|
|
3756
|
+
if (isFirstBlock && focusBlock && Editor.isVoid(editor, focusBlock)) {
|
|
3757
|
+
Transforms.insertNodes(
|
|
3758
|
+
editor,
|
|
3759
|
+
editor.pteCreateTextBlock({ decorators: [] }),
|
|
3760
|
+
{
|
|
3761
|
+
at: [0]
|
|
3762
|
+
}
|
|
3763
|
+
), Transforms.select(editor, { path: [0, 0], offset: 0 }), editor.onChange();
|
|
3223
3764
|
return;
|
|
3224
3765
|
}
|
|
3225
3766
|
}
|
|
3226
3767
|
if ((isTab || isShiftTab) && editor.selection) {
|
|
3227
|
-
const [focusChild] = Editor.node(editor, editor.selection.focus, {
|
|
3768
|
+
const [focusChild] = Editor.node(editor, editor.selection.focus, {
|
|
3769
|
+
depth: 2
|
|
3770
|
+
}), [focusBlock] = isPortableTextSpan$1(focusChild) ? Editor.node(editor, editor.selection.focus, { depth: 1 }) : [], hasAnnotationFocus = focusChild && isPortableTextTextBlock(focusBlock) && isPortableTextSpan$1(focusChild) && (focusChild.marks || []).filter(
|
|
3228
3771
|
(m) => (focusBlock.markDefs || []).map((def) => def._key).includes(m)
|
|
3229
3772
|
).length > 0, [start] = Range.edges(editor.selection), atStartOfNode = Editor.isStart(editor, start, start.path);
|
|
3230
3773
|
focusChild && isPortableTextSpan$1(focusChild) && (!hasAnnotationFocus || atStartOfNode) && editor.pteIncrementBlockLevels(isShiftTab) && event.preventDefault();
|
|
@@ -3238,12 +3781,15 @@ function createWithHotkeys(types, portableTextEditor, hotkeysFromOptions) {
|
|
|
3238
3781
|
if (editor.isTextBlock(focusBlock) && focusBlock.style && focusBlock.style !== types.styles[0].value) {
|
|
3239
3782
|
const [, end] = Range.edges(editor.selection);
|
|
3240
3783
|
if (Editor.isEnd(editor, end, end.path)) {
|
|
3241
|
-
Editor.insertNode(
|
|
3784
|
+
Editor.insertNode(
|
|
3785
|
+
editor,
|
|
3786
|
+
editor.pteCreateTextBlock({ decorators: [] })
|
|
3787
|
+
), event.preventDefault(), editor.onChange();
|
|
3242
3788
|
return;
|
|
3243
3789
|
}
|
|
3244
3790
|
}
|
|
3245
3791
|
if (focusBlock && Editor.isVoid(editor, focusBlock)) {
|
|
3246
|
-
Editor.insertNode(editor, editor.
|
|
3792
|
+
Editor.insertNode(editor, editor.pteCreateTextBlock({ decorators: [] })), event.preventDefault(), editor.onChange();
|
|
3247
3793
|
return;
|
|
3248
3794
|
}
|
|
3249
3795
|
event.preventDefault(), editor.insertBreak(), editor.onChange();
|
|
@@ -3263,7 +3809,13 @@ function createWithHotkeys(types, portableTextEditor, hotkeysFromOptions) {
|
|
|
3263
3809
|
}
|
|
3264
3810
|
function validateValue(value, types, keyGenerator) {
|
|
3265
3811
|
let resolution = null, valid = !0;
|
|
3266
|
-
const validChildTypes = [
|
|
3812
|
+
const validChildTypes = [
|
|
3813
|
+
types.span.name,
|
|
3814
|
+
...types.inlineObjects.map((t) => t.name)
|
|
3815
|
+
], validBlockTypes = [
|
|
3816
|
+
types.block.name,
|
|
3817
|
+
...types.blockObjects.map((t) => t.name)
|
|
3818
|
+
];
|
|
3267
3819
|
return value === void 0 ? { valid: !0, resolution: null, value } : !Array.isArray(value) || value.length === 0 ? {
|
|
3268
3820
|
valid: !1,
|
|
3269
3821
|
resolution: {
|
|
@@ -3306,7 +3858,9 @@ function validateValue(value, types, keyGenerator) {
|
|
|
3306
3858
|
if (blk._type === "block") {
|
|
3307
3859
|
const currentBlockTypeName = types.block.name;
|
|
3308
3860
|
return resolution = {
|
|
3309
|
-
patches: [
|
|
3861
|
+
patches: [
|
|
3862
|
+
set({ ...blk, _type: currentBlockTypeName }, [{ _key: blk._key }])
|
|
3863
|
+
],
|
|
3310
3864
|
description: `Block with _key '${blk._key}' has invalid type name '${blk._type}'. According to the schema, the block type name is '${currentBlockTypeName}'`,
|
|
3311
3865
|
action: `Use type '${currentBlockTypeName}'`,
|
|
3312
3866
|
item: blk,
|
|
@@ -3318,7 +3872,9 @@ function validateValue(value, types, keyGenerator) {
|
|
|
3318
3872
|
}, !0;
|
|
3319
3873
|
}
|
|
3320
3874
|
return !blk._type && isPortableTextTextBlock({ ...blk, _type: types.block.name }) ? (resolution = {
|
|
3321
|
-
patches: [
|
|
3875
|
+
patches: [
|
|
3876
|
+
set({ ...blk, _type: types.block.name }, [{ _key: blk._key }])
|
|
3877
|
+
],
|
|
3322
3878
|
description: `Block with _key '${blk._key}' is missing a type name. According to the schema, the block type name is '${types.block.name}'`,
|
|
3323
3879
|
action: `Use type '${types.block.name}'`,
|
|
3324
3880
|
item: blk,
|
|
@@ -3388,7 +3944,11 @@ function validateValue(value, types, keyGenerator) {
|
|
|
3388
3944
|
}
|
|
3389
3945
|
if (blk.markDefs && !Array.isArray(blk.markDefs))
|
|
3390
3946
|
return resolution = {
|
|
3391
|
-
patches: [
|
|
3947
|
+
patches: [
|
|
3948
|
+
set({ ...textBlock, markDefs: EMPTY_MARKDEFS }, [
|
|
3949
|
+
{ _key: textBlock._key }
|
|
3950
|
+
])
|
|
3951
|
+
],
|
|
3392
3952
|
description: "Block has invalid required property 'markDefs'.",
|
|
3393
3953
|
action: "Add empty markDefs array",
|
|
3394
3954
|
item: textBlock,
|
|
@@ -3421,7 +3981,10 @@ function validateValue(value, types, keyGenerator) {
|
|
|
3421
3981
|
i18n: {
|
|
3422
3982
|
description: "inputs.portable-text.invalid-value.orphaned-mark-defs.description",
|
|
3423
3983
|
action: "inputs.portable-text.invalid-value.orphaned-mark-defs.action",
|
|
3424
|
-
values: {
|
|
3984
|
+
values: {
|
|
3985
|
+
key: blk._key,
|
|
3986
|
+
unusedMarkDefs: unusedMarkDefs.map((m) => m.toString())
|
|
3987
|
+
}
|
|
3425
3988
|
}
|
|
3426
3989
|
}, !0;
|
|
3427
3990
|
}
|
|
@@ -3439,7 +4002,9 @@ function validateValue(value, types, keyGenerator) {
|
|
|
3439
4002
|
return resolution = {
|
|
3440
4003
|
autoResolve: !0,
|
|
3441
4004
|
patches: spanChildren.map((child) => set(
|
|
3442
|
-
(child.marks || []).filter(
|
|
4005
|
+
(child.marks || []).filter(
|
|
4006
|
+
(cMrk) => !orphanedMarks.includes(cMrk)
|
|
4007
|
+
),
|
|
3443
4008
|
[{ _key: blk._key }, "children", { _key: child._key }, "marks"]
|
|
3444
4009
|
)),
|
|
3445
4010
|
description: `Block with _key '${blk._key}' contains marks (${orphaned}) not supported by the current content model.`,
|
|
@@ -3448,7 +4013,10 @@ function validateValue(value, types, keyGenerator) {
|
|
|
3448
4013
|
i18n: {
|
|
3449
4014
|
description: "inputs.portable-text.invalid-value.orphaned-marks.description",
|
|
3450
4015
|
action: "inputs.portable-text.invalid-value.orphaned-marks.action",
|
|
3451
|
-
values: {
|
|
4016
|
+
values: {
|
|
4017
|
+
key: blk._key,
|
|
4018
|
+
orphanedMarks: orphanedMarks.map((m) => m.toString())
|
|
4019
|
+
}
|
|
3452
4020
|
}
|
|
3453
4021
|
}, !0;
|
|
3454
4022
|
}
|
|
@@ -3470,7 +4038,9 @@ function validateValue(value, types, keyGenerator) {
|
|
|
3470
4038
|
const newChild = { ...child, _key: keyGenerator() };
|
|
3471
4039
|
return resolution = {
|
|
3472
4040
|
autoResolve: !0,
|
|
3473
|
-
patches: [
|
|
4041
|
+
patches: [
|
|
4042
|
+
set(newChild, [{ _key: blk._key }, "children", cIndex])
|
|
4043
|
+
],
|
|
3474
4044
|
description: `Child at index ${cIndex} is missing required _key in block with _key ${blk._key}.`,
|
|
3475
4045
|
action: "Set a new random _key on the object",
|
|
3476
4046
|
item: blk,
|
|
@@ -3483,7 +4053,11 @@ function validateValue(value, types, keyGenerator) {
|
|
|
3483
4053
|
}
|
|
3484
4054
|
return child._type ? validChildTypes.includes(child._type) ? child._type === types.span.name && typeof child.text != "string" ? (resolution = {
|
|
3485
4055
|
patches: [
|
|
3486
|
-
set({ ...child, text: "" }, [
|
|
4056
|
+
set({ ...child, text: "" }, [
|
|
4057
|
+
{ _key: blk._key },
|
|
4058
|
+
"children",
|
|
4059
|
+
{ _key: child._key }
|
|
4060
|
+
])
|
|
3487
4061
|
],
|
|
3488
4062
|
description: `Child with _key '${child._key}' in block with key '${blk._key}' has missing or invalid text property!`,
|
|
3489
4063
|
action: "Write an empty text property to the object",
|
|
@@ -3494,17 +4068,25 @@ function validateValue(value, types, keyGenerator) {
|
|
|
3494
4068
|
values: { key: blk._key, childKey: child._key }
|
|
3495
4069
|
}
|
|
3496
4070
|
}, !0) : !1 : (resolution = {
|
|
3497
|
-
patches: [
|
|
4071
|
+
patches: [
|
|
4072
|
+
unset([{ _key: blk._key }, "children", { _key: child._key }])
|
|
4073
|
+
],
|
|
3498
4074
|
description: `Child with _key '${child._key}' in block with key '${blk._key}' has invalid '_type' property (${child._type}).`,
|
|
3499
4075
|
action: "Remove the object",
|
|
3500
4076
|
item: blk,
|
|
3501
4077
|
i18n: {
|
|
3502
4078
|
description: "inputs.portable-text.invalid-value.disallowed-child-type.description",
|
|
3503
4079
|
action: "inputs.portable-text.invalid-value.disallowed-child-type.action",
|
|
3504
|
-
values: {
|
|
4080
|
+
values: {
|
|
4081
|
+
key: blk._key,
|
|
4082
|
+
childKey: child._key,
|
|
4083
|
+
childType: child._type
|
|
4084
|
+
}
|
|
3505
4085
|
}
|
|
3506
4086
|
}, !0) : (resolution = {
|
|
3507
|
-
patches: [
|
|
4087
|
+
patches: [
|
|
4088
|
+
unset([{ _key: blk._key }, "children", { _key: child._key }])
|
|
4089
|
+
],
|
|
3508
4090
|
description: `Child with _key '${child._key}' in block with key '${blk._key}' is missing '_type' property.`,
|
|
3509
4091
|
action: "Remove the object",
|
|
3510
4092
|
item: blk,
|
|
@@ -3538,11 +4120,13 @@ function createWithInsertData(change$, schemaTypes, keyGenerator) {
|
|
|
3538
4120
|
const [voidNode] = endVoid, r = domRange.cloneRange(), domNode = ReactEditor.toDOMNode(editor, voidNode);
|
|
3539
4121
|
r.setEndAfter(domNode), contents = r.cloneContents();
|
|
3540
4122
|
}
|
|
3541
|
-
Array.from(contents.querySelectorAll("[data-slate-zero-width]")).forEach(
|
|
3542
|
-
|
|
3543
|
-
|
|
4123
|
+
Array.from(contents.querySelectorAll("[data-slate-zero-width]")).forEach(
|
|
4124
|
+
(zw) => {
|
|
4125
|
+
const isNewline = zw.getAttribute("data-slate-zero-width") === "n";
|
|
4126
|
+
zw.textContent = isNewline ? `
|
|
3544
4127
|
` : "";
|
|
3545
|
-
|
|
4128
|
+
}
|
|
4129
|
+
), Array.from(contents.querySelectorAll("*")).forEach((elm) => {
|
|
3546
4130
|
elm.removeAttribute("contentEditable"), elm.removeAttribute("data-slate-inline"), elm.removeAttribute("data-slate-leaf"), elm.removeAttribute("data-slate-node"), elm.removeAttribute("data-slate-spacer"), elm.removeAttribute("data-slate-string"), elm.removeAttribute("data-slate-zero-width"), elm.removeAttribute("draggable");
|
|
3547
4131
|
for (const key in elm.attributes)
|
|
3548
4132
|
elm.hasAttribute(key) && elm.removeAttribute(key);
|
|
@@ -3552,7 +4136,10 @@ function createWithInsertData(change$, schemaTypes, keyGenerator) {
|
|
|
3552
4136
|
const asHTML = div.innerHTML;
|
|
3553
4137
|
contents.ownerDocument.body.removeChild(div);
|
|
3554
4138
|
const fragment = editor.getFragment(), portableText = fromSlateValue(fragment, blockTypeName), asJSON = JSON.stringify(portableText), asPlainText = toPlainText(portableText);
|
|
3555
|
-
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(
|
|
4139
|
+
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(
|
|
4140
|
+
"application/x-portable-text-event-origin",
|
|
4141
|
+
originEvent || "external"
|
|
4142
|
+
), debug$7("Set fragment data", asJSON, asHTML);
|
|
3556
4143
|
}, editor.insertPortableTextData = (data) => {
|
|
3557
4144
|
if (!editor.selection)
|
|
3558
4145
|
return !1;
|
|
@@ -3592,7 +4179,9 @@ function createWithInsertData(change$, schemaTypes, keyGenerator) {
|
|
|
3592
4179
|
if (html) {
|
|
3593
4180
|
if (portableText = htmlToBlocks(html, schemaTypes.portableText, {
|
|
3594
4181
|
unstable_whitespaceOnPasteMode: whitespaceOnPasteMode
|
|
3595
|
-
}).map(
|
|
4182
|
+
}).map(
|
|
4183
|
+
(block) => normalizeBlock(block, { blockTypeName })
|
|
4184
|
+
), fragment = toSlateValue(portableText, { schemaTypes }), insertedType = "HTML", portableText.length === 0)
|
|
3596
4185
|
return !1;
|
|
3597
4186
|
} else {
|
|
3598
4187
|
const textToHtml = `<html><body>${escapeHtml(text).split(/\n{2,}/).map(
|
|
@@ -3604,7 +4193,11 @@ function createWithInsertData(change$, schemaTypes, keyGenerator) {
|
|
|
3604
4193
|
schemaTypes
|
|
3605
4194
|
}), insertedType = "text";
|
|
3606
4195
|
}
|
|
3607
|
-
const validation = validateValue(
|
|
4196
|
+
const validation = validateValue(
|
|
4197
|
+
portableText,
|
|
4198
|
+
schemaTypes,
|
|
4199
|
+
keyGenerator
|
|
4200
|
+
);
|
|
3608
4201
|
if (!validation.valid) {
|
|
3609
4202
|
const errorDescription = `Could not validate the resulting portable text to insert.
|
|
3610
4203
|
${validation.resolution?.description}
|
|
@@ -3617,7 +4210,9 @@ Try to insert as plain text (shift-paste) instead.`;
|
|
|
3617
4210
|
data: validation
|
|
3618
4211
|
}), debug$7("Invalid insert result", validation), !1;
|
|
3619
4212
|
}
|
|
3620
|
-
return debug$7(
|
|
4213
|
+
return debug$7(
|
|
4214
|
+
`Inserting ${insertedType} fragment at ${JSON.stringify(editor.selection)}`
|
|
4215
|
+
), _insertFragment(editor, fragment, schemaTypes), change$.next({ type: "loading", isLoading: !1 }), !0;
|
|
3621
4216
|
}
|
|
3622
4217
|
return change$.next({ type: "loading", isLoading: !1 }), !1;
|
|
3623
4218
|
}, editor.insertData = (data) => {
|
|
@@ -3682,18 +4277,30 @@ function _insertFragment(editor, fragment, schemaTypes) {
|
|
|
3682
4277
|
editor.withoutNormalizing(() => {
|
|
3683
4278
|
if (!editor.selection)
|
|
3684
4279
|
return;
|
|
3685
|
-
const [focusBlock, focusPath] = Editor.node(editor, editor.selection, {
|
|
4280
|
+
const [focusBlock, focusPath] = Editor.node(editor, editor.selection, {
|
|
4281
|
+
depth: 1
|
|
4282
|
+
});
|
|
3686
4283
|
if (editor.isTextBlock(focusBlock) && editor.isTextBlock(fragment[0])) {
|
|
3687
4284
|
const { markDefs } = focusBlock;
|
|
3688
|
-
debug$7(
|
|
4285
|
+
debug$7(
|
|
4286
|
+
"Mixing markDefs of focusBlock and fragments[0] block",
|
|
4287
|
+
markDefs,
|
|
4288
|
+
fragment[0].markDefs
|
|
4289
|
+
), isEqual(markDefs, fragment[0].markDefs) || Transforms.setNodes(
|
|
3689
4290
|
editor,
|
|
3690
4291
|
{
|
|
3691
|
-
markDefs: uniq([
|
|
4292
|
+
markDefs: uniq([
|
|
4293
|
+
...fragment[0].markDefs || [],
|
|
4294
|
+
...markDefs || []
|
|
4295
|
+
])
|
|
3692
4296
|
},
|
|
3693
4297
|
{ at: focusPath, mode: "lowest", voids: !1 }
|
|
3694
4298
|
);
|
|
3695
4299
|
}
|
|
3696
|
-
isEqualToEmptyEditor(
|
|
4300
|
+
isEqualToEmptyEditor(
|
|
4301
|
+
editor.children,
|
|
4302
|
+
schemaTypes
|
|
4303
|
+
) ? (Transforms.splitNodes(editor, { at: [0, 0] }), editor.insertFragment(fragment), Transforms.removeNodes(editor, { at: [0] })) : editor.insertFragment(fragment);
|
|
3697
4304
|
}), editor.onChange();
|
|
3698
4305
|
}
|
|
3699
4306
|
const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, options) => {
|
|
@@ -3703,7 +4310,11 @@ const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, opti
|
|
|
3703
4310
|
onChange: e.onChange,
|
|
3704
4311
|
normalizeNode: e.normalizeNode
|
|
3705
4312
|
});
|
|
3706
|
-
const operationToPatches = createOperationToPatches(schemaTypes), withObjectKeys = createWithObjectKeys(schemaTypes, keyGenerator), withSchemaTypes = createWithSchemaTypes({ schemaTypes, keyGenerator }), withEditableAPI = createWithEditableAPI(
|
|
4313
|
+
const operationToPatches = createOperationToPatches(schemaTypes), withObjectKeys = createWithObjectKeys(schemaTypes, keyGenerator), withSchemaTypes = createWithSchemaTypes({ schemaTypes, keyGenerator }), withEditableAPI = createWithEditableAPI(
|
|
4314
|
+
portableTextEditor,
|
|
4315
|
+
schemaTypes,
|
|
4316
|
+
keyGenerator
|
|
4317
|
+
), withPatches = createWithPatches({
|
|
3707
4318
|
change$,
|
|
3708
4319
|
keyGenerator,
|
|
3709
4320
|
patches$,
|
|
@@ -3718,7 +4329,14 @@ const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, opti
|
|
|
3718
4329
|
schemaTypes,
|
|
3719
4330
|
change$,
|
|
3720
4331
|
keyGenerator
|
|
3721
|
-
), withPortableTextBlockStyle = createWithPortableTextBlockStyle(schemaTypes), withPlaceholderBlock = createWithPlaceholderBlock(), withInsertBreak = createWithInsertBreak(schemaTypes), withUtils = createWithUtils({
|
|
4332
|
+
), withPortableTextBlockStyle = createWithPortableTextBlockStyle(schemaTypes), withPlaceholderBlock = createWithPlaceholderBlock(), withInsertBreak = createWithInsertBreak(schemaTypes, keyGenerator), withUtils = createWithUtils({
|
|
4333
|
+
keyGenerator,
|
|
4334
|
+
schemaTypes,
|
|
4335
|
+
portableTextEditor
|
|
4336
|
+
}), withPortableTextSelections = createWithPortableTextSelections(
|
|
4337
|
+
change$,
|
|
4338
|
+
schemaTypes
|
|
4339
|
+
);
|
|
3722
4340
|
return e.destroy = () => {
|
|
3723
4341
|
const originalFunctions = originalFnMap.get(e);
|
|
3724
4342
|
if (!originalFunctions)
|
|
@@ -3732,7 +4350,9 @@ const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, opti
|
|
|
3732
4350
|
withUtils(
|
|
3733
4351
|
withPlaceholderBlock(
|
|
3734
4352
|
withPortableTextLists(
|
|
3735
|
-
withPortableTextSelections(
|
|
4353
|
+
withPortableTextSelections(
|
|
4354
|
+
withEditableAPI(withInsertBreak(e))
|
|
4355
|
+
)
|
|
3736
4356
|
)
|
|
3737
4357
|
)
|
|
3738
4358
|
)
|
|
@@ -3751,7 +4371,11 @@ const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, opti
|
|
|
3751
4371
|
withUtils(
|
|
3752
4372
|
withMaxBlocks(
|
|
3753
4373
|
withUndoRedo(
|
|
3754
|
-
withPatches(
|
|
4374
|
+
withPatches(
|
|
4375
|
+
withPortableTextSelections(
|
|
4376
|
+
withEditableAPI(withInsertBreak(e))
|
|
4377
|
+
)
|
|
4378
|
+
)
|
|
3755
4379
|
)
|
|
3756
4380
|
)
|
|
3757
4381
|
)
|
|
@@ -3798,8 +4422,15 @@ function SlateContainer(props) {
|
|
|
3798
4422
|
portableTextEditor,
|
|
3799
4423
|
readOnly
|
|
3800
4424
|
});
|
|
3801
|
-
}, [
|
|
3802
|
-
|
|
4425
|
+
}, [
|
|
4426
|
+
keyGenerator,
|
|
4427
|
+
portableTextEditor,
|
|
4428
|
+
maxBlocks,
|
|
4429
|
+
readOnly,
|
|
4430
|
+
patches$,
|
|
4431
|
+
slateEditor
|
|
4432
|
+
]);
|
|
4433
|
+
const initialValue = useMemo(() => [slateEditor.pteCreateTextBlock({ decorators: [] })], [slateEditor]);
|
|
3803
4434
|
return useEffect(() => () => {
|
|
3804
4435
|
debug$6("Destroying Slate editor"), slateEditor.destroy();
|
|
3805
4436
|
}, [slateEditor]), /* @__PURE__ */ jsx(Slate, { editor: slateEditor, initialValue, children: props.children });
|
|
@@ -3856,7 +4487,11 @@ function useSyncValue(props) {
|
|
|
3856
4487
|
Transforms.removeNodes(slateEditor, {
|
|
3857
4488
|
at: [childrenLength - 1 - index]
|
|
3858
4489
|
});
|
|
3859
|
-
}), Transforms.insertNodes(
|
|
4490
|
+
}), Transforms.insertNodes(
|
|
4491
|
+
slateEditor,
|
|
4492
|
+
slateEditor.pteCreateTextBlock({ decorators: [] }),
|
|
4493
|
+
{ at: [0] }
|
|
4494
|
+
), hadSelection && Transforms.select(slateEditor, [0, 0]);
|
|
3860
4495
|
});
|
|
3861
4496
|
});
|
|
3862
4497
|
}), isChanged = !0), value && value.length > 0) {
|
|
@@ -3875,34 +4510,53 @@ function useSyncValue(props) {
|
|
|
3875
4510
|
});
|
|
3876
4511
|
isChanged = !0;
|
|
3877
4512
|
}
|
|
3878
|
-
slateValueFromProps.forEach(
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
currentBlock
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
4513
|
+
slateValueFromProps.forEach(
|
|
4514
|
+
(currentBlock, currentBlockIndex) => {
|
|
4515
|
+
const oldBlock = slateEditor.children[currentBlockIndex];
|
|
4516
|
+
if (oldBlock && !isEqual(currentBlock, oldBlock) && isValid) {
|
|
4517
|
+
const validationValue = [value[currentBlockIndex]], validation = validateValue(
|
|
4518
|
+
validationValue,
|
|
4519
|
+
schemaTypes,
|
|
4520
|
+
keyGenerator
|
|
4521
|
+
);
|
|
4522
|
+
!validation.valid && validation.resolution?.autoResolve && validation.resolution?.patches.length > 0 && !readOnly && previousValue.current && previousValue.current !== value && (console.warn(
|
|
4523
|
+
`${validation.resolution.action} for block with _key '${validationValue[0]._key}'. ${validation.resolution?.description}`
|
|
4524
|
+
), validation.resolution.patches.forEach((patch) => {
|
|
4525
|
+
change$.next({ type: "patch", patch });
|
|
4526
|
+
})), validation.valid || validation.resolution?.autoResolve ? (oldBlock._key === currentBlock._key ? (debug$5.enabled && debug$5("Updating block", oldBlock, currentBlock), _updateBlock(
|
|
4527
|
+
slateEditor,
|
|
4528
|
+
currentBlock,
|
|
4529
|
+
oldBlock,
|
|
4530
|
+
currentBlockIndex
|
|
4531
|
+
)) : (debug$5.enabled && debug$5("Replacing block", oldBlock, currentBlock), _replaceBlock(
|
|
4532
|
+
slateEditor,
|
|
4533
|
+
currentBlock,
|
|
4534
|
+
currentBlockIndex
|
|
4535
|
+
)), isChanged = !0) : (change$.next({
|
|
4536
|
+
type: "invalidValue",
|
|
4537
|
+
resolution: validation.resolution,
|
|
4538
|
+
value
|
|
4539
|
+
}), isValid = !1);
|
|
4540
|
+
}
|
|
4541
|
+
if (!oldBlock && isValid) {
|
|
4542
|
+
const validationValue = [value[currentBlockIndex]], validation = validateValue(
|
|
4543
|
+
validationValue,
|
|
4544
|
+
schemaTypes,
|
|
4545
|
+
keyGenerator
|
|
4546
|
+
);
|
|
4547
|
+
debug$5.enabled && debug$5(
|
|
4548
|
+
"Validating and inserting new block in the end of the value",
|
|
4549
|
+
currentBlock
|
|
4550
|
+
), validation.valid || validation.resolution?.autoResolve ? Transforms.insertNodes(slateEditor, currentBlock, {
|
|
4551
|
+
at: [currentBlockIndex]
|
|
4552
|
+
}) : (debug$5("Invalid", validation), change$.next({
|
|
4553
|
+
type: "invalidValue",
|
|
4554
|
+
resolution: validation.resolution,
|
|
4555
|
+
value
|
|
4556
|
+
}), isValid = !1);
|
|
4557
|
+
}
|
|
3904
4558
|
}
|
|
3905
|
-
|
|
4559
|
+
);
|
|
3906
4560
|
});
|
|
3907
4561
|
});
|
|
3908
4562
|
});
|
|
@@ -3952,41 +4606,53 @@ function _updateBlock(slateEditor, currentBlock, oldBlock, currentBlockIndex) {
|
|
|
3952
4606
|
at: [currentBlockIndex]
|
|
3953
4607
|
}), slateEditor.isTextBlock(currentBlock) && slateEditor.isTextBlock(oldBlock)) {
|
|
3954
4608
|
const oldBlockChildrenLength = oldBlock.children.length;
|
|
3955
|
-
currentBlock.children.length < oldBlockChildrenLength && Array.from(
|
|
3956
|
-
(
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
4609
|
+
currentBlock.children.length < oldBlockChildrenLength && Array.from(
|
|
4610
|
+
Array(oldBlockChildrenLength - currentBlock.children.length)
|
|
4611
|
+
).forEach((_, index) => {
|
|
4612
|
+
const childIndex = oldBlockChildrenLength - 1 - index;
|
|
4613
|
+
childIndex > 0 && (debug$5("Removing child"), Transforms.removeNodes(slateEditor, {
|
|
4614
|
+
at: [currentBlockIndex, childIndex]
|
|
4615
|
+
}));
|
|
4616
|
+
}), currentBlock.children.forEach(
|
|
4617
|
+
(currentBlockChild, currentBlockChildIndex) => {
|
|
4618
|
+
const oldBlockChild = oldBlock.children[currentBlockChildIndex], isChildChanged = !isEqual(currentBlockChild, oldBlockChild), isTextChanged = !isEqual(
|
|
4619
|
+
currentBlockChild.text,
|
|
4620
|
+
oldBlockChild?.text
|
|
4621
|
+
), path = [currentBlockIndex, currentBlockChildIndex];
|
|
4622
|
+
if (isChildChanged)
|
|
4623
|
+
if (currentBlockChild._key === oldBlockChild?._key) {
|
|
4624
|
+
debug$5("Updating changed child", currentBlockChild, oldBlockChild), Transforms.setNodes(
|
|
4625
|
+
slateEditor,
|
|
4626
|
+
currentBlockChild,
|
|
4627
|
+
{
|
|
4628
|
+
at: path
|
|
4629
|
+
}
|
|
4630
|
+
);
|
|
4631
|
+
const isSpanNode = Text.isText(currentBlockChild) && currentBlockChild._type === "span" && Text.isText(oldBlockChild) && oldBlockChild._type === "span";
|
|
4632
|
+
isSpanNode && isTextChanged ? (Transforms.delete(slateEditor, {
|
|
4633
|
+
at: {
|
|
4634
|
+
focus: { path, offset: 0 },
|
|
4635
|
+
anchor: { path, offset: oldBlockChild.text.length }
|
|
4636
|
+
}
|
|
4637
|
+
}), Transforms.insertText(slateEditor, currentBlockChild.text, {
|
|
4638
|
+
at: path
|
|
4639
|
+
}), slateEditor.onChange()) : isSpanNode || (debug$5("Updating changed inline object child", currentBlockChild), Transforms.setNodes(
|
|
4640
|
+
slateEditor,
|
|
4641
|
+
{ _key: VOID_CHILD_KEY },
|
|
4642
|
+
{
|
|
4643
|
+
at: [...path, 0],
|
|
4644
|
+
voids: !0
|
|
4645
|
+
}
|
|
4646
|
+
));
|
|
4647
|
+
} else oldBlockChild ? (debug$5("Replacing child", currentBlockChild), Transforms.removeNodes(slateEditor, {
|
|
4648
|
+
at: [currentBlockIndex, currentBlockChildIndex]
|
|
4649
|
+
}), Transforms.insertNodes(slateEditor, currentBlockChild, {
|
|
4650
|
+
at: [currentBlockIndex, currentBlockChildIndex]
|
|
4651
|
+
}), slateEditor.onChange()) : oldBlockChild || (debug$5("Inserting new child", currentBlockChild), Transforms.insertNodes(slateEditor, currentBlockChild, {
|
|
4652
|
+
at: [currentBlockIndex, currentBlockChildIndex]
|
|
4653
|
+
}), slateEditor.onChange());
|
|
3961
4654
|
}
|
|
3962
|
-
)
|
|
3963
|
-
const oldBlockChild = oldBlock.children[currentBlockChildIndex], isChildChanged = !isEqual(currentBlockChild, oldBlockChild), isTextChanged = !isEqual(currentBlockChild.text, oldBlockChild?.text), path = [currentBlockIndex, currentBlockChildIndex];
|
|
3964
|
-
if (isChildChanged)
|
|
3965
|
-
if (currentBlockChild._key === oldBlockChild?._key) {
|
|
3966
|
-
debug$5("Updating changed child", currentBlockChild, oldBlockChild), Transforms.setNodes(slateEditor, currentBlockChild, {
|
|
3967
|
-
at: path
|
|
3968
|
-
});
|
|
3969
|
-
const isSpanNode = Text.isText(currentBlockChild) && currentBlockChild._type === "span" && Text.isText(oldBlockChild) && oldBlockChild._type === "span";
|
|
3970
|
-
isSpanNode && isTextChanged ? (Transforms.delete(slateEditor, {
|
|
3971
|
-
at: { focus: { path, offset: 0 }, anchor: { path, offset: oldBlockChild.text.length } }
|
|
3972
|
-
}), Transforms.insertText(slateEditor, currentBlockChild.text, {
|
|
3973
|
-
at: path
|
|
3974
|
-
}), slateEditor.onChange()) : isSpanNode || (debug$5("Updating changed inline object child", currentBlockChild), Transforms.setNodes(
|
|
3975
|
-
slateEditor,
|
|
3976
|
-
{ _key: VOID_CHILD_KEY },
|
|
3977
|
-
{
|
|
3978
|
-
at: [...path, 0],
|
|
3979
|
-
voids: !0
|
|
3980
|
-
}
|
|
3981
|
-
));
|
|
3982
|
-
} else oldBlockChild ? (debug$5("Replacing child", currentBlockChild), Transforms.removeNodes(slateEditor, {
|
|
3983
|
-
at: [currentBlockIndex, currentBlockChildIndex]
|
|
3984
|
-
}), Transforms.insertNodes(slateEditor, currentBlockChild, {
|
|
3985
|
-
at: [currentBlockIndex, currentBlockChildIndex]
|
|
3986
|
-
}), slateEditor.onChange()) : oldBlockChild || (debug$5("Inserting new child", currentBlockChild), Transforms.insertNodes(slateEditor, currentBlockChild, {
|
|
3987
|
-
at: [currentBlockIndex, currentBlockChildIndex]
|
|
3988
|
-
}), slateEditor.onChange());
|
|
3989
|
-
});
|
|
4655
|
+
);
|
|
3990
4656
|
}
|
|
3991
4657
|
}
|
|
3992
4658
|
const debug$4 = debugWithName("component:PortableTextEditor:Synchronizer"), debugVerbose$1 = debug$4.enabled && !1, FLUSH_PATCHES_THROTTLED_MS = process.env.NODE_ENV === "test" ? 500 : 1e3;
|
|
@@ -4005,7 +4671,11 @@ function Synchronizer(props) {
|
|
|
4005
4671
|
debug$4("Flushing pending patches"), debugVerbose$1 && debug$4(`Patches:
|
|
4006
4672
|
${JSON.stringify(pendingPatches.current, null, 2)}`);
|
|
4007
4673
|
const snapshot = getValue();
|
|
4008
|
-
change$.next({
|
|
4674
|
+
change$.next({
|
|
4675
|
+
type: "mutation",
|
|
4676
|
+
patches: pendingPatches.current,
|
|
4677
|
+
snapshot
|
|
4678
|
+
}), pendingPatches.current = [];
|
|
4009
4679
|
}
|
|
4010
4680
|
IS_PROCESSING_LOCAL_CHANGES.set(slateEditor, !1);
|
|
4011
4681
|
}, [slateEditor, getValue, change$]), onFlushPendingPatchesThrottled = useMemo(() => throttle(
|
|
@@ -4091,7 +4761,9 @@ class PortableTextEditor extends Component {
|
|
|
4091
4761
|
constructor(props) {
|
|
4092
4762
|
if (super(props), !props.schemaType)
|
|
4093
4763
|
throw new Error('PortableTextEditor: missing "schemaType" property');
|
|
4094
|
-
props.incomingPatches$ && console.warn(
|
|
4764
|
+
props.incomingPatches$ && console.warn(
|
|
4765
|
+
"The prop 'incomingPatches$' is deprecated and renamed to 'patches$'"
|
|
4766
|
+
), this.change$.next({ type: "loading", isLoading: !0 }), this.schemaTypes = getPortableTextMemberSchemaTypes(
|
|
4095
4767
|
props.schemaType.hasOwnProperty("jsonType") ? props.schemaType : compileType(props.schemaType)
|
|
4096
4768
|
);
|
|
4097
4769
|
}
|
|
@@ -4183,14 +4855,26 @@ class PortableTextEditor extends Component {
|
|
|
4183
4855
|
static isSelectionsOverlapping = (editor, selectionA, selectionB) => editor.editable?.isSelectionsOverlapping(selectionA, selectionB);
|
|
4184
4856
|
}
|
|
4185
4857
|
const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (props) => {
|
|
4186
|
-
const {
|
|
4858
|
+
const {
|
|
4859
|
+
attributes,
|
|
4860
|
+
children,
|
|
4861
|
+
leaf,
|
|
4862
|
+
schemaTypes,
|
|
4863
|
+
renderChild,
|
|
4864
|
+
renderDecorator,
|
|
4865
|
+
renderAnnotation
|
|
4866
|
+
} = props, spanRef = useRef(null), portableTextEditor = usePortableTextEditor(), blockSelected = useSelected(), [focused, setFocused] = useState(!1), [selected, setSelected] = useState(!1), block = children.props.parent, path = useMemo(
|
|
4187
4867
|
() => block ? [{ _key: block?._key }, "children", { _key: leaf._key }] : [],
|
|
4188
4868
|
[block, leaf._key]
|
|
4189
4869
|
), decoratorValues = useMemo(
|
|
4190
4870
|
() => schemaTypes.decorators.map((dec) => dec.value),
|
|
4191
4871
|
[schemaTypes.decorators]
|
|
4192
4872
|
), marks = useMemo(
|
|
4193
|
-
() => uniq(
|
|
4873
|
+
() => uniq(
|
|
4874
|
+
(leaf.marks || EMPTY_MARKS).filter(
|
|
4875
|
+
(mark) => decoratorValues.includes(mark)
|
|
4876
|
+
)
|
|
4877
|
+
),
|
|
4194
4878
|
[decoratorValues, leaf.marks]
|
|
4195
4879
|
), annotationMarks = Array.isArray(leaf.marks) ? leaf.marks : EMPTY_MARKS, annotations = useMemo(
|
|
4196
4880
|
() => annotationMarks.map(
|
|
@@ -4241,11 +4925,18 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4241
4925
|
return () => {
|
|
4242
4926
|
sub.unsubscribe();
|
|
4243
4927
|
};
|
|
4244
|
-
}, [
|
|
4928
|
+
}, [
|
|
4929
|
+
path,
|
|
4930
|
+
portableTextEditor,
|
|
4931
|
+
setSelectedFromRange,
|
|
4932
|
+
shouldTrackSelectionAndFocus
|
|
4933
|
+
]), useEffect(() => setSelectedFromRange(), [setSelectedFromRange]);
|
|
4245
4934
|
const content = useMemo(() => {
|
|
4246
4935
|
let returnedChildren = children;
|
|
4247
4936
|
if (Text.isText(leaf) && leaf._type === schemaTypes.span.name && (marks.forEach((mark) => {
|
|
4248
|
-
const schemaType = schemaTypes.decorators.find(
|
|
4937
|
+
const schemaType = schemaTypes.decorators.find(
|
|
4938
|
+
(dec) => dec.value === mark
|
|
4939
|
+
);
|
|
4249
4940
|
if (schemaType && renderDecorator) {
|
|
4250
4941
|
const _props = Object.defineProperty(
|
|
4251
4942
|
{
|
|
@@ -4261,14 +4952,20 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4261
4952
|
{
|
|
4262
4953
|
enumerable: !1,
|
|
4263
4954
|
get() {
|
|
4264
|
-
return console.warn(
|
|
4955
|
+
return console.warn(
|
|
4956
|
+
"Property 'type' is deprecated, use 'schemaType' instead."
|
|
4957
|
+
), schemaType;
|
|
4265
4958
|
}
|
|
4266
4959
|
}
|
|
4267
4960
|
);
|
|
4268
|
-
returnedChildren = renderDecorator(
|
|
4961
|
+
returnedChildren = renderDecorator(
|
|
4962
|
+
_props
|
|
4963
|
+
);
|
|
4269
4964
|
}
|
|
4270
4965
|
}), block && annotations.length > 0 && annotations.forEach((annotation) => {
|
|
4271
|
-
const schemaType = schemaTypes.annotations.find(
|
|
4966
|
+
const schemaType = schemaTypes.annotations.find(
|
|
4967
|
+
(t) => t.name === annotation._type
|
|
4968
|
+
);
|
|
4272
4969
|
if (schemaType)
|
|
4273
4970
|
if (renderAnnotation) {
|
|
4274
4971
|
const _props = Object.defineProperty(
|
|
@@ -4286,7 +4983,9 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4286
4983
|
{
|
|
4287
4984
|
enumerable: !1,
|
|
4288
4985
|
get() {
|
|
4289
|
-
return console.warn(
|
|
4986
|
+
return console.warn(
|
|
4987
|
+
"Property 'type' is deprecated, use 'schemaType' instead."
|
|
4988
|
+
), schemaType;
|
|
4290
4989
|
}
|
|
4291
4990
|
}
|
|
4292
4991
|
);
|
|
@@ -4311,7 +5010,9 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4311
5010
|
{
|
|
4312
5011
|
enumerable: !1,
|
|
4313
5012
|
get() {
|
|
4314
|
-
return console.warn(
|
|
5013
|
+
return console.warn(
|
|
5014
|
+
"Property 'type' is deprecated, use 'schemaType' instead."
|
|
5015
|
+
), schemaTypes.span;
|
|
4315
5016
|
}
|
|
4316
5017
|
}
|
|
4317
5018
|
);
|
|
@@ -4366,8 +5067,13 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4366
5067
|
scrollSelectionIntoView,
|
|
4367
5068
|
spellCheck,
|
|
4368
5069
|
...restProps
|
|
4369
|
-
} = props, portableTextEditor = usePortableTextEditor(), readOnly = usePortableTextEditorReadOnlyStatus(), keyGenerator = usePortableTextEditorKeyGenerator(), ref = useRef(null), [editableElement, setEditableElement] = useState(
|
|
4370
|
-
|
|
5070
|
+
} = props, portableTextEditor = usePortableTextEditor(), readOnly = usePortableTextEditorReadOnlyStatus(), keyGenerator = usePortableTextEditorKeyGenerator(), ref = useRef(null), [editableElement, setEditableElement] = useState(
|
|
5071
|
+
null
|
|
5072
|
+
), [hasInvalidValue, setHasInvalidValue] = useState(!1), [rangeDecorationState, setRangeDecorationsState] = useState([]);
|
|
5073
|
+
useImperativeHandle(
|
|
5074
|
+
forwardedRef,
|
|
5075
|
+
() => ref.current
|
|
5076
|
+
);
|
|
4371
5077
|
const rangeDecorationsRef = useRef(rangeDecorations), { change$, schemaTypes } = portableTextEditor, slateEditor = useSlate(), blockTypeName = schemaTypes.block.name, withInsertData = useMemo(
|
|
4372
5078
|
() => createWithInsertData(change$, schemaTypes, keyGenerator),
|
|
4373
5079
|
[change$, keyGenerator, schemaTypes]
|
|
@@ -4390,7 +5096,15 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4390
5096
|
spellCheck
|
|
4391
5097
|
}
|
|
4392
5098
|
),
|
|
4393
|
-
[
|
|
5099
|
+
[
|
|
5100
|
+
schemaTypes,
|
|
5101
|
+
spellCheck,
|
|
5102
|
+
readOnly,
|
|
5103
|
+
renderBlock,
|
|
5104
|
+
renderChild,
|
|
5105
|
+
renderListItem,
|
|
5106
|
+
renderStyle
|
|
5107
|
+
]
|
|
4394
5108
|
), renderLeaf = useCallback(
|
|
4395
5109
|
(lProps) => {
|
|
4396
5110
|
if (lProps.leaf._type === "span") {
|
|
@@ -4415,7 +5129,14 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4415
5129
|
}
|
|
4416
5130
|
return lProps.children;
|
|
4417
5131
|
},
|
|
4418
|
-
[
|
|
5132
|
+
[
|
|
5133
|
+
readOnly,
|
|
5134
|
+
renderAnnotation,
|
|
5135
|
+
renderChild,
|
|
5136
|
+
renderDecorator,
|
|
5137
|
+
renderPlaceholder,
|
|
5138
|
+
schemaTypes
|
|
5139
|
+
]
|
|
4419
5140
|
), restoreSelectionFromProps = useCallback(() => {
|
|
4420
5141
|
if (propsSelection) {
|
|
4421
5142
|
debug(`Selection from props ${JSON.stringify(propsSelection)}`);
|
|
@@ -4424,7 +5145,9 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4424
5145
|
fromSlateValue(slateEditor.children, blockTypeName)
|
|
4425
5146
|
);
|
|
4426
5147
|
if (normalizedSelection !== null) {
|
|
4427
|
-
debug(
|
|
5148
|
+
debug(
|
|
5149
|
+
`Normalized selection from props ${JSON.stringify(normalizedSelection)}`
|
|
5150
|
+
);
|
|
4428
5151
|
const slateRange = toSlateRange(normalizedSelection, slateEditor);
|
|
4429
5152
|
slateRange && (Transforms.select(slateEditor, slateRange), slateEditor.operations.some((o) => o.type === "set_selection") || change$.next({ type: "selection", selection: normalizedSelection }), slateEditor.onChange());
|
|
4430
5153
|
}
|
|
@@ -4434,7 +5157,10 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4434
5157
|
if (rangeDecorations && rangeDecorations.length > 0) {
|
|
4435
5158
|
const newSlateRanges = [];
|
|
4436
5159
|
if (rangeDecorations.forEach((rangeDecorationItem) => {
|
|
4437
|
-
const slateRange = toSlateRange(
|
|
5160
|
+
const slateRange = toSlateRange(
|
|
5161
|
+
rangeDecorationItem.selection,
|
|
5162
|
+
slateEditor
|
|
5163
|
+
);
|
|
4438
5164
|
if (!Range.isRange(slateRange)) {
|
|
4439
5165
|
rangeDecorationItem.onMoved && rangeDecorationItem.onMoved({
|
|
4440
5166
|
newSelection: null,
|
|
@@ -4445,14 +5171,21 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4445
5171
|
}
|
|
4446
5172
|
let newRange;
|
|
4447
5173
|
if (operation && (newRange = moveRangeByOperation(slateRange, operation), newRange && newRange !== slateRange || newRange === null && slateRange)) {
|
|
4448
|
-
const value = PortableTextEditor.getValue(portableTextEditor), newRangeSelection = toPortableTextRange(
|
|
5174
|
+
const value = PortableTextEditor.getValue(portableTextEditor), newRangeSelection = toPortableTextRange(
|
|
5175
|
+
value,
|
|
5176
|
+
newRange,
|
|
5177
|
+
schemaTypes
|
|
5178
|
+
);
|
|
4449
5179
|
rangeDecorationItem.onMoved && rangeDecorationItem.onMoved({
|
|
4450
5180
|
newSelection: newRangeSelection,
|
|
4451
5181
|
rangeDecoration: rangeDecorationItem,
|
|
4452
5182
|
origin: "local"
|
|
4453
5183
|
});
|
|
4454
5184
|
}
|
|
4455
|
-
newRange !== null && newSlateRanges.push({
|
|
5185
|
+
newRange !== null && newSlateRanges.push({
|
|
5186
|
+
...newRange || slateRange,
|
|
5187
|
+
rangeDecoration: rangeDecorationItem
|
|
5188
|
+
});
|
|
4456
5189
|
}), newSlateRanges.length > 0) {
|
|
4457
5190
|
setRangeDecorationsState(newSlateRanges);
|
|
4458
5191
|
return;
|
|
@@ -4505,11 +5238,20 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4505
5238
|
debug("Pasting normally"), slateEditor.insertData(event.clipboardData);
|
|
4506
5239
|
return;
|
|
4507
5240
|
}
|
|
4508
|
-
const value = PortableTextEditor.getValue(portableTextEditor), path = toPortableTextRange(
|
|
5241
|
+
const value = PortableTextEditor.getValue(portableTextEditor), path = toPortableTextRange(
|
|
5242
|
+
value,
|
|
5243
|
+
slateEditor.selection,
|
|
5244
|
+
schemaTypes
|
|
5245
|
+
)?.focus.path || [], onPasteResult = onPaste({ event, value, path, schemaTypes });
|
|
4509
5246
|
onPasteResult === void 0 ? (debug("No result from custom paste handler, pasting normally"), slateEditor.insertData(event.clipboardData)) : (change$.next({ type: "loading", isLoading: !0 }), Promise.resolve(onPasteResult).then((result) => {
|
|
4510
5247
|
debug("Custom paste function from client resolved", result), !result || !result.insert ? (debug("No result from custom paste handler, pasting normally"), slateEditor.insertData(event.clipboardData)) : result.insert ? slateEditor.insertFragment(
|
|
4511
|
-
toSlateValue(result.insert, {
|
|
4512
|
-
|
|
5248
|
+
toSlateValue(result.insert, {
|
|
5249
|
+
schemaTypes
|
|
5250
|
+
})
|
|
5251
|
+
) : console.warn(
|
|
5252
|
+
"Your onPaste function returned something unexpected:",
|
|
5253
|
+
result
|
|
5254
|
+
);
|
|
4513
5255
|
}).catch((error) => (console.error(error), error)).finally(() => {
|
|
4514
5256
|
change$.next({ type: "loading", isLoading: !1 });
|
|
4515
5257
|
}));
|
|
@@ -4534,7 +5276,10 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4534
5276
|
const [lastBlock, path] = Node.last(slateEditor, []), focusPath = slateEditor.selection.focus.path.slice(0, 1), lastPath = path.slice(0, 1);
|
|
4535
5277
|
if (Path.equals(focusPath, lastPath)) {
|
|
4536
5278
|
const node = Node.descendant(slateEditor, path.slice(0, 1));
|
|
4537
|
-
lastBlock && Editor.isVoid(slateEditor, node) && (Transforms.insertNodes(
|
|
5279
|
+
lastBlock && Editor.isVoid(slateEditor, node) && (Transforms.insertNodes(
|
|
5280
|
+
slateEditor,
|
|
5281
|
+
slateEditor.pteCreateTextBlock({ decorators: [] })
|
|
5282
|
+
), slateEditor.onChange());
|
|
4538
5283
|
}
|
|
4539
5284
|
}
|
|
4540
5285
|
},
|
|
@@ -4560,7 +5305,10 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4560
5305
|
return;
|
|
4561
5306
|
const existingDOMRange = domSelection.getRangeAt(0);
|
|
4562
5307
|
try {
|
|
4563
|
-
const newDOMRange = ReactEditor.toDOMRange(
|
|
5308
|
+
const newDOMRange = ReactEditor.toDOMRange(
|
|
5309
|
+
slateEditor,
|
|
5310
|
+
slateEditor.selection
|
|
5311
|
+
);
|
|
4564
5312
|
(newDOMRange.startOffset !== existingDOMRange.startOffset || newDOMRange.endOffset !== existingDOMRange.endOffset) && (debug("DOM range out of sync, validating selection"), domSelection?.removeAllRanges(), domSelection.addRange(newDOMRange));
|
|
4565
5313
|
} catch {
|
|
4566
5314
|
debug("Could not resolve selection, selecting top document"), Transforms.deselect(slateEditor), slateEditor.children.length > 0 && Transforms.select(slateEditor, [0, 0]), slateEditor.onChange();
|
|
@@ -4608,13 +5356,19 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4608
5356
|
];
|
|
4609
5357
|
if (path.length === 0)
|
|
4610
5358
|
return [];
|
|
4611
|
-
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, {
|
|
5359
|
+
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, {
|
|
5360
|
+
anchor: { path, offset: 0 },
|
|
5361
|
+
focus: { path, offset: 0 }
|
|
5362
|
+
}) || Range.includes(item, path));
|
|
4612
5363
|
return result.length > 0 ? result : [];
|
|
4613
5364
|
},
|
|
4614
5365
|
[slateEditor, schemaTypes, rangeDecorationState]
|
|
4615
5366
|
);
|
|
4616
5367
|
return useEffect(() => {
|
|
4617
|
-
ref.current = ReactEditor.toDOMNode(
|
|
5368
|
+
ref.current = ReactEditor.toDOMNode(
|
|
5369
|
+
slateEditor,
|
|
5370
|
+
slateEditor
|
|
5371
|
+
), setEditableElement(ref.current);
|
|
4618
5372
|
}, [slateEditor, ref]), portableTextEditor ? hasInvalidValue ? null : /* @__PURE__ */ jsx(
|
|
4619
5373
|
Editable,
|
|
4620
5374
|
{
|