@tiptap/y-tiptap 3.0.0 → 3.0.2

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/y-tiptap.cjs CHANGED
@@ -330,7 +330,7 @@ const restoreRelativeSelection = (tr, relSel, binding) => {
330
330
  relSel.anchor,
331
331
  binding.mapping
332
332
  );
333
- tr.setSelection(prosemirrorState.NodeSelection.create(tr.doc, anchor));
333
+ tr.setSelection(createSafeNodeSelection(tr, anchor));
334
334
  } else {
335
335
  const anchor = relativePositionToAbsolutePosition(
336
336
  binding.doc,
@@ -351,6 +351,23 @@ const restoreRelativeSelection = (tr, relSel, binding) => {
351
351
  }
352
352
  };
353
353
 
354
+ /**
355
+ * @param {import('prosemirror-state').Transaction} tr
356
+ * @param {number} pos
357
+ * @returns {import('prosemirror-state').Selection}
358
+ *
359
+ * Creates a NodeSelection if the position points to a valid node, otherwise
360
+ * creates a TextSelection near the position.
361
+ */
362
+ const createSafeNodeSelection = (tr, pos) => {
363
+ const $pos = tr.doc.resolve(pos);
364
+ if ($pos.nodeAfter) {
365
+ return prosemirrorState.NodeSelection.create(tr.doc, pos)
366
+ } else {
367
+ return prosemirrorState.TextSelection.near($pos)
368
+ }
369
+ };
370
+
354
371
  /**
355
372
  * @param {ProsemirrorBinding} pmbinding
356
373
  * @param {import('prosemirror-state').EditorState} state
@@ -1033,9 +1050,18 @@ const equalYTextPText = (ytext, ptexts) => {
1033
1050
  delta.every(/** @type {(d:any,i:number) => boolean} */ (d, i) =>
1034
1051
  d.insert === /** @type {any} */ (ptexts[i]).text &&
1035
1052
  object__namespace.keys(d.attributes || {}).length === ptexts[i].marks.length &&
1036
- object__namespace.every(d.attributes, (attr, yattrname) => {
1053
+ object__namespace.every(d.attributes, (attr, /** @type {string} */ yattrname) => {
1037
1054
  const markname = yattr2markname(yattrname);
1038
1055
  const pmarks = ptexts[i].marks;
1056
+
1057
+ const pmark = pmarks.find(/** @param {any} mark */ mark => mark.type.name === markname);
1058
+
1059
+ // Ensure the pmark is present in the ptexts before checking equality. When replacing a mark with another mark
1060
+ // the pmark will be missing from the ptexts and the equalAttrs will throw an error.
1061
+ if (!pmark) {
1062
+ return false
1063
+ }
1064
+
1039
1065
  return equalAttrs(attr, pmarks.find(/** @param {any} mark */ mark => mark.type.name === markname)?.attrs)
1040
1066
  })
1041
1067
  )
@@ -1816,7 +1842,11 @@ function yXmlFragmentToProsemirrorJSON (xmlFragment) {
1816
1842
  * @param {any} _user user data
1817
1843
  * @return {boolean}
1818
1844
  */
1819
- const defaultAwarenessStateFilter = (currentClientId, userClientId, _user) => currentClientId !== userClientId;
1845
+ const defaultAwarenessStateFilter = (
1846
+ currentClientId,
1847
+ userClientId,
1848
+ _user
1849
+ ) => currentClientId !== userClientId;
1820
1850
 
1821
1851
  /**
1822
1852
  * Default generator for a cursor element
@@ -1870,10 +1900,14 @@ const createDecorations = (
1870
1900
  createSelection
1871
1901
  ) => {
1872
1902
  const ystate = ySyncPluginKey.getState(state);
1903
+ if (ystate == null || ystate.doc == null || ystate.binding == null) {
1904
+ return prosemirrorView.DecorationSet.create(state.doc, [])
1905
+ }
1873
1906
  const y = ystate.doc;
1874
1907
  const decorations = [];
1875
1908
  if (
1876
- ystate.snapshot != null || ystate.prevSnapshot != null ||
1909
+ ystate.snapshot != null ||
1910
+ ystate.prevSnapshot != null ||
1877
1911
  ystate.binding.mapping.size === 0
1878
1912
  ) {
1879
1913
  // do not render cursors while snapshot is active