@portabletext/editor 8.0.2 → 8.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/{behavior.types.action-C6D8CCF9.d.ts → behavior.types.action-C0XDEQnB.d.ts} +18 -1
- package/lib/behavior.types.action-C0XDEQnB.d.ts.map +1 -0
- package/lib/behaviors/index.d.ts +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +268 -110
- package/lib/index.js.map +1 -1
- package/lib/plugins/index.d.ts +1 -1
- package/lib/selectors/index.d.ts +1 -1
- package/lib/traversal/index.d.ts +1 -1
- package/lib/utils/index.d.ts +1 -1
- package/package.json +5 -5
- package/lib/behavior.types.action-C6D8CCF9.d.ts.map +0 -1
package/lib/index.js
CHANGED
|
@@ -746,6 +746,40 @@ function move(editor, options = {}) {
|
|
|
746
746
|
}
|
|
747
747
|
editor.setSelection(props);
|
|
748
748
|
}
|
|
749
|
+
function subscribeToOperations(editor, listener, options) {
|
|
750
|
+
let phase = options?.phase ?? "after";
|
|
751
|
+
return editor.operationListeners[phase] = [...editor.operationListeners[phase], listener], () => {
|
|
752
|
+
let listeners = editor.operationListeners[phase], index = listeners.indexOf(listener);
|
|
753
|
+
index !== -1 && (editor.operationListeners[phase] = [...listeners.slice(0, index), ...listeners.slice(index + 1)]);
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
/**
|
|
757
|
+
* Captures the operation together with the engine state that `after`
|
|
758
|
+
* listeners can no longer read once the operation has been applied. All
|
|
759
|
+
* engine flags are stable for the duration of a single apply call, so
|
|
760
|
+
* capturing them at entry is equivalent to reading them at any point during
|
|
761
|
+
* the apply.
|
|
762
|
+
*/
|
|
763
|
+
function createOperationEvent(editor, operation) {
|
|
764
|
+
let isNormalizingNode = !!editor.isNormalizingNode, isProcessingRemoteChanges = !!editor.isProcessingRemoteChanges, isUndoing = !!editor.isUndoing, isRedoing = !!editor.isRedoing;
|
|
765
|
+
return {
|
|
766
|
+
operation,
|
|
767
|
+
beforeValue: editor.snapshot.context.value,
|
|
768
|
+
beforeSelection: editor.snapshot.context.selection,
|
|
769
|
+
operationsInProgress: editor.operations.length > 0,
|
|
770
|
+
isNormalizingNode,
|
|
771
|
+
isPatching: !!editor.isPatching,
|
|
772
|
+
isProcessingRemoteChanges,
|
|
773
|
+
isUndoing,
|
|
774
|
+
isRedoing,
|
|
775
|
+
withHistory: !!editor.withHistory,
|
|
776
|
+
undoStepId: editor.undoStepId,
|
|
777
|
+
origin: isProcessingRemoteChanges ? "remote" : isUndoing ? "undo" : isRedoing ? "redo" : isNormalizingNode ? "normalization" : "local"
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
function emitOperationEvent(listeners, event) {
|
|
781
|
+
for (let index = 0; index < listeners.length; index++) listeners[index]?.(event);
|
|
782
|
+
}
|
|
749
783
|
const bold$1 = createKeyboardShortcut({
|
|
750
784
|
default: [{
|
|
751
785
|
key: "B",
|
|
@@ -1179,13 +1213,14 @@ function mapPointThroughStep(step, point, options = {}) {
|
|
|
1179
1213
|
};
|
|
1180
1214
|
}
|
|
1181
1215
|
case "rekey": {
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1216
|
+
if (point.path.length <= step.path.length || !pathEquals(point.path.slice(0, step.path.length), step.path)) return point;
|
|
1217
|
+
let segment = point.path[step.path.length];
|
|
1218
|
+
return !isKeyedSegment(segment) || segment._key !== step.oldKey ? point : {
|
|
1219
|
+
path: [
|
|
1220
|
+
...step.path,
|
|
1221
|
+
{ _key: step.newKey },
|
|
1222
|
+
...point.path.slice(step.path.length + 1)
|
|
1223
|
+
],
|
|
1189
1224
|
offset: point.offset
|
|
1190
1225
|
};
|
|
1191
1226
|
}
|
|
@@ -1303,6 +1338,7 @@ function operationToSteps(op) {
|
|
|
1303
1338
|
let oldKey = op.inverse?.type === "set" && typeof op.inverse.value == "string" ? op.inverse.value : void 0;
|
|
1304
1339
|
return oldKey ? [{
|
|
1305
1340
|
type: "rekey",
|
|
1341
|
+
path: nodePath.slice(0, -1),
|
|
1306
1342
|
oldKey,
|
|
1307
1343
|
newKey: op.value
|
|
1308
1344
|
}] : [];
|
|
@@ -2787,9 +2823,12 @@ const RestoreDOM = IS_ANDROID ? RestoreDOMComponent : ({ children }) => /* @__PU
|
|
|
2787
2823
|
editor.forceRender = forceRender, editor.readOnly = readOnly;
|
|
2788
2824
|
let state = useMemo(() => ({
|
|
2789
2825
|
isUpdatingSelection: !1,
|
|
2790
|
-
latestElement: null
|
|
2826
|
+
latestElement: null,
|
|
2827
|
+
localContentChangePending: !1
|
|
2791
2828
|
}), []);
|
|
2792
|
-
useEffect(() => {
|
|
2829
|
+
useEffect(() => subscribeToOperations(editor, (event) => {
|
|
2830
|
+
event.operation.type !== "set.selection" && (event.origin === "local" || event.origin === "undo" || event.origin === "redo") && (state.localContentChangePending = !0);
|
|
2831
|
+
}), [editor, state]), useEffect(() => {
|
|
2793
2832
|
ref.current && autoFocus && ref.current.focus();
|
|
2794
2833
|
}, [autoFocus]);
|
|
2795
2834
|
/**
|
|
@@ -2844,6 +2883,8 @@ const RestoreDOM = IS_ANDROID ? RestoreDOMComponent : ({ children }) => /* @__PU
|
|
|
2844
2883
|
onDOMSelectionChange,
|
|
2845
2884
|
scheduleOnDOMSelectionChange
|
|
2846
2885
|
}), useIsomorphicLayoutEffect(() => {
|
|
2886
|
+
let hadPendingLocalContentChange = state.localContentChangePending;
|
|
2887
|
+
state.localContentChangePending = !1;
|
|
2847
2888
|
let window = null;
|
|
2848
2889
|
ref.current && (window = getDefaultView(ref.current)) && (editor.domWindow = window, editor.domElement = ref.current);
|
|
2849
2890
|
let { selection } = editor.snapshot.context, root = DOMEditor.findDocumentOrShadowRoot(editor), domSelection = getSelection(root);
|
|
@@ -2862,7 +2903,13 @@ const RestoreDOM = IS_ANDROID ? RestoreDOMComponent : ({ children }) => /* @__PU
|
|
|
2862
2903
|
exactMatch: !0,
|
|
2863
2904
|
suppressThrow: !0
|
|
2864
2905
|
});
|
|
2865
|
-
if (editorSelection && rangeEquals(editorSelection, selection))
|
|
2906
|
+
if (editorSelection && rangeEquals(editorSelection, selection)) {
|
|
2907
|
+
if (hadPendingLocalContentChange) try {
|
|
2908
|
+
let domRange = DOMEditor.toDOMRange(editor, selection);
|
|
2909
|
+
scrollSelectionIntoView(editor, domRange);
|
|
2910
|
+
} catch {}
|
|
2911
|
+
return;
|
|
2912
|
+
}
|
|
2866
2913
|
}
|
|
2867
2914
|
if (selection && !DOMEditor.hasRange(editor, selection)) {
|
|
2868
2915
|
let fallbackRange = DOMEditor.toEditorSelection(editor, domSelection, {
|
|
@@ -4114,40 +4161,6 @@ function performHotkey({ editorActor, editor, portableTextEditor, hotkeys, event
|
|
|
4114
4161
|
}
|
|
4115
4162
|
});
|
|
4116
4163
|
}
|
|
4117
|
-
function subscribeToOperations(editor, listener, options) {
|
|
4118
|
-
let phase = options?.phase ?? "after";
|
|
4119
|
-
return editor.operationListeners[phase] = [...editor.operationListeners[phase], listener], () => {
|
|
4120
|
-
let listeners = editor.operationListeners[phase], index = listeners.indexOf(listener);
|
|
4121
|
-
index !== -1 && (editor.operationListeners[phase] = [...listeners.slice(0, index), ...listeners.slice(index + 1)]);
|
|
4122
|
-
};
|
|
4123
|
-
}
|
|
4124
|
-
/**
|
|
4125
|
-
* Captures the operation together with the engine state that `after`
|
|
4126
|
-
* listeners can no longer read once the operation has been applied. All
|
|
4127
|
-
* engine flags are stable for the duration of a single apply call, so
|
|
4128
|
-
* capturing them at entry is equivalent to reading them at any point during
|
|
4129
|
-
* the apply.
|
|
4130
|
-
*/
|
|
4131
|
-
function createOperationEvent(editor, operation) {
|
|
4132
|
-
let isNormalizingNode = !!editor.isNormalizingNode, isProcessingRemoteChanges = !!editor.isProcessingRemoteChanges, isUndoing = !!editor.isUndoing, isRedoing = !!editor.isRedoing;
|
|
4133
|
-
return {
|
|
4134
|
-
operation,
|
|
4135
|
-
beforeValue: editor.snapshot.context.value,
|
|
4136
|
-
beforeSelection: editor.snapshot.context.selection,
|
|
4137
|
-
operationsInProgress: editor.operations.length > 0,
|
|
4138
|
-
isNormalizingNode,
|
|
4139
|
-
isPatching: !!editor.isPatching,
|
|
4140
|
-
isProcessingRemoteChanges,
|
|
4141
|
-
isUndoing,
|
|
4142
|
-
isRedoing,
|
|
4143
|
-
withHistory: !!editor.withHistory,
|
|
4144
|
-
undoStepId: editor.undoStepId,
|
|
4145
|
-
origin: isProcessingRemoteChanges ? "remote" : isUndoing ? "undo" : isRedoing ? "redo" : isNormalizingNode ? "normalization" : "local"
|
|
4146
|
-
};
|
|
4147
|
-
}
|
|
4148
|
-
function emitOperationEvent(listeners, event) {
|
|
4149
|
-
for (let index = 0; index < listeners.length; index++) listeners[index]?.(event);
|
|
4150
|
-
}
|
|
4151
4164
|
function isForwardRange(range, root) {
|
|
4152
4165
|
return !isBackwardRange(range, root);
|
|
4153
4166
|
}
|
|
@@ -4190,7 +4203,12 @@ const engineOperationCallback = ({ input, sendBack }) => subscribeToOperations(i
|
|
|
4190
4203
|
operation: event.operation,
|
|
4191
4204
|
origin: event.origin
|
|
4192
4205
|
});
|
|
4193
|
-
}, { phase: "before" })
|
|
4206
|
+
}, { phase: "before" });
|
|
4207
|
+
function mergeRangeDecoration(leaf, decoration) {
|
|
4208
|
+
let { rangeDecoration } = decoration;
|
|
4209
|
+
leaf.rangeDecorations = [...leaf.rangeDecorations ?? [], rangeDecoration];
|
|
4210
|
+
}
|
|
4211
|
+
const rangeDecorationsMachine = setup({
|
|
4194
4212
|
types: {
|
|
4195
4213
|
context: {},
|
|
4196
4214
|
input: {},
|
|
@@ -4211,6 +4229,7 @@ const engineOperationCallback = ({ input, sendBack }) => subscribeToOperations(i
|
|
|
4211
4229
|
}
|
|
4212
4230
|
rangeDecorationState.push({
|
|
4213
4231
|
rangeDecoration,
|
|
4232
|
+
merge: mergeRangeDecoration,
|
|
4214
4233
|
...rangeDecoration.selection
|
|
4215
4234
|
});
|
|
4216
4235
|
}
|
|
@@ -4230,6 +4249,7 @@ const engineOperationCallback = ({ input, sendBack }) => subscribeToOperations(i
|
|
|
4230
4249
|
}
|
|
4231
4250
|
rangeDecorationState.push({
|
|
4232
4251
|
rangeDecoration,
|
|
4252
|
+
merge: mergeRangeDecoration,
|
|
4233
4253
|
...rangeDecoration.selection
|
|
4234
4254
|
});
|
|
4235
4255
|
}
|
|
@@ -4258,7 +4278,8 @@ const engineOperationCallback = ({ input, sendBack }) => subscribeToOperations(i
|
|
|
4258
4278
|
rangeDecoration: {
|
|
4259
4279
|
...decoratedRange.rangeDecoration,
|
|
4260
4280
|
selection: newRange || currentSelection
|
|
4261
|
-
}
|
|
4281
|
+
},
|
|
4282
|
+
merge: mergeRangeDecoration
|
|
4262
4283
|
});
|
|
4263
4284
|
}
|
|
4264
4285
|
context.editorEngine.decoratedRanges = rangeDecorationState;
|
|
@@ -5166,29 +5187,33 @@ const PLACEHOLDER_STYLE = {
|
|
|
5166
5187
|
right: 0
|
|
5167
5188
|
};
|
|
5168
5189
|
function RenderLeaf(props) {
|
|
5169
|
-
let $ = c(
|
|
5190
|
+
let $ = c(16), schema = props.schema;
|
|
5170
5191
|
if (props.leaf._type !== schema.span.name) return props.children;
|
|
5171
5192
|
let t0;
|
|
5172
5193
|
$[0] === props ? t0 = $[1] : (t0 = /* @__PURE__ */ jsx(RenderSpan, { ...props }), $[0] = props, $[1] = t0);
|
|
5173
|
-
let renderedSpan
|
|
5174
|
-
if (props.
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5194
|
+
let renderedSpan, t1;
|
|
5195
|
+
if ($[2] !== props.leaf.placeholder || $[3] !== props.leaf.rangeDecorations || $[4] !== props.renderPlaceholder || $[5] !== props.text || $[6] !== t0) {
|
|
5196
|
+
t1 = Symbol.for("react.early_return_sentinel");
|
|
5197
|
+
bb0: {
|
|
5198
|
+
if (renderedSpan = t0, props.renderPlaceholder && props.leaf.placeholder && props.text.text === "") {
|
|
5199
|
+
let t2;
|
|
5200
|
+
$[9] === props.renderPlaceholder ? t2 = $[10] : (t2 = props.renderPlaceholder(), $[9] = props.renderPlaceholder, $[10] = t2);
|
|
5201
|
+
let t3;
|
|
5202
|
+
$[11] === t2 ? t3 = $[12] : (t3 = /* @__PURE__ */ jsx("span", {
|
|
5203
|
+
style: PLACEHOLDER_STYLE,
|
|
5204
|
+
contentEditable: !1,
|
|
5205
|
+
children: t2
|
|
5206
|
+
}), $[11] = t2, $[12] = t3);
|
|
5207
|
+
let t4;
|
|
5208
|
+
$[13] !== renderedSpan || $[14] !== t3 ? (t4 = /* @__PURE__ */ jsxs(Fragment, { children: [t3, renderedSpan] }), $[13] = renderedSpan, $[14] = t3, $[15] = t4) : t4 = $[15], t1 = t4;
|
|
5209
|
+
break bb0;
|
|
5210
|
+
}
|
|
5211
|
+
let rangeDecorations = props.leaf.rangeDecorations;
|
|
5212
|
+
if (rangeDecorations) for (let rangeDecoration of [...rangeDecorations].reverse()) renderedSpan = rangeDecoration.component({ children: renderedSpan });
|
|
5213
|
+
}
|
|
5214
|
+
$[2] = props.leaf.placeholder, $[3] = props.leaf.rangeDecorations, $[4] = props.renderPlaceholder, $[5] = props.text, $[6] = t0, $[7] = renderedSpan, $[8] = t1;
|
|
5215
|
+
} else renderedSpan = $[7], t1 = $[8];
|
|
5216
|
+
return t1 === Symbol.for("react.early_return_sentinel") ? renderedSpan : t1;
|
|
5192
5217
|
}
|
|
5193
5218
|
function RenderText(props) {
|
|
5194
5219
|
let $ = c(3), t0;
|
|
@@ -6892,13 +6917,17 @@ function applyOperation(editor, op) {
|
|
|
6892
6917
|
case "set": {
|
|
6893
6918
|
let { path, value } = op;
|
|
6894
6919
|
if (!op.inverse && !editor.isProcessingRemoteChanges) {
|
|
6895
|
-
let previousValue = getValue(editor.snapshot.context.value, path)
|
|
6920
|
+
let previousValue = getValue(editor.snapshot.context.value, path), inversePath = path[path.length - 1] === "_key" && typeof value == "string" && isKeyedSegment(path[path.length - 2]) ? [
|
|
6921
|
+
...path.slice(0, -2),
|
|
6922
|
+
{ _key: value },
|
|
6923
|
+
"_key"
|
|
6924
|
+
] : path;
|
|
6896
6925
|
op.inverse = previousValue === void 0 ? {
|
|
6897
6926
|
type: "unset",
|
|
6898
|
-
path
|
|
6927
|
+
path: inversePath
|
|
6899
6928
|
} : {
|
|
6900
6929
|
type: "set",
|
|
6901
|
-
path,
|
|
6930
|
+
path: inversePath,
|
|
6902
6931
|
value: previousValue
|
|
6903
6932
|
};
|
|
6904
6933
|
}
|
|
@@ -7537,8 +7566,7 @@ function applyMergeNode(editor, path, position) {
|
|
|
7537
7566
|
if (!prevEntry || !isTextBlock({ schema: editor.snapshot.context.schema }, prevEntry.node)) return;
|
|
7538
7567
|
let prevChildren = prevEntry.node.children, lastInsertedKey = prevChildren.length > 0 ? prevChildren[prevChildren.length - 1]._key : void 0;
|
|
7539
7568
|
for (let i = 0; i < node.children.length; i++) {
|
|
7540
|
-
let child = node.children[i]
|
|
7541
|
-
lastInsertedKey === void 0 ? editor.apply({
|
|
7569
|
+
let child = node.children[i], operation = lastInsertedKey === void 0 ? {
|
|
7542
7570
|
type: "insert",
|
|
7543
7571
|
path: [
|
|
7544
7572
|
...prevPath,
|
|
@@ -7547,7 +7575,7 @@ function applyMergeNode(editor, path, position) {
|
|
|
7547
7575
|
],
|
|
7548
7576
|
node: child,
|
|
7549
7577
|
position: "before"
|
|
7550
|
-
}
|
|
7578
|
+
} : {
|
|
7551
7579
|
type: "insert",
|
|
7552
7580
|
path: [
|
|
7553
7581
|
...prevPath,
|
|
@@ -7556,7 +7584,8 @@ function applyMergeNode(editor, path, position) {
|
|
|
7556
7584
|
],
|
|
7557
7585
|
node: child,
|
|
7558
7586
|
position: "after"
|
|
7559
|
-
}
|
|
7587
|
+
};
|
|
7588
|
+
editor.apply(operation), lastInsertedKey = operation.node._key;
|
|
7560
7589
|
}
|
|
7561
7590
|
editor.apply({
|
|
7562
7591
|
type: "unset",
|
|
@@ -7675,23 +7704,20 @@ function setNodeProperties(editor, props, path) {
|
|
|
7675
7704
|
keyIndex !== -1 && (keys.splice(keyIndex, 1), keys.unshift("_key"));
|
|
7676
7705
|
let currentPath = path;
|
|
7677
7706
|
for (let key of keys) if (propsRecord[key] !== nodeRecord[key]) if (propsRecord[key] != null) {
|
|
7678
|
-
let hadProperty = nodeRecord.hasOwnProperty(key);
|
|
7679
|
-
|
|
7707
|
+
let hadProperty = nodeRecord.hasOwnProperty(key), lastSegment = currentPath[currentPath.length - 1], renamedPath = key === "_key" && typeof propsRecord[key] == "string" && isKeyedSegment(lastSegment) ? [...currentPath.slice(0, -1), { _key: propsRecord[key] }] : void 0, inversePath = renamedPath ? [...renamedPath, key] : [...currentPath, key];
|
|
7708
|
+
editor.apply({
|
|
7680
7709
|
type: "set",
|
|
7681
7710
|
path: [...currentPath, key],
|
|
7682
7711
|
value: propsRecord[key],
|
|
7683
7712
|
inverse: hadProperty ? {
|
|
7684
7713
|
type: "set",
|
|
7685
|
-
path:
|
|
7714
|
+
path: inversePath,
|
|
7686
7715
|
value: nodeRecord[key]
|
|
7687
7716
|
} : {
|
|
7688
7717
|
type: "unset",
|
|
7689
|
-
path:
|
|
7718
|
+
path: inversePath
|
|
7690
7719
|
}
|
|
7691
|
-
}),
|
|
7692
|
-
let lastSegment = currentPath[currentPath.length - 1];
|
|
7693
|
-
isKeyedSegment(lastSegment) && (currentPath = [...currentPath.slice(0, -1), { _key: propsRecord[key] }]);
|
|
7694
|
-
}
|
|
7720
|
+
}), renamedPath && (currentPath = renamedPath);
|
|
7695
7721
|
} else nodeRecord.hasOwnProperty(key) && editor.apply({
|
|
7696
7722
|
type: "unset",
|
|
7697
7723
|
path: [...currentPath, key],
|
|
@@ -11607,6 +11633,63 @@ function fieldAcceptsTextBlock(editor, node, _path) {
|
|
|
11607
11633
|
return container ? container.field.of.some((member) => member.type === editor.snapshot.context.schema.block.name) : !1;
|
|
11608
11634
|
}
|
|
11609
11635
|
/**
|
|
11636
|
+
* A block merge folds `mergingBlock`'s children (and markDefs) into
|
|
11637
|
+
* `destinationBlock` by key. Any child key the merging block shares with
|
|
11638
|
+
* the destination has to be renamed before the merge, or the engine's own
|
|
11639
|
+
* collision handling mints a fresh key for it, which reads on the wire as
|
|
11640
|
+
* that node being destroyed and a new one created instead of moved. There
|
|
11641
|
+
* is no such backstop for markDefs: an unrenamed collision either loses
|
|
11642
|
+
* one of the two defs to last-wins replacement, or, on the `insert.block`
|
|
11643
|
+
* path, gets silently re-minted by `adjustFragmentKeys` (see
|
|
11644
|
+
* `dedupeEqualMarkDefs` below).
|
|
11645
|
+
*
|
|
11646
|
+
* Pure: computes the renames and the block they produce without touching
|
|
11647
|
+
* an editor. Callers raise or apply the renames themselves, ahead of the
|
|
11648
|
+
* merge, against the still-living `mergingBlock`.
|
|
11649
|
+
*/
|
|
11650
|
+
function planMergeKeyRenames(args) {
|
|
11651
|
+
let { context, mergingBlock, destinationBlock, dedupeEqualMarkDefs } = args, destinationChildKeys = new Set(destinationBlock.children.map((child) => child._key)), destinationMarkDefsByKey = new Map((destinationBlock.markDefs ?? []).map((markDef) => [markDef._key, markDef])), markDefKeyMap = /* @__PURE__ */ new Map(), renamedMarkDefs = mergingBlock.markDefs?.flatMap((markDef) => {
|
|
11652
|
+
let destinationMarkDef = destinationMarkDefsByKey.get(markDef._key);
|
|
11653
|
+
if (!destinationMarkDef) return [markDef];
|
|
11654
|
+
if (dedupeEqualMarkDefs && isDeepEqual(markDef, destinationMarkDef)) return [];
|
|
11655
|
+
let newKey = context.keyGenerator();
|
|
11656
|
+
return markDefKeyMap.set(markDef._key, newKey), [{
|
|
11657
|
+
...markDef,
|
|
11658
|
+
_key: newKey
|
|
11659
|
+
}];
|
|
11660
|
+
}), markDefRenames = [];
|
|
11661
|
+
for (let markDef of mergingBlock.markDefs ?? []) {
|
|
11662
|
+
let newKey = markDefKeyMap.get(markDef._key);
|
|
11663
|
+
newKey && markDefRenames.push({
|
|
11664
|
+
markDefKey: markDef._key,
|
|
11665
|
+
newKey
|
|
11666
|
+
});
|
|
11667
|
+
}
|
|
11668
|
+
let childRenames = [], renamedChildren = mergingBlock.children.map((child) => {
|
|
11669
|
+
let currentMarks = isSpan(context, child) ? child.marks : void 0, remappedMarks = currentMarks?.map((mark) => markDefKeyMap.get(mark) ?? mark), marksChanged = !!(remappedMarks && !isEqualMarks(remappedMarks, currentMarks)), newKey = destinationChildKeys.has(child._key) ? context.keyGenerator() : child._key, props = {};
|
|
11670
|
+
return newKey !== child._key && (props._key = newKey), marksChanged && (props.marks = remappedMarks), Object.keys(props).length > 0 && childRenames.push({
|
|
11671
|
+
childKey: child._key,
|
|
11672
|
+
props
|
|
11673
|
+
}), marksChanged ? {
|
|
11674
|
+
...child,
|
|
11675
|
+
_key: newKey,
|
|
11676
|
+
marks: remappedMarks
|
|
11677
|
+
} : {
|
|
11678
|
+
...child,
|
|
11679
|
+
_key: newKey
|
|
11680
|
+
};
|
|
11681
|
+
});
|
|
11682
|
+
return {
|
|
11683
|
+
renamedBlock: {
|
|
11684
|
+
...mergingBlock,
|
|
11685
|
+
children: renamedChildren,
|
|
11686
|
+
...mergingBlock.markDefs ? { markDefs: renamedMarkDefs } : {}
|
|
11687
|
+
},
|
|
11688
|
+
childRenames,
|
|
11689
|
+
markDefRenames
|
|
11690
|
+
};
|
|
11691
|
+
}
|
|
11692
|
+
/**
|
|
11610
11693
|
* Indic scripts whose grapheme clusters span multiple code points. Backward
|
|
11611
11694
|
* character delete on these scripts removes one code point at a time instead
|
|
11612
11695
|
* of the entire cluster. Besides the script ranges, the class lists the BMP
|
|
@@ -11939,12 +12022,29 @@ function mergeBlock(editor, startBlockPath, endBlockPath, removeEmptyStartBlock)
|
|
|
11939
12022
|
removeNodeAt(editor, startBlockPath);
|
|
11940
12023
|
return;
|
|
11941
12024
|
}
|
|
11942
|
-
let
|
|
11943
|
-
|
|
11944
|
-
|
|
11945
|
-
|
|
11946
|
-
|
|
11947
|
-
|
|
12025
|
+
let { renamedBlock, childRenames, markDefRenames } = planMergeKeyRenames({
|
|
12026
|
+
context: editor.snapshot.context,
|
|
12027
|
+
mergingBlock: endBlock.node,
|
|
12028
|
+
destinationBlock: startBlock.node,
|
|
12029
|
+
dedupeEqualMarkDefs: !0
|
|
12030
|
+
});
|
|
12031
|
+
for (let { markDefKey, newKey } of markDefRenames) editor.apply({
|
|
12032
|
+
type: "set",
|
|
12033
|
+
path: [
|
|
12034
|
+
...endBlockPath,
|
|
12035
|
+
"markDefs",
|
|
12036
|
+
{ _key: markDefKey },
|
|
12037
|
+
"_key"
|
|
12038
|
+
],
|
|
12039
|
+
value: newKey
|
|
12040
|
+
});
|
|
12041
|
+
for (let { childKey, props } of childRenames) setNodeProperties(editor, props, [
|
|
12042
|
+
...endBlockPath,
|
|
12043
|
+
"children",
|
|
12044
|
+
{ _key: childKey }
|
|
12045
|
+
]);
|
|
12046
|
+
let endMarkDefs = renamedBlock.markDefs;
|
|
12047
|
+
Array.isArray(endMarkDefs) && endMarkDefs.length > 0 && setNodeProperties(editor, { markDefs: [...startBlock.node.markDefs ?? [], ...endMarkDefs] }, startBlockPath), applyMergeNode(editor, endBlockPath, startBlock.node.children.length);
|
|
11948
12048
|
}
|
|
11949
12049
|
function removeNodeAt(editor, path) {
|
|
11950
12050
|
getNode(editor.snapshot, path) && editor.apply({
|
|
@@ -13132,16 +13232,24 @@ const abstractAnnotationBehaviors = [
|
|
|
13132
13232
|
let previousBlock = {
|
|
13133
13233
|
node: previousSibling.node,
|
|
13134
13234
|
path: previousSibling.path
|
|
13135
|
-
}
|
|
13235
|
+
}, previousBlockEndPoint = getBlockEndPoint({
|
|
13236
|
+
context: snapshot.context,
|
|
13237
|
+
block: previousBlock
|
|
13238
|
+
}), { renamedBlock, renameActions } = planMergeKeyRenameActions({
|
|
13239
|
+
context: snapshot.context,
|
|
13240
|
+
mergingBlockPath: focusTextBlock.path,
|
|
13241
|
+
mergingBlock: focusTextBlock.node,
|
|
13242
|
+
destinationBlock: previousBlock.node
|
|
13243
|
+
});
|
|
13136
13244
|
return {
|
|
13137
|
-
previousBlockEndPoint
|
|
13138
|
-
|
|
13139
|
-
|
|
13140
|
-
|
|
13141
|
-
focusTextBlock
|
|
13245
|
+
previousBlockEndPoint,
|
|
13246
|
+
focusTextBlock,
|
|
13247
|
+
renamedBlock,
|
|
13248
|
+
renameActions
|
|
13142
13249
|
};
|
|
13143
13250
|
},
|
|
13144
|
-
actions: [(_, { previousBlockEndPoint, focusTextBlock }) => [
|
|
13251
|
+
actions: [(_, { previousBlockEndPoint, focusTextBlock, renamedBlock, renameActions }) => [
|
|
13252
|
+
...renameActions,
|
|
13145
13253
|
raise$1({
|
|
13146
13254
|
type: "delete.block",
|
|
13147
13255
|
at: focusTextBlock.path
|
|
@@ -13155,7 +13263,7 @@ const abstractAnnotationBehaviors = [
|
|
|
13155
13263
|
}),
|
|
13156
13264
|
raise$1({
|
|
13157
13265
|
type: "insert.block",
|
|
13158
|
-
block:
|
|
13266
|
+
block: renamedBlock,
|
|
13159
13267
|
placement: "auto",
|
|
13160
13268
|
select: "start"
|
|
13161
13269
|
})
|
|
@@ -13224,20 +13332,32 @@ const abstractAnnotationBehaviors = [
|
|
|
13224
13332
|
}, focusTextBlock = getFocusTextBlock(adjustedSnapshot);
|
|
13225
13333
|
if (!focusTextBlock) return !1;
|
|
13226
13334
|
let nextSibling = getSibling(adjustedSnapshot, focusTextBlock.path, { direction: "next" });
|
|
13227
|
-
|
|
13228
|
-
|
|
13229
|
-
|
|
13230
|
-
|
|
13335
|
+
if (!nextSibling || !isAtTheEndOfBlock(focusTextBlock)(adjustedSnapshot) || !isTextBlock(snapshot.context, nextSibling.node)) return !1;
|
|
13336
|
+
let { renamedBlock, renameActions } = planMergeKeyRenameActions({
|
|
13337
|
+
context: snapshot.context,
|
|
13338
|
+
mergingBlockPath: nextSibling.path,
|
|
13339
|
+
mergingBlock: nextSibling.node,
|
|
13340
|
+
destinationBlock: focusTextBlock.node
|
|
13341
|
+
});
|
|
13342
|
+
return {
|
|
13343
|
+
nextBlockPath: nextSibling.path,
|
|
13344
|
+
renamedBlock,
|
|
13345
|
+
renameActions
|
|
13346
|
+
};
|
|
13231
13347
|
},
|
|
13232
|
-
actions: [(_, {
|
|
13233
|
-
|
|
13234
|
-
|
|
13235
|
-
|
|
13236
|
-
|
|
13237
|
-
|
|
13238
|
-
|
|
13239
|
-
|
|
13240
|
-
|
|
13348
|
+
actions: [(_, { nextBlockPath, renamedBlock, renameActions }) => [
|
|
13349
|
+
...renameActions,
|
|
13350
|
+
raise$1({
|
|
13351
|
+
type: "delete.block",
|
|
13352
|
+
at: nextBlockPath
|
|
13353
|
+
}),
|
|
13354
|
+
raise$1({
|
|
13355
|
+
type: "insert.block",
|
|
13356
|
+
block: renamedBlock,
|
|
13357
|
+
placement: "auto",
|
|
13358
|
+
select: "none"
|
|
13359
|
+
})
|
|
13360
|
+
]]
|
|
13241
13361
|
}),
|
|
13242
13362
|
defineBehavior({
|
|
13243
13363
|
on: "delete.block",
|
|
@@ -13307,7 +13427,44 @@ const abstractAnnotationBehaviors = [
|
|
|
13307
13427
|
type: "delete"
|
|
13308
13428
|
})]]
|
|
13309
13429
|
})
|
|
13310
|
-
]
|
|
13430
|
+
];
|
|
13431
|
+
/**
|
|
13432
|
+
* Raise the child/markDef renames `planMergeKeyRenames` computed as
|
|
13433
|
+
* `set`/`child.set` events against the still-living `mergingBlock`, so
|
|
13434
|
+
* they land on the wire before the merge's `unset`.
|
|
13435
|
+
*/
|
|
13436
|
+
function planMergeKeyRenameActions(args) {
|
|
13437
|
+
let { context, mergingBlockPath, mergingBlock, destinationBlock } = args, { renamedBlock, childRenames, markDefRenames } = planMergeKeyRenames({
|
|
13438
|
+
context,
|
|
13439
|
+
mergingBlock,
|
|
13440
|
+
destinationBlock,
|
|
13441
|
+
dedupeEqualMarkDefs: !1
|
|
13442
|
+
}), renameActions = [];
|
|
13443
|
+
for (let { markDefKey, newKey } of markDefRenames) renameActions.push(raise$1({
|
|
13444
|
+
type: "set",
|
|
13445
|
+
at: [
|
|
13446
|
+
...mergingBlockPath,
|
|
13447
|
+
"markDefs",
|
|
13448
|
+
{ _key: markDefKey },
|
|
13449
|
+
"_key"
|
|
13450
|
+
],
|
|
13451
|
+
value: newKey
|
|
13452
|
+
}));
|
|
13453
|
+
for (let { childKey, props } of childRenames) renameActions.push(raise$1({
|
|
13454
|
+
type: "child.set",
|
|
13455
|
+
at: [
|
|
13456
|
+
...mergingBlockPath,
|
|
13457
|
+
"children",
|
|
13458
|
+
{ _key: childKey }
|
|
13459
|
+
],
|
|
13460
|
+
props
|
|
13461
|
+
}));
|
|
13462
|
+
return {
|
|
13463
|
+
renamedBlock,
|
|
13464
|
+
renameActions
|
|
13465
|
+
};
|
|
13466
|
+
}
|
|
13467
|
+
const mimeTypePriority = [
|
|
13311
13468
|
"application/x-portable-text",
|
|
13312
13469
|
"application/json",
|
|
13313
13470
|
"text/markdown",
|
|
@@ -16455,7 +16612,8 @@ function createActors(config) {
|
|
|
16455
16612
|
return config.subscriptions.push(mutationBatcher.subscribe), config.subscriptions.push(() => subscribeToOperations(config.editorEngine, (event) => {
|
|
16456
16613
|
isPublicOperation(event.operation) && config.relay.send({
|
|
16457
16614
|
type: "operation",
|
|
16458
|
-
operation: event.operation
|
|
16615
|
+
operation: event.operation,
|
|
16616
|
+
origin: event.origin === "remote" ? "remote" : "local"
|
|
16459
16617
|
});
|
|
16460
16618
|
})), config.subscriptions.push(() => {
|
|
16461
16619
|
let subscription = syncActor.on("*", (event) => {
|