@tiptap/y-tiptap 3.0.4 → 3.0.5
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/src/plugins/sync-plugin.d.ts +2 -0
- package/dist/y-tiptap.cjs +87 -16
- package/dist/y-tiptap.cjs.map +1 -1
- package/dist/y-tiptap.js +88 -17
- package/dist/y-tiptap.js.map +1 -1
- package/package.json +1 -1
|
@@ -6,6 +6,7 @@ export function isVisible(item: Y.Item, snapshot?: Y.Snapshot): boolean;
|
|
|
6
6
|
export function ySyncPlugin(yXmlFragment: Y.XmlFragment, { colors, colorMapping, permanentUserData, onFirstRender, mapping }?: YSyncOpts): any;
|
|
7
7
|
export function getRelativeSelection(pmbinding: ProsemirrorBinding, state: import('prosemirror-state').EditorState): {
|
|
8
8
|
type: any;
|
|
9
|
+
depth: any;
|
|
9
10
|
anchor: any;
|
|
10
11
|
head: any;
|
|
11
12
|
};
|
|
@@ -44,6 +45,7 @@ export class ProsemirrorBinding {
|
|
|
44
45
|
*/
|
|
45
46
|
beforeTransactionSelection: {
|
|
46
47
|
type: any;
|
|
48
|
+
depth: any;
|
|
47
49
|
anchor: any;
|
|
48
50
|
head: any;
|
|
49
51
|
};
|
package/dist/y-tiptap.cjs
CHANGED
|
@@ -330,7 +330,28 @@ const restoreRelativeSelection = (tr, relSel, binding) => {
|
|
|
330
330
|
relSel.anchor,
|
|
331
331
|
binding.mapping
|
|
332
332
|
);
|
|
333
|
-
|
|
333
|
+
// anchor is null when the referenced node was deleted or moved out of
|
|
334
|
+
// binding.type by a remote update; resolving null would throw.
|
|
335
|
+
if (anchor !== null) {
|
|
336
|
+
tr.setSelection(createSafeNodeSelection(tr, anchor));
|
|
337
|
+
}
|
|
338
|
+
} else if (relSel.type === 'nodeRange') {
|
|
339
|
+
const anchor = relativePositionToAbsolutePosition(
|
|
340
|
+
binding.doc,
|
|
341
|
+
binding.type,
|
|
342
|
+
relSel.anchor,
|
|
343
|
+
binding.mapping
|
|
344
|
+
);
|
|
345
|
+
const head = relativePositionToAbsolutePosition(
|
|
346
|
+
binding.doc,
|
|
347
|
+
binding.type,
|
|
348
|
+
relSel.head,
|
|
349
|
+
binding.mapping
|
|
350
|
+
);
|
|
351
|
+
const selection = createSafeNodeRangeSelection(tr, anchor, head, relSel.depth);
|
|
352
|
+
if (selection !== null) {
|
|
353
|
+
tr.setSelection(selection);
|
|
354
|
+
}
|
|
334
355
|
} else {
|
|
335
356
|
const anchor = relativePositionToAbsolutePosition(
|
|
336
357
|
binding.doc,
|
|
@@ -368,23 +389,65 @@ const createSafeNodeSelection = (tr, pos) => {
|
|
|
368
389
|
}
|
|
369
390
|
};
|
|
370
391
|
|
|
392
|
+
/**
|
|
393
|
+
* Safely reconstructs a NodeRangeSelection from resolved absolute positions.
|
|
394
|
+
*
|
|
395
|
+
* @param {import('prosemirror-state').Transaction} tr - The transaction whose document provides resolved positions.
|
|
396
|
+
* @param {number|null} anchor - Absolute document position marking the start (boundary) of the node range.
|
|
397
|
+
* Use `relativePositionToAbsolutePosition` before calling this function.
|
|
398
|
+
* @param {number|null} head - Absolute document position marking the end (boundary) of the node range.
|
|
399
|
+
* Use `relativePositionToAbsolutePosition` before calling this function.
|
|
400
|
+
* @param {number|undefined} depth - The nesting depth at which the range operates (e.g. 0 for
|
|
401
|
+
* top-level blocks, 1 for blocks nested inside a wrapper). Passed through to
|
|
402
|
+
* `Selection.fromJSON`; ignored by `@tiptap/extension-node-range` < v2.29 but
|
|
403
|
+
* properly stored starting from that version.
|
|
404
|
+
* @returns {import('prosemirror-state').Selection|null} Reconstructed selection, or null if
|
|
405
|
+
* anchor/head could not be resolved.
|
|
406
|
+
*/
|
|
407
|
+
const createSafeNodeRangeSelection = (tr, anchor, head, depth) => {
|
|
408
|
+
if (anchor === null || head === null) {
|
|
409
|
+
return null
|
|
410
|
+
}
|
|
411
|
+
const clampedAnchor = Math.min(Math.max(anchor, 0), tr.doc.content.size);
|
|
412
|
+
const clampedHead = Math.min(Math.max(head, 0), tr.doc.content.size);
|
|
413
|
+
try {
|
|
414
|
+
const selection = prosemirrorState.Selection.fromJSON(tr.doc, {
|
|
415
|
+
type: 'nodeRange',
|
|
416
|
+
anchor: clampedAnchor,
|
|
417
|
+
head: clampedHead,
|
|
418
|
+
depth
|
|
419
|
+
});
|
|
420
|
+
if (!selection.ranges.length) {
|
|
421
|
+
return prosemirrorState.TextSelection.near(tr.doc.resolve(clampedAnchor))
|
|
422
|
+
}
|
|
423
|
+
return selection
|
|
424
|
+
} catch (e) {
|
|
425
|
+
return prosemirrorState.TextSelection.near(tr.doc.resolve(clampedAnchor))
|
|
426
|
+
}
|
|
427
|
+
};
|
|
428
|
+
|
|
371
429
|
/**
|
|
372
430
|
* @param {ProsemirrorBinding} pmbinding
|
|
373
431
|
* @param {import('prosemirror-state').EditorState} state
|
|
374
432
|
*/
|
|
375
|
-
const getRelativeSelection = (pmbinding, state) =>
|
|
376
|
-
type
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
433
|
+
const getRelativeSelection = (pmbinding, state) => {
|
|
434
|
+
const type = /** @type {any} */ (state.selection).jsonID;
|
|
435
|
+
return {
|
|
436
|
+
type,
|
|
437
|
+
// `depth` is only meaningful for NodeRangeSelection; undefined for every other type.
|
|
438
|
+
depth: type === 'nodeRange' ? /** @type {any} */ (state.selection).depth : undefined,
|
|
439
|
+
anchor: absolutePositionToRelativePosition(
|
|
440
|
+
state.selection.anchor,
|
|
441
|
+
pmbinding.type,
|
|
442
|
+
pmbinding.mapping
|
|
443
|
+
),
|
|
444
|
+
head: absolutePositionToRelativePosition(
|
|
445
|
+
state.selection.head,
|
|
446
|
+
pmbinding.type,
|
|
447
|
+
pmbinding.mapping
|
|
448
|
+
)
|
|
449
|
+
}
|
|
450
|
+
};
|
|
388
451
|
|
|
389
452
|
/**
|
|
390
453
|
* Binding for prosemirror.
|
|
@@ -1643,7 +1706,11 @@ const relativePositionToAbsolutePosition = (y, documentType, relPos, mapping) =>
|
|
|
1643
1706
|
if (t instanceof Y__namespace.XmlText) {
|
|
1644
1707
|
pos += t._length;
|
|
1645
1708
|
} else {
|
|
1646
|
-
|
|
1709
|
+
const mapped = mapping.get(t);
|
|
1710
|
+
if (mapped == null) {
|
|
1711
|
+
return null
|
|
1712
|
+
}
|
|
1713
|
+
pos += /** @type {any} */ (mapped).nodeSize;
|
|
1647
1714
|
}
|
|
1648
1715
|
}
|
|
1649
1716
|
n = /** @type {Y.Item} */ (n.right);
|
|
@@ -1667,7 +1734,11 @@ const relativePositionToAbsolutePosition = (y, documentType, relPos, mapping) =>
|
|
|
1667
1734
|
if (contentType instanceof Y__namespace.XmlText) {
|
|
1668
1735
|
pos += contentType._length;
|
|
1669
1736
|
} else {
|
|
1670
|
-
|
|
1737
|
+
const mapped = mapping.get(contentType);
|
|
1738
|
+
if (mapped == null) {
|
|
1739
|
+
return null
|
|
1740
|
+
}
|
|
1741
|
+
pos += /** @type {any} */ (mapped).nodeSize;
|
|
1671
1742
|
}
|
|
1672
1743
|
}
|
|
1673
1744
|
n = n.right;
|