@portabletext/editor 2.1.10 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/_chunks-cjs/util.merge-text-blocks.cjs +2 -2
- package/lib/_chunks-cjs/util.merge-text-blocks.cjs.map +1 -1
- package/lib/_chunks-es/selector.is-selection-expanded.js +1 -1
- package/lib/_chunks-es/util.merge-text-blocks.js +2 -2
- package/lib/_chunks-es/util.merge-text-blocks.js.map +1 -1
- package/lib/index.cjs +166 -25
- package/lib/index.cjs.map +1 -1
- package/lib/index.js +169 -28
- package/lib/index.js.map +1 -1
- package/lib/plugins/index.d.cts +3 -3
- package/lib/utils/index.d.ts +2 -2
- package/package.json +7 -7
- package/src/behaviors/behavior.abstract.split.ts +77 -1
- package/src/converters/converter.portable-text.deserialize.test.ts +3 -3
- package/src/converters/converter.portable-text.ts +1 -1
- package/src/converters/converter.text-html.ts +1 -1
- package/src/converters/converter.text-plain.ts +1 -1
- package/src/editor/Editable.tsx +2 -2
- package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +29 -35
- package/src/editor/plugins/createWithEditableAPI.ts +1 -1
- package/src/editor/plugins/createWithObjectKeys.ts +110 -1
- package/src/internal-utils/applyPatch.ts +1 -1
- package/src/internal-utils/test-editor.tsx +2 -0
- package/src/internal-utils/text-marks.ts +1 -1
- package/src/internal-utils/to-slate-range.ts +1 -1
- package/src/operations/behavior.operation.annotation.add.ts +1 -1
- package/src/operations/behavior.operation.delete.ts +31 -2
- package/src/operations/behavior.operation.insert.block.ts +85 -13
- package/src/utils/util.merge-text-blocks.ts +1 -1
package/lib/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { useEditor, EditorContext } from "./_chunks-es/use-editor.js";
|
|
|
4
4
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
5
5
|
import { useSelector, useActorRef } from "@xstate/react";
|
|
6
6
|
import noop from "lodash/noop.js";
|
|
7
|
-
import { Element as Element$1, Text, Range, Editor, Node, Transforms, Path, Operation, Point, createEditor
|
|
7
|
+
import { Element as Element$1, Text, Range, Editor, Node, Transforms, Path, Operation, deleteText, setSelection, Point, createEditor } from "slate";
|
|
8
8
|
import { useSelected, useSlateSelector, useSlateStatic, withReact, ReactEditor, Slate, useSlate, Editable } from "slate-react";
|
|
9
9
|
import debug$f from "debug";
|
|
10
10
|
import { DOMEditor, isDOMNode, EDITOR_TO_PENDING_SELECTION } from "slate-dom";
|
|
@@ -1165,7 +1165,7 @@ const converterJson = {
|
|
|
1165
1165
|
context: snapshot.context,
|
|
1166
1166
|
block,
|
|
1167
1167
|
options: {
|
|
1168
|
-
refreshKeys: !
|
|
1168
|
+
refreshKeys: !1,
|
|
1169
1169
|
validateFields: !1
|
|
1170
1170
|
}
|
|
1171
1171
|
});
|
|
@@ -1229,7 +1229,7 @@ function createConverterTextHtml(legacySchema) {
|
|
|
1229
1229
|
block,
|
|
1230
1230
|
options: {
|
|
1231
1231
|
refreshKeys: !1,
|
|
1232
|
-
validateFields: !
|
|
1232
|
+
validateFields: !1
|
|
1233
1233
|
}
|
|
1234
1234
|
});
|
|
1235
1235
|
return parsedBlock ? [parsedBlock] : [];
|
|
@@ -1277,7 +1277,7 @@ function createConverterTextPlain(legacySchema) {
|
|
|
1277
1277
|
block,
|
|
1278
1278
|
options: {
|
|
1279
1279
|
refreshKeys: !1,
|
|
1280
|
-
validateFields: !
|
|
1280
|
+
validateFields: !1
|
|
1281
1281
|
}
|
|
1282
1282
|
});
|
|
1283
1283
|
return parsedBlock ? [parsedBlock] : [];
|
|
@@ -3305,9 +3305,17 @@ const addAnnotationOperationImplementation = ({
|
|
|
3305
3305
|
context,
|
|
3306
3306
|
operation
|
|
3307
3307
|
}) => {
|
|
3308
|
-
const anchorBlockKey = getBlockKeyFromSelectionPoint(operation.at.anchor), focusBlockKey = getBlockKeyFromSelectionPoint(operation.at.focus), endBlockKey = operation.at.backward ? anchorBlockKey : focusBlockKey, endOffset = operation.at.backward ? operation.at.focus.offset : operation.at.anchor.offset;
|
|
3308
|
+
const anchorBlockKey = getBlockKeyFromSelectionPoint(operation.at.anchor), focusBlockKey = getBlockKeyFromSelectionPoint(operation.at.focus), startBlockKey = operation.at.backward ? focusBlockKey : anchorBlockKey, endBlockKey = operation.at.backward ? anchorBlockKey : focusBlockKey, endOffset = operation.at.backward ? operation.at.focus.offset : operation.at.anchor.offset;
|
|
3309
|
+
if (!startBlockKey)
|
|
3310
|
+
throw new Error("Failed to get start block key");
|
|
3309
3311
|
if (!endBlockKey)
|
|
3310
3312
|
throw new Error("Failed to get end block key");
|
|
3313
|
+
const startBlockIndex = operation.editor.blockIndexMap.get(startBlockKey);
|
|
3314
|
+
if (startBlockIndex === void 0)
|
|
3315
|
+
throw new Error("Failed to get start block index");
|
|
3316
|
+
const startBlock = operation.editor.value.at(startBlockIndex);
|
|
3317
|
+
if (!startBlock)
|
|
3318
|
+
throw new Error("Failed to get start block");
|
|
3311
3319
|
const endBlockIndex = operation.editor.blockIndexMap.get(endBlockKey);
|
|
3312
3320
|
if (endBlockIndex === void 0)
|
|
3313
3321
|
throw new Error("Failed to get end block index");
|
|
@@ -3338,11 +3346,14 @@ const addAnnotationOperationImplementation = ({
|
|
|
3338
3346
|
if (!range)
|
|
3339
3347
|
throw new Error(`Failed to get Slate Range for selection ${JSON.stringify(operation.at)}`);
|
|
3340
3348
|
const hanging = isTextBlock(context, endBlock) && endOffset === 0;
|
|
3341
|
-
operation.editor
|
|
3349
|
+
deleteText(operation.editor, {
|
|
3342
3350
|
at: range,
|
|
3343
3351
|
reverse: operation.direction === "backward",
|
|
3344
3352
|
unit: operation.unit,
|
|
3345
3353
|
hanging
|
|
3354
|
+
}), operation.editor.selection && isTextBlock(context, startBlock) && isTextBlock(context, endBlock) && setSelection(operation.editor, {
|
|
3355
|
+
anchor: operation.editor.selection.focus,
|
|
3356
|
+
focus: operation.editor.selection.focus
|
|
3346
3357
|
});
|
|
3347
3358
|
}, insertInlineObjectOperationImplementation = ({
|
|
3348
3359
|
context,
|
|
@@ -3434,19 +3445,19 @@ const addAnnotationOperationImplementation = ({
|
|
|
3434
3445
|
if (!fragment)
|
|
3435
3446
|
throw new Error(`Failed to convert block to Slate fragment ${JSON.stringify(parsedBlock)}`);
|
|
3436
3447
|
insertBlock({
|
|
3448
|
+
context,
|
|
3437
3449
|
block: fragment,
|
|
3438
3450
|
placement: operation.placement,
|
|
3439
3451
|
select: operation.select ?? "start",
|
|
3440
|
-
editor: operation.editor
|
|
3441
|
-
schema: context.schema
|
|
3452
|
+
editor: operation.editor
|
|
3442
3453
|
});
|
|
3443
3454
|
};
|
|
3444
3455
|
function insertBlock({
|
|
3456
|
+
context,
|
|
3445
3457
|
block,
|
|
3446
3458
|
placement,
|
|
3447
3459
|
select,
|
|
3448
|
-
editor
|
|
3449
|
-
schema
|
|
3460
|
+
editor
|
|
3450
3461
|
}) {
|
|
3451
3462
|
const [startBlock, startBlockPath] = getSelectionStartBlock({
|
|
3452
3463
|
editor
|
|
@@ -3468,7 +3479,7 @@ function insertBlock({
|
|
|
3468
3479
|
at: nextPath
|
|
3469
3480
|
}), select === "start" ? Transforms.select(editor, Editor.start(editor, nextPath)) : select === "end" && Transforms.select(editor, Editor.end(editor, nextPath));
|
|
3470
3481
|
} else {
|
|
3471
|
-
if (lastBlock && isEqualToEmptyEditor([lastBlock], schema)) {
|
|
3482
|
+
if (lastBlock && isEqualToEmptyEditor([lastBlock], context.schema)) {
|
|
3472
3483
|
Transforms.removeNodes(editor, {
|
|
3473
3484
|
at: lastBlockPath
|
|
3474
3485
|
}), Transforms.insertNodes(editor, [block], {
|
|
@@ -3519,14 +3530,14 @@ function insertBlock({
|
|
|
3519
3530
|
node: block,
|
|
3520
3531
|
path: [newSelection.anchor.path[0]]
|
|
3521
3532
|
}) : newSelection;
|
|
3522
|
-
select === "none" && adjustedSelection && Transforms.select(editor, adjustedSelection), focusBlock && isEqualToEmptyEditor([focusBlock], schema) && Transforms.removeNodes(editor, {
|
|
3533
|
+
select === "none" && adjustedSelection && Transforms.select(editor, adjustedSelection), focusBlock && isEqualToEmptyEditor([focusBlock], context.schema) && Transforms.removeNodes(editor, {
|
|
3523
3534
|
at: focusBlockPath
|
|
3524
3535
|
});
|
|
3525
3536
|
return;
|
|
3526
3537
|
}
|
|
3527
3538
|
if (editor.isTextBlock(endBlock) && editor.isTextBlock(block)) {
|
|
3528
3539
|
const selectionStartPoint = Range.start(currentSelection);
|
|
3529
|
-
if (isEqualToEmptyEditor([endBlock], schema)) {
|
|
3540
|
+
if (isEqualToEmptyEditor([endBlock], context.schema)) {
|
|
3530
3541
|
const currentSelection2 = editor.selection;
|
|
3531
3542
|
Transforms.insertNodes(editor, [block], {
|
|
3532
3543
|
at: endBlockPath,
|
|
@@ -3536,17 +3547,46 @@ function insertBlock({
|
|
|
3536
3547
|
}), select === "start" ? Transforms.select(editor, selectionStartPoint) : select === "end" ? Transforms.select(editor, Editor.end(editor, endBlockPath)) : Transforms.select(editor, currentSelection2);
|
|
3537
3548
|
return;
|
|
3538
3549
|
}
|
|
3539
|
-
|
|
3540
|
-
|
|
3550
|
+
const endBlockChildKeys = endBlock.children.map((child) => child._key), endBlockMarkDefsKeys = endBlock.markDefs?.map((markDef) => markDef._key) ?? [], markDefKeyMap = /* @__PURE__ */ new Map(), adjustedMarkDefs = block.markDefs?.map((markDef) => {
|
|
3551
|
+
if (endBlockMarkDefsKeys.includes(markDef._key)) {
|
|
3552
|
+
const newKey = context.keyGenerator();
|
|
3553
|
+
return markDefKeyMap.set(markDef._key, newKey), {
|
|
3554
|
+
...markDef,
|
|
3555
|
+
_key: newKey
|
|
3556
|
+
};
|
|
3557
|
+
}
|
|
3558
|
+
return markDef;
|
|
3559
|
+
}), adjustedChildren = block.children.map((child) => {
|
|
3560
|
+
if (isSpan(context, child)) {
|
|
3561
|
+
const marks = child.marks?.map((mark) => markDefKeyMap.get(mark) || mark) ?? [];
|
|
3562
|
+
if (!isEqual(child.marks, marks))
|
|
3563
|
+
return {
|
|
3564
|
+
...child,
|
|
3565
|
+
_key: endBlockChildKeys.includes(child._key) ? context.keyGenerator() : child._key,
|
|
3566
|
+
marks
|
|
3567
|
+
};
|
|
3568
|
+
}
|
|
3569
|
+
return endBlockChildKeys.includes(child._key) ? {
|
|
3570
|
+
...child,
|
|
3571
|
+
_key: context.keyGenerator()
|
|
3572
|
+
} : child;
|
|
3573
|
+
});
|
|
3574
|
+
Transforms.setNodes(editor, {
|
|
3575
|
+
markDefs: [...endBlock.markDefs ?? [], ...adjustedMarkDefs ?? []]
|
|
3541
3576
|
}, {
|
|
3542
3577
|
at: endBlockPath
|
|
3543
|
-
})
|
|
3544
|
-
|
|
3578
|
+
});
|
|
3579
|
+
const adjustedBlock = isEqual(block.children, adjustedChildren) ? block : {
|
|
3580
|
+
...block,
|
|
3581
|
+
children: adjustedChildren
|
|
3582
|
+
};
|
|
3583
|
+
if (select === "end") {
|
|
3584
|
+
Transforms.insertFragment(editor, [adjustedBlock], {
|
|
3545
3585
|
voids: !0
|
|
3546
3586
|
});
|
|
3547
3587
|
return;
|
|
3548
3588
|
}
|
|
3549
|
-
Transforms.insertFragment(editor, [
|
|
3589
|
+
Transforms.insertFragment(editor, [adjustedBlock], {
|
|
3550
3590
|
at: currentSelection,
|
|
3551
3591
|
voids: !0
|
|
3552
3592
|
}), select === "start" ? Transforms.select(editor, selectionStartPoint) : Point.equals(selectionStartPoint, endBlockEndPoint) || Transforms.select(editor, selectionStartPoint);
|
|
@@ -3556,9 +3596,7 @@ function insertBlock({
|
|
|
3556
3596
|
Transforms.insertNodes(editor, [block], {
|
|
3557
3597
|
at: endBlockPath,
|
|
3558
3598
|
select: !1
|
|
3559
|
-
}), (select === "start" || select === "end") && Transforms.select(editor, Editor.start(editor, endBlockPath)), isEmptyTextBlock({
|
|
3560
|
-
schema
|
|
3561
|
-
}, endBlock) && Transforms.removeNodes(editor, {
|
|
3599
|
+
}), (select === "start" || select === "end") && Transforms.select(editor, Editor.start(editor, endBlockPath)), isEmptyTextBlock(context, endBlock) && Transforms.removeNodes(editor, {
|
|
3562
3600
|
at: Path.next(endBlockPath)
|
|
3563
3601
|
});
|
|
3564
3602
|
else if (Range.isCollapsed(currentSelection) && Point.equals(selectionEndPoint, endBlockEndPoint2)) {
|
|
@@ -4094,6 +4132,58 @@ function createWithObjectKeys(editorActor) {
|
|
|
4094
4132
|
});
|
|
4095
4133
|
return;
|
|
4096
4134
|
}
|
|
4135
|
+
if (operation.type === "merge_node") {
|
|
4136
|
+
const index = operation.path[operation.path.length - 1], prevPath = Path.previous(operation.path), prevIndex = prevPath[prevPath.length - 1];
|
|
4137
|
+
if (operation.path.length !== 1 || prevPath.length !== 1) {
|
|
4138
|
+
apply2(operation);
|
|
4139
|
+
return;
|
|
4140
|
+
}
|
|
4141
|
+
const block = editor.value.at(index), previousBlock = editor.value.at(prevIndex);
|
|
4142
|
+
if (!block || !previousBlock) {
|
|
4143
|
+
apply2(operation);
|
|
4144
|
+
return;
|
|
4145
|
+
}
|
|
4146
|
+
if (!isTextBlock(editorActor.getSnapshot().context, block) || !isTextBlock(editorActor.getSnapshot().context, previousBlock)) {
|
|
4147
|
+
apply2(operation);
|
|
4148
|
+
return;
|
|
4149
|
+
}
|
|
4150
|
+
const previousBlockChildKeys = previousBlock.children.map((child) => child._key), previousBlockMarkDefKeys = previousBlock.markDefs?.map((markDef) => markDef._key) ?? [], markDefKeyMap = /* @__PURE__ */ new Map(), adjustedMarkDefs = block.markDefs?.map((markDef) => {
|
|
4151
|
+
if (previousBlockMarkDefKeys.includes(markDef._key)) {
|
|
4152
|
+
const newKey = editorActor.getSnapshot().context.keyGenerator();
|
|
4153
|
+
return markDefKeyMap.set(markDef._key, newKey), {
|
|
4154
|
+
...markDef,
|
|
4155
|
+
_key: newKey
|
|
4156
|
+
};
|
|
4157
|
+
}
|
|
4158
|
+
return markDef;
|
|
4159
|
+
});
|
|
4160
|
+
let childIndex = 0;
|
|
4161
|
+
for (const child of block.children) {
|
|
4162
|
+
if (isSpan(editorActor.getSnapshot().context, child)) {
|
|
4163
|
+
const marks = child.marks?.map((mark) => markDefKeyMap.get(mark) || mark) ?? [];
|
|
4164
|
+
isEqual(child.marks, marks) || Transforms.setNodes(editor, {
|
|
4165
|
+
marks
|
|
4166
|
+
}, {
|
|
4167
|
+
at: [index, childIndex]
|
|
4168
|
+
});
|
|
4169
|
+
}
|
|
4170
|
+
previousBlockChildKeys.includes(child._key) && Transforms.setNodes(editor, {
|
|
4171
|
+
_key: editorActor.getSnapshot().context.keyGenerator()
|
|
4172
|
+
}, {
|
|
4173
|
+
at: [index, childIndex]
|
|
4174
|
+
}), childIndex++;
|
|
4175
|
+
}
|
|
4176
|
+
apply2({
|
|
4177
|
+
...operation,
|
|
4178
|
+
properties: {
|
|
4179
|
+
...operation.properties,
|
|
4180
|
+
// Make sure the adjusted markDefs are carried along for the merge
|
|
4181
|
+
// operation
|
|
4182
|
+
markDefs: adjustedMarkDefs
|
|
4183
|
+
}
|
|
4184
|
+
});
|
|
4185
|
+
return;
|
|
4186
|
+
}
|
|
4097
4187
|
apply2(operation);
|
|
4098
4188
|
}, editor.normalizeNode = (entry) => {
|
|
4099
4189
|
const [node, path] = entry;
|
|
@@ -4268,7 +4358,7 @@ function setPatch(editor, patch) {
|
|
|
4268
4358
|
children,
|
|
4269
4359
|
...nextRest
|
|
4270
4360
|
} = value, {
|
|
4271
|
-
children:
|
|
4361
|
+
children: _prevChildren,
|
|
4272
4362
|
...prevRest
|
|
4273
4363
|
} = block.node || {
|
|
4274
4364
|
children: void 0
|
|
@@ -6996,6 +7086,57 @@ const MAX_LIST_LEVEL = 10, clearListOnBackspace = defineBehavior({
|
|
|
6996
7086
|
at: selection
|
|
6997
7087
|
})]]
|
|
6998
7088
|
}),
|
|
7089
|
+
defineBehavior({
|
|
7090
|
+
on: "split",
|
|
7091
|
+
guard: ({
|
|
7092
|
+
snapshot
|
|
7093
|
+
}) => {
|
|
7094
|
+
const selection = snapshot.context.selection;
|
|
7095
|
+
if (!selection || isSelectionCollapsed(selection))
|
|
7096
|
+
return !1;
|
|
7097
|
+
const selectionStartBlock = getSelectionStartBlock$1(snapshot), selectionEndBlock = getSelectionEndBlock$1(snapshot);
|
|
7098
|
+
if (!selectionStartBlock || !selectionEndBlock || selectionStartBlock.node._key === selectionEndBlock.node._key)
|
|
7099
|
+
return !1;
|
|
7100
|
+
const startPoint = getSelectionStartPoint(selection), startBlockEndPoint = getBlockEndPoint({
|
|
7101
|
+
context: snapshot.context,
|
|
7102
|
+
block: selectionStartBlock
|
|
7103
|
+
}), endPoint = getSelectionEndPoint(selection), endBlockStartPoint = getBlockStartPoint({
|
|
7104
|
+
context: snapshot.context,
|
|
7105
|
+
block: selectionEndBlock
|
|
7106
|
+
}), blocksInBetween = getSelectedValue(snapshot).filter((block) => block._key !== selectionStartBlock.node._key && block._key !== selectionEndBlock.node._key);
|
|
7107
|
+
return {
|
|
7108
|
+
startPoint,
|
|
7109
|
+
startBlockEndPoint,
|
|
7110
|
+
endPoint,
|
|
7111
|
+
endBlockStartPoint,
|
|
7112
|
+
blocksInBetween
|
|
7113
|
+
};
|
|
7114
|
+
},
|
|
7115
|
+
actions: [(_, {
|
|
7116
|
+
startPoint,
|
|
7117
|
+
startBlockEndPoint,
|
|
7118
|
+
endPoint,
|
|
7119
|
+
endBlockStartPoint,
|
|
7120
|
+
blocksInBetween
|
|
7121
|
+
}) => [raise({
|
|
7122
|
+
type: "delete",
|
|
7123
|
+
at: {
|
|
7124
|
+
anchor: startPoint,
|
|
7125
|
+
focus: startBlockEndPoint
|
|
7126
|
+
}
|
|
7127
|
+
}), ...blocksInBetween.map((block) => raise({
|
|
7128
|
+
type: "delete.block",
|
|
7129
|
+
at: [{
|
|
7130
|
+
_key: block._key
|
|
7131
|
+
}]
|
|
7132
|
+
})), raise({
|
|
7133
|
+
type: "delete",
|
|
7134
|
+
at: {
|
|
7135
|
+
anchor: endBlockStartPoint,
|
|
7136
|
+
focus: endPoint
|
|
7137
|
+
}
|
|
7138
|
+
})]]
|
|
7139
|
+
}),
|
|
6999
7140
|
defineBehavior({
|
|
7000
7141
|
on: "split",
|
|
7001
7142
|
guard: ({
|
|
@@ -7042,8 +7183,8 @@ const MAX_LIST_LEVEL = 10, clearListOnBackspace = defineBehavior({
|
|
|
7042
7183
|
}),
|
|
7043
7184
|
context: snapshot.context,
|
|
7044
7185
|
options: {
|
|
7045
|
-
refreshKeys: !
|
|
7046
|
-
validateFields: !
|
|
7186
|
+
refreshKeys: !1,
|
|
7187
|
+
validateFields: !1
|
|
7047
7188
|
}
|
|
7048
7189
|
});
|
|
7049
7190
|
return newTextBlock ? {
|
|
@@ -11370,8 +11511,8 @@ const debug = debugWithName("component:Editable"), PortableTextEditable = forwar
|
|
|
11370
11511
|
},
|
|
11371
11512
|
blocks: result_1.insert,
|
|
11372
11513
|
options: {
|
|
11373
|
-
refreshKeys: !
|
|
11374
|
-
validateFields: !
|
|
11514
|
+
refreshKeys: !1,
|
|
11515
|
+
validateFields: !1
|
|
11375
11516
|
}
|
|
11376
11517
|
}),
|
|
11377
11518
|
placement: "auto"
|
|
@@ -11752,12 +11893,12 @@ function defineSchema(definition) {
|
|
|
11752
11893
|
return definition;
|
|
11753
11894
|
}
|
|
11754
11895
|
const usePortableTextEditorSelection = () => {
|
|
11755
|
-
const $ = c(3), editorActor = useContext(EditorActorContext), [selection,
|
|
11896
|
+
const $ = c(3), editorActor = useContext(EditorActorContext), [selection, setSelection2] = useState(null);
|
|
11756
11897
|
let t0, t1;
|
|
11757
11898
|
return $[0] !== editorActor ? (t0 = () => {
|
|
11758
11899
|
const subscription = editorActor.on("selection", (event) => {
|
|
11759
11900
|
startTransition(() => {
|
|
11760
|
-
|
|
11901
|
+
setSelection2(event.selection);
|
|
11761
11902
|
});
|
|
11762
11903
|
});
|
|
11763
11904
|
return () => {
|