@lofcz/platejs-suggestion 53.0.0 → 53.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -1
- package/dist/react/index.js +1 -1
- package/dist/{src-CruTaHKh.js → src-CTTgK2Pn.js} +151 -43
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -61,6 +61,7 @@ declare function diffToSuggestions<E extends SlateEditor>(editor: E, doc0: Desce
|
|
|
61
61
|
getInsertProps,
|
|
62
62
|
getUpdateProps,
|
|
63
63
|
isInline,
|
|
64
|
+
generatePairId,
|
|
64
65
|
...options
|
|
65
66
|
}?: Partial<ComputeDiffOptions>): ValueOf<E>;
|
|
66
67
|
//#endregion
|
|
@@ -185,6 +186,7 @@ declare const removeNodesSuggestion: (editor: SlateEditor, nodes: NodeEntry<TEle
|
|
|
185
186
|
//#region src/lib/transforms/setSuggestionNodes.d.ts
|
|
186
187
|
declare const setSuggestionNodes: (editor: SlateEditor, options?: {
|
|
187
188
|
createdAt?: number;
|
|
189
|
+
includeInlineElements?: boolean;
|
|
188
190
|
suggestionDeletion?: boolean;
|
|
189
191
|
suggestionId?: string;
|
|
190
192
|
} & SetNodesOptions) => void;
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { A as SkipSuggestionDeletes, C as getSuggestionUserIdByKey, D as getInlineSuggestionData, E as isSuggestionKey, O as getSuggestionKeyId, S as getSuggestionUserId, T as isCurrentUserSuggestion, _ as getTransientSuggestionKey, a as BaseSuggestionPlugin, b as getSuggestionKey, c as removeMarkSuggestion, d as deleteFragmentSuggestion, f as deleteSuggestion, g as findInlineSuggestionNode, h as findSuggestionProps, i as acceptSuggestion, k as keyId2SuggestionId, l as insertTextSuggestion, m as addMarkSuggestion, n as rejectSuggestion, o as withSuggestion, p as setSuggestionNodes, r as getSuggestionProps, s as removeNodesSuggestion, t as diffToSuggestions, u as insertFragmentSuggestion, v as getActiveSuggestionDescriptions, w as getSuggestionUserIds, x as getSuggestionKeys, y as getSuggestionNodeEntries } from "./src-
|
|
1
|
+
import { A as SkipSuggestionDeletes, C as getSuggestionUserIdByKey, D as getInlineSuggestionData, E as isSuggestionKey, O as getSuggestionKeyId, S as getSuggestionUserId, T as isCurrentUserSuggestion, _ as getTransientSuggestionKey, a as BaseSuggestionPlugin, b as getSuggestionKey, c as removeMarkSuggestion, d as deleteFragmentSuggestion, f as deleteSuggestion, g as findInlineSuggestionNode, h as findSuggestionProps, i as acceptSuggestion, k as keyId2SuggestionId, l as insertTextSuggestion, m as addMarkSuggestion, n as rejectSuggestion, o as withSuggestion, p as setSuggestionNodes, r as getSuggestionProps, s as removeNodesSuggestion, t as diffToSuggestions, u as insertFragmentSuggestion, v as getActiveSuggestionDescriptions, w as getSuggestionUserIds, x as getSuggestionKeys, y as getSuggestionNodeEntries } from "./src-CTTgK2Pn.js";
|
|
2
2
|
|
|
3
3
|
export { BaseSuggestionPlugin, SkipSuggestionDeletes, acceptSuggestion, addMarkSuggestion, deleteFragmentSuggestion, deleteSuggestion, diffToSuggestions, findInlineSuggestionNode, findSuggestionProps, getActiveSuggestionDescriptions, getInlineSuggestionData, getSuggestionKey, getSuggestionKeyId, getSuggestionKeys, getSuggestionNodeEntries, getSuggestionProps, getSuggestionUserId, getSuggestionUserIdByKey, getSuggestionUserIds, getTransientSuggestionKey, insertFragmentSuggestion, insertTextSuggestion, isCurrentUserSuggestion, isSuggestionKey, keyId2SuggestionId, rejectSuggestion, removeMarkSuggestion, removeNodesSuggestion, setSuggestionNodes, withSuggestion };
|
package/dist/react/index.js
CHANGED
|
@@ -116,10 +116,15 @@ const findSuggestionProps = (editor, { at, type }) => {
|
|
|
116
116
|
createdAt: Date.now()
|
|
117
117
|
};
|
|
118
118
|
const api = editor.getApi(BaseSuggestionPlugin);
|
|
119
|
+
const getInlineElementEntry = (point) => editor.api.above({
|
|
120
|
+
at: point,
|
|
121
|
+
match: (node) => ElementApi.isElement(node) && editor.api.isInline(node) && !!api.suggestion.nodeId(node)
|
|
122
|
+
});
|
|
119
123
|
let entry = api.suggestion.node({
|
|
120
124
|
at,
|
|
121
125
|
isText: true
|
|
122
126
|
});
|
|
127
|
+
let inlineEntry;
|
|
123
128
|
if (!entry) {
|
|
124
129
|
let start;
|
|
125
130
|
let end;
|
|
@@ -129,16 +134,22 @@ const findSuggestionProps = (editor, { at, type }) => {
|
|
|
129
134
|
return defaultProps;
|
|
130
135
|
}
|
|
131
136
|
const nextPoint = editor.api.after(end);
|
|
132
|
-
if (nextPoint)
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
});
|
|
136
|
-
if (!entry) {
|
|
137
|
-
const prevPoint = editor.api.before(start);
|
|
138
|
-
if (prevPoint) entry = api.suggestion.node({
|
|
139
|
-
at: prevPoint,
|
|
137
|
+
if (nextPoint) {
|
|
138
|
+
entry = api.suggestion.node({
|
|
139
|
+
at: nextPoint,
|
|
140
140
|
isText: true
|
|
141
141
|
});
|
|
142
|
+
if (!entry) inlineEntry = getInlineElementEntry(nextPoint);
|
|
143
|
+
}
|
|
144
|
+
if (!entry && !inlineEntry) {
|
|
145
|
+
const prevPoint = editor.api.before(start);
|
|
146
|
+
if (prevPoint) {
|
|
147
|
+
entry = api.suggestion.node({
|
|
148
|
+
at: prevPoint,
|
|
149
|
+
isText: true
|
|
150
|
+
});
|
|
151
|
+
if (!entry) inlineEntry = getInlineElementEntry(prevPoint);
|
|
152
|
+
}
|
|
142
153
|
const blockEntry = editor.api.block({ at: start });
|
|
143
154
|
if (!entry && blockEntry && editor.api.isStart(start, blockEntry[1])) {
|
|
144
155
|
const lineBreakData = editor.api.above({ at: prevPoint ?? start })?.[0].suggestion;
|
|
@@ -153,6 +164,11 @@ const findSuggestionProps = (editor, { at, type }) => {
|
|
|
153
164
|
id: api.suggestion.nodeId(entry[0]) ?? nanoid(),
|
|
154
165
|
createdAt: getInlineSuggestionData(entry[0])?.createdAt ?? Date.now()
|
|
155
166
|
};
|
|
167
|
+
const inlineSuggestionData = inlineEntry && api.suggestion.suggestionData(inlineEntry[0]);
|
|
168
|
+
if (inlineEntry && inlineSuggestionData?.type === type && isCurrentUserSuggestion(editor, inlineEntry[0])) return {
|
|
169
|
+
id: api.suggestion.nodeId(inlineEntry[0]) ?? nanoid(),
|
|
170
|
+
createdAt: inlineSuggestionData.createdAt ?? Date.now()
|
|
171
|
+
};
|
|
156
172
|
return defaultProps;
|
|
157
173
|
};
|
|
158
174
|
|
|
@@ -198,10 +214,10 @@ const setSuggestionNodes = (editor, options) => {
|
|
|
198
214
|
const at = getAt(editor, options?.at) ?? editor.selection;
|
|
199
215
|
if (!at) return;
|
|
200
216
|
const { suggestionId = nanoid() } = options ?? {};
|
|
201
|
-
const nodeEntries = [...editor.api.nodes({
|
|
217
|
+
const nodeEntries = [...options?.includeInlineElements ?? true ? editor.api.nodes({
|
|
202
218
|
match: (n) => ElementApi.isElement(n) && editor.api.isInline(n),
|
|
203
219
|
...options
|
|
204
|
-
})];
|
|
220
|
+
}) : []];
|
|
205
221
|
editor.tf.withoutNormalizing(() => {
|
|
206
222
|
const data = {
|
|
207
223
|
id: suggestionId,
|
|
@@ -235,6 +251,23 @@ const setSuggestionNodes = (editor, options) => {
|
|
|
235
251
|
*/
|
|
236
252
|
const deleteSuggestion = (editor, at, { reverse } = {}) => {
|
|
237
253
|
let resId;
|
|
254
|
+
const getInlineEntryAt = (point) => editor.api.above({
|
|
255
|
+
at: point,
|
|
256
|
+
match: (node) => ElementApi.isElement(node) && editor.api.isInline(node)
|
|
257
|
+
});
|
|
258
|
+
const getAdjacentInlineVoidEntry = (point, { reverse: reverse$1 }) => {
|
|
259
|
+
try {
|
|
260
|
+
const adjacentPath = reverse$1 ? PathApi.previous(point.path) : PathApi.next(point.path);
|
|
261
|
+
if (!adjacentPath) return;
|
|
262
|
+
const entry = editor.api.node(adjacentPath);
|
|
263
|
+
if (entry && ElementApi.isElement(entry[0]) && editor.api.isInline(entry[0]) && editor.api.isVoid(entry[0])) return entry;
|
|
264
|
+
} catch {}
|
|
265
|
+
};
|
|
266
|
+
const isBoundaryPoint = (point, { reverse: reverse$1 }) => {
|
|
267
|
+
const range = editor.api.range(point.path);
|
|
268
|
+
if (!range) return false;
|
|
269
|
+
return reverse$1 ? editor.api.isStart(point, range) : editor.api.isEnd(point, range);
|
|
270
|
+
};
|
|
238
271
|
editor.tf.withoutNormalizing(() => {
|
|
239
272
|
const { anchor: from, focus: to } = at;
|
|
240
273
|
const { id, createdAt } = findSuggestionProps(editor, {
|
|
@@ -249,6 +282,7 @@ const deleteSuggestion = (editor, at, { reverse } = {}) => {
|
|
|
249
282
|
if (!pointCurrent) break;
|
|
250
283
|
const pointTarget = toRef.current;
|
|
251
284
|
if (!pointTarget) break;
|
|
285
|
+
if (PointApi.equals(pointCurrent, pointTarget)) break;
|
|
252
286
|
if (!editor.api.isAt({
|
|
253
287
|
at: {
|
|
254
288
|
anchor: pointCurrent,
|
|
@@ -256,13 +290,19 @@ const deleteSuggestion = (editor, at, { reverse } = {}) => {
|
|
|
256
290
|
},
|
|
257
291
|
blocks: true
|
|
258
292
|
})) {
|
|
259
|
-
|
|
293
|
+
const inlineRange = reverse ? {
|
|
260
294
|
anchor: pointTarget,
|
|
261
295
|
focus: pointCurrent
|
|
262
296
|
} : {
|
|
263
297
|
anchor: pointCurrent,
|
|
264
298
|
focus: pointTarget
|
|
265
|
-
}
|
|
299
|
+
};
|
|
300
|
+
const str = editor.api.string(inlineRange);
|
|
301
|
+
const hasInlineNode = editor.api.some({
|
|
302
|
+
at: inlineRange,
|
|
303
|
+
match: (n) => ElementApi.isElement(n) && editor.api.isInline(n)
|
|
304
|
+
});
|
|
305
|
+
if (str.length === 0 && !hasInlineNode) break;
|
|
266
306
|
}
|
|
267
307
|
const pointNext = (reverse ? editor.api.before : editor.api.after)(pointCurrent, { unit: "character" });
|
|
268
308
|
if (!pointNext) break;
|
|
@@ -274,6 +314,40 @@ const deleteSuggestion = (editor, at, { reverse } = {}) => {
|
|
|
274
314
|
focus: pointNext
|
|
275
315
|
};
|
|
276
316
|
range = editor.api.unhangRange(range, { character: true });
|
|
317
|
+
const inlineEntryAtNext = getInlineEntryAt(pointNext);
|
|
318
|
+
const inlineEntryAtCurrent = inlineEntryAtNext ? void 0 : getInlineEntryAt(pointCurrent);
|
|
319
|
+
const canUseAdjacentInlineFallback = isBoundaryPoint(pointCurrent, { reverse });
|
|
320
|
+
const adjacentInlineEntry = inlineEntryAtNext || inlineEntryAtCurrent || !canUseAdjacentInlineFallback ? void 0 : getAdjacentInlineVoidEntry(pointCurrent, { reverse });
|
|
321
|
+
const inlineEntryAtCurrentIsNonSelectable = !!inlineEntryAtCurrent && !editor.api.isSelectable(inlineEntryAtCurrent[0]);
|
|
322
|
+
const adjacentInlineEntryIsNonSelectable = !!adjacentInlineEntry && !editor.api.isSelectable(adjacentInlineEntry[0]);
|
|
323
|
+
const inlineEntry = inlineEntryAtNext ?? (inlineEntryAtCurrentIsNonSelectable ? inlineEntryAtCurrent : void 0) ?? (adjacentInlineEntryIsNonSelectable ? adjacentInlineEntry : void 0);
|
|
324
|
+
const pointCurrentInsideInline = !!inlineEntry && PathApi.isAncestor(inlineEntry[1], pointCurrent.path);
|
|
325
|
+
if (inlineEntry && editor.api.isVoid(inlineEntry[0]) && (!inlineEntryAtNext || !pointCurrentInsideInline)) {
|
|
326
|
+
editor.tf.setNodes({
|
|
327
|
+
[getSuggestionKey(id)]: {
|
|
328
|
+
id,
|
|
329
|
+
createdAt,
|
|
330
|
+
type: "remove",
|
|
331
|
+
userId: editor.getOptions(BaseSuggestionPlugin).currentUserId
|
|
332
|
+
},
|
|
333
|
+
[KEYS.suggestion]: true
|
|
334
|
+
}, { at: inlineEntry[1] });
|
|
335
|
+
const beforeInlineElement = editor.api.before(inlineEntry[1]);
|
|
336
|
+
const targetIsInsideInlineElement = PathApi.equals(inlineEntry[1], pointTarget.path) || PathApi.isAncestor(inlineEntry[1], pointTarget.path);
|
|
337
|
+
if (reverse) {
|
|
338
|
+
if (beforeInlineElement) {
|
|
339
|
+
editor.tf.select(beforeInlineElement);
|
|
340
|
+
if (!targetIsInsideInlineElement && !PointApi.equals(beforeInlineElement, pointTarget)) continue;
|
|
341
|
+
}
|
|
342
|
+
break;
|
|
343
|
+
}
|
|
344
|
+
const afterInlineElement = editor.api.after(inlineEntry[1]);
|
|
345
|
+
if (afterInlineElement) {
|
|
346
|
+
editor.tf.select(afterInlineElement);
|
|
347
|
+
if (!PointApi.equals(afterInlineElement, pointTarget)) continue;
|
|
348
|
+
} else if (beforeInlineElement) editor.tf.select(beforeInlineElement);
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
277
351
|
const entryBlock = editor.api.node({
|
|
278
352
|
at: pointCurrent,
|
|
279
353
|
block: true,
|
|
@@ -303,11 +377,13 @@ const deleteSuggestion = (editor, at, { reverse } = {}) => {
|
|
|
303
377
|
break;
|
|
304
378
|
}
|
|
305
379
|
if (!isBlockSuggestion) {
|
|
380
|
+
const isPreviousBlockVoid = editor.api.isVoid(previousAboveNode[0]) && !editor.api.isInline(previousAboveNode[0]);
|
|
306
381
|
editor.tf.setNodes({ [KEYS.suggestion]: {
|
|
307
382
|
id,
|
|
308
383
|
createdAt,
|
|
309
384
|
type: "remove",
|
|
310
|
-
userId: editor.getOptions(BaseSuggestionPlugin).currentUserId
|
|
385
|
+
userId: editor.getOptions(BaseSuggestionPlugin).currentUserId,
|
|
386
|
+
...isPreviousBlockVoid ? {} : { isLineBreak: true }
|
|
311
387
|
} }, { at: previousAboveNode[1] });
|
|
312
388
|
editor.tf.move({
|
|
313
389
|
reverse,
|
|
@@ -336,6 +412,7 @@ const deleteSuggestion = (editor, at, { reverse } = {}) => {
|
|
|
336
412
|
setSuggestionNodes(editor, {
|
|
337
413
|
at: range,
|
|
338
414
|
createdAt,
|
|
415
|
+
includeInlineElements: false,
|
|
339
416
|
suggestionDeletion: true,
|
|
340
417
|
suggestionId: id
|
|
341
418
|
});
|
|
@@ -475,7 +552,8 @@ const removeNodesSuggestion = (editor, nodes) => {
|
|
|
475
552
|
editor.tf.setNodes({ [KEYS.suggestion]: {
|
|
476
553
|
id,
|
|
477
554
|
createdAt,
|
|
478
|
-
type: "remove"
|
|
555
|
+
type: "remove",
|
|
556
|
+
userId: editor.getOptions(BaseSuggestionPlugin).currentUserId
|
|
479
557
|
} }, { at: blockPath });
|
|
480
558
|
});
|
|
481
559
|
};
|
|
@@ -491,11 +569,12 @@ const withSuggestion = ({ api, editor, getOptions, tf: { addMark, apply, deleteB
|
|
|
491
569
|
return apply(operation);
|
|
492
570
|
},
|
|
493
571
|
deleteBackward(unit) {
|
|
572
|
+
const resolvedUnit = unit ?? "character";
|
|
494
573
|
const selection = editor.selection;
|
|
495
|
-
const pointTarget = editor.api.before(selection, { unit });
|
|
574
|
+
const pointTarget = editor.api.before(selection, { unit: resolvedUnit });
|
|
496
575
|
if (getOptions().isSuggesting) {
|
|
497
576
|
const node = editor.api.above();
|
|
498
|
-
if (node?.[0][KEYS.suggestion] && !node?.[0].suggestion.isLineBreak) return deleteBackward(
|
|
577
|
+
if (node?.[0][KEYS.suggestion] && !node?.[0].suggestion.isLineBreak) return deleteBackward(resolvedUnit);
|
|
499
578
|
if (!pointTarget) return;
|
|
500
579
|
deleteSuggestion(editor, {
|
|
501
580
|
anchor: selection.anchor,
|
|
@@ -512,12 +591,13 @@ const withSuggestion = ({ api, editor, getOptions, tf: { addMark, apply, deleteB
|
|
|
512
591
|
blocks: true
|
|
513
592
|
})) editor.tf.unsetNodes([KEYS.suggestion], { at: pointTarget });
|
|
514
593
|
}
|
|
515
|
-
deleteBackward(
|
|
594
|
+
deleteBackward(resolvedUnit);
|
|
516
595
|
},
|
|
517
596
|
deleteForward(unit) {
|
|
597
|
+
const resolvedUnit = unit ?? "character";
|
|
518
598
|
if (getOptions().isSuggesting) {
|
|
519
599
|
const selection = editor.selection;
|
|
520
|
-
const pointTarget = editor.api.after(selection, { unit });
|
|
600
|
+
const pointTarget = editor.api.after(selection, { unit: resolvedUnit });
|
|
521
601
|
if (!pointTarget) return;
|
|
522
602
|
deleteSuggestion(editor, {
|
|
523
603
|
anchor: selection.anchor,
|
|
@@ -525,7 +605,7 @@ const withSuggestion = ({ api, editor, getOptions, tf: { addMark, apply, deleteB
|
|
|
525
605
|
});
|
|
526
606
|
return;
|
|
527
607
|
}
|
|
528
|
-
deleteForward(
|
|
608
|
+
deleteForward(resolvedUnit);
|
|
529
609
|
},
|
|
530
610
|
deleteFragment(direction) {
|
|
531
611
|
if (getOptions().isSuggesting) {
|
|
@@ -778,6 +858,14 @@ const getSuggestionProps = (editor, node, { id = nanoid(), createdAt = Date.now(
|
|
|
778
858
|
//#region src/lib/transforms/rejectSuggestion.ts
|
|
779
859
|
const rejectSuggestion = (editor, description) => {
|
|
780
860
|
editor.tf.withoutNormalizing(() => {
|
|
861
|
+
const inlineInsertElementEntries = [...editor.api.nodes({
|
|
862
|
+
at: [],
|
|
863
|
+
match: (n) => {
|
|
864
|
+
if (!ElementApi.isElement(n) || !editor.api.isInline(n)) return false;
|
|
865
|
+
const suggestionData = getInlineSuggestionData(n);
|
|
866
|
+
return suggestionData?.type === "insert" && suggestionData.id === description.suggestionId;
|
|
867
|
+
}
|
|
868
|
+
})];
|
|
781
869
|
[...editor.api.nodes({
|
|
782
870
|
at: [],
|
|
783
871
|
match: (n) => {
|
|
@@ -799,7 +887,7 @@ const rejectSuggestion = (editor, description) => {
|
|
|
799
887
|
at: [],
|
|
800
888
|
mode: "all",
|
|
801
889
|
match: (n) => {
|
|
802
|
-
if (TextApi.isText(n)) {
|
|
890
|
+
if (TextApi.isText(n) || ElementApi.isElement(n) && editor.api.isInline(n)) {
|
|
803
891
|
const suggestionData = getInlineSuggestionData(n);
|
|
804
892
|
if (suggestionData) return suggestionData.type === "remove" && suggestionData.id === description.suggestionId;
|
|
805
893
|
return false;
|
|
@@ -828,6 +916,9 @@ const rejectSuggestion = (editor, description) => {
|
|
|
828
916
|
return false;
|
|
829
917
|
}
|
|
830
918
|
});
|
|
919
|
+
inlineInsertElementEntries.reverse().forEach(([, path]) => {
|
|
920
|
+
editor.tf.removeNodes({ at: path });
|
|
921
|
+
});
|
|
831
922
|
[...editor.api.nodes({
|
|
832
923
|
at: [],
|
|
833
924
|
match: (n) => {
|
|
@@ -856,12 +947,16 @@ const rejectSuggestion = (editor, description) => {
|
|
|
856
947
|
|
|
857
948
|
//#endregion
|
|
858
949
|
//#region src/lib/diffToSuggestions.ts
|
|
859
|
-
function diffToSuggestions(editor, doc0, doc1, { getDeleteProps = (node
|
|
950
|
+
function diffToSuggestions(editor, doc0, doc1, { getDeleteProps = (node, ctx) => getSuggestionProps(editor, node, {
|
|
951
|
+
id: ctx?.pairId,
|
|
952
|
+
suggestionDeletion: true
|
|
953
|
+
}), getInsertProps = (node, ctx) => getSuggestionProps(editor, node, { id: ctx?.pairId }), getUpdateProps = (node, _properties, newProperties) => getSuggestionProps(editor, node, { suggestionUpdate: newProperties }), isInline = editor.api.isInline, generatePairId = () => nanoid(), ...options } = {}) {
|
|
860
954
|
const values = computeDiff(doc0, doc1, {
|
|
861
955
|
getDeleteProps,
|
|
862
956
|
getInsertProps,
|
|
863
957
|
getUpdateProps,
|
|
864
958
|
isInline,
|
|
959
|
+
generatePairId,
|
|
865
960
|
...options
|
|
866
961
|
});
|
|
867
962
|
const traverseNodes = (nodes) => {
|
|
@@ -877,35 +972,48 @@ function diffToSuggestions(editor, doc0, doc1, { getDeleteProps = (node) => getS
|
|
|
877
972
|
return traverseNodes(values);
|
|
878
973
|
}
|
|
879
974
|
/**
|
|
880
|
-
* Unifies the ID of adjacent insert and remove suggestions
|
|
881
|
-
*
|
|
882
|
-
*
|
|
883
|
-
*
|
|
975
|
+
* Unifies the ID of adjacent insert and remove suggestions so the UI treats
|
|
976
|
+
* them as a single reviewable change.
|
|
977
|
+
*
|
|
978
|
+
* Two orderings are handled:
|
|
979
|
+
*
|
|
980
|
+
* - Remove → Insert (default / `delete-first` flush order):
|
|
981
|
+
* the insert leaf inherits the remove leaf's id + createdAt.
|
|
982
|
+
* - Insert → Remove (`insert-first` flush order):
|
|
983
|
+
* the remove leaf inherits the insert leaf's id + createdAt.
|
|
984
|
+
*
|
|
985
|
+
* Without this pass, the new-above-old presentation would emit two separate
|
|
986
|
+
* suggestion groups for what is conceptually one change.
|
|
884
987
|
*/
|
|
885
988
|
function unifyAdjacentSuggestionIds(node, index, nodes, editor) {
|
|
886
989
|
const api = editor.getApi(BaseSuggestionPlugin);
|
|
887
990
|
const currentNodeData = api.suggestion.suggestionData(node);
|
|
888
|
-
if (currentNodeData
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
createdAt: previousData.createdAt
|
|
899
|
-
}
|
|
900
|
-
};
|
|
901
|
-
const key = getSuggestionKey(currentNodeData.id);
|
|
902
|
-
delete updatedNode[key];
|
|
903
|
-
return updatedNode;
|
|
904
|
-
}
|
|
905
|
-
}
|
|
991
|
+
if (!currentNodeData) return node;
|
|
992
|
+
const previousNode = index > 0 ? nodes[index - 1] : null;
|
|
993
|
+
index < nodes.length - 1 && nodes[index + 1];
|
|
994
|
+
if (currentNodeData.type === "insert" && previousNode?.[KEYS.suggestion]) {
|
|
995
|
+
const previousData = api.suggestion.suggestionData(previousNode);
|
|
996
|
+
if (previousData?.type === "remove") return rewriteSuggestionId(node, currentNodeData, previousData.id, previousData.createdAt);
|
|
997
|
+
}
|
|
998
|
+
if (currentNodeData.type === "remove" && previousNode?.[KEYS.suggestion]) {
|
|
999
|
+
const previousData = api.suggestion.suggestionData(previousNode);
|
|
1000
|
+
if (previousData?.type === "insert") return rewriteSuggestionId(node, currentNodeData, previousData.id, previousData.createdAt);
|
|
906
1001
|
}
|
|
907
1002
|
return node;
|
|
908
1003
|
}
|
|
1004
|
+
function rewriteSuggestionId(node, currentNodeData, targetId, targetCreatedAt) {
|
|
1005
|
+
const updatedNode = {
|
|
1006
|
+
...node,
|
|
1007
|
+
[getSuggestionKey(targetId)]: {
|
|
1008
|
+
...currentNodeData,
|
|
1009
|
+
id: targetId,
|
|
1010
|
+
createdAt: targetCreatedAt
|
|
1011
|
+
}
|
|
1012
|
+
};
|
|
1013
|
+
const oldKey = getSuggestionKey(currentNodeData.id);
|
|
1014
|
+
if (oldKey !== getSuggestionKey(targetId)) delete updatedNode[oldKey];
|
|
1015
|
+
return updatedNode;
|
|
1016
|
+
}
|
|
909
1017
|
|
|
910
1018
|
//#endregion
|
|
911
1019
|
export { SkipSuggestionDeletes as A, getSuggestionUserIdByKey as C, getInlineSuggestionData as D, isSuggestionKey as E, getSuggestionKeyId as O, getSuggestionUserId as S, isCurrentUserSuggestion as T, getTransientSuggestionKey as _, BaseSuggestionPlugin as a, getSuggestionKey as b, removeMarkSuggestion as c, deleteFragmentSuggestion as d, deleteSuggestion as f, findInlineSuggestionNode as g, findSuggestionProps as h, acceptSuggestion as i, keyId2SuggestionId as k, insertTextSuggestion as l, addMarkSuggestion as m, rejectSuggestion as n, withSuggestion as o, setSuggestionNodes as p, getSuggestionProps as r, removeNodesSuggestion as s, diffToSuggestions as t, insertFragmentSuggestion as u, getActiveSuggestionDescriptions as v, getSuggestionUserIds as w, getSuggestionKeys as x, getSuggestionNodeEntries as y };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lofcz/platejs-suggestion",
|
|
3
|
-
"version": "53.
|
|
3
|
+
"version": "53.2.3",
|
|
4
4
|
"description": "Plate plugin for suggestions",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"plate",
|
|
@@ -31,14 +31,14 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"lodash": "^4.17.21",
|
|
33
33
|
"react-compiler-runtime": "^1.0.0",
|
|
34
|
-
"@platejs/diff": "npm:@lofcz/platejs-diff@53.
|
|
34
|
+
"@platejs/diff": "npm:@lofcz/platejs-diff@53.1.3"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@plate/scripts": "1.0.0",
|
|
38
|
-
"platejs": "npm:@lofcz/platejs@53.
|
|
38
|
+
"platejs": "npm:@lofcz/platejs@53.2.4"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
|
-
"platejs": ">=53.0.
|
|
41
|
+
"platejs": ">=53.0.3",
|
|
42
42
|
"react": ">=18.0.0",
|
|
43
43
|
"react-dom": ">=18.0.0"
|
|
44
44
|
},
|