@portabletext/editor 1.0.19 → 1.1.1
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 +142 -67
- package/lib/index.d.ts +142 -67
- package/lib/index.esm.js +1130 -371
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +1130 -371
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +1130 -371
- package/lib/index.mjs.map +1 -1
- package/package.json +4 -18
- package/src/editor/Editable.tsx +128 -55
- package/src/editor/PortableTextEditor.tsx +66 -32
- package/src/editor/__tests__/PortableTextEditor.test.tsx +44 -18
- package/src/editor/__tests__/PortableTextEditorTester.tsx +50 -38
- package/src/editor/__tests__/RangeDecorations.test.tsx +4 -6
- package/src/editor/__tests__/handleClick.test.tsx +28 -9
- package/src/editor/__tests__/insert-block.test.tsx +24 -8
- package/src/editor/__tests__/pteWarningsSelfSolving.test.tsx +31 -63
- package/src/editor/__tests__/utils.ts +10 -4
- package/src/editor/components/DraggableBlock.tsx +36 -13
- package/src/editor/components/Element.tsx +73 -33
- package/src/editor/components/Leaf.tsx +114 -76
- package/src/editor/components/SlateContainer.tsx +14 -7
- package/src/editor/components/Synchronizer.tsx +8 -5
- package/src/editor/hooks/usePortableTextEditor.ts +3 -3
- package/src/editor/hooks/usePortableTextEditorSelection.tsx +10 -4
- package/src/editor/hooks/useSyncValue.test.tsx +9 -4
- package/src/editor/hooks/useSyncValue.ts +198 -133
- package/src/editor/nodes/DefaultAnnotation.tsx +6 -4
- package/src/editor/nodes/DefaultObject.tsx +1 -1
- package/src/editor/plugins/__tests__/createWithInsertData.test.tsx +23 -8
- 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 +5 -3
- package/src/editor/plugins/__tests__/withPortableTextLists.test.tsx +4 -2
- package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +61 -19
- 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 +361 -131
- package/src/editor/plugins/createWithHotKeys.ts +46 -130
- package/src/editor/plugins/createWithInsertBreak.ts +167 -28
- package/src/editor/plugins/createWithInsertData.ts +66 -30
- package/src/editor/plugins/createWithMaxBlocks.ts +6 -3
- package/src/editor/plugins/createWithObjectKeys.ts +7 -3
- package/src/editor/plugins/createWithPatches.ts +66 -24
- package/src/editor/plugins/createWithPlaceholderBlock.ts +9 -5
- package/src/editor/plugins/createWithPortableTextBlockStyle.ts +17 -7
- package/src/editor/plugins/createWithPortableTextLists.ts +21 -9
- package/src/editor/plugins/createWithPortableTextMarkModel.ts +217 -52
- package/src/editor/plugins/createWithPortableTextSelections.ts +11 -9
- package/src/editor/plugins/createWithSchemaTypes.ts +26 -10
- package/src/editor/plugins/createWithUndoRedo.ts +106 -27
- package/src/editor/plugins/createWithUtils.ts +33 -11
- package/src/editor/plugins/index.ts +34 -13
- package/src/types/editor.ts +73 -44
- package/src/types/options.ts +7 -5
- package/src/types/slate.ts +6 -6
- package/src/utils/__tests__/dmpToOperations.test.ts +41 -16
- package/src/utils/__tests__/operationToPatches.test.ts +4 -3
- package/src/utils/__tests__/patchToOperations.test.ts +16 -5
- package/src/utils/__tests__/ranges.test.ts +9 -4
- package/src/utils/__tests__/valueNormalization.test.tsx +12 -4
- package/src/utils/__tests__/values.test.ts +0 -1
- package/src/utils/applyPatch.ts +78 -29
- package/src/utils/getPortableTextMemberSchemaTypes.ts +38 -23
- package/src/utils/operationToPatches.ts +123 -44
- package/src/utils/paths.ts +26 -9
- package/src/utils/ranges.ts +16 -10
- package/src/utils/selection.ts +21 -9
- package/src/utils/ucs2Indices.ts +2 -2
- package/src/utils/validateValue.ts +118 -45
- package/src/utils/values.ts +38 -17
- package/src/utils/weakMaps.ts +20 -10
- package/src/utils/withChanges.ts +5 -3
- package/src/utils/withUndoRedo.ts +1 -1
- package/src/utils/withoutPatching.ts +1 -1
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
|
|
@@ -129,7 +133,9 @@ function keepObjectEquality(object, keyMap) {
|
|
|
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,10 @@ 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
|
+
() => alert(JSON.stringify(props.annotation)),
|
|
728
|
+
[props.annotation]
|
|
729
|
+
);
|
|
654
730
|
return /* @__PURE__ */ jsx("span", { style: { color: "blue" }, onClick: handleClick, children: props.children });
|
|
655
731
|
}
|
|
656
732
|
function getPortableTextMemberSchemaTypes(portableTextType) {
|
|
@@ -659,16 +735,24 @@ function getPortableTextMemberSchemaTypes(portableTextType) {
|
|
|
659
735
|
const blockType = portableTextType.of?.find(findBlockType);
|
|
660
736
|
if (!blockType)
|
|
661
737
|
throw new Error("Block type is not defined in this schema (required)");
|
|
662
|
-
const childrenField = blockType.fields?.find(
|
|
738
|
+
const childrenField = blockType.fields?.find(
|
|
739
|
+
(field) => field.name === "children"
|
|
740
|
+
);
|
|
663
741
|
if (!childrenField)
|
|
664
742
|
throw new Error("Children field for block type found in schema (required)");
|
|
665
743
|
const ofType = childrenField.type.of;
|
|
666
744
|
if (!ofType)
|
|
667
|
-
throw new Error(
|
|
745
|
+
throw new Error(
|
|
746
|
+
"Valid types for block children not found in schema (required)"
|
|
747
|
+
);
|
|
668
748
|
const spanType = ofType.find((memberType) => memberType.name === "span");
|
|
669
749
|
if (!spanType)
|
|
670
750
|
throw new Error("Span type not found in schema (required)");
|
|
671
|
-
const inlineObjectTypes = ofType.filter(
|
|
751
|
+
const inlineObjectTypes = ofType.filter(
|
|
752
|
+
(memberType) => memberType.name !== "span"
|
|
753
|
+
) || [], blockObjectTypes = portableTextType.of?.filter(
|
|
754
|
+
(field) => field.name !== blockType.name
|
|
755
|
+
) || [];
|
|
672
756
|
return {
|
|
673
757
|
styles: resolveEnabledStyles(blockType),
|
|
674
758
|
decorators: resolveEnabledDecorators(spanType),
|
|
@@ -682,10 +766,16 @@ function getPortableTextMemberSchemaTypes(portableTextType) {
|
|
|
682
766
|
};
|
|
683
767
|
}
|
|
684
768
|
function resolveEnabledStyles(blockType) {
|
|
685
|
-
const styleField = blockType.fields?.find(
|
|
769
|
+
const styleField = blockType.fields?.find(
|
|
770
|
+
(btField) => btField.name === "style"
|
|
771
|
+
);
|
|
686
772
|
if (!styleField)
|
|
687
|
-
throw new Error(
|
|
688
|
-
|
|
773
|
+
throw new Error(
|
|
774
|
+
"A field with name 'style' is not defined in the block type (required)."
|
|
775
|
+
);
|
|
776
|
+
const textStyles = styleField.type.options?.list && styleField.type.options.list?.filter(
|
|
777
|
+
(style) => style.value
|
|
778
|
+
);
|
|
689
779
|
if (!textStyles || textStyles.length === 0)
|
|
690
780
|
throw new Error(
|
|
691
781
|
"The style fields need at least one style defined. I.e: {title: 'Normal', value: 'normal'}."
|
|
@@ -696,9 +786,13 @@ function resolveEnabledDecorators(spanType) {
|
|
|
696
786
|
return spanType.decorators;
|
|
697
787
|
}
|
|
698
788
|
function resolveEnabledListItems(blockType) {
|
|
699
|
-
const listField = blockType.fields?.find(
|
|
789
|
+
const listField = blockType.fields?.find(
|
|
790
|
+
(btField) => btField.name === "listItem"
|
|
791
|
+
);
|
|
700
792
|
if (!listField)
|
|
701
|
-
throw new Error(
|
|
793
|
+
throw new Error(
|
|
794
|
+
"A field with name 'listItem' is not defined in the block type (required)."
|
|
795
|
+
);
|
|
702
796
|
const listItems = listField.type.options?.list && listField.type.options.list.filter((list) => list.value);
|
|
703
797
|
if (!listItems)
|
|
704
798
|
throw new Error("The list field need at least to be an empty array");
|
|
@@ -724,7 +818,12 @@ function createOperationToPatches(types) {
|
|
|
724
818
|
const textChild = editor.isTextBlock(block) && editor.isTextSpan(block.children[operation.path[1]]) && block.children[operation.path[1]];
|
|
725
819
|
if (!textChild)
|
|
726
820
|
throw new Error("Could not find child");
|
|
727
|
-
const path = [
|
|
821
|
+
const path = [
|
|
822
|
+
{ _key: block._key },
|
|
823
|
+
"children",
|
|
824
|
+
{ _key: textChild._key },
|
|
825
|
+
"text"
|
|
826
|
+
], 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
827
|
return patch.value.length ? [patch] : [];
|
|
729
828
|
}
|
|
730
829
|
function removeTextPatch(editor, operation, beforeValue) {
|
|
@@ -736,7 +835,12 @@ function createOperationToPatches(types) {
|
|
|
736
835
|
throw new Error("Expected span");
|
|
737
836
|
if (!textChild)
|
|
738
837
|
throw new Error("Could not find child");
|
|
739
|
-
const path = [
|
|
838
|
+
const path = [
|
|
839
|
+
{ _key: block._key },
|
|
840
|
+
"children",
|
|
841
|
+
{ _key: textChild._key },
|
|
842
|
+
"text"
|
|
843
|
+
], 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
844
|
return patch.value ? [patch] : [];
|
|
741
845
|
}
|
|
742
846
|
function setNodePatch(editor, operation) {
|
|
@@ -748,7 +852,9 @@ function createOperationToPatches(types) {
|
|
|
748
852
|
{ ...editor.children[operation.path[0]], ...operation.newProperties },
|
|
749
853
|
isUndefined
|
|
750
854
|
);
|
|
751
|
-
return [
|
|
855
|
+
return [
|
|
856
|
+
set(fromSlateValue([setNode], textBlockName)[0], [{ _key: block._key }])
|
|
857
|
+
];
|
|
752
858
|
} else if (operation.path.length === 2) {
|
|
753
859
|
const block = editor.children[operation.path[0]];
|
|
754
860
|
if (editor.isTextBlock(block)) {
|
|
@@ -759,11 +865,23 @@ function createOperationToPatches(types) {
|
|
|
759
865
|
if (keys.length === 1 && keyName === "_key") {
|
|
760
866
|
const val = get(operation.newProperties, keyName);
|
|
761
867
|
patches.push(
|
|
762
|
-
set(val, [
|
|
868
|
+
set(val, [
|
|
869
|
+
{ _key: blockKey },
|
|
870
|
+
"children",
|
|
871
|
+
block.children.indexOf(child),
|
|
872
|
+
keyName
|
|
873
|
+
])
|
|
763
874
|
);
|
|
764
875
|
} else {
|
|
765
876
|
const val = get(operation.newProperties, keyName);
|
|
766
|
-
patches.push(
|
|
877
|
+
patches.push(
|
|
878
|
+
set(val, [
|
|
879
|
+
{ _key: blockKey },
|
|
880
|
+
"children",
|
|
881
|
+
{ _key: childKey },
|
|
882
|
+
keyName
|
|
883
|
+
])
|
|
884
|
+
);
|
|
767
885
|
}
|
|
768
886
|
}), patches;
|
|
769
887
|
}
|
|
@@ -771,21 +889,27 @@ function createOperationToPatches(types) {
|
|
|
771
889
|
}
|
|
772
890
|
throw new Error("Could not find a valid block");
|
|
773
891
|
} else
|
|
774
|
-
throw new Error(
|
|
892
|
+
throw new Error(
|
|
893
|
+
`Unexpected path encountered: ${JSON.stringify(operation.path)}`
|
|
894
|
+
);
|
|
775
895
|
}
|
|
776
896
|
function insertNodePatch(editor, operation, beforeValue) {
|
|
777
897
|
const block = beforeValue[operation.path[0]], isTextBlock = editor.isTextBlock(block);
|
|
778
898
|
if (operation.path.length === 1) {
|
|
779
899
|
const position = operation.path[0] === 0 ? "before" : "after", beforeBlock = beforeValue[operation.path[0] - 1], targetKey = operation.path[0] === 0 ? block?._key : beforeBlock?._key;
|
|
780
900
|
return targetKey ? [
|
|
781
|
-
insert(
|
|
782
|
-
|
|
783
|
-
|
|
901
|
+
insert(
|
|
902
|
+
[fromSlateValue([operation.node], textBlockName)[0]],
|
|
903
|
+
position,
|
|
904
|
+
[{ _key: targetKey }]
|
|
905
|
+
)
|
|
784
906
|
] : [
|
|
785
907
|
setIfMissing(beforeValue, []),
|
|
786
|
-
insert(
|
|
787
|
-
operation.
|
|
788
|
-
|
|
908
|
+
insert(
|
|
909
|
+
[fromSlateValue([operation.node], textBlockName)[0]],
|
|
910
|
+
"before",
|
|
911
|
+
[operation.path[0]]
|
|
912
|
+
)
|
|
789
913
|
];
|
|
790
914
|
} else if (isTextBlock && operation.path.length === 2 && editor.children[operation.path[0]]) {
|
|
791
915
|
const position = block.children.length === 0 || !block.children[operation.path[1] - 1] ? "before" : "after", node = { ...operation.node };
|
|
@@ -808,7 +932,9 @@ function createOperationToPatches(types) {
|
|
|
808
932
|
])
|
|
809
933
|
];
|
|
810
934
|
}
|
|
811
|
-
return debug$k(
|
|
935
|
+
return debug$k(
|
|
936
|
+
"Something was inserted into a void block. Not producing editor patches."
|
|
937
|
+
), [];
|
|
812
938
|
}
|
|
813
939
|
function splitNodePatch(editor, operation, beforeValue) {
|
|
814
940
|
const patches = [], splitBlock = editor.children[operation.path[0]];
|
|
@@ -825,7 +951,9 @@ function createOperationToPatches(types) {
|
|
|
825
951
|
[editor.children[operation.path[0] + 1]],
|
|
826
952
|
textBlockName
|
|
827
953
|
)[0];
|
|
828
|
-
targetValue && (patches.push(
|
|
954
|
+
targetValue && (patches.push(
|
|
955
|
+
insert([targetValue], "after", [{ _key: splitBlock._key }])
|
|
956
|
+
), oldBlock.children.slice(operation.position).forEach((span) => {
|
|
829
957
|
const path = [{ _key: oldBlock._key }, "children", { _key: span._key }];
|
|
830
958
|
patches.push(unset(path));
|
|
831
959
|
}));
|
|
@@ -839,7 +967,10 @@ function createOperationToPatches(types) {
|
|
|
839
967
|
[
|
|
840
968
|
{
|
|
841
969
|
...splitBlock,
|
|
842
|
-
children: splitBlock.children.slice(
|
|
970
|
+
children: splitBlock.children.slice(
|
|
971
|
+
operation.path[1] + 1,
|
|
972
|
+
operation.path[1] + 2
|
|
973
|
+
)
|
|
843
974
|
}
|
|
844
975
|
],
|
|
845
976
|
textBlockName
|
|
@@ -871,10 +1002,14 @@ function createOperationToPatches(types) {
|
|
|
871
1002
|
throw new Error("Block not found");
|
|
872
1003
|
} else if (editor.isTextBlock(block) && operation.path.length === 2) {
|
|
873
1004
|
const spanToRemove = block.children[operation.path[1]];
|
|
874
|
-
return spanToRemove ? block.children.filter(
|
|
1005
|
+
return spanToRemove ? block.children.filter(
|
|
1006
|
+
(span) => span._key === operation.node._key
|
|
1007
|
+
).length > 1 ? (console.warn(
|
|
875
1008
|
`Multiple spans have \`_key\` ${operation.node._key}. It's ambiguous which one to remove.`,
|
|
876
1009
|
JSON.stringify(block, null, 2)
|
|
877
|
-
), []) : [
|
|
1010
|
+
), []) : [
|
|
1011
|
+
unset([{ _key: block._key }, "children", { _key: spanToRemove._key }])
|
|
1012
|
+
] : (debug$k("Span not found in editor trying to remove node"), []);
|
|
878
1013
|
} else
|
|
879
1014
|
return debug$k("Not creating patch inside object block"), [];
|
|
880
1015
|
}
|
|
@@ -882,13 +1017,18 @@ function createOperationToPatches(types) {
|
|
|
882
1017
|
const patches = [], block = beforeValue[operation.path[0]], updatedBlock = editor.children[operation.path[0]];
|
|
883
1018
|
if (operation.path.length === 1)
|
|
884
1019
|
if (block?._key) {
|
|
885
|
-
const newBlock = fromSlateValue(
|
|
1020
|
+
const newBlock = fromSlateValue(
|
|
1021
|
+
[editor.children[operation.path[0] - 1]],
|
|
1022
|
+
textBlockName
|
|
1023
|
+
)[0];
|
|
886
1024
|
patches.push(set(newBlock, [{ _key: newBlock._key }])), patches.push(unset([{ _key: block._key }]));
|
|
887
1025
|
} else
|
|
888
1026
|
throw new Error("Target key not found!");
|
|
889
1027
|
else if (editor.isTextBlock(block) && editor.isTextBlock(updatedBlock) && operation.path.length === 2) {
|
|
890
1028
|
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(
|
|
1029
|
+
updatedSpan && (block.children.filter(
|
|
1030
|
+
(span) => span._key === updatedSpan._key
|
|
1031
|
+
).length === 1 ? patches.push(
|
|
892
1032
|
set(updatedSpan.text, [
|
|
893
1033
|
{ _key: block._key },
|
|
894
1034
|
"children",
|
|
@@ -898,7 +1038,11 @@ function createOperationToPatches(types) {
|
|
|
898
1038
|
) : console.warn(
|
|
899
1039
|
`Multiple spans have \`_key\` ${updatedSpan._key}. It's ambiguous which one to update.`,
|
|
900
1040
|
JSON.stringify(block, null, 2)
|
|
901
|
-
)), removedSpan && (block.children.filter(
|
|
1041
|
+
)), removedSpan && (block.children.filter(
|
|
1042
|
+
(span) => span._key === removedSpan._key
|
|
1043
|
+
).length === 1 ? patches.push(
|
|
1044
|
+
unset([{ _key: block._key }, "children", { _key: removedSpan._key }])
|
|
1045
|
+
) : console.warn(
|
|
902
1046
|
`Multiple spans have \`_key\` ${removedSpan._key}. It's ambiguous which one to remove.`,
|
|
903
1047
|
JSON.stringify(block, null, 2)
|
|
904
1048
|
));
|
|
@@ -911,7 +1055,9 @@ function createOperationToPatches(types) {
|
|
|
911
1055
|
if (operation.path.length === 1) {
|
|
912
1056
|
const position = operation.path[0] > operation.newPath[0] ? "before" : "after";
|
|
913
1057
|
patches.push(unset([{ _key: block._key }])), patches.push(
|
|
914
|
-
insert([fromSlateValue([block], textBlockName)[0]], position, [
|
|
1058
|
+
insert([fromSlateValue([block], textBlockName)[0]], position, [
|
|
1059
|
+
{ _key: targetBlock._key }
|
|
1060
|
+
])
|
|
915
1061
|
);
|
|
916
1062
|
} else if (operation.path.length === 2 && editor.isTextBlock(block) && editor.isTextBlock(targetBlock)) {
|
|
917
1063
|
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 +1119,24 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
973
1119
|
},
|
|
974
1120
|
focusBlock: () => {
|
|
975
1121
|
if (editor.selection) {
|
|
976
|
-
const block = Node.descendant(
|
|
1122
|
+
const block = Node.descendant(
|
|
1123
|
+
editor,
|
|
1124
|
+
editor.selection.focus.path.slice(0, 1)
|
|
1125
|
+
);
|
|
977
1126
|
if (block)
|
|
978
|
-
return fromSlateValue(
|
|
1127
|
+
return fromSlateValue(
|
|
1128
|
+
[block],
|
|
1129
|
+
types.block.name,
|
|
1130
|
+
KEY_TO_VALUE_ELEMENT.get(editor)
|
|
1131
|
+
)[0];
|
|
979
1132
|
}
|
|
980
1133
|
},
|
|
981
1134
|
focusChild: () => {
|
|
982
1135
|
if (editor.selection) {
|
|
983
|
-
const block = Node.descendant(
|
|
1136
|
+
const block = Node.descendant(
|
|
1137
|
+
editor,
|
|
1138
|
+
editor.selection.focus.path.slice(0, 1)
|
|
1139
|
+
);
|
|
984
1140
|
if (block && editor.isTextBlock(block))
|
|
985
1141
|
return fromSlateValue(
|
|
986
1142
|
[block],
|
|
@@ -1001,7 +1157,9 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1001
1157
|
if (!focusBlock)
|
|
1002
1158
|
throw new Error("No focused text block");
|
|
1003
1159
|
if (type.name !== types.span.name && !types.inlineObjects.some((t) => t.name === type.name))
|
|
1004
|
-
throw new Error(
|
|
1160
|
+
throw new Error(
|
|
1161
|
+
"This type cannot be inserted as a child to a text block"
|
|
1162
|
+
);
|
|
1005
1163
|
const child = toSlateValue(
|
|
1006
1164
|
[
|
|
1007
1165
|
{
|
|
@@ -1018,11 +1176,17 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1018
1176
|
],
|
|
1019
1177
|
portableTextEditor
|
|
1020
1178
|
)[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(
|
|
1179
|
+
return isSpanNode && focusNode._type !== types.span.name && (debug$j(
|
|
1180
|
+
"Inserting span child next to inline object child, moving selection + 1"
|
|
1181
|
+
), editor.move({ distance: 1, unit: "character" })), Transforms.insertNodes(editor, child, {
|
|
1022
1182
|
select: !0,
|
|
1023
1183
|
at: editor.selection
|
|
1024
1184
|
}), editor.onChange(), toPortableTextRange(
|
|
1025
|
-
fromSlateValue(
|
|
1185
|
+
fromSlateValue(
|
|
1186
|
+
editor.children,
|
|
1187
|
+
types.block.name,
|
|
1188
|
+
KEY_TO_VALUE_ELEMENT.get(editor)
|
|
1189
|
+
),
|
|
1026
1190
|
editor.selection,
|
|
1027
1191
|
types
|
|
1028
1192
|
)?.focus.path || [];
|
|
@@ -1047,7 +1211,11 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1047
1211
|
})
|
|
1048
1212
|
)[0];
|
|
1049
1213
|
return Editor.insertNode(editor, block), lastBlock && isEqualToEmptyEditor([lastBlock[0]], types) && Transforms.removeNodes(editor, { at: lastBlock[1] }), editor.onChange(), toPortableTextRange(
|
|
1050
|
-
fromSlateValue(
|
|
1214
|
+
fromSlateValue(
|
|
1215
|
+
editor.children,
|
|
1216
|
+
types.block.name,
|
|
1217
|
+
KEY_TO_VALUE_ELEMENT.get(editor)
|
|
1218
|
+
),
|
|
1051
1219
|
editor.selection,
|
|
1052
1220
|
types
|
|
1053
1221
|
)?.focus.path ?? [];
|
|
@@ -1059,7 +1227,11 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1059
1227
|
})
|
|
1060
1228
|
)[0];
|
|
1061
1229
|
return Editor.insertNode(editor, block), focusBlock && isEqualToEmptyEditor([focusBlock[0]], types) && Transforms.removeNodes(editor, { at: focusBlock[1] }), editor.onChange(), toPortableTextRange(
|
|
1062
|
-
fromSlateValue(
|
|
1230
|
+
fromSlateValue(
|
|
1231
|
+
editor.children,
|
|
1232
|
+
types.block.name,
|
|
1233
|
+
KEY_TO_VALUE_ELEMENT.get(editor)
|
|
1234
|
+
),
|
|
1063
1235
|
editor.selection,
|
|
1064
1236
|
types
|
|
1065
1237
|
)?.focus.path || [];
|
|
@@ -1085,10 +1257,16 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1085
1257
|
editor
|
|
1086
1258
|
);
|
|
1087
1259
|
if (slatePath) {
|
|
1088
|
-
const [block, blockPath] = Editor.node(
|
|
1260
|
+
const [block, blockPath] = Editor.node(
|
|
1261
|
+
editor,
|
|
1262
|
+
slatePath.focus.path.slice(0, 1)
|
|
1263
|
+
);
|
|
1089
1264
|
if (block && blockPath && typeof block._key == "string") {
|
|
1090
1265
|
if (path.length === 1 && slatePath.focus.path.length === 1)
|
|
1091
|
-
return [
|
|
1266
|
+
return [
|
|
1267
|
+
fromSlateValue([block], types.block.name)[0],
|
|
1268
|
+
[{ _key: block._key }]
|
|
1269
|
+
];
|
|
1092
1270
|
const ptBlock = fromSlateValue(
|
|
1093
1271
|
[block],
|
|
1094
1272
|
types.block.name,
|
|
@@ -1097,7 +1275,10 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1097
1275
|
if (editor.isTextBlock(ptBlock)) {
|
|
1098
1276
|
const ptChild = ptBlock.children[slatePath.focus.path[1]];
|
|
1099
1277
|
if (ptChild)
|
|
1100
|
-
return [
|
|
1278
|
+
return [
|
|
1279
|
+
ptChild,
|
|
1280
|
+
[{ _key: block._key }, "children", { _key: ptChild._key }]
|
|
1281
|
+
];
|
|
1101
1282
|
}
|
|
1102
1283
|
}
|
|
1103
1284
|
}
|
|
@@ -1164,44 +1345,74 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1164
1345
|
addAnnotation: (type, value) => {
|
|
1165
1346
|
const { selection: originalSelection } = editor;
|
|
1166
1347
|
let returnValue;
|
|
1167
|
-
if (originalSelection) {
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1348
|
+
if (originalSelection && (Range.isCollapsed(originalSelection) && (editor.pteExpandToWord(), editor.onChange()), editor.selection)) {
|
|
1349
|
+
let spanPath, markDefPath;
|
|
1350
|
+
const markDefPaths = [];
|
|
1351
|
+
Editor.withoutNormalizing(editor, () => {
|
|
1352
|
+
if (!editor.selection)
|
|
1353
|
+
return;
|
|
1354
|
+
const selectedBlocks = Editor.nodes(editor, {
|
|
1355
|
+
at: editor.selection,
|
|
1356
|
+
match: (node) => editor.isTextBlock(node),
|
|
1357
|
+
reverse: Range.isBackward(editor.selection)
|
|
1358
|
+
});
|
|
1359
|
+
for (const [block, blockPath] of selectedBlocks) {
|
|
1360
|
+
if (block.children.length === 0 || block.children.length === 1 && block.children[0].text === "")
|
|
1361
|
+
continue;
|
|
1362
|
+
const annotationKey = keyGenerator(), markDefs = block.markDefs ?? [];
|
|
1363
|
+
markDefs.find(
|
|
1364
|
+
(markDef) => markDef._type === type.name && markDef._key === annotationKey
|
|
1365
|
+
) === void 0 && (Transforms.setNodes(
|
|
1366
|
+
editor,
|
|
1367
|
+
{
|
|
1368
|
+
markDefs: [
|
|
1369
|
+
...markDefs,
|
|
1370
|
+
{
|
|
1371
|
+
_type: type.name,
|
|
1372
|
+
_key: annotationKey,
|
|
1373
|
+
...value
|
|
1374
|
+
}
|
|
1375
|
+
]
|
|
1376
|
+
},
|
|
1377
|
+
{ at: blockPath }
|
|
1378
|
+
), markDefPath = [
|
|
1379
|
+
{ _key: block._key },
|
|
1380
|
+
"markDefs",
|
|
1381
|
+
{ _key: annotationKey }
|
|
1382
|
+
], Range.isBackward(editor.selection) ? markDefPaths.unshift(markDefPath) : markDefPaths.push(markDefPath)), Transforms.setNodes(
|
|
1383
|
+
editor,
|
|
1384
|
+
{},
|
|
1385
|
+
{ match: Text.isText, split: !0 }
|
|
1386
|
+
);
|
|
1387
|
+
const children = Node.children(editor, blockPath);
|
|
1388
|
+
for (const [span, path] of children) {
|
|
1389
|
+
if (!editor.isTextSpan(span) || !Range.includes(editor.selection, path))
|
|
1390
|
+
continue;
|
|
1391
|
+
const marks = span.marks ?? [], existingSameTypeAnnotations = marks.filter(
|
|
1392
|
+
(mark) => markDefs.some(
|
|
1393
|
+
(markDef) => markDef._key === mark && markDef._type === type.name
|
|
1394
|
+
)
|
|
1395
|
+
);
|
|
1396
|
+
Transforms.setNodes(
|
|
1397
|
+
editor,
|
|
1398
|
+
{
|
|
1399
|
+
marks: [
|
|
1400
|
+
...marks.filter(
|
|
1401
|
+
(mark) => !existingSameTypeAnnotations.includes(mark)
|
|
1402
|
+
),
|
|
1403
|
+
annotationKey
|
|
1404
|
+
]
|
|
1405
|
+
},
|
|
1406
|
+
{ at: path }
|
|
1407
|
+
), spanPath = [{ _key: block._key }, "children", { _key: span._key }];
|
|
1193
1408
|
}
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
);
|
|
1200
|
-
newPortableTextEditorSelection && (returnValue = {
|
|
1201
|
-
spanPath: newPortableTextEditorSelection.focus.path,
|
|
1202
|
-
markDefPath: [{ _key: block._key }, "markDefs", { _key: annotationKey }]
|
|
1409
|
+
}
|
|
1410
|
+
markDefPath && spanPath && (returnValue = {
|
|
1411
|
+
markDefPath,
|
|
1412
|
+
markDefPaths,
|
|
1413
|
+
spanPath
|
|
1203
1414
|
});
|
|
1204
|
-
}),
|
|
1415
|
+
}), editor.onChange();
|
|
1205
1416
|
}
|
|
1206
1417
|
return returnValue;
|
|
1207
1418
|
},
|
|
@@ -1228,34 +1439,98 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1228
1439
|
voids: !0,
|
|
1229
1440
|
match: (node) => node._type === types.span.name || // Text children
|
|
1230
1441
|
!editor.isTextBlock(node) && Element$1.isElement(node)
|
|
1231
|
-
})), editor.children.length === 0 && (editor.children = [editor.
|
|
1442
|
+
})), editor.children.length === 0 && (editor.children = [editor.pteCreateTextBlock({ decorators: [] })]), editor.onChange();
|
|
1232
1443
|
}
|
|
1233
1444
|
}
|
|
1234
1445
|
},
|
|
1235
1446
|
removeAnnotation: (type) => {
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
if (selection && Range.isExpanded(selection)) {
|
|
1244
|
-
if (selection = editor.selection, !selection)
|
|
1447
|
+
debug$j("Removing annotation", type), Editor.withoutNormalizing(editor, () => {
|
|
1448
|
+
if (editor.selection)
|
|
1449
|
+
if (Range.isCollapsed(editor.selection)) {
|
|
1450
|
+
const [block, blockPath] = Editor.node(editor, editor.selection, {
|
|
1451
|
+
depth: 1
|
|
1452
|
+
});
|
|
1453
|
+
if (!editor.isTextBlock(block))
|
|
1245
1454
|
return;
|
|
1246
|
-
[
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1455
|
+
const potentialAnnotations = (block.markDefs ?? []).filter(
|
|
1456
|
+
(markDef) => markDef._type === type.name
|
|
1457
|
+
), [selectedChild, selectedChildPath] = Editor.node(
|
|
1458
|
+
editor,
|
|
1459
|
+
editor.selection,
|
|
1460
|
+
{
|
|
1461
|
+
depth: 2
|
|
1462
|
+
}
|
|
1463
|
+
);
|
|
1464
|
+
if (!editor.isTextSpan(selectedChild))
|
|
1465
|
+
return;
|
|
1466
|
+
const annotationToRemove = selectedChild.marks?.find(
|
|
1467
|
+
(mark) => potentialAnnotations.some((markDef) => markDef._key === mark)
|
|
1468
|
+
);
|
|
1469
|
+
if (!annotationToRemove)
|
|
1470
|
+
return;
|
|
1471
|
+
const previousSpansWithSameAnnotation = [];
|
|
1472
|
+
for (const [child, childPath] of Node.children(editor, blockPath, {
|
|
1473
|
+
reverse: !0
|
|
1474
|
+
}))
|
|
1475
|
+
if (editor.isTextSpan(child) && Path.isBefore(childPath, selectedChildPath))
|
|
1476
|
+
if (child.marks?.includes(annotationToRemove))
|
|
1477
|
+
previousSpansWithSameAnnotation.push([child, childPath]);
|
|
1478
|
+
else
|
|
1479
|
+
break;
|
|
1480
|
+
const nextSpansWithSameAnnotation = [];
|
|
1481
|
+
for (const [child, childPath] of Node.children(editor, blockPath))
|
|
1482
|
+
if (editor.isTextSpan(child) && Path.isAfter(childPath, selectedChildPath))
|
|
1483
|
+
if (child.marks?.includes(annotationToRemove))
|
|
1484
|
+
nextSpansWithSameAnnotation.push([child, childPath]);
|
|
1485
|
+
else
|
|
1486
|
+
break;
|
|
1487
|
+
for (const [child, childPath] of [
|
|
1488
|
+
...previousSpansWithSameAnnotation,
|
|
1489
|
+
[selectedChild, selectedChildPath],
|
|
1490
|
+
...nextSpansWithSameAnnotation
|
|
1491
|
+
])
|
|
1492
|
+
Transforms.setNodes(
|
|
1493
|
+
editor,
|
|
1494
|
+
{
|
|
1495
|
+
marks: child.marks?.filter(
|
|
1496
|
+
(mark) => mark !== annotationToRemove
|
|
1497
|
+
)
|
|
1498
|
+
},
|
|
1499
|
+
{ at: childPath }
|
|
1500
|
+
);
|
|
1501
|
+
} else {
|
|
1502
|
+
Transforms.setNodes(
|
|
1503
|
+
editor,
|
|
1504
|
+
{},
|
|
1505
|
+
{
|
|
1506
|
+
match: (node) => editor.isTextSpan(node),
|
|
1507
|
+
split: !0,
|
|
1508
|
+
hanging: !0
|
|
1509
|
+
}
|
|
1510
|
+
);
|
|
1511
|
+
const blocks = Editor.nodes(editor, {
|
|
1512
|
+
at: editor.selection,
|
|
1513
|
+
match: (node) => editor.isTextBlock(node)
|
|
1255
1514
|
});
|
|
1515
|
+
for (const [block, blockPath] of blocks) {
|
|
1516
|
+
const children = Node.children(editor, blockPath);
|
|
1517
|
+
for (const [child, childPath] of children) {
|
|
1518
|
+
if (!editor.isTextSpan(child) || !Range.includes(editor.selection, childPath))
|
|
1519
|
+
continue;
|
|
1520
|
+
const markDefs = block.markDefs ?? [], marks = child.marks ?? [], marksWithoutAnnotation = marks.filter((mark) => markDefs.find(
|
|
1521
|
+
(markDef2) => markDef2._key === mark
|
|
1522
|
+
)?._type !== type.name);
|
|
1523
|
+
marksWithoutAnnotation.length !== marks.length && Transforms.setNodes(
|
|
1524
|
+
editor,
|
|
1525
|
+
{
|
|
1526
|
+
marks: marksWithoutAnnotation
|
|
1527
|
+
},
|
|
1528
|
+
{ at: childPath }
|
|
1529
|
+
);
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1256
1532
|
}
|
|
1257
|
-
|
|
1258
|
-
}
|
|
1533
|
+
}), editor.onChange();
|
|
1259
1534
|
},
|
|
1260
1535
|
getSelection: () => {
|
|
1261
1536
|
let ptRange = null;
|
|
@@ -1264,14 +1539,22 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1264
1539
|
if (existing)
|
|
1265
1540
|
return existing;
|
|
1266
1541
|
ptRange = toPortableTextRange(
|
|
1267
|
-
fromSlateValue(
|
|
1542
|
+
fromSlateValue(
|
|
1543
|
+
editor.children,
|
|
1544
|
+
types.block.name,
|
|
1545
|
+
KEY_TO_VALUE_ELEMENT.get(editor)
|
|
1546
|
+
),
|
|
1268
1547
|
editor.selection,
|
|
1269
1548
|
types
|
|
1270
1549
|
), SLATE_TO_PORTABLE_TEXT_RANGE.set(editor.selection, ptRange);
|
|
1271
1550
|
}
|
|
1272
1551
|
return ptRange;
|
|
1273
1552
|
},
|
|
1274
|
-
getValue: () => fromSlateValue(
|
|
1553
|
+
getValue: () => fromSlateValue(
|
|
1554
|
+
editor.children,
|
|
1555
|
+
types.block.name,
|
|
1556
|
+
KEY_TO_VALUE_ELEMENT.get(editor)
|
|
1557
|
+
),
|
|
1275
1558
|
isCollapsedSelection: () => !!editor.selection && Range.isCollapsed(editor.selection),
|
|
1276
1559
|
isExpandedSelection: () => !!editor.selection && Range.isExpanded(editor.selection),
|
|
1277
1560
|
insertBreak: () => {
|
|
@@ -1285,23 +1568,94 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
|
|
|
1285
1568
|
}), editor;
|
|
1286
1569
|
};
|
|
1287
1570
|
}
|
|
1288
|
-
function createWithInsertBreak(types) {
|
|
1571
|
+
function createWithInsertBreak(types, keyGenerator) {
|
|
1289
1572
|
return function(editor) {
|
|
1290
1573
|
const { insertBreak } = editor;
|
|
1291
1574
|
return editor.insertBreak = () => {
|
|
1292
|
-
if (editor.selection) {
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1575
|
+
if (!editor.selection) {
|
|
1576
|
+
insertBreak();
|
|
1577
|
+
return;
|
|
1578
|
+
}
|
|
1579
|
+
const focusBlockPath = editor.selection.focus.path.slice(0, 1), focusBlock = Node.descendant(editor, focusBlockPath);
|
|
1580
|
+
if (editor.isTextBlock(focusBlock)) {
|
|
1581
|
+
const [start, end] = Range.edges(editor.selection), isEndAtStartOfBlock = isEqual(end, {
|
|
1582
|
+
path: [...focusBlockPath, 0],
|
|
1583
|
+
offset: 0
|
|
1584
|
+
});
|
|
1585
|
+
if (isEndAtStartOfBlock && Range.isCollapsed(editor.selection)) {
|
|
1586
|
+
const focusDecorators = editor.isTextSpan(focusBlock.children[0]) ? (focusBlock.children[0].marks ?? []).filter(
|
|
1587
|
+
(mark) => types.decorators.some((decorator) => decorator.value === mark)
|
|
1588
|
+
) : [];
|
|
1589
|
+
Editor.insertNode(
|
|
1590
|
+
editor,
|
|
1591
|
+
editor.pteCreateTextBlock({ decorators: focusDecorators })
|
|
1592
|
+
);
|
|
1593
|
+
const [nextBlockPath] = Path.next(focusBlockPath);
|
|
1594
|
+
Transforms.select(editor, {
|
|
1595
|
+
anchor: { path: [nextBlockPath, 0], offset: 0 },
|
|
1596
|
+
focus: { path: [nextBlockPath, 0], offset: 0 }
|
|
1597
|
+
}), editor.onChange();
|
|
1598
|
+
return;
|
|
1599
|
+
}
|
|
1600
|
+
const lastFocusBlockChild = focusBlock.children[focusBlock.children.length - 1], isStartAtEndOfBlock = isEqual(start, {
|
|
1601
|
+
path: [...focusBlockPath, focusBlock.children.length - 1],
|
|
1602
|
+
offset: editor.isTextSpan(lastFocusBlockChild) ? lastFocusBlockChild.text.length : 0
|
|
1603
|
+
});
|
|
1604
|
+
if (!isEndAtStartOfBlock && !isStartAtEndOfBlock) {
|
|
1605
|
+
Editor.withoutNormalizing(editor, () => {
|
|
1606
|
+
if (!editor.selection)
|
|
1607
|
+
return;
|
|
1608
|
+
Transforms.splitNodes(editor, {
|
|
1609
|
+
at: editor.selection
|
|
1610
|
+
});
|
|
1611
|
+
const [nextNode, nextNodePath] = Editor.node(
|
|
1612
|
+
editor,
|
|
1613
|
+
Path.next(focusBlockPath),
|
|
1614
|
+
{ depth: 1 }
|
|
1615
|
+
);
|
|
1616
|
+
if (Transforms.setSelection(editor, {
|
|
1617
|
+
anchor: { path: [...nextNodePath, 0], offset: 0 },
|
|
1618
|
+
focus: { path: [...nextNodePath, 0], offset: 0 }
|
|
1619
|
+
}), editor.isTextBlock(nextNode) && nextNode.markDefs && nextNode.markDefs.length > 0) {
|
|
1620
|
+
const newMarkDefKeys = /* @__PURE__ */ new Map(), prevNodeSpans = Array.from(
|
|
1621
|
+
Node.children(editor, focusBlockPath)
|
|
1622
|
+
).map((entry) => entry[0]).filter((node) => editor.isTextSpan(node)), children = Node.children(editor, nextNodePath);
|
|
1623
|
+
for (const [child, childPath] of children) {
|
|
1624
|
+
if (!editor.isTextSpan(child))
|
|
1625
|
+
continue;
|
|
1626
|
+
const marks = child.marks ?? [];
|
|
1627
|
+
for (const mark of marks)
|
|
1628
|
+
types.decorators.some(
|
|
1629
|
+
(decorator) => decorator.value === mark
|
|
1630
|
+
) || prevNodeSpans.some(
|
|
1631
|
+
(prevNodeSpan) => prevNodeSpan.marks?.includes(mark)
|
|
1632
|
+
) && !newMarkDefKeys.has(mark) && newMarkDefKeys.set(mark, keyGenerator());
|
|
1633
|
+
const newMarks = marks.map(
|
|
1634
|
+
(mark) => newMarkDefKeys.get(mark) ?? mark
|
|
1635
|
+
);
|
|
1636
|
+
isEqual(marks, newMarks) || Transforms.setNodes(
|
|
1637
|
+
editor,
|
|
1638
|
+
{ marks: newMarks },
|
|
1639
|
+
{
|
|
1640
|
+
at: childPath
|
|
1641
|
+
}
|
|
1642
|
+
);
|
|
1643
|
+
}
|
|
1644
|
+
const newMarkDefs = nextNode.markDefs.map((markDef) => ({
|
|
1645
|
+
...markDef,
|
|
1646
|
+
_key: newMarkDefKeys.get(markDef._key) ?? markDef._key
|
|
1647
|
+
}));
|
|
1648
|
+
isEqual(nextNode.markDefs, newMarkDefs) || Transforms.setNodes(
|
|
1649
|
+
editor,
|
|
1650
|
+
{ markDefs: newMarkDefs },
|
|
1651
|
+
{
|
|
1652
|
+
at: nextNodePath,
|
|
1653
|
+
match: (node) => editor.isTextBlock(node)
|
|
1654
|
+
}
|
|
1655
|
+
);
|
|
1656
|
+
}
|
|
1657
|
+
}), editor.onChange();
|
|
1658
|
+
return;
|
|
1305
1659
|
}
|
|
1306
1660
|
}
|
|
1307
1661
|
insertBreak();
|
|
@@ -2101,11 +2455,13 @@ function toInt(num) {
|
|
|
2101
2455
|
const debug$i = debugWithName("applyPatches"), debugVerbose$4 = debug$i.enabled && !0;
|
|
2102
2456
|
function createApplyPatch(schemaTypes) {
|
|
2103
2457
|
let previousPatch;
|
|
2104
|
-
return
|
|
2458
|
+
return (editor, patch) => {
|
|
2105
2459
|
let changed = !1;
|
|
2106
|
-
debugVerbose$4 && (debug$i(
|
|
2460
|
+
debugVerbose$4 && (debug$i(
|
|
2461
|
+
`
|
|
2107
2462
|
|
|
2108
|
-
NEW PATCH =============================================================`
|
|
2463
|
+
NEW PATCH =============================================================`
|
|
2464
|
+
), debug$i(JSON.stringify(patch, null, 2)));
|
|
2109
2465
|
try {
|
|
2110
2466
|
switch (patch.type) {
|
|
2111
2467
|
case "insert":
|
|
@@ -2130,14 +2486,19 @@ NEW PATCH =============================================================`), debug
|
|
|
2130
2486
|
};
|
|
2131
2487
|
}
|
|
2132
2488
|
function diffMatchPatch(editor, patch) {
|
|
2133
|
-
const { block, child, childPath } = findBlockAndChildFromPath(
|
|
2489
|
+
const { block, child, childPath } = findBlockAndChildFromPath(
|
|
2490
|
+
editor,
|
|
2491
|
+
patch.path
|
|
2492
|
+
);
|
|
2134
2493
|
if (!block)
|
|
2135
2494
|
return debug$i("Block not found"), !1;
|
|
2136
2495
|
if (!child || !childPath)
|
|
2137
2496
|
return debug$i("Child not found"), !1;
|
|
2138
2497
|
if (!(block && editor.isTextBlock(block) && patch.path.length === 4 && patch.path[1] === "children" && patch.path[3] === "text") || !Text.isText(child))
|
|
2139
2498
|
return !1;
|
|
2140
|
-
const patches = parse(patch.value), [newValue] = apply(patches, child.text, {
|
|
2499
|
+
const patches = parse(patch.value), [newValue] = apply(patches, child.text, {
|
|
2500
|
+
allowExceedingIndices: !0
|
|
2501
|
+
}), diff$1 = cleanupEfficiency(diff(child.text, newValue), 5);
|
|
2141
2502
|
debugState(editor, "before");
|
|
2142
2503
|
let offset = 0;
|
|
2143
2504
|
for (const [op, text] of diff$1)
|
|
@@ -2171,12 +2532,17 @@ function insertPatch(editor, patch, schemaTypes) {
|
|
|
2171
2532
|
{ schemaTypes },
|
|
2172
2533
|
KEY_TO_SLATE_ELEMENT.get(editor)
|
|
2173
2534
|
), targetChildIndex = targetChildPath[1], normalizedIdx = position === "after" ? targetChildIndex + 1 : targetChildIndex, childInsertPath = [targetChildPath[0], normalizedIdx];
|
|
2174
|
-
return debug$i(`Inserting children at path ${childInsertPath}`), debugState(editor, "before"), childrenToInsert && Element$1.isElement(childrenToInsert[0]) && Transforms.insertNodes(editor, childrenToInsert[0].children, {
|
|
2535
|
+
return debug$i(`Inserting children at path ${childInsertPath}`), debugState(editor, "before"), childrenToInsert && Element$1.isElement(childrenToInsert[0]) && Transforms.insertNodes(editor, childrenToInsert[0].children, {
|
|
2536
|
+
at: childInsertPath
|
|
2537
|
+
}), debugState(editor, "after"), !0;
|
|
2175
2538
|
}
|
|
2176
2539
|
function setPatch(editor, patch) {
|
|
2177
2540
|
let value = patch.value;
|
|
2178
2541
|
typeof patch.path[3] == "string" && (value = {}, value[patch.path[3]] = patch.value);
|
|
2179
|
-
const { block, blockPath, child, childPath } = findBlockAndChildFromPath(
|
|
2542
|
+
const { block, blockPath, child, childPath } = findBlockAndChildFromPath(
|
|
2543
|
+
editor,
|
|
2544
|
+
patch.path
|
|
2545
|
+
);
|
|
2180
2546
|
if (!block)
|
|
2181
2547
|
return debug$i("Block not found"), !1;
|
|
2182
2548
|
const isTextBlock = editor.isTextBlock(block);
|
|
@@ -2237,12 +2603,15 @@ function unsetPatch(editor, patch, previousPatch) {
|
|
|
2237
2603
|
const previousSelection = editor.selection;
|
|
2238
2604
|
return Transforms.deselect(editor), editor.children.forEach((c, i) => {
|
|
2239
2605
|
Transforms.removeNodes(editor, { at: [i] });
|
|
2240
|
-
}), Transforms.insertNodes(editor, editor.
|
|
2606
|
+
}), Transforms.insertNodes(editor, editor.pteCreateTextBlock({ decorators: [] })), previousSelection && Transforms.select(editor, {
|
|
2241
2607
|
anchor: { path: [0, 0], offset: 0 },
|
|
2242
2608
|
focus: { path: [0, 0], offset: 0 }
|
|
2243
2609
|
}), editor.onChange(), debugState(editor, "after"), !0;
|
|
2244
2610
|
}
|
|
2245
|
-
const { block, blockPath, child, childPath } = findBlockAndChildFromPath(
|
|
2611
|
+
const { block, blockPath, child, childPath } = findBlockAndChildFromPath(
|
|
2612
|
+
editor,
|
|
2613
|
+
patch.path
|
|
2614
|
+
);
|
|
2246
2615
|
if (patch.path.length === 1) {
|
|
2247
2616
|
if (!block || !blockPath)
|
|
2248
2617
|
return debug$i("Block not found"), !1;
|
|
@@ -2274,7 +2643,12 @@ function findBlockAndChildFromPath(editor, path) {
|
|
|
2274
2643
|
const isMatch = isKeyedSegment(path[2]) ? node._key === path[2]._key : index === path[2];
|
|
2275
2644
|
return isMatch && (childIndex = index), isMatch;
|
|
2276
2645
|
});
|
|
2277
|
-
return child ? {
|
|
2646
|
+
return child ? {
|
|
2647
|
+
block,
|
|
2648
|
+
child,
|
|
2649
|
+
blockPath,
|
|
2650
|
+
childPath: blockPath?.concat(childIndex)
|
|
2651
|
+
} : { block, blockPath, child: void 0, childPath: void 0 };
|
|
2278
2652
|
}
|
|
2279
2653
|
const PATCHING = /* @__PURE__ */ new WeakMap();
|
|
2280
2654
|
function withoutPatching(editor, fn) {
|
|
@@ -2303,10 +2677,17 @@ function createWithUndoRedo(options) {
|
|
|
2303
2677
|
patches.forEach((patch) => {
|
|
2304
2678
|
if (!reset && patch.origin !== "local" && remotePatches) {
|
|
2305
2679
|
if (patch.type === "unset" && patch.path.length === 0) {
|
|
2306
|
-
debug$h(
|
|
2680
|
+
debug$h(
|
|
2681
|
+
"Someone else cleared the content, resetting undo/redo history"
|
|
2682
|
+
), editor.history = { undos: [], redos: [] }, remotePatches.splice(0, remotePatches.length), SAVING.set(editor, !0), reset = !0;
|
|
2307
2683
|
return;
|
|
2308
2684
|
}
|
|
2309
|
-
remotePatches.push({
|
|
2685
|
+
remotePatches.push({
|
|
2686
|
+
patch,
|
|
2687
|
+
time: /* @__PURE__ */ new Date(),
|
|
2688
|
+
snapshot,
|
|
2689
|
+
previousSnapshot
|
|
2690
|
+
});
|
|
2310
2691
|
}
|
|
2311
2692
|
}), previousSnapshot = snapshot;
|
|
2312
2693
|
});
|
|
@@ -2327,7 +2708,10 @@ function createWithUndoRedo(options) {
|
|
|
2327
2708
|
step.operations.push(op);
|
|
2328
2709
|
else {
|
|
2329
2710
|
const newStep = {
|
|
2330
|
-
operations: [
|
|
2711
|
+
operations: [
|
|
2712
|
+
...editor.selection === null ? [] : [createSelectOperation(editor)],
|
|
2713
|
+
op
|
|
2714
|
+
],
|
|
2331
2715
|
timestamp: /* @__PURE__ */ new Date()
|
|
2332
2716
|
};
|
|
2333
2717
|
undos.push(newStep), debug$h("Created new undo step", step);
|
|
@@ -2344,12 +2728,20 @@ function createWithUndoRedo(options) {
|
|
|
2344
2728
|
if (undos.length > 0) {
|
|
2345
2729
|
const step = undos[undos.length - 1];
|
|
2346
2730
|
if (debug$h("Undoing", step), step.operations.length > 0) {
|
|
2347
|
-
const otherPatches = remotePatches.filter(
|
|
2731
|
+
const otherPatches = remotePatches.filter(
|
|
2732
|
+
(item) => item.time >= step.timestamp
|
|
2733
|
+
);
|
|
2348
2734
|
let transformedOperations = step.operations;
|
|
2349
2735
|
otherPatches.forEach((item) => {
|
|
2350
2736
|
transformedOperations = flatten(
|
|
2351
2737
|
transformedOperations.map(
|
|
2352
|
-
(op) => transformOperation(
|
|
2738
|
+
(op) => transformOperation(
|
|
2739
|
+
editor,
|
|
2740
|
+
item.patch,
|
|
2741
|
+
op,
|
|
2742
|
+
item.snapshot,
|
|
2743
|
+
item.previousSnapshot
|
|
2744
|
+
)
|
|
2353
2745
|
)
|
|
2354
2746
|
);
|
|
2355
2747
|
});
|
|
@@ -2378,12 +2770,20 @@ function createWithUndoRedo(options) {
|
|
|
2378
2770
|
if (redos.length > 0) {
|
|
2379
2771
|
const step = redos[redos.length - 1];
|
|
2380
2772
|
if (debug$h("Redoing", step), step.operations.length > 0) {
|
|
2381
|
-
const otherPatches = remotePatches.filter(
|
|
2773
|
+
const otherPatches = remotePatches.filter(
|
|
2774
|
+
(item) => item.time >= step.timestamp
|
|
2775
|
+
);
|
|
2382
2776
|
let transformedOperations = step.operations;
|
|
2383
2777
|
otherPatches.forEach((item) => {
|
|
2384
2778
|
transformedOperations = flatten(
|
|
2385
2779
|
transformedOperations.map(
|
|
2386
|
-
(op) => transformOperation(
|
|
2780
|
+
(op) => transformOperation(
|
|
2781
|
+
editor,
|
|
2782
|
+
item.patch,
|
|
2783
|
+
op,
|
|
2784
|
+
item.snapshot,
|
|
2785
|
+
item.previousSnapshot
|
|
2786
|
+
)
|
|
2387
2787
|
)
|
|
2388
2788
|
);
|
|
2389
2789
|
});
|
|
@@ -2408,7 +2808,9 @@ function createWithUndoRedo(options) {
|
|
|
2408
2808
|
};
|
|
2409
2809
|
}
|
|
2410
2810
|
function transformOperation(editor, patch, operation, snapshot, previousSnapshot) {
|
|
2411
|
-
debugVerbose$3 && (debug$h(
|
|
2811
|
+
debugVerbose$3 && (debug$h(
|
|
2812
|
+
`Adjusting '${operation.type}' operation paths for '${patch.type}' patch`
|
|
2813
|
+
), debug$h(`Operation ${JSON.stringify(operation)}`), debug$h(`Patch ${JSON.stringify(patch)}`));
|
|
2412
2814
|
const transformedOperation = { ...operation };
|
|
2413
2815
|
if (patch.type === "insert" && patch.path.length === 1) {
|
|
2414
2816
|
const insertBlockIndex = (snapshot || []).findIndex(
|
|
@@ -2416,7 +2818,13 @@ function transformOperation(editor, patch, operation, snapshot, previousSnapshot
|
|
|
2416
2818
|
);
|
|
2417
2819
|
return debug$h(
|
|
2418
2820
|
`Adjusting block path (+${patch.items.length}) for '${transformedOperation.type}' operation and patch '${patch.type}'`
|
|
2419
|
-
), [
|
|
2821
|
+
), [
|
|
2822
|
+
adjustBlockPath(
|
|
2823
|
+
transformedOperation,
|
|
2824
|
+
patch.items.length,
|
|
2825
|
+
insertBlockIndex
|
|
2826
|
+
)
|
|
2827
|
+
];
|
|
2420
2828
|
}
|
|
2421
2829
|
if (patch.type === "unset" && patch.path.length === 1) {
|
|
2422
2830
|
const unsetBlockIndex = (previousSnapshot || []).findIndex(
|
|
@@ -2427,9 +2835,14 @@ function transformOperation(editor, patch, operation, snapshot, previousSnapshot
|
|
|
2427
2835
|
)), [adjustBlockPath(transformedOperation, -1, unsetBlockIndex)]);
|
|
2428
2836
|
}
|
|
2429
2837
|
if (patch.type === "unset" && patch.path.length === 0)
|
|
2430
|
-
return debug$h(
|
|
2838
|
+
return debug$h(
|
|
2839
|
+
`Adjusting selection for unset everything patch and ${operation.type} operation`
|
|
2840
|
+
), [];
|
|
2431
2841
|
if (patch.type === "diffMatchPatch") {
|
|
2432
|
-
const operationTargetBlock = findOperationTargetBlock(
|
|
2842
|
+
const operationTargetBlock = findOperationTargetBlock(
|
|
2843
|
+
editor,
|
|
2844
|
+
transformedOperation
|
|
2845
|
+
);
|
|
2433
2846
|
return !operationTargetBlock || !isEqual({ _key: operationTargetBlock._key }, patch.path[0]) ? [transformedOperation] : (parse(patch.value).forEach((diffPatch) => {
|
|
2434
2847
|
let adjustOffsetBy = 0, changedOffset = diffPatch.utf8Start1;
|
|
2435
2848
|
const { diffs } = diffPatch;
|
|
@@ -2455,7 +2868,10 @@ function transformOperation(editor, patch, operation, snapshot, previousSnapshot
|
|
|
2455
2868
|
function adjustBlockPath(operation, level, blockIndex) {
|
|
2456
2869
|
const transformedOperation = { ...operation };
|
|
2457
2870
|
if (blockIndex >= 0 && transformedOperation.type !== "set_selection" && Array.isArray(transformedOperation.path) && transformedOperation.path[0] >= blockIndex + level && transformedOperation.path[0] + level > -1) {
|
|
2458
|
-
const newPath = [
|
|
2871
|
+
const newPath = [
|
|
2872
|
+
transformedOperation.path[0] + level,
|
|
2873
|
+
...transformedOperation.path.slice(1)
|
|
2874
|
+
];
|
|
2459
2875
|
transformedOperation.path = newPath;
|
|
2460
2876
|
}
|
|
2461
2877
|
if (transformedOperation.type === "set_selection") {
|
|
@@ -2543,31 +2959,51 @@ function createWithPatches({
|
|
|
2543
2959
|
case "insert_text":
|
|
2544
2960
|
patches = [
|
|
2545
2961
|
...patches,
|
|
2546
|
-
...patchFunctions.insertTextPatch(
|
|
2962
|
+
...patchFunctions.insertTextPatch(
|
|
2963
|
+
editor,
|
|
2964
|
+
operation,
|
|
2965
|
+
previousChildren
|
|
2966
|
+
)
|
|
2547
2967
|
];
|
|
2548
2968
|
break;
|
|
2549
2969
|
case "remove_text":
|
|
2550
2970
|
patches = [
|
|
2551
2971
|
...patches,
|
|
2552
|
-
...patchFunctions.removeTextPatch(
|
|
2972
|
+
...patchFunctions.removeTextPatch(
|
|
2973
|
+
editor,
|
|
2974
|
+
operation,
|
|
2975
|
+
previousChildren
|
|
2976
|
+
)
|
|
2553
2977
|
];
|
|
2554
2978
|
break;
|
|
2555
2979
|
case "remove_node":
|
|
2556
2980
|
patches = [
|
|
2557
2981
|
...patches,
|
|
2558
|
-
...patchFunctions.removeNodePatch(
|
|
2982
|
+
...patchFunctions.removeNodePatch(
|
|
2983
|
+
editor,
|
|
2984
|
+
operation,
|
|
2985
|
+
previousChildren
|
|
2986
|
+
)
|
|
2559
2987
|
];
|
|
2560
2988
|
break;
|
|
2561
2989
|
case "split_node":
|
|
2562
2990
|
patches = [
|
|
2563
2991
|
...patches,
|
|
2564
|
-
...patchFunctions.splitNodePatch(
|
|
2992
|
+
...patchFunctions.splitNodePatch(
|
|
2993
|
+
editor,
|
|
2994
|
+
operation,
|
|
2995
|
+
previousChildren
|
|
2996
|
+
)
|
|
2565
2997
|
];
|
|
2566
2998
|
break;
|
|
2567
2999
|
case "insert_node":
|
|
2568
3000
|
patches = [
|
|
2569
3001
|
...patches,
|
|
2570
|
-
...patchFunctions.insertNodePatch(
|
|
3002
|
+
...patchFunctions.insertNodePatch(
|
|
3003
|
+
editor,
|
|
3004
|
+
operation,
|
|
3005
|
+
previousChildren
|
|
3006
|
+
)
|
|
2571
3007
|
];
|
|
2572
3008
|
break;
|
|
2573
3009
|
case "set_node":
|
|
@@ -2579,17 +3015,27 @@ function createWithPatches({
|
|
|
2579
3015
|
case "merge_node":
|
|
2580
3016
|
patches = [
|
|
2581
3017
|
...patches,
|
|
2582
|
-
...patchFunctions.mergeNodePatch(
|
|
3018
|
+
...patchFunctions.mergeNodePatch(
|
|
3019
|
+
editor,
|
|
3020
|
+
operation,
|
|
3021
|
+
previousChildren
|
|
3022
|
+
)
|
|
2583
3023
|
];
|
|
2584
3024
|
break;
|
|
2585
3025
|
case "move_node":
|
|
2586
3026
|
patches = [
|
|
2587
3027
|
...patches,
|
|
2588
|
-
...patchFunctions.moveNodePatch(
|
|
3028
|
+
...patchFunctions.moveNodePatch(
|
|
3029
|
+
editor,
|
|
3030
|
+
operation,
|
|
3031
|
+
previousChildren
|
|
3032
|
+
)
|
|
2589
3033
|
];
|
|
2590
3034
|
break;
|
|
2591
3035
|
}
|
|
2592
|
-
return !editorWasEmpty && editorIsEmpty && ["merge_node", "set_node", "remove_text", "remove_node"].includes(
|
|
3036
|
+
return !editorWasEmpty && editorIsEmpty && ["merge_node", "set_node", "remove_text", "remove_node"].includes(
|
|
3037
|
+
operation.type
|
|
3038
|
+
) && (patches = [...patches, unset([])], change$.next({
|
|
2593
3039
|
type: "unset",
|
|
2594
3040
|
previousValue: fromSlateValue(
|
|
2595
3041
|
previousChildren,
|
|
@@ -2622,7 +3068,10 @@ function createWithPlaceholderBlock() {
|
|
|
2622
3068
|
const node = op.node;
|
|
2623
3069
|
if (op.path[0] === 0 && Editor.isVoid(editor, node)) {
|
|
2624
3070
|
const nextPath = Path.next(op.path);
|
|
2625
|
-
editor.children[nextPath[0]] || (debug$f("Adding placeholder block"), Editor.insertNode(
|
|
3071
|
+
editor.children[nextPath[0]] || (debug$f("Adding placeholder block"), Editor.insertNode(
|
|
3072
|
+
editor,
|
|
3073
|
+
editor.pteCreateTextBlock({ decorators: [] })
|
|
3074
|
+
));
|
|
2626
3075
|
}
|
|
2627
3076
|
}
|
|
2628
3077
|
apply2(op);
|
|
@@ -2641,7 +3090,11 @@ function createWithPortableTextBlockStyle(types) {
|
|
|
2641
3090
|
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)) {
|
|
2642
3091
|
const [child] = Editor.node(editor, [op.path[0] + 1, 0]);
|
|
2643
3092
|
if (Text.isText(child) && child.text === "") {
|
|
2644
|
-
debug$e(`Normalizing split node to ${defaultStyle} style`, op), Transforms.setNodes(
|
|
3093
|
+
debug$e(`Normalizing split node to ${defaultStyle} style`, op), Transforms.setNodes(
|
|
3094
|
+
editor,
|
|
3095
|
+
{ style: defaultStyle },
|
|
3096
|
+
{ at: [op.path[0] + 1], voids: !1 }
|
|
3097
|
+
);
|
|
2645
3098
|
break;
|
|
2646
3099
|
}
|
|
2647
3100
|
}
|
|
@@ -2657,9 +3110,13 @@ function createWithPortableTextBlockStyle(types) {
|
|
|
2657
3110
|
match: (node) => editor.isTextBlock(node)
|
|
2658
3111
|
})
|
|
2659
3112
|
].forEach(([node, path]) => {
|
|
2660
|
-
editor.isTextBlock(node) && node.style === blockStyle ? (debug$e(`Unsetting block style '${blockStyle}'`), Transforms.setNodes(
|
|
2661
|
-
|
|
2662
|
-
|
|
3113
|
+
editor.isTextBlock(node) && node.style === blockStyle ? (debug$e(`Unsetting block style '${blockStyle}'`), Transforms.setNodes(
|
|
3114
|
+
editor,
|
|
3115
|
+
{ ...node, style: defaultStyle },
|
|
3116
|
+
{
|
|
3117
|
+
at: path
|
|
3118
|
+
}
|
|
3119
|
+
)) : (blockStyle ? debug$e(`Setting style '${blockStyle}'`) : debug$e("Setting default style", defaultStyle), Transforms.setNodes(
|
|
2663
3120
|
editor,
|
|
2664
3121
|
{
|
|
2665
3122
|
...node,
|
|
@@ -2741,7 +3198,13 @@ function createWithPortableTextLists(types) {
|
|
|
2741
3198
|
return selectedBlocks.length === 0 ? !1 : (selectedBlocks.forEach(([node, path]) => {
|
|
2742
3199
|
if (editor.isListBlock(node)) {
|
|
2743
3200
|
let level = node.level || 1;
|
|
2744
|
-
reverse ? (level--, debug$d(
|
|
3201
|
+
reverse ? (level--, debug$d(
|
|
3202
|
+
"Decrementing list level",
|
|
3203
|
+
Math.min(MAX_LIST_LEVEL, Math.max(1, level))
|
|
3204
|
+
)) : (level++, debug$d(
|
|
3205
|
+
"Incrementing list level",
|
|
3206
|
+
Math.min(MAX_LIST_LEVEL, Math.max(1, level))
|
|
3207
|
+
)), Transforms.setNodes(
|
|
2745
3208
|
editor,
|
|
2746
3209
|
{ level: Math.min(MAX_LIST_LEVEL, Math.max(1, level)) },
|
|
2747
3210
|
{ at: path }
|
|
@@ -2783,7 +3246,11 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
2783
3246
|
return function(editor) {
|
|
2784
3247
|
const { apply: apply2, normalizeNode } = editor, decorators = types.decorators.map((t) => t.value), forceNewSelection = () => {
|
|
2785
3248
|
editor.selection && (Transforms.select(editor, { ...editor.selection }), editor.selection = { ...editor.selection });
|
|
2786
|
-
const ptRange = toPortableTextRange(
|
|
3249
|
+
const ptRange = toPortableTextRange(
|
|
3250
|
+
editor.children,
|
|
3251
|
+
editor.selection,
|
|
3252
|
+
types
|
|
3253
|
+
);
|
|
2787
3254
|
change$.next({ type: "selection", selection: ptRange });
|
|
2788
3255
|
};
|
|
2789
3256
|
return editor.normalizeNode = (nodeEntry) => {
|
|
@@ -2797,17 +3264,26 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
2797
3264
|
"Merging spans",
|
|
2798
3265
|
JSON.stringify(child, null, 2),
|
|
2799
3266
|
JSON.stringify(nextNode, null, 2)
|
|
2800
|
-
), Transforms.mergeNodes(editor, {
|
|
3267
|
+
), Transforms.mergeNodes(editor, {
|
|
3268
|
+
at: [childPath[0], childPath[1] + 1],
|
|
3269
|
+
voids: !0
|
|
3270
|
+
});
|
|
2801
3271
|
return;
|
|
2802
3272
|
}
|
|
2803
3273
|
}
|
|
2804
3274
|
}
|
|
3275
|
+
if (editor.isTextBlock(node) && !Array.isArray(node.markDefs)) {
|
|
3276
|
+
debug$c("Adding .markDefs to block node"), Transforms.setNodes(editor, { markDefs: [] }, { at: path });
|
|
3277
|
+
return;
|
|
3278
|
+
}
|
|
2805
3279
|
if (editor.isTextSpan(node) && !Array.isArray(node.marks)) {
|
|
2806
3280
|
debug$c("Adding .marks to span node"), Transforms.setNodes(editor, { marks: [] }, { at: path });
|
|
2807
3281
|
return;
|
|
2808
3282
|
}
|
|
2809
3283
|
if (editor.isTextSpan(node)) {
|
|
2810
|
-
const blockPath = Path.parent(path), [block] = Editor.node(editor, blockPath), decorators2 = types.decorators.map((decorator) => decorator.value), annotations = node.marks?.filter(
|
|
3284
|
+
const blockPath = Path.parent(path), [block] = Editor.node(editor, blockPath), decorators2 = types.decorators.map((decorator) => decorator.value), annotations = node.marks?.filter(
|
|
3285
|
+
(mark) => !decorators2.includes(mark)
|
|
3286
|
+
);
|
|
2811
3287
|
if (editor.isTextBlock(block) && node.text === "" && annotations && annotations.length > 0) {
|
|
2812
3288
|
debug$c("Removing annotations from empty span node"), Transforms.setNodes(
|
|
2813
3289
|
editor,
|
|
@@ -2825,7 +3301,11 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
2825
3301
|
if (orphanedAnnotations.length > 0) {
|
|
2826
3302
|
debug$c("Removing orphaned annotations from span node"), Transforms.setNodes(
|
|
2827
3303
|
editor,
|
|
2828
|
-
{
|
|
3304
|
+
{
|
|
3305
|
+
marks: marks.filter(
|
|
3306
|
+
(mark) => !orphanedAnnotations.includes(mark)
|
|
3307
|
+
)
|
|
3308
|
+
},
|
|
2829
3309
|
{ at: childPath }
|
|
2830
3310
|
);
|
|
2831
3311
|
return;
|
|
@@ -2835,17 +3315,29 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
2835
3315
|
if (editor.isTextSpan(node)) {
|
|
2836
3316
|
const blockPath = Path.parent(path), [block] = Editor.node(editor, blockPath);
|
|
2837
3317
|
if (editor.isTextBlock(block)) {
|
|
2838
|
-
const decorators2 = types.decorators.map(
|
|
3318
|
+
const decorators2 = types.decorators.map(
|
|
3319
|
+
(decorator) => decorator.value
|
|
3320
|
+
), marks = node.marks ?? [], orphanedAnnotations = marks.filter((mark) => !decorators2.includes(mark) && !block.markDefs?.find((def) => def._key === mark));
|
|
2839
3321
|
if (orphanedAnnotations.length > 0) {
|
|
2840
3322
|
debug$c("Removing orphaned annotations from span node"), Transforms.setNodes(
|
|
2841
3323
|
editor,
|
|
2842
|
-
{
|
|
3324
|
+
{
|
|
3325
|
+
marks: marks.filter(
|
|
3326
|
+
(mark) => !orphanedAnnotations.includes(mark)
|
|
3327
|
+
)
|
|
3328
|
+
},
|
|
2843
3329
|
{ at: path }
|
|
2844
3330
|
);
|
|
2845
3331
|
return;
|
|
2846
3332
|
}
|
|
2847
3333
|
}
|
|
2848
3334
|
}
|
|
3335
|
+
if (editor.isTextBlock(node)) {
|
|
3336
|
+
const markDefs = node.markDefs ?? [], markDefKeys = /* @__PURE__ */ new Set(), newMarkDefs = [];
|
|
3337
|
+
for (const markDef of markDefs)
|
|
3338
|
+
markDefKeys.has(markDef._key) || (markDefKeys.add(markDef._key), newMarkDefs.push(markDef));
|
|
3339
|
+
markDefs.length !== newMarkDefs.length && (debug$c("Removing duplicate markDefs"), Transforms.setNodes(editor, { markDefs: newMarkDefs }, { at: path }));
|
|
3340
|
+
}
|
|
2849
3341
|
if (editor.isTextBlock(node) && !editor.operations.some(
|
|
2850
3342
|
(op) => op.type === "merge_node" && "markDefs" in op.properties && op.path.length === 1
|
|
2851
3343
|
)) {
|
|
@@ -2873,7 +3365,9 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
2873
3365
|
}
|
|
2874
3366
|
if (op.type === "insert_text") {
|
|
2875
3367
|
const { selection } = editor;
|
|
2876
|
-
if (selection && Range.isCollapsed(selection) && Editor.marks(editor)?.marks?.some(
|
|
3368
|
+
if (selection && Range.isCollapsed(selection) && Editor.marks(editor)?.marks?.some(
|
|
3369
|
+
(mark) => !decorators.includes(mark)
|
|
3370
|
+
)) {
|
|
2877
3371
|
const [node] = Array.from(
|
|
2878
3372
|
Editor.nodes(editor, {
|
|
2879
3373
|
mode: "lowest",
|
|
@@ -2924,7 +3418,11 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
2924
3418
|
...Editor.marks(editor) || {}
|
|
2925
3419
|
}.marks || []).filter((mark) => decorators.includes(mark));
|
|
2926
3420
|
Editor.withoutNormalizing(editor, () => {
|
|
2927
|
-
apply2(op), Transforms.setNodes(
|
|
3421
|
+
apply2(op), Transforms.setNodes(
|
|
3422
|
+
editor,
|
|
3423
|
+
{ marks: marksWithoutAnnotationMarks },
|
|
3424
|
+
{ at: op.path }
|
|
3425
|
+
);
|
|
2928
3426
|
}), editor.onChange();
|
|
2929
3427
|
return;
|
|
2930
3428
|
}
|
|
@@ -2940,7 +3438,11 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
2940
3438
|
const [targetBlock, targetPath] = Editor.node(editor, [op.path[0] - 1]);
|
|
2941
3439
|
if (editor.isTextBlock(targetBlock)) {
|
|
2942
3440
|
const oldDefs = Array.isArray(targetBlock.markDefs) && targetBlock.markDefs || [], newMarkDefs = uniq([...oldDefs, ...op.properties.markDefs]);
|
|
2943
|
-
debug$c("Copying markDefs over to merged block", op), Transforms.setNodes(
|
|
3441
|
+
debug$c("Copying markDefs over to merged block", op), Transforms.setNodes(
|
|
3442
|
+
editor,
|
|
3443
|
+
{ markDefs: newMarkDefs },
|
|
3444
|
+
{ at: targetPath, voids: !1 }
|
|
3445
|
+
), apply2(op);
|
|
2944
3446
|
return;
|
|
2945
3447
|
}
|
|
2946
3448
|
}
|
|
@@ -2949,8 +3451,17 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
2949
3451
|
if (editor.selection) {
|
|
2950
3452
|
if (Range.isExpanded(editor.selection))
|
|
2951
3453
|
Editor.withoutNormalizing(editor, () => {
|
|
2952
|
-
Transforms.setNodes(
|
|
2953
|
-
|
|
3454
|
+
Transforms.setNodes(
|
|
3455
|
+
editor,
|
|
3456
|
+
{},
|
|
3457
|
+
{ match: Text.isText, split: !0, hanging: !0 }
|
|
3458
|
+
);
|
|
3459
|
+
const splitTextNodes = Range.isRange(editor.selection) ? [
|
|
3460
|
+
...Editor.nodes(editor, {
|
|
3461
|
+
at: editor.selection,
|
|
3462
|
+
match: Text.isText
|
|
3463
|
+
})
|
|
3464
|
+
] : [];
|
|
2954
3465
|
splitTextNodes.length > 1 && splitTextNodes.every((node) => node[0].marks?.includes(mark)) ? editor.removeMark(mark) : splitTextNodes.forEach(([node, path]) => {
|
|
2955
3466
|
const marks = [
|
|
2956
3467
|
...(Array.isArray(node.marks) ? node.marks : []).filter(
|
|
@@ -2966,13 +3477,32 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
2966
3477
|
});
|
|
2967
3478
|
});
|
|
2968
3479
|
else {
|
|
2969
|
-
const
|
|
2970
|
-
|
|
2971
|
-
}.
|
|
2972
|
-
|
|
2973
|
-
marks
|
|
2974
|
-
|
|
2975
|
-
|
|
3480
|
+
const [block, blockPath] = Editor.node(editor, editor.selection, {
|
|
3481
|
+
depth: 1
|
|
3482
|
+
}), lonelyEmptySpan = editor.isTextBlock(block) && block.children.length === 1 && editor.isTextSpan(block.children[0]) && block.children[0].text === "" ? block.children[0] : void 0;
|
|
3483
|
+
if (lonelyEmptySpan) {
|
|
3484
|
+
const existingMarks = lonelyEmptySpan.marks ?? [], existingMarksWithoutDecorator = existingMarks.filter(
|
|
3485
|
+
(existingMark) => existingMark !== mark
|
|
3486
|
+
);
|
|
3487
|
+
Transforms.setNodes(
|
|
3488
|
+
editor,
|
|
3489
|
+
{
|
|
3490
|
+
marks: existingMarks.length === existingMarksWithoutDecorator.length ? [...existingMarks, mark] : existingMarksWithoutDecorator
|
|
3491
|
+
},
|
|
3492
|
+
{
|
|
3493
|
+
at: blockPath,
|
|
3494
|
+
match: (node) => editor.isTextSpan(node)
|
|
3495
|
+
}
|
|
3496
|
+
);
|
|
3497
|
+
} else {
|
|
3498
|
+
const existingMarks = {
|
|
3499
|
+
...Editor.marks(editor) || {}
|
|
3500
|
+
}.marks || [], marks = {
|
|
3501
|
+
...Editor.marks(editor) || {},
|
|
3502
|
+
marks: [...existingMarks, mark]
|
|
3503
|
+
};
|
|
3504
|
+
return editor.marks = marks, forceNewSelection(), editor;
|
|
3505
|
+
}
|
|
2976
3506
|
}
|
|
2977
3507
|
editor.onChange(), forceNewSelection();
|
|
2978
3508
|
}
|
|
@@ -2982,16 +3512,21 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
2982
3512
|
if (selection) {
|
|
2983
3513
|
if (Range.isExpanded(selection))
|
|
2984
3514
|
Editor.withoutNormalizing(editor, () => {
|
|
2985
|
-
Transforms.setNodes(
|
|
2986
|
-
|
|
3515
|
+
Transforms.setNodes(
|
|
3516
|
+
editor,
|
|
3517
|
+
{},
|
|
3518
|
+
{ match: Text.isText, split: !0, hanging: !0 }
|
|
3519
|
+
), editor.selection && [
|
|
3520
|
+
...Editor.nodes(editor, {
|
|
3521
|
+
at: editor.selection,
|
|
3522
|
+
match: Text.isText
|
|
3523
|
+
})
|
|
2987
3524
|
].forEach(([node, path]) => {
|
|
2988
3525
|
const block = editor.children[path[0]];
|
|
2989
3526
|
Element$1.isElement(block) && block.children.includes(node) && Transforms.setNodes(
|
|
2990
3527
|
editor,
|
|
2991
3528
|
{
|
|
2992
|
-
marks: (Array.isArray(node.marks) ? node.marks : []).filter(
|
|
2993
|
-
(eMark) => eMark !== mark
|
|
2994
|
-
),
|
|
3529
|
+
marks: (Array.isArray(node.marks) ? node.marks : []).filter((eMark) => eMark !== mark),
|
|
2995
3530
|
_type: "span"
|
|
2996
3531
|
},
|
|
2997
3532
|
{ at: path }
|
|
@@ -2999,13 +3534,32 @@ function createWithPortableTextMarkModel(types, change$, keyGenerator) {
|
|
|
2999
3534
|
});
|
|
3000
3535
|
}), Editor.normalize(editor);
|
|
3001
3536
|
else {
|
|
3002
|
-
const
|
|
3003
|
-
|
|
3004
|
-
}.
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3537
|
+
const [block, blockPath] = Editor.node(editor, selection, {
|
|
3538
|
+
depth: 1
|
|
3539
|
+
}), lonelyEmptySpan = editor.isTextBlock(block) && block.children.length === 1 && editor.isTextSpan(block.children[0]) && block.children[0].text === "" ? block.children[0] : void 0;
|
|
3540
|
+
if (lonelyEmptySpan) {
|
|
3541
|
+
const existingMarksWithoutDecorator = (lonelyEmptySpan.marks ?? []).filter(
|
|
3542
|
+
(existingMark) => existingMark !== mark
|
|
3543
|
+
);
|
|
3544
|
+
Transforms.setNodes(
|
|
3545
|
+
editor,
|
|
3546
|
+
{
|
|
3547
|
+
marks: existingMarksWithoutDecorator
|
|
3548
|
+
},
|
|
3549
|
+
{
|
|
3550
|
+
at: blockPath,
|
|
3551
|
+
match: (node) => editor.isTextSpan(node)
|
|
3552
|
+
}
|
|
3553
|
+
);
|
|
3554
|
+
} else {
|
|
3555
|
+
const existingMarks = {
|
|
3556
|
+
...Editor.marks(editor) || {}
|
|
3557
|
+
}.marks || [], marks = {
|
|
3558
|
+
...Editor.marks(editor) || {},
|
|
3559
|
+
marks: existingMarks.filter((eMark) => eMark !== mark)
|
|
3560
|
+
};
|
|
3561
|
+
return editor.marks = { marks: marks.marks, _type: "span" }, forceNewSelection(), editor;
|
|
3562
|
+
}
|
|
3009
3563
|
}
|
|
3010
3564
|
editor.onChange(), forceNewSelection();
|
|
3011
3565
|
}
|
|
@@ -3063,14 +3617,18 @@ function createWithSchemaTypes({
|
|
|
3063
3617
|
keyGenerator
|
|
3064
3618
|
}) {
|
|
3065
3619
|
return function(editor) {
|
|
3066
|
-
editor.isTextBlock = (value) => isPortableTextTextBlock(value) && value._type === schemaTypes.block.name, editor.isTextSpan = (value) => isPortableTextSpan$1(value) && value._type
|
|
3620
|
+
editor.isTextBlock = (value) => isPortableTextTextBlock(value) && value._type === schemaTypes.block.name, editor.isTextSpan = (value) => isPortableTextSpan$1(value) && value._type === schemaTypes.span.name, editor.isListBlock = (value) => isPortableTextListBlock(value) && value._type === schemaTypes.block.name, editor.isVoid = (element) => schemaTypes.block.name !== element._type && (schemaTypes.blockObjects.map((obj) => obj.name).includes(element._type) || schemaTypes.inlineObjects.map((obj) => obj.name).includes(element._type)), editor.isInline = (element) => schemaTypes.inlineObjects.map((obj) => obj.name).includes(element._type) && "__inline" in element && element.__inline === !0;
|
|
3067
3621
|
const { normalizeNode } = editor;
|
|
3068
3622
|
return editor.normalizeNode = (entry) => {
|
|
3069
3623
|
const [node, path] = entry;
|
|
3070
3624
|
if (node._type === void 0 && path.length === 2) {
|
|
3071
3625
|
debug$a("Setting span type on text node without a type");
|
|
3072
3626
|
const span = node, key = span._key || keyGenerator();
|
|
3073
|
-
Transforms.setNodes(
|
|
3627
|
+
Transforms.setNodes(
|
|
3628
|
+
editor,
|
|
3629
|
+
{ ...span, _type: schemaTypes.span.name, _key: key },
|
|
3630
|
+
{ at: path }
|
|
3631
|
+
);
|
|
3074
3632
|
}
|
|
3075
3633
|
if (node._key === void 0 && (path.length === 1 || path.length === 2)) {
|
|
3076
3634
|
debug$a("Setting missing key on child node without a key");
|
|
@@ -3082,7 +3640,11 @@ function createWithSchemaTypes({
|
|
|
3082
3640
|
};
|
|
3083
3641
|
}
|
|
3084
3642
|
const debug$9 = debugWithName("plugin:withUtils");
|
|
3085
|
-
function createWithUtils({
|
|
3643
|
+
function createWithUtils({
|
|
3644
|
+
schemaTypes,
|
|
3645
|
+
keyGenerator,
|
|
3646
|
+
portableTextEditor
|
|
3647
|
+
}) {
|
|
3086
3648
|
return function(editor) {
|
|
3087
3649
|
return editor.pteExpandToWord = () => {
|
|
3088
3650
|
const { selection } = editor;
|
|
@@ -3093,7 +3655,7 @@ function createWithUtils({ schemaTypes, keyGenerator, portableTextEditor }) {
|
|
|
3093
3655
|
return;
|
|
3094
3656
|
}
|
|
3095
3657
|
const { focus } = selection, focusOffset = focus.offset, charsBefore = textNode.text.slice(0, focusOffset), charsAfter = textNode.text.slice(focusOffset, -1), isEmpty = (str) => str.match(/\s/g), whiteSpaceBeforeIndex = charsBefore.split("").reverse().findIndex((str) => isEmpty(str)), newStartOffset = whiteSpaceBeforeIndex > -1 ? charsBefore.length - whiteSpaceBeforeIndex : 0, whiteSpaceAfterIndex = charsAfter.split("").findIndex((obj) => isEmpty(obj)), newEndOffset = charsBefore.length + (whiteSpaceAfterIndex > -1 ? whiteSpaceAfterIndex : charsAfter.length + 1);
|
|
3096
|
-
if (!(newStartOffset === newEndOffset || isNaN(newStartOffset) || isNaN(newEndOffset))) {
|
|
3658
|
+
if (!(newStartOffset === newEndOffset || Number.isNaN(newStartOffset) || Number.isNaN(newEndOffset))) {
|
|
3097
3659
|
debug$9("pteExpandToWord: Expanding to focused word"), Transforms.setSelection(editor, {
|
|
3098
3660
|
anchor: { ...selection.anchor, offset: newStartOffset },
|
|
3099
3661
|
focus: { ...selection.focus, offset: newEndOffset }
|
|
@@ -3102,7 +3664,7 @@ function createWithUtils({ schemaTypes, keyGenerator, portableTextEditor }) {
|
|
|
3102
3664
|
}
|
|
3103
3665
|
debug$9("pteExpandToWord: Can't expand to word here");
|
|
3104
3666
|
}
|
|
3105
|
-
}, editor.
|
|
3667
|
+
}, editor.pteCreateTextBlock = (options) => toSlateValue(
|
|
3106
3668
|
[
|
|
3107
3669
|
{
|
|
3108
3670
|
_type: schemaTypes.block.name,
|
|
@@ -3114,7 +3676,9 @@ function createWithUtils({ schemaTypes, keyGenerator, portableTextEditor }) {
|
|
|
3114
3676
|
_type: "span",
|
|
3115
3677
|
_key: keyGenerator(),
|
|
3116
3678
|
text: "",
|
|
3117
|
-
marks:
|
|
3679
|
+
marks: options.decorators.filter(
|
|
3680
|
+
(decorator) => schemaTypes.decorators.find(({ value }) => value === decorator)
|
|
3681
|
+
)
|
|
3118
3682
|
}
|
|
3119
3683
|
]
|
|
3120
3684
|
}
|
|
@@ -3163,59 +3727,46 @@ function createWithHotkeys(types, portableTextEditor, hotkeysFromOptions) {
|
|
|
3163
3727
|
}
|
|
3164
3728
|
}
|
|
3165
3729
|
});
|
|
3166
|
-
const isEnter = isHotkey("enter", event.nativeEvent), isTab = isHotkey("tab", event.nativeEvent), isShiftEnter = isHotkey("shift+enter", event.nativeEvent), isShiftTab = isHotkey("shift+tab", event.nativeEvent),
|
|
3730
|
+
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);
|
|
3167
3731
|
if (isArrowDown && editor.selection) {
|
|
3168
|
-
const focusBlock = Node.descendant(
|
|
3732
|
+
const focusBlock = Node.descendant(
|
|
3733
|
+
editor,
|
|
3734
|
+
editor.selection.focus.path.slice(0, 1)
|
|
3735
|
+
);
|
|
3169
3736
|
if (focusBlock && Editor.isVoid(editor, focusBlock)) {
|
|
3170
3737
|
const nextPath = Path.next(editor.selection.focus.path.slice(0, 1));
|
|
3171
3738
|
if (!Node.has(editor, nextPath)) {
|
|
3172
|
-
Transforms.insertNodes(
|
|
3739
|
+
Transforms.insertNodes(
|
|
3740
|
+
editor,
|
|
3741
|
+
editor.pteCreateTextBlock({ decorators: [] }),
|
|
3742
|
+
{
|
|
3743
|
+
at: nextPath
|
|
3744
|
+
}
|
|
3745
|
+
), editor.onChange();
|
|
3173
3746
|
return;
|
|
3174
3747
|
}
|
|
3175
3748
|
}
|
|
3176
3749
|
}
|
|
3177
3750
|
if (isArrowUp && editor.selection) {
|
|
3178
|
-
const isFirstBlock = editor.selection.focus.path[0] === 0, focusBlock = Node.descendant(
|
|
3179
|
-
if (isFirstBlock && focusBlock && Editor.isVoid(editor, focusBlock)) {
|
|
3180
|
-
Transforms.insertNodes(editor, editor.pteCreateEmptyBlock(), { at: [0] }), Transforms.select(editor, { path: [0, 0], offset: 0 }), editor.onChange();
|
|
3181
|
-
return;
|
|
3182
|
-
}
|
|
3183
|
-
}
|
|
3184
|
-
if (isBackspace && editor.selection && editor.selection.focus.path[0] === 0 && Range.isCollapsed(editor.selection)) {
|
|
3185
|
-
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 === "";
|
|
3186
|
-
if (nextBlock && isTextBlock && isEmptyFocusBlock) {
|
|
3187
|
-
event.preventDefault(), event.stopPropagation(), Transforms.removeNodes(editor, { match: (n) => n === focusBlock }), editor.onChange();
|
|
3188
|
-
return;
|
|
3189
|
-
}
|
|
3190
|
-
}
|
|
3191
|
-
if (isBackspace && editor.selection && editor.selection.focus.path[0] > 0 && Range.isCollapsed(editor.selection)) {
|
|
3192
|
-
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));
|
|
3193
|
-
if (prevBlock && focusBlock && Editor.isVoid(editor, prevBlock) && editor.selection.focus.offset === 0) {
|
|
3194
|
-
debug$8("Preventing deleting void block above"), event.preventDefault(), event.stopPropagation();
|
|
3195
|
-
const isTextBlock = isPortableTextTextBlock(focusBlock), isEmptyFocusBlock = isTextBlock && focusBlock.children.length === 1 && focusBlock.children?.[0]?.text === "";
|
|
3196
|
-
if (!isTextBlock || isEmptyFocusBlock) {
|
|
3197
|
-
Transforms.removeNodes(editor, { match: (n) => n === focusBlock }), Transforms.select(editor, prevPath), editor.onChange();
|
|
3198
|
-
return;
|
|
3199
|
-
}
|
|
3200
|
-
if (isTextBlock && !isEmptyFocusBlock) {
|
|
3201
|
-
Transforms.select(editor, prevPath), editor.onChange();
|
|
3202
|
-
return;
|
|
3203
|
-
}
|
|
3204
|
-
return;
|
|
3205
|
-
}
|
|
3206
|
-
}
|
|
3207
|
-
if (isDelete && editor.selection && editor.selection.focus.offset === 0 && Range.isCollapsed(editor.selection) && editor.children[editor.selection.focus.path[0] + 1]) {
|
|
3208
|
-
const nextBlock = Node.descendant(
|
|
3751
|
+
const isFirstBlock = editor.selection.focus.path[0] === 0, focusBlock = Node.descendant(
|
|
3209
3752
|
editor,
|
|
3210
|
-
|
|
3211
|
-
)
|
|
3212
|
-
if (
|
|
3213
|
-
|
|
3753
|
+
editor.selection.focus.path.slice(0, 1)
|
|
3754
|
+
);
|
|
3755
|
+
if (isFirstBlock && focusBlock && Editor.isVoid(editor, focusBlock)) {
|
|
3756
|
+
Transforms.insertNodes(
|
|
3757
|
+
editor,
|
|
3758
|
+
editor.pteCreateTextBlock({ decorators: [] }),
|
|
3759
|
+
{
|
|
3760
|
+
at: [0]
|
|
3761
|
+
}
|
|
3762
|
+
), Transforms.select(editor, { path: [0, 0], offset: 0 }), editor.onChange();
|
|
3214
3763
|
return;
|
|
3215
3764
|
}
|
|
3216
3765
|
}
|
|
3217
3766
|
if ((isTab || isShiftTab) && editor.selection) {
|
|
3218
|
-
const [focusChild] = Editor.node(editor, editor.selection.focus, {
|
|
3767
|
+
const [focusChild] = Editor.node(editor, editor.selection.focus, {
|
|
3768
|
+
depth: 2
|
|
3769
|
+
}), [focusBlock] = isPortableTextSpan$1(focusChild) ? Editor.node(editor, editor.selection.focus, { depth: 1 }) : [], hasAnnotationFocus = focusChild && isPortableTextTextBlock(focusBlock) && isPortableTextSpan$1(focusChild) && (focusChild.marks || []).filter(
|
|
3219
3770
|
(m) => (focusBlock.markDefs || []).map((def) => def._key).includes(m)
|
|
3220
3771
|
).length > 0, [start] = Range.edges(editor.selection), atStartOfNode = Editor.isStart(editor, start, start.path);
|
|
3221
3772
|
focusChild && isPortableTextSpan$1(focusChild) && (!hasAnnotationFocus || atStartOfNode) && editor.pteIncrementBlockLevels(isShiftTab) && event.preventDefault();
|
|
@@ -3229,12 +3780,15 @@ function createWithHotkeys(types, portableTextEditor, hotkeysFromOptions) {
|
|
|
3229
3780
|
if (editor.isTextBlock(focusBlock) && focusBlock.style && focusBlock.style !== types.styles[0].value) {
|
|
3230
3781
|
const [, end] = Range.edges(editor.selection);
|
|
3231
3782
|
if (Editor.isEnd(editor, end, end.path)) {
|
|
3232
|
-
Editor.insertNode(
|
|
3783
|
+
Editor.insertNode(
|
|
3784
|
+
editor,
|
|
3785
|
+
editor.pteCreateTextBlock({ decorators: [] })
|
|
3786
|
+
), event.preventDefault(), editor.onChange();
|
|
3233
3787
|
return;
|
|
3234
3788
|
}
|
|
3235
3789
|
}
|
|
3236
3790
|
if (focusBlock && Editor.isVoid(editor, focusBlock)) {
|
|
3237
|
-
Editor.insertNode(editor, editor.
|
|
3791
|
+
Editor.insertNode(editor, editor.pteCreateTextBlock({ decorators: [] })), event.preventDefault(), editor.onChange();
|
|
3238
3792
|
return;
|
|
3239
3793
|
}
|
|
3240
3794
|
event.preventDefault(), editor.insertBreak(), editor.onChange();
|
|
@@ -3254,7 +3808,13 @@ function createWithHotkeys(types, portableTextEditor, hotkeysFromOptions) {
|
|
|
3254
3808
|
}
|
|
3255
3809
|
function validateValue(value, types, keyGenerator) {
|
|
3256
3810
|
let resolution = null, valid = !0;
|
|
3257
|
-
const validChildTypes = [
|
|
3811
|
+
const validChildTypes = [
|
|
3812
|
+
types.span.name,
|
|
3813
|
+
...types.inlineObjects.map((t) => t.name)
|
|
3814
|
+
], validBlockTypes = [
|
|
3815
|
+
types.block.name,
|
|
3816
|
+
...types.blockObjects.map((t) => t.name)
|
|
3817
|
+
];
|
|
3258
3818
|
return value === void 0 ? { valid: !0, resolution: null, value } : !Array.isArray(value) || value.length === 0 ? {
|
|
3259
3819
|
valid: !1,
|
|
3260
3820
|
resolution: {
|
|
@@ -3297,7 +3857,9 @@ function validateValue(value, types, keyGenerator) {
|
|
|
3297
3857
|
if (blk._type === "block") {
|
|
3298
3858
|
const currentBlockTypeName = types.block.name;
|
|
3299
3859
|
return resolution = {
|
|
3300
|
-
patches: [
|
|
3860
|
+
patches: [
|
|
3861
|
+
set({ ...blk, _type: currentBlockTypeName }, [{ _key: blk._key }])
|
|
3862
|
+
],
|
|
3301
3863
|
description: `Block with _key '${blk._key}' has invalid type name '${blk._type}'. According to the schema, the block type name is '${currentBlockTypeName}'`,
|
|
3302
3864
|
action: `Use type '${currentBlockTypeName}'`,
|
|
3303
3865
|
item: blk,
|
|
@@ -3309,7 +3871,9 @@ function validateValue(value, types, keyGenerator) {
|
|
|
3309
3871
|
}, !0;
|
|
3310
3872
|
}
|
|
3311
3873
|
return !blk._type && isPortableTextTextBlock({ ...blk, _type: types.block.name }) ? (resolution = {
|
|
3312
|
-
patches: [
|
|
3874
|
+
patches: [
|
|
3875
|
+
set({ ...blk, _type: types.block.name }, [{ _key: blk._key }])
|
|
3876
|
+
],
|
|
3313
3877
|
description: `Block with _key '${blk._key}' is missing a type name. According to the schema, the block type name is '${types.block.name}'`,
|
|
3314
3878
|
action: `Use type '${types.block.name}'`,
|
|
3315
3879
|
item: blk,
|
|
@@ -3379,7 +3943,11 @@ function validateValue(value, types, keyGenerator) {
|
|
|
3379
3943
|
}
|
|
3380
3944
|
if (blk.markDefs && !Array.isArray(blk.markDefs))
|
|
3381
3945
|
return resolution = {
|
|
3382
|
-
patches: [
|
|
3946
|
+
patches: [
|
|
3947
|
+
set({ ...textBlock, markDefs: EMPTY_MARKDEFS }, [
|
|
3948
|
+
{ _key: textBlock._key }
|
|
3949
|
+
])
|
|
3950
|
+
],
|
|
3383
3951
|
description: "Block has invalid required property 'markDefs'.",
|
|
3384
3952
|
action: "Add empty markDefs array",
|
|
3385
3953
|
item: textBlock,
|
|
@@ -3412,7 +3980,10 @@ function validateValue(value, types, keyGenerator) {
|
|
|
3412
3980
|
i18n: {
|
|
3413
3981
|
description: "inputs.portable-text.invalid-value.orphaned-mark-defs.description",
|
|
3414
3982
|
action: "inputs.portable-text.invalid-value.orphaned-mark-defs.action",
|
|
3415
|
-
values: {
|
|
3983
|
+
values: {
|
|
3984
|
+
key: blk._key,
|
|
3985
|
+
unusedMarkDefs: unusedMarkDefs.map((m) => m.toString())
|
|
3986
|
+
}
|
|
3416
3987
|
}
|
|
3417
3988
|
}, !0;
|
|
3418
3989
|
}
|
|
@@ -3430,7 +4001,9 @@ function validateValue(value, types, keyGenerator) {
|
|
|
3430
4001
|
return resolution = {
|
|
3431
4002
|
autoResolve: !0,
|
|
3432
4003
|
patches: spanChildren.map((child) => set(
|
|
3433
|
-
(child.marks || []).filter(
|
|
4004
|
+
(child.marks || []).filter(
|
|
4005
|
+
(cMrk) => !orphanedMarks.includes(cMrk)
|
|
4006
|
+
),
|
|
3434
4007
|
[{ _key: blk._key }, "children", { _key: child._key }, "marks"]
|
|
3435
4008
|
)),
|
|
3436
4009
|
description: `Block with _key '${blk._key}' contains marks (${orphaned}) not supported by the current content model.`,
|
|
@@ -3439,7 +4012,10 @@ function validateValue(value, types, keyGenerator) {
|
|
|
3439
4012
|
i18n: {
|
|
3440
4013
|
description: "inputs.portable-text.invalid-value.orphaned-marks.description",
|
|
3441
4014
|
action: "inputs.portable-text.invalid-value.orphaned-marks.action",
|
|
3442
|
-
values: {
|
|
4015
|
+
values: {
|
|
4016
|
+
key: blk._key,
|
|
4017
|
+
orphanedMarks: orphanedMarks.map((m) => m.toString())
|
|
4018
|
+
}
|
|
3443
4019
|
}
|
|
3444
4020
|
}, !0;
|
|
3445
4021
|
}
|
|
@@ -3461,7 +4037,9 @@ function validateValue(value, types, keyGenerator) {
|
|
|
3461
4037
|
const newChild = { ...child, _key: keyGenerator() };
|
|
3462
4038
|
return resolution = {
|
|
3463
4039
|
autoResolve: !0,
|
|
3464
|
-
patches: [
|
|
4040
|
+
patches: [
|
|
4041
|
+
set(newChild, [{ _key: blk._key }, "children", cIndex])
|
|
4042
|
+
],
|
|
3465
4043
|
description: `Child at index ${cIndex} is missing required _key in block with _key ${blk._key}.`,
|
|
3466
4044
|
action: "Set a new random _key on the object",
|
|
3467
4045
|
item: blk,
|
|
@@ -3474,7 +4052,11 @@ function validateValue(value, types, keyGenerator) {
|
|
|
3474
4052
|
}
|
|
3475
4053
|
return child._type ? validChildTypes.includes(child._type) ? child._type === types.span.name && typeof child.text != "string" ? (resolution = {
|
|
3476
4054
|
patches: [
|
|
3477
|
-
set({ ...child, text: "" }, [
|
|
4055
|
+
set({ ...child, text: "" }, [
|
|
4056
|
+
{ _key: blk._key },
|
|
4057
|
+
"children",
|
|
4058
|
+
{ _key: child._key }
|
|
4059
|
+
])
|
|
3478
4060
|
],
|
|
3479
4061
|
description: `Child with _key '${child._key}' in block with key '${blk._key}' has missing or invalid text property!`,
|
|
3480
4062
|
action: "Write an empty text property to the object",
|
|
@@ -3485,17 +4067,25 @@ function validateValue(value, types, keyGenerator) {
|
|
|
3485
4067
|
values: { key: blk._key, childKey: child._key }
|
|
3486
4068
|
}
|
|
3487
4069
|
}, !0) : !1 : (resolution = {
|
|
3488
|
-
patches: [
|
|
4070
|
+
patches: [
|
|
4071
|
+
unset([{ _key: blk._key }, "children", { _key: child._key }])
|
|
4072
|
+
],
|
|
3489
4073
|
description: `Child with _key '${child._key}' in block with key '${blk._key}' has invalid '_type' property (${child._type}).`,
|
|
3490
4074
|
action: "Remove the object",
|
|
3491
4075
|
item: blk,
|
|
3492
4076
|
i18n: {
|
|
3493
4077
|
description: "inputs.portable-text.invalid-value.disallowed-child-type.description",
|
|
3494
4078
|
action: "inputs.portable-text.invalid-value.disallowed-child-type.action",
|
|
3495
|
-
values: {
|
|
4079
|
+
values: {
|
|
4080
|
+
key: blk._key,
|
|
4081
|
+
childKey: child._key,
|
|
4082
|
+
childType: child._type
|
|
4083
|
+
}
|
|
3496
4084
|
}
|
|
3497
4085
|
}, !0) : (resolution = {
|
|
3498
|
-
patches: [
|
|
4086
|
+
patches: [
|
|
4087
|
+
unset([{ _key: blk._key }, "children", { _key: child._key }])
|
|
4088
|
+
],
|
|
3499
4089
|
description: `Child with _key '${child._key}' in block with key '${blk._key}' is missing '_type' property.`,
|
|
3500
4090
|
action: "Remove the object",
|
|
3501
4091
|
item: blk,
|
|
@@ -3529,11 +4119,13 @@ function createWithInsertData(change$, schemaTypes, keyGenerator) {
|
|
|
3529
4119
|
const [voidNode] = endVoid, r = domRange.cloneRange(), domNode = ReactEditor.toDOMNode(editor, voidNode);
|
|
3530
4120
|
r.setEndAfter(domNode), contents = r.cloneContents();
|
|
3531
4121
|
}
|
|
3532
|
-
Array.from(contents.querySelectorAll("[data-slate-zero-width]")).forEach(
|
|
3533
|
-
|
|
3534
|
-
|
|
4122
|
+
Array.from(contents.querySelectorAll("[data-slate-zero-width]")).forEach(
|
|
4123
|
+
(zw) => {
|
|
4124
|
+
const isNewline = zw.getAttribute("data-slate-zero-width") === "n";
|
|
4125
|
+
zw.textContent = isNewline ? `
|
|
3535
4126
|
` : "";
|
|
3536
|
-
|
|
4127
|
+
}
|
|
4128
|
+
), Array.from(contents.querySelectorAll("*")).forEach((elm) => {
|
|
3537
4129
|
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");
|
|
3538
4130
|
for (const key in elm.attributes)
|
|
3539
4131
|
elm.hasAttribute(key) && elm.removeAttribute(key);
|
|
@@ -3543,7 +4135,10 @@ function createWithInsertData(change$, schemaTypes, keyGenerator) {
|
|
|
3543
4135
|
const asHTML = div.innerHTML;
|
|
3544
4136
|
contents.ownerDocument.body.removeChild(div);
|
|
3545
4137
|
const fragment = editor.getFragment(), portableText = fromSlateValue(fragment, blockTypeName), asJSON = JSON.stringify(portableText), asPlainText = toPlainText(portableText);
|
|
3546
|
-
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(
|
|
4138
|
+
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
|
+
"application/x-portable-text-event-origin",
|
|
4140
|
+
originEvent || "external"
|
|
4141
|
+
), debug$7("Set fragment data", asJSON, asHTML);
|
|
3547
4142
|
}, editor.insertPortableTextData = (data) => {
|
|
3548
4143
|
if (!editor.selection)
|
|
3549
4144
|
return !1;
|
|
@@ -3583,7 +4178,9 @@ function createWithInsertData(change$, schemaTypes, keyGenerator) {
|
|
|
3583
4178
|
if (html) {
|
|
3584
4179
|
if (portableText = htmlToBlocks(html, schemaTypes.portableText, {
|
|
3585
4180
|
unstable_whitespaceOnPasteMode: whitespaceOnPasteMode
|
|
3586
|
-
}).map(
|
|
4181
|
+
}).map(
|
|
4182
|
+
(block) => normalizeBlock(block, { blockTypeName })
|
|
4183
|
+
), fragment = toSlateValue(portableText, { schemaTypes }), insertedType = "HTML", portableText.length === 0)
|
|
3587
4184
|
return !1;
|
|
3588
4185
|
} else {
|
|
3589
4186
|
const textToHtml = `<html><body>${escapeHtml(text).split(/\n{2,}/).map(
|
|
@@ -3595,7 +4192,11 @@ function createWithInsertData(change$, schemaTypes, keyGenerator) {
|
|
|
3595
4192
|
schemaTypes
|
|
3596
4193
|
}), insertedType = "text";
|
|
3597
4194
|
}
|
|
3598
|
-
const validation = validateValue(
|
|
4195
|
+
const validation = validateValue(
|
|
4196
|
+
portableText,
|
|
4197
|
+
schemaTypes,
|
|
4198
|
+
keyGenerator
|
|
4199
|
+
);
|
|
3599
4200
|
if (!validation.valid) {
|
|
3600
4201
|
const errorDescription = `Could not validate the resulting portable text to insert.
|
|
3601
4202
|
${validation.resolution?.description}
|
|
@@ -3608,7 +4209,9 @@ Try to insert as plain text (shift-paste) instead.`;
|
|
|
3608
4209
|
data: validation
|
|
3609
4210
|
}), debug$7("Invalid insert result", validation), !1;
|
|
3610
4211
|
}
|
|
3611
|
-
return debug$7(
|
|
4212
|
+
return debug$7(
|
|
4213
|
+
`Inserting ${insertedType} fragment at ${JSON.stringify(editor.selection)}`
|
|
4214
|
+
), _insertFragment(editor, fragment, schemaTypes), change$.next({ type: "loading", isLoading: !1 }), !0;
|
|
3612
4215
|
}
|
|
3613
4216
|
return change$.next({ type: "loading", isLoading: !1 }), !1;
|
|
3614
4217
|
}, editor.insertData = (data) => {
|
|
@@ -3654,10 +4257,7 @@ function _regenerateKeys(editor, fragment, keyGenerator, spanTypeName, editorTyp
|
|
|
3654
4257
|
return newNode.children = newNode.children.map(
|
|
3655
4258
|
(child) => child._type === spanTypeName && editor.isTextSpan(child) ? {
|
|
3656
4259
|
...child,
|
|
3657
|
-
marks: child.marks && child.marks.includes(oldKey) ? (
|
|
3658
|
-
// eslint-disable-next-line max-nested-callbacks
|
|
3659
|
-
[...child.marks].filter((mark) => mark !== oldKey).concat(newKey)
|
|
3660
|
-
) : child.marks
|
|
4260
|
+
marks: child.marks && child.marks.includes(oldKey) ? [...child.marks].filter((mark) => mark !== oldKey).concat(newKey) : child.marks
|
|
3661
4261
|
} : child
|
|
3662
4262
|
), { ...def, _key: newKey };
|
|
3663
4263
|
});
|
|
@@ -3673,18 +4273,30 @@ function _insertFragment(editor, fragment, schemaTypes) {
|
|
|
3673
4273
|
editor.withoutNormalizing(() => {
|
|
3674
4274
|
if (!editor.selection)
|
|
3675
4275
|
return;
|
|
3676
|
-
const [focusBlock, focusPath] = Editor.node(editor, editor.selection, {
|
|
4276
|
+
const [focusBlock, focusPath] = Editor.node(editor, editor.selection, {
|
|
4277
|
+
depth: 1
|
|
4278
|
+
});
|
|
3677
4279
|
if (editor.isTextBlock(focusBlock) && editor.isTextBlock(fragment[0])) {
|
|
3678
4280
|
const { markDefs } = focusBlock;
|
|
3679
|
-
debug$7(
|
|
4281
|
+
debug$7(
|
|
4282
|
+
"Mixing markDefs of focusBlock and fragments[0] block",
|
|
4283
|
+
markDefs,
|
|
4284
|
+
fragment[0].markDefs
|
|
4285
|
+
), isEqual(markDefs, fragment[0].markDefs) || Transforms.setNodes(
|
|
3680
4286
|
editor,
|
|
3681
4287
|
{
|
|
3682
|
-
markDefs: uniq([
|
|
4288
|
+
markDefs: uniq([
|
|
4289
|
+
...fragment[0].markDefs || [],
|
|
4290
|
+
...markDefs || []
|
|
4291
|
+
])
|
|
3683
4292
|
},
|
|
3684
4293
|
{ at: focusPath, mode: "lowest", voids: !1 }
|
|
3685
4294
|
);
|
|
3686
4295
|
}
|
|
3687
|
-
isEqualToEmptyEditor(
|
|
4296
|
+
isEqualToEmptyEditor(
|
|
4297
|
+
editor.children,
|
|
4298
|
+
schemaTypes
|
|
4299
|
+
) ? (Transforms.splitNodes(editor, { at: [0, 0] }), editor.insertFragment(fragment), Transforms.removeNodes(editor, { at: [0] })) : editor.insertFragment(fragment);
|
|
3688
4300
|
}), editor.onChange();
|
|
3689
4301
|
}
|
|
3690
4302
|
const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, options) => {
|
|
@@ -3694,7 +4306,11 @@ const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, opti
|
|
|
3694
4306
|
onChange: e.onChange,
|
|
3695
4307
|
normalizeNode: e.normalizeNode
|
|
3696
4308
|
});
|
|
3697
|
-
const operationToPatches = createOperationToPatches(schemaTypes), withObjectKeys = createWithObjectKeys(schemaTypes, keyGenerator), withSchemaTypes = createWithSchemaTypes({ schemaTypes, keyGenerator }), withEditableAPI = createWithEditableAPI(
|
|
4309
|
+
const operationToPatches = createOperationToPatches(schemaTypes), withObjectKeys = createWithObjectKeys(schemaTypes, keyGenerator), withSchemaTypes = createWithSchemaTypes({ schemaTypes, keyGenerator }), withEditableAPI = createWithEditableAPI(
|
|
4310
|
+
portableTextEditor,
|
|
4311
|
+
schemaTypes,
|
|
4312
|
+
keyGenerator
|
|
4313
|
+
), withPatches = createWithPatches({
|
|
3698
4314
|
change$,
|
|
3699
4315
|
keyGenerator,
|
|
3700
4316
|
patches$,
|
|
@@ -3709,7 +4325,14 @@ const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, opti
|
|
|
3709
4325
|
schemaTypes,
|
|
3710
4326
|
change$,
|
|
3711
4327
|
keyGenerator
|
|
3712
|
-
), withPortableTextBlockStyle = createWithPortableTextBlockStyle(schemaTypes), withPlaceholderBlock = createWithPlaceholderBlock(), withInsertBreak = createWithInsertBreak(schemaTypes), withUtils = createWithUtils({
|
|
4328
|
+
), withPortableTextBlockStyle = createWithPortableTextBlockStyle(schemaTypes), withPlaceholderBlock = createWithPlaceholderBlock(), withInsertBreak = createWithInsertBreak(schemaTypes, keyGenerator), withUtils = createWithUtils({
|
|
4329
|
+
keyGenerator,
|
|
4330
|
+
schemaTypes,
|
|
4331
|
+
portableTextEditor
|
|
4332
|
+
}), withPortableTextSelections = createWithPortableTextSelections(
|
|
4333
|
+
change$,
|
|
4334
|
+
schemaTypes
|
|
4335
|
+
);
|
|
3713
4336
|
return e.destroy = () => {
|
|
3714
4337
|
const originalFunctions = originalFnMap.get(e);
|
|
3715
4338
|
if (!originalFunctions)
|
|
@@ -3723,7 +4346,9 @@ const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, opti
|
|
|
3723
4346
|
withUtils(
|
|
3724
4347
|
withPlaceholderBlock(
|
|
3725
4348
|
withPortableTextLists(
|
|
3726
|
-
withPortableTextSelections(
|
|
4349
|
+
withPortableTextSelections(
|
|
4350
|
+
withEditableAPI(withInsertBreak(e))
|
|
4351
|
+
)
|
|
3727
4352
|
)
|
|
3728
4353
|
)
|
|
3729
4354
|
)
|
|
@@ -3742,7 +4367,11 @@ const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, opti
|
|
|
3742
4367
|
withUtils(
|
|
3743
4368
|
withMaxBlocks(
|
|
3744
4369
|
withUndoRedo(
|
|
3745
|
-
withPatches(
|
|
4370
|
+
withPatches(
|
|
4371
|
+
withPortableTextSelections(
|
|
4372
|
+
withEditableAPI(withInsertBreak(e))
|
|
4373
|
+
)
|
|
4374
|
+
)
|
|
3746
4375
|
)
|
|
3747
4376
|
)
|
|
3748
4377
|
)
|
|
@@ -3789,8 +4418,15 @@ function SlateContainer(props) {
|
|
|
3789
4418
|
portableTextEditor,
|
|
3790
4419
|
readOnly
|
|
3791
4420
|
});
|
|
3792
|
-
}, [
|
|
3793
|
-
|
|
4421
|
+
}, [
|
|
4422
|
+
keyGenerator,
|
|
4423
|
+
portableTextEditor,
|
|
4424
|
+
maxBlocks,
|
|
4425
|
+
readOnly,
|
|
4426
|
+
patches$,
|
|
4427
|
+
slateEditor
|
|
4428
|
+
]);
|
|
4429
|
+
const initialValue = useMemo(() => [slateEditor.pteCreateTextBlock({ decorators: [] })], [slateEditor]);
|
|
3794
4430
|
return useEffect(() => () => {
|
|
3795
4431
|
debug$6("Destroying Slate editor"), slateEditor.destroy();
|
|
3796
4432
|
}, [slateEditor]), /* @__PURE__ */ jsx(Slate, { editor: slateEditor, initialValue, children: props.children });
|
|
@@ -3847,7 +4483,11 @@ function useSyncValue(props) {
|
|
|
3847
4483
|
Transforms.removeNodes(slateEditor, {
|
|
3848
4484
|
at: [childrenLength - 1 - index]
|
|
3849
4485
|
});
|
|
3850
|
-
}), Transforms.insertNodes(
|
|
4486
|
+
}), Transforms.insertNodes(
|
|
4487
|
+
slateEditor,
|
|
4488
|
+
slateEditor.pteCreateTextBlock({ decorators: [] }),
|
|
4489
|
+
{ at: [0] }
|
|
4490
|
+
), hadSelection && Transforms.select(slateEditor, [0, 0]);
|
|
3851
4491
|
});
|
|
3852
4492
|
});
|
|
3853
4493
|
}), isChanged = !0), value && value.length > 0) {
|
|
@@ -3866,34 +4506,53 @@ function useSyncValue(props) {
|
|
|
3866
4506
|
});
|
|
3867
4507
|
isChanged = !0;
|
|
3868
4508
|
}
|
|
3869
|
-
slateValueFromProps.forEach(
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
4509
|
+
slateValueFromProps.forEach(
|
|
4510
|
+
(currentBlock, currentBlockIndex) => {
|
|
4511
|
+
const oldBlock = slateEditor.children[currentBlockIndex];
|
|
4512
|
+
if (oldBlock && !isEqual(currentBlock, oldBlock) && isValid) {
|
|
4513
|
+
const validationValue = [value[currentBlockIndex]], validation = validateValue(
|
|
4514
|
+
validationValue,
|
|
4515
|
+
schemaTypes,
|
|
4516
|
+
keyGenerator
|
|
4517
|
+
);
|
|
4518
|
+
!validation.valid && validation.resolution?.autoResolve && validation.resolution?.patches.length > 0 && !readOnly && previousValue.current && previousValue.current !== value && (console.warn(
|
|
4519
|
+
`${validation.resolution.action} for block with _key '${validationValue[0]._key}'. ${validation.resolution?.description}`
|
|
4520
|
+
), validation.resolution.patches.forEach((patch) => {
|
|
4521
|
+
change$.next({ type: "patch", patch });
|
|
4522
|
+
})), validation.valid || validation.resolution?.autoResolve ? (oldBlock._key === currentBlock._key ? (debug$5.enabled && debug$5("Updating block", oldBlock, currentBlock), _updateBlock(
|
|
4523
|
+
slateEditor,
|
|
4524
|
+
currentBlock,
|
|
4525
|
+
oldBlock,
|
|
4526
|
+
currentBlockIndex
|
|
4527
|
+
)) : (debug$5.enabled && debug$5("Replacing block", oldBlock, currentBlock), _replaceBlock(
|
|
4528
|
+
slateEditor,
|
|
4529
|
+
currentBlock,
|
|
4530
|
+
currentBlockIndex
|
|
4531
|
+
)), isChanged = !0) : (change$.next({
|
|
4532
|
+
type: "invalidValue",
|
|
4533
|
+
resolution: validation.resolution,
|
|
4534
|
+
value
|
|
4535
|
+
}), isValid = !1);
|
|
4536
|
+
}
|
|
4537
|
+
if (!oldBlock && isValid) {
|
|
4538
|
+
const validationValue = [value[currentBlockIndex]], validation = validateValue(
|
|
4539
|
+
validationValue,
|
|
4540
|
+
schemaTypes,
|
|
4541
|
+
keyGenerator
|
|
4542
|
+
);
|
|
4543
|
+
debug$5.enabled && debug$5(
|
|
4544
|
+
"Validating and inserting new block in the end of the value",
|
|
4545
|
+
currentBlock
|
|
4546
|
+
), validation.valid || validation.resolution?.autoResolve ? Transforms.insertNodes(slateEditor, currentBlock, {
|
|
4547
|
+
at: [currentBlockIndex]
|
|
4548
|
+
}) : (debug$5("Invalid", validation), change$.next({
|
|
4549
|
+
type: "invalidValue",
|
|
4550
|
+
resolution: validation.resolution,
|
|
4551
|
+
value
|
|
4552
|
+
}), isValid = !1);
|
|
4553
|
+
}
|
|
3882
4554
|
}
|
|
3883
|
-
|
|
3884
|
-
const validationValue = [value[currentBlockIndex]], validation = validateValue(validationValue, schemaTypes, keyGenerator);
|
|
3885
|
-
debug$5.enabled && debug$5(
|
|
3886
|
-
"Validating and inserting new block in the end of the value",
|
|
3887
|
-
currentBlock
|
|
3888
|
-
), validation.valid || validation.resolution?.autoResolve ? Transforms.insertNodes(slateEditor, currentBlock, {
|
|
3889
|
-
at: [currentBlockIndex]
|
|
3890
|
-
}) : (debug$5("Invalid", validation), change$.next({
|
|
3891
|
-
type: "invalidValue",
|
|
3892
|
-
resolution: validation.resolution,
|
|
3893
|
-
value
|
|
3894
|
-
}), isValid = !1);
|
|
3895
|
-
}
|
|
3896
|
-
});
|
|
4555
|
+
);
|
|
3897
4556
|
});
|
|
3898
4557
|
});
|
|
3899
4558
|
});
|
|
@@ -3943,41 +4602,53 @@ function _updateBlock(slateEditor, currentBlock, oldBlock, currentBlockIndex) {
|
|
|
3943
4602
|
at: [currentBlockIndex]
|
|
3944
4603
|
}), slateEditor.isTextBlock(currentBlock) && slateEditor.isTextBlock(oldBlock)) {
|
|
3945
4604
|
const oldBlockChildrenLength = oldBlock.children.length;
|
|
3946
|
-
currentBlock.children.length < oldBlockChildrenLength && Array.from(
|
|
3947
|
-
(
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
4605
|
+
currentBlock.children.length < oldBlockChildrenLength && Array.from(
|
|
4606
|
+
Array(oldBlockChildrenLength - currentBlock.children.length)
|
|
4607
|
+
).forEach((_, index) => {
|
|
4608
|
+
const childIndex = oldBlockChildrenLength - 1 - index;
|
|
4609
|
+
childIndex > 0 && (debug$5("Removing child"), Transforms.removeNodes(slateEditor, {
|
|
4610
|
+
at: [currentBlockIndex, childIndex]
|
|
4611
|
+
}));
|
|
4612
|
+
}), currentBlock.children.forEach(
|
|
4613
|
+
(currentBlockChild, currentBlockChildIndex) => {
|
|
4614
|
+
const oldBlockChild = oldBlock.children[currentBlockChildIndex], isChildChanged = !isEqual(currentBlockChild, oldBlockChild), isTextChanged = !isEqual(
|
|
4615
|
+
currentBlockChild.text,
|
|
4616
|
+
oldBlockChild?.text
|
|
4617
|
+
), path = [currentBlockIndex, currentBlockChildIndex];
|
|
4618
|
+
if (isChildChanged)
|
|
4619
|
+
if (currentBlockChild._key === oldBlockChild?._key) {
|
|
4620
|
+
debug$5("Updating changed child", currentBlockChild, oldBlockChild), Transforms.setNodes(
|
|
4621
|
+
slateEditor,
|
|
4622
|
+
currentBlockChild,
|
|
4623
|
+
{
|
|
4624
|
+
at: path
|
|
4625
|
+
}
|
|
4626
|
+
);
|
|
4627
|
+
const isSpanNode = Text.isText(currentBlockChild) && currentBlockChild._type === "span" && Text.isText(oldBlockChild) && oldBlockChild._type === "span";
|
|
4628
|
+
isSpanNode && isTextChanged ? (Transforms.delete(slateEditor, {
|
|
4629
|
+
at: {
|
|
4630
|
+
focus: { path, offset: 0 },
|
|
4631
|
+
anchor: { path, offset: oldBlockChild.text.length }
|
|
4632
|
+
}
|
|
4633
|
+
}), Transforms.insertText(slateEditor, currentBlockChild.text, {
|
|
4634
|
+
at: path
|
|
4635
|
+
}), slateEditor.onChange()) : isSpanNode || (debug$5("Updating changed inline object child", currentBlockChild), Transforms.setNodes(
|
|
4636
|
+
slateEditor,
|
|
4637
|
+
{ _key: VOID_CHILD_KEY },
|
|
4638
|
+
{
|
|
4639
|
+
at: [...path, 0],
|
|
4640
|
+
voids: !0
|
|
4641
|
+
}
|
|
4642
|
+
));
|
|
4643
|
+
} else oldBlockChild ? (debug$5("Replacing child", currentBlockChild), Transforms.removeNodes(slateEditor, {
|
|
4644
|
+
at: [currentBlockIndex, currentBlockChildIndex]
|
|
4645
|
+
}), Transforms.insertNodes(slateEditor, currentBlockChild, {
|
|
4646
|
+
at: [currentBlockIndex, currentBlockChildIndex]
|
|
4647
|
+
}), slateEditor.onChange()) : oldBlockChild || (debug$5("Inserting new child", currentBlockChild), Transforms.insertNodes(slateEditor, currentBlockChild, {
|
|
4648
|
+
at: [currentBlockIndex, currentBlockChildIndex]
|
|
4649
|
+
}), slateEditor.onChange());
|
|
3952
4650
|
}
|
|
3953
|
-
)
|
|
3954
|
-
const oldBlockChild = oldBlock.children[currentBlockChildIndex], isChildChanged = !isEqual(currentBlockChild, oldBlockChild), isTextChanged = !isEqual(currentBlockChild.text, oldBlockChild?.text), path = [currentBlockIndex, currentBlockChildIndex];
|
|
3955
|
-
if (isChildChanged)
|
|
3956
|
-
if (currentBlockChild._key === oldBlockChild?._key) {
|
|
3957
|
-
debug$5("Updating changed child", currentBlockChild, oldBlockChild), Transforms.setNodes(slateEditor, currentBlockChild, {
|
|
3958
|
-
at: path
|
|
3959
|
-
});
|
|
3960
|
-
const isSpanNode = Text.isText(currentBlockChild) && currentBlockChild._type === "span" && Text.isText(oldBlockChild) && oldBlockChild._type === "span";
|
|
3961
|
-
isSpanNode && isTextChanged ? (Transforms.delete(slateEditor, {
|
|
3962
|
-
at: { focus: { path, offset: 0 }, anchor: { path, offset: oldBlockChild.text.length } }
|
|
3963
|
-
}), Transforms.insertText(slateEditor, currentBlockChild.text, {
|
|
3964
|
-
at: path
|
|
3965
|
-
}), slateEditor.onChange()) : isSpanNode || (debug$5("Updating changed inline object child", currentBlockChild), Transforms.setNodes(
|
|
3966
|
-
slateEditor,
|
|
3967
|
-
{ _key: VOID_CHILD_KEY },
|
|
3968
|
-
{
|
|
3969
|
-
at: [...path, 0],
|
|
3970
|
-
voids: !0
|
|
3971
|
-
}
|
|
3972
|
-
));
|
|
3973
|
-
} else oldBlockChild ? (debug$5("Replacing child", currentBlockChild), Transforms.removeNodes(slateEditor, {
|
|
3974
|
-
at: [currentBlockIndex, currentBlockChildIndex]
|
|
3975
|
-
}), Transforms.insertNodes(slateEditor, currentBlockChild, {
|
|
3976
|
-
at: [currentBlockIndex, currentBlockChildIndex]
|
|
3977
|
-
}), slateEditor.onChange()) : oldBlockChild || (debug$5("Inserting new child", currentBlockChild), Transforms.insertNodes(slateEditor, currentBlockChild, {
|
|
3978
|
-
at: [currentBlockIndex, currentBlockChildIndex]
|
|
3979
|
-
}), slateEditor.onChange());
|
|
3980
|
-
});
|
|
4651
|
+
);
|
|
3981
4652
|
}
|
|
3982
4653
|
}
|
|
3983
4654
|
const debug$4 = debugWithName("component:PortableTextEditor:Synchronizer"), debugVerbose$1 = debug$4.enabled && !1, FLUSH_PATCHES_THROTTLED_MS = process.env.NODE_ENV === "test" ? 500 : 1e3;
|
|
@@ -3996,7 +4667,11 @@ function Synchronizer(props) {
|
|
|
3996
4667
|
debug$4("Flushing pending patches"), debugVerbose$1 && debug$4(`Patches:
|
|
3997
4668
|
${JSON.stringify(pendingPatches.current, null, 2)}`);
|
|
3998
4669
|
const snapshot = getValue();
|
|
3999
|
-
change$.next({
|
|
4670
|
+
change$.next({
|
|
4671
|
+
type: "mutation",
|
|
4672
|
+
patches: pendingPatches.current,
|
|
4673
|
+
snapshot
|
|
4674
|
+
}), pendingPatches.current = [];
|
|
4000
4675
|
}
|
|
4001
4676
|
IS_PROCESSING_LOCAL_CHANGES.set(slateEditor, !1);
|
|
4002
4677
|
}, [slateEditor, getValue, change$]), onFlushPendingPatchesThrottled = useMemo(() => throttle(
|
|
@@ -4082,7 +4757,9 @@ class PortableTextEditor extends Component {
|
|
|
4082
4757
|
constructor(props) {
|
|
4083
4758
|
if (super(props), !props.schemaType)
|
|
4084
4759
|
throw new Error('PortableTextEditor: missing "schemaType" property');
|
|
4085
|
-
props.incomingPatches$ && console.warn(
|
|
4760
|
+
props.incomingPatches$ && console.warn(
|
|
4761
|
+
"The prop 'incomingPatches$' is deprecated and renamed to 'patches$'"
|
|
4762
|
+
), this.change$.next({ type: "loading", isLoading: !0 }), this.schemaTypes = getPortableTextMemberSchemaTypes(
|
|
4086
4763
|
props.schemaType.hasOwnProperty("jsonType") ? props.schemaType : compileType(props.schemaType)
|
|
4087
4764
|
);
|
|
4088
4765
|
}
|
|
@@ -4099,7 +4776,7 @@ class PortableTextEditor extends Component {
|
|
|
4099
4776
|
return this.editable.getValue();
|
|
4100
4777
|
};
|
|
4101
4778
|
render() {
|
|
4102
|
-
const { onChange, value, children, patches$, incomingPatches$ } = this.props, { change$ } = this, _patches$ = incomingPatches$ || patches$, maxBlocks = typeof this.props.maxBlocks > "u" ? void 0 : parseInt(this.props.maxBlocks.toString(), 10) || void 0, readOnly = !!this.props.readOnly, keyGenerator = this.props.keyGenerator || defaultKeyGenerator;
|
|
4779
|
+
const { onChange, value, children, patches$, incomingPatches$ } = this.props, { change$ } = this, _patches$ = incomingPatches$ || patches$, maxBlocks = typeof this.props.maxBlocks > "u" ? void 0 : Number.parseInt(this.props.maxBlocks.toString(), 10) || void 0, readOnly = !!this.props.readOnly, keyGenerator = this.props.keyGenerator || defaultKeyGenerator;
|
|
4103
4780
|
return /* @__PURE__ */ jsx(
|
|
4104
4781
|
SlateContainer,
|
|
4105
4782
|
{
|
|
@@ -4174,14 +4851,26 @@ class PortableTextEditor extends Component {
|
|
|
4174
4851
|
static isSelectionsOverlapping = (editor, selectionA, selectionB) => editor.editable?.isSelectionsOverlapping(selectionA, selectionB);
|
|
4175
4852
|
}
|
|
4176
4853
|
const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (props) => {
|
|
4177
|
-
const {
|
|
4854
|
+
const {
|
|
4855
|
+
attributes,
|
|
4856
|
+
children,
|
|
4857
|
+
leaf,
|
|
4858
|
+
schemaTypes,
|
|
4859
|
+
renderChild,
|
|
4860
|
+
renderDecorator,
|
|
4861
|
+
renderAnnotation
|
|
4862
|
+
} = props, spanRef = useRef(null), portableTextEditor = usePortableTextEditor(), blockSelected = useSelected(), [focused, setFocused] = useState(!1), [selected, setSelected] = useState(!1), block = children.props.parent, path = useMemo(
|
|
4178
4863
|
() => block ? [{ _key: block?._key }, "children", { _key: leaf._key }] : [],
|
|
4179
4864
|
[block, leaf._key]
|
|
4180
4865
|
), decoratorValues = useMemo(
|
|
4181
4866
|
() => schemaTypes.decorators.map((dec) => dec.value),
|
|
4182
4867
|
[schemaTypes.decorators]
|
|
4183
4868
|
), marks = useMemo(
|
|
4184
|
-
() => uniq(
|
|
4869
|
+
() => uniq(
|
|
4870
|
+
(leaf.marks || EMPTY_MARKS).filter(
|
|
4871
|
+
(mark) => decoratorValues.includes(mark)
|
|
4872
|
+
)
|
|
4873
|
+
),
|
|
4185
4874
|
[decoratorValues, leaf.marks]
|
|
4186
4875
|
), annotationMarks = Array.isArray(leaf.marks) ? leaf.marks : EMPTY_MARKS, annotations = useMemo(
|
|
4187
4876
|
() => annotationMarks.map(
|
|
@@ -4232,11 +4921,18 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4232
4921
|
return () => {
|
|
4233
4922
|
sub.unsubscribe();
|
|
4234
4923
|
};
|
|
4235
|
-
}, [
|
|
4924
|
+
}, [
|
|
4925
|
+
path,
|
|
4926
|
+
portableTextEditor,
|
|
4927
|
+
setSelectedFromRange,
|
|
4928
|
+
shouldTrackSelectionAndFocus
|
|
4929
|
+
]), useEffect(() => setSelectedFromRange(), [setSelectedFromRange]);
|
|
4236
4930
|
const content = useMemo(() => {
|
|
4237
4931
|
let returnedChildren = children;
|
|
4238
4932
|
if (Text.isText(leaf) && leaf._type === schemaTypes.span.name && (marks.forEach((mark) => {
|
|
4239
|
-
const schemaType = schemaTypes.decorators.find(
|
|
4933
|
+
const schemaType = schemaTypes.decorators.find(
|
|
4934
|
+
(dec) => dec.value === mark
|
|
4935
|
+
);
|
|
4240
4936
|
if (schemaType && renderDecorator) {
|
|
4241
4937
|
const _props = Object.defineProperty(
|
|
4242
4938
|
{
|
|
@@ -4252,14 +4948,20 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4252
4948
|
{
|
|
4253
4949
|
enumerable: !1,
|
|
4254
4950
|
get() {
|
|
4255
|
-
return console.warn(
|
|
4951
|
+
return console.warn(
|
|
4952
|
+
"Property 'type' is deprecated, use 'schemaType' instead."
|
|
4953
|
+
), schemaType;
|
|
4256
4954
|
}
|
|
4257
4955
|
}
|
|
4258
4956
|
);
|
|
4259
|
-
returnedChildren = renderDecorator(
|
|
4957
|
+
returnedChildren = renderDecorator(
|
|
4958
|
+
_props
|
|
4959
|
+
);
|
|
4260
4960
|
}
|
|
4261
4961
|
}), block && annotations.length > 0 && annotations.forEach((annotation) => {
|
|
4262
|
-
const schemaType = schemaTypes.annotations.find(
|
|
4962
|
+
const schemaType = schemaTypes.annotations.find(
|
|
4963
|
+
(t) => t.name === annotation._type
|
|
4964
|
+
);
|
|
4263
4965
|
if (schemaType)
|
|
4264
4966
|
if (renderAnnotation) {
|
|
4265
4967
|
const _props = Object.defineProperty(
|
|
@@ -4277,7 +4979,9 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4277
4979
|
{
|
|
4278
4980
|
enumerable: !1,
|
|
4279
4981
|
get() {
|
|
4280
|
-
return console.warn(
|
|
4982
|
+
return console.warn(
|
|
4983
|
+
"Property 'type' is deprecated, use 'schemaType' instead."
|
|
4984
|
+
), schemaType;
|
|
4281
4985
|
}
|
|
4282
4986
|
}
|
|
4283
4987
|
);
|
|
@@ -4302,7 +5006,9 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4302
5006
|
{
|
|
4303
5007
|
enumerable: !1,
|
|
4304
5008
|
get() {
|
|
4305
|
-
return console.warn(
|
|
5009
|
+
return console.warn(
|
|
5010
|
+
"Property 'type' is deprecated, use 'schemaType' instead."
|
|
5011
|
+
), schemaTypes.span;
|
|
4306
5012
|
}
|
|
4307
5013
|
}
|
|
4308
5014
|
);
|
|
@@ -4357,8 +5063,13 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4357
5063
|
scrollSelectionIntoView,
|
|
4358
5064
|
spellCheck,
|
|
4359
5065
|
...restProps
|
|
4360
|
-
} = props, portableTextEditor = usePortableTextEditor(), readOnly = usePortableTextEditorReadOnlyStatus(), keyGenerator = usePortableTextEditorKeyGenerator(), ref = useRef(null), [editableElement, setEditableElement] = useState(
|
|
4361
|
-
|
|
5066
|
+
} = props, portableTextEditor = usePortableTextEditor(), readOnly = usePortableTextEditorReadOnlyStatus(), keyGenerator = usePortableTextEditorKeyGenerator(), ref = useRef(null), [editableElement, setEditableElement] = useState(
|
|
5067
|
+
null
|
|
5068
|
+
), [hasInvalidValue, setHasInvalidValue] = useState(!1), [rangeDecorationState, setRangeDecorationsState] = useState([]);
|
|
5069
|
+
useImperativeHandle(
|
|
5070
|
+
forwardedRef,
|
|
5071
|
+
() => ref.current
|
|
5072
|
+
);
|
|
4362
5073
|
const rangeDecorationsRef = useRef(rangeDecorations), { change$, schemaTypes } = portableTextEditor, slateEditor = useSlate(), blockTypeName = schemaTypes.block.name, withInsertData = useMemo(
|
|
4363
5074
|
() => createWithInsertData(change$, schemaTypes, keyGenerator),
|
|
4364
5075
|
[change$, keyGenerator, schemaTypes]
|
|
@@ -4381,7 +5092,15 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4381
5092
|
spellCheck
|
|
4382
5093
|
}
|
|
4383
5094
|
),
|
|
4384
|
-
[
|
|
5095
|
+
[
|
|
5096
|
+
schemaTypes,
|
|
5097
|
+
spellCheck,
|
|
5098
|
+
readOnly,
|
|
5099
|
+
renderBlock,
|
|
5100
|
+
renderChild,
|
|
5101
|
+
renderListItem,
|
|
5102
|
+
renderStyle
|
|
5103
|
+
]
|
|
4385
5104
|
), renderLeaf = useCallback(
|
|
4386
5105
|
(lProps) => {
|
|
4387
5106
|
if (lProps.leaf._type === "span") {
|
|
@@ -4406,7 +5125,14 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4406
5125
|
}
|
|
4407
5126
|
return lProps.children;
|
|
4408
5127
|
},
|
|
4409
|
-
[
|
|
5128
|
+
[
|
|
5129
|
+
readOnly,
|
|
5130
|
+
renderAnnotation,
|
|
5131
|
+
renderChild,
|
|
5132
|
+
renderDecorator,
|
|
5133
|
+
renderPlaceholder,
|
|
5134
|
+
schemaTypes
|
|
5135
|
+
]
|
|
4410
5136
|
), restoreSelectionFromProps = useCallback(() => {
|
|
4411
5137
|
if (propsSelection) {
|
|
4412
5138
|
debug(`Selection from props ${JSON.stringify(propsSelection)}`);
|
|
@@ -4415,7 +5141,9 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4415
5141
|
fromSlateValue(slateEditor.children, blockTypeName)
|
|
4416
5142
|
);
|
|
4417
5143
|
if (normalizedSelection !== null) {
|
|
4418
|
-
debug(
|
|
5144
|
+
debug(
|
|
5145
|
+
`Normalized selection from props ${JSON.stringify(normalizedSelection)}`
|
|
5146
|
+
);
|
|
4419
5147
|
const slateRange = toSlateRange(normalizedSelection, slateEditor);
|
|
4420
5148
|
slateRange && (Transforms.select(slateEditor, slateRange), slateEditor.operations.some((o) => o.type === "set_selection") || change$.next({ type: "selection", selection: normalizedSelection }), slateEditor.onChange());
|
|
4421
5149
|
}
|
|
@@ -4425,7 +5153,10 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4425
5153
|
if (rangeDecorations && rangeDecorations.length > 0) {
|
|
4426
5154
|
const newSlateRanges = [];
|
|
4427
5155
|
if (rangeDecorations.forEach((rangeDecorationItem) => {
|
|
4428
|
-
const slateRange = toSlateRange(
|
|
5156
|
+
const slateRange = toSlateRange(
|
|
5157
|
+
rangeDecorationItem.selection,
|
|
5158
|
+
slateEditor
|
|
5159
|
+
);
|
|
4429
5160
|
if (!Range.isRange(slateRange)) {
|
|
4430
5161
|
rangeDecorationItem.onMoved && rangeDecorationItem.onMoved({
|
|
4431
5162
|
newSelection: null,
|
|
@@ -4436,20 +5167,27 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4436
5167
|
}
|
|
4437
5168
|
let newRange;
|
|
4438
5169
|
if (operation && (newRange = moveRangeByOperation(slateRange, operation), newRange && newRange !== slateRange || newRange === null && slateRange)) {
|
|
4439
|
-
const value = PortableTextEditor.getValue(portableTextEditor), newRangeSelection = toPortableTextRange(
|
|
5170
|
+
const value = PortableTextEditor.getValue(portableTextEditor), newRangeSelection = toPortableTextRange(
|
|
5171
|
+
value,
|
|
5172
|
+
newRange,
|
|
5173
|
+
schemaTypes
|
|
5174
|
+
);
|
|
4440
5175
|
rangeDecorationItem.onMoved && rangeDecorationItem.onMoved({
|
|
4441
5176
|
newSelection: newRangeSelection,
|
|
4442
5177
|
rangeDecoration: rangeDecorationItem,
|
|
4443
5178
|
origin: "local"
|
|
4444
5179
|
});
|
|
4445
5180
|
}
|
|
4446
|
-
newRange !== null && newSlateRanges.push({
|
|
5181
|
+
newRange !== null && newSlateRanges.push({
|
|
5182
|
+
...newRange || slateRange,
|
|
5183
|
+
rangeDecoration: rangeDecorationItem
|
|
5184
|
+
});
|
|
4447
5185
|
}), newSlateRanges.length > 0) {
|
|
4448
5186
|
setRangeDecorationsState(newSlateRanges);
|
|
4449
5187
|
return;
|
|
4450
5188
|
}
|
|
4451
5189
|
}
|
|
4452
|
-
setRangeDecorationsState([]);
|
|
5190
|
+
rangeDecorationState.length > 0 && setRangeDecorationsState([]);
|
|
4453
5191
|
},
|
|
4454
5192
|
[portableTextEditor, rangeDecorations, schemaTypes, slateEditor]
|
|
4455
5193
|
);
|
|
@@ -4496,11 +5234,20 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4496
5234
|
debug("Pasting normally"), slateEditor.insertData(event.clipboardData);
|
|
4497
5235
|
return;
|
|
4498
5236
|
}
|
|
4499
|
-
const value = PortableTextEditor.getValue(portableTextEditor), path = toPortableTextRange(
|
|
5237
|
+
const value = PortableTextEditor.getValue(portableTextEditor), path = toPortableTextRange(
|
|
5238
|
+
value,
|
|
5239
|
+
slateEditor.selection,
|
|
5240
|
+
schemaTypes
|
|
5241
|
+
)?.focus.path || [], onPasteResult = onPaste({ event, value, path, schemaTypes });
|
|
4500
5242
|
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) => {
|
|
4501
5243
|
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(
|
|
4502
|
-
toSlateValue(result.insert, {
|
|
4503
|
-
|
|
5244
|
+
toSlateValue(result.insert, {
|
|
5245
|
+
schemaTypes
|
|
5246
|
+
})
|
|
5247
|
+
) : console.warn(
|
|
5248
|
+
"Your onPaste function returned something unexpected:",
|
|
5249
|
+
result
|
|
5250
|
+
);
|
|
4504
5251
|
}).catch((error) => (console.error(error), error)).finally(() => {
|
|
4505
5252
|
change$.next({ type: "loading", isLoading: !1 });
|
|
4506
5253
|
}));
|
|
@@ -4525,7 +5272,10 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4525
5272
|
const [lastBlock, path] = Node.last(slateEditor, []), focusPath = slateEditor.selection.focus.path.slice(0, 1), lastPath = path.slice(0, 1);
|
|
4526
5273
|
if (Path.equals(focusPath, lastPath)) {
|
|
4527
5274
|
const node = Node.descendant(slateEditor, path.slice(0, 1));
|
|
4528
|
-
lastBlock && Editor.isVoid(slateEditor, node) && (Transforms.insertNodes(
|
|
5275
|
+
lastBlock && Editor.isVoid(slateEditor, node) && (Transforms.insertNodes(
|
|
5276
|
+
slateEditor,
|
|
5277
|
+
slateEditor.pteCreateTextBlock({ decorators: [] })
|
|
5278
|
+
), slateEditor.onChange());
|
|
4529
5279
|
}
|
|
4530
5280
|
}
|
|
4531
5281
|
},
|
|
@@ -4551,7 +5301,10 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4551
5301
|
return;
|
|
4552
5302
|
const existingDOMRange = domSelection.getRangeAt(0);
|
|
4553
5303
|
try {
|
|
4554
|
-
const newDOMRange = ReactEditor.toDOMRange(
|
|
5304
|
+
const newDOMRange = ReactEditor.toDOMRange(
|
|
5305
|
+
slateEditor,
|
|
5306
|
+
slateEditor.selection
|
|
5307
|
+
);
|
|
4555
5308
|
(newDOMRange.startOffset !== existingDOMRange.startOffset || newDOMRange.endOffset !== existingDOMRange.endOffset) && (debug("DOM range out of sync, validating selection"), domSelection?.removeAllRanges(), domSelection.addRange(newDOMRange));
|
|
4556
5309
|
} catch {
|
|
4557
5310
|
debug("Could not resolve selection, selecting top document"), Transforms.deselect(slateEditor), slateEditor.children.length > 0 && Transforms.select(slateEditor, [0, 0]), slateEditor.onChange();
|
|
@@ -4599,13 +5352,19 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
|
|
|
4599
5352
|
];
|
|
4600
5353
|
if (path.length === 0)
|
|
4601
5354
|
return [];
|
|
4602
|
-
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, {
|
|
5355
|
+
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, {
|
|
5356
|
+
anchor: { path, offset: 0 },
|
|
5357
|
+
focus: { path, offset: 0 }
|
|
5358
|
+
}) || Range.includes(item, path));
|
|
4603
5359
|
return result.length > 0 ? result : [];
|
|
4604
5360
|
},
|
|
4605
5361
|
[slateEditor, schemaTypes, rangeDecorationState]
|
|
4606
5362
|
);
|
|
4607
5363
|
return useEffect(() => {
|
|
4608
|
-
ref.current = ReactEditor.toDOMNode(
|
|
5364
|
+
ref.current = ReactEditor.toDOMNode(
|
|
5365
|
+
slateEditor,
|
|
5366
|
+
slateEditor
|
|
5367
|
+
), setEditableElement(ref.current);
|
|
4609
5368
|
}, [slateEditor, ref]), portableTextEditor ? hasInvalidValue ? null : /* @__PURE__ */ jsx(
|
|
4610
5369
|
Editable,
|
|
4611
5370
|
{
|