superdoc 2.24.0-next.4 → 2.24.0-next.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.
@@ -19,7 +19,7 @@ var COLLABORATION_UPGRADE_ENGINE_MINIMUM_NODE_MAJOR = 20;
19
19
  var PRIVATE_ENGINE_INFO = (0, _superdoc_docx_engine_collaboration_upgrade_engine.getCollaborationUpgradeEngineInfo)();
20
20
  var ENGINE_INFO = Object.freeze({
21
21
  ...PRIVATE_ENGINE_INFO,
22
- superdocVersion: "2.24.0-next.4",
22
+ superdocVersion: "2.24.0-next.5",
23
23
  roomSchemaVersion: Object.freeze({ ...PRIVATE_ENGINE_INFO.roomSchemaVersion }),
24
24
  supportedBundleVersions: SUPPORTED_COLLABORATION_UPGRADE_BUNDLE_VERSIONS,
25
25
  supportedV1ReaderContractVersions: SUPPORTED_V1_READER_CONTRACT_VERSIONS
@@ -18,7 +18,7 @@ var COLLABORATION_UPGRADE_ENGINE_MINIMUM_NODE_MAJOR = 20;
18
18
  var PRIVATE_ENGINE_INFO = getCollaborationUpgradeEngineInfo$1();
19
19
  var ENGINE_INFO = Object.freeze({
20
20
  ...PRIVATE_ENGINE_INFO,
21
- superdocVersion: "2.24.0-next.4",
21
+ superdocVersion: "2.24.0-next.5",
22
22
  roomSchemaVersion: Object.freeze({ ...PRIVATE_ENGINE_INFO.roomSchemaVersion }),
23
23
  supportedBundleVersions: SUPPORTED_COLLABORATION_UPGRADE_BUNDLE_VERSIONS,
24
24
  supportedV1ReaderContractVersions: SUPPORTED_V1_READER_CONTRACT_VERSIONS
package/dist/superdoc.cjs CHANGED
@@ -304,7 +304,7 @@ var awarenessStatesToArray = (context, states) => {
304
304
  var DEFAULT_ENDPOINT = "https://ingest.superdoc.dev/v1/collect";
305
305
  function getSuperdocVersion() {
306
306
  try {
307
- return "2.24.0-next.4";
307
+ return "2.24.0-next.5";
308
308
  } catch {
309
309
  return "unknown";
310
310
  }
@@ -19735,6 +19735,11 @@ function textTargetFromQueryMatch(doc, text, blockId) {
19735
19735
  function isTocEntryLinkElement(element) {
19736
19736
  return Boolean(element && typeof element.closest === "function" && element.closest(".superdoc-toc-entry"));
19737
19737
  }
19738
+ /** @param {Element | null | undefined} element */
19739
+ function isNoteCrossReferenceLinkElement(element) {
19740
+ const kind = element?.getAttribute("data-sd-note-cross-reference");
19741
+ return (kind === "ref" || kind === "noteRef") && Boolean(element?.closest("[data-sd-note-role=\"body\"]"));
19742
+ }
19738
19743
  /**
19739
19744
  * @param {Object} options
19740
19745
  * @param {() => SurfaceManager | null | undefined} options.getSurfaceManager
@@ -19878,9 +19883,9 @@ function useLinkPopover({ getSurfaceManager, getActiveEditor, getUi, getActivati
19878
19883
  * Navigate to a body bookmark through its model address. A mounted-anchor
19879
19884
  * fallback is reserved for runtimes without a callable bookmark model.
19880
19885
  * @param {string | null | undefined} anchorUrl
19881
- * @param {{ placeCaret?: boolean }} [options]
19886
+ * @param {{ placeCaret?: boolean, revalidateCaretAfterReveal?: boolean }} [options]
19882
19887
  */
19883
- async function navigateToAnchor(anchorUrl, { placeCaret = false } = {}) {
19888
+ async function navigateToAnchor(anchorUrl, { placeCaret = false, revalidateCaretAfterReveal = false } = {}) {
19884
19889
  if (typeof anchorUrl !== "string" || !anchorUrl.startsWith("#")) return false;
19885
19890
  const anchorName = decodeAnchorFragment(anchorUrl.slice(1));
19886
19891
  const editor = getActiveEditor();
@@ -19897,48 +19902,65 @@ function useLinkPopover({ getSurfaceManager, getActiveEditor, getUi, getActivati
19897
19902
  });
19898
19903
  return true;
19899
19904
  }
19900
- /** @type {BookmarkGetResult | null} */
19901
- let bookmark = null;
19902
- try {
19903
- const list = doc?.bookmarks?.list;
19904
- if (typeof list === "function") {
19905
- if ((await Promise.resolve(list.call(doc.bookmarks)))?.items?.filter((item) => item.name === anchorName).length !== 1) return false;
19905
+ async function readBodyBookmark() {
19906
+ try {
19907
+ const list = doc?.bookmarks?.list;
19908
+ if (typeof list === "function") {
19909
+ if ((await Promise.resolve(list.call(doc.bookmarks)))?.items?.filter((item) => item.name === anchorName).length !== 1) return null;
19910
+ }
19911
+ const bookmark = await Promise.resolve(bookmarkGet.call(doc.bookmarks, { target: {
19912
+ kind: "entity",
19913
+ entityType: "bookmark",
19914
+ name: anchorName
19915
+ } }));
19916
+ if (editor !== getActiveEditor() || generation !== openGeneration) return null;
19917
+ const story = bookmark?.address?.story;
19918
+ if (story && story.storyType !== "body" || bookmark?.tableColumn) return null;
19919
+ const blockId = bookmark?.range?.from?.blockId;
19920
+ const offset = bookmark?.range?.from?.offset ?? 0;
19921
+ if (typeof blockId !== "string" || !Number.isInteger(offset) || offset < 0) return null;
19922
+ return {
19923
+ blockId,
19924
+ offset
19925
+ };
19926
+ } catch {
19927
+ return null;
19906
19928
  }
19907
- bookmark = await Promise.resolve(bookmarkGet.call(doc.bookmarks, { target: {
19908
- kind: "entity",
19909
- entityType: "bookmark",
19910
- name: anchorName
19911
- } }));
19912
- bookmark ??= null;
19913
- } catch {
19914
- return false;
19915
19929
  }
19916
- if (editor !== getActiveEditor() || generation !== openGeneration) return false;
19917
- const story = bookmark?.address?.story;
19918
- if (story && story.storyType !== "body" || bookmark?.tableColumn) return false;
19919
- const blockId = bookmark?.range?.from?.blockId;
19920
- const offset = bookmark?.range?.from?.offset ?? 0;
19921
- if (typeof blockId !== "string" || !Number.isInteger(offset) || offset < 0) return false;
19922
- if (placeCaret) await placeCaretAtBookmark(blockId, offset);
19930
+ let position = await readBodyBookmark();
19931
+ if (!position) return false;
19932
+ if (placeCaret && !revalidateCaretAfterReveal) await placeCaretAtBookmark(position.blockId, position.offset);
19923
19933
  const viewport = getUi()?.viewport;
19924
19934
  const scrollIntoView = viewport?.scrollIntoView;
19925
19935
  if (typeof scrollIntoView !== "function") return false;
19926
- const target = {
19927
- kind: "text",
19928
- blockId,
19929
- range: {
19930
- start: offset,
19931
- end: offset
19932
- }
19933
- };
19934
19936
  for (let step = 0; step < MAX_ANCHOR_NAVIGATION_STEPS; step += 1) try {
19937
+ const target = {
19938
+ kind: "text",
19939
+ blockId: position.blockId,
19940
+ range: {
19941
+ start: position.offset,
19942
+ end: position.offset
19943
+ }
19944
+ };
19935
19945
  const result = await Promise.resolve(scrollIntoView.call(viewport, {
19936
19946
  target,
19937
19947
  block: "start",
19938
19948
  behavior: "instant"
19939
19949
  }));
19940
19950
  if (editor !== getActiveEditor() || generation !== openGeneration) return false;
19941
- if (result?.success !== false) return true;
19951
+ if (result?.success !== false) {
19952
+ if (revalidateCaretAfterReveal) {
19953
+ const current = await readBodyBookmark();
19954
+ if (!current) return false;
19955
+ if (current.blockId !== position.blockId || current.offset !== position.offset) {
19956
+ position = current;
19957
+ continue;
19958
+ }
19959
+ if (placeCaret) await placeCaretAtBookmark(current.blockId, current.offset);
19960
+ if (editor !== getActiveEditor() || generation !== openGeneration) return false;
19961
+ }
19962
+ return true;
19963
+ }
19942
19964
  } catch {
19943
19965
  return false;
19944
19966
  }
@@ -20064,8 +20086,13 @@ function useLinkPopover({ getSurfaceManager, getActiveEditor, getUi, getActivati
20064
20086
  return;
20065
20087
  }
20066
20088
  if (ctx.defaultAction === "navigate") {
20067
- if (ctx.isAnchorLink) navigateToAnchor(ctx.href);
20068
- else if (ctx.href) {
20089
+ if (ctx.isAnchorLink) {
20090
+ const noteReference = isNoteCrossReferenceLinkElement(ctx.element);
20091
+ navigateToAnchor(ctx.href, {
20092
+ placeCaret: noteReference && ctx.documentMode !== "viewing",
20093
+ revalidateCaretAfterReveal: noteReference && ctx.documentMode !== "viewing"
20094
+ });
20095
+ } else if (ctx.href) {
20069
20096
  const target = ctx.target || "_self";
20070
20097
  const features = linkOpenFeaturesForTarget(ctx.rel, target);
20071
20098
  if (features) window.open(ctx.href, target, features);
@@ -46564,7 +46591,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
46564
46591
  }
46565
46592
  this.userColorMap = /* @__PURE__ */ new Map();
46566
46593
  this.colorIndex = 0;
46567
- this.version = "2.24.0-next.4";
46594
+ this.version = "2.24.0-next.5";
46568
46595
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
46569
46596
  this.superdocId = config.superdocId || require_uuid.v4();
46570
46597
  this.colors = this.config.colors ?? [];
@@ -302,7 +302,7 @@ var awarenessStatesToArray = (context, states) => {
302
302
  var DEFAULT_ENDPOINT = "https://ingest.superdoc.dev/v1/collect";
303
303
  function getSuperdocVersion() {
304
304
  try {
305
- return "2.24.0-next.4";
305
+ return "2.24.0-next.5";
306
306
  } catch {
307
307
  return "unknown";
308
308
  }
@@ -19702,6 +19702,11 @@ function textTargetFromQueryMatch(doc, text, blockId) {
19702
19702
  function isTocEntryLinkElement(element) {
19703
19703
  return Boolean(element && typeof element.closest === "function" && element.closest(".superdoc-toc-entry"));
19704
19704
  }
19705
+ /** @param {Element | null | undefined} element */
19706
+ function isNoteCrossReferenceLinkElement(element) {
19707
+ const kind = element?.getAttribute("data-sd-note-cross-reference");
19708
+ return (kind === "ref" || kind === "noteRef") && Boolean(element?.closest("[data-sd-note-role=\"body\"]"));
19709
+ }
19705
19710
  /**
19706
19711
  * @param {Object} options
19707
19712
  * @param {() => SurfaceManager | null | undefined} options.getSurfaceManager
@@ -19845,9 +19850,9 @@ function useLinkPopover({ getSurfaceManager, getActiveEditor, getUi, getActivati
19845
19850
  * Navigate to a body bookmark through its model address. A mounted-anchor
19846
19851
  * fallback is reserved for runtimes without a callable bookmark model.
19847
19852
  * @param {string | null | undefined} anchorUrl
19848
- * @param {{ placeCaret?: boolean }} [options]
19853
+ * @param {{ placeCaret?: boolean, revalidateCaretAfterReveal?: boolean }} [options]
19849
19854
  */
19850
- async function navigateToAnchor(anchorUrl, { placeCaret = false } = {}) {
19855
+ async function navigateToAnchor(anchorUrl, { placeCaret = false, revalidateCaretAfterReveal = false } = {}) {
19851
19856
  if (typeof anchorUrl !== "string" || !anchorUrl.startsWith("#")) return false;
19852
19857
  const anchorName = decodeAnchorFragment(anchorUrl.slice(1));
19853
19858
  const editor = getActiveEditor();
@@ -19864,48 +19869,65 @@ function useLinkPopover({ getSurfaceManager, getActiveEditor, getUi, getActivati
19864
19869
  });
19865
19870
  return true;
19866
19871
  }
19867
- /** @type {BookmarkGetResult | null} */
19868
- let bookmark = null;
19869
- try {
19870
- const list = doc?.bookmarks?.list;
19871
- if (typeof list === "function") {
19872
- if ((await Promise.resolve(list.call(doc.bookmarks)))?.items?.filter((item) => item.name === anchorName).length !== 1) return false;
19872
+ async function readBodyBookmark() {
19873
+ try {
19874
+ const list = doc?.bookmarks?.list;
19875
+ if (typeof list === "function") {
19876
+ if ((await Promise.resolve(list.call(doc.bookmarks)))?.items?.filter((item) => item.name === anchorName).length !== 1) return null;
19877
+ }
19878
+ const bookmark = await Promise.resolve(bookmarkGet.call(doc.bookmarks, { target: {
19879
+ kind: "entity",
19880
+ entityType: "bookmark",
19881
+ name: anchorName
19882
+ } }));
19883
+ if (editor !== getActiveEditor() || generation !== openGeneration) return null;
19884
+ const story = bookmark?.address?.story;
19885
+ if (story && story.storyType !== "body" || bookmark?.tableColumn) return null;
19886
+ const blockId = bookmark?.range?.from?.blockId;
19887
+ const offset = bookmark?.range?.from?.offset ?? 0;
19888
+ if (typeof blockId !== "string" || !Number.isInteger(offset) || offset < 0) return null;
19889
+ return {
19890
+ blockId,
19891
+ offset
19892
+ };
19893
+ } catch {
19894
+ return null;
19873
19895
  }
19874
- bookmark = await Promise.resolve(bookmarkGet.call(doc.bookmarks, { target: {
19875
- kind: "entity",
19876
- entityType: "bookmark",
19877
- name: anchorName
19878
- } }));
19879
- bookmark ??= null;
19880
- } catch {
19881
- return false;
19882
19896
  }
19883
- if (editor !== getActiveEditor() || generation !== openGeneration) return false;
19884
- const story = bookmark?.address?.story;
19885
- if (story && story.storyType !== "body" || bookmark?.tableColumn) return false;
19886
- const blockId = bookmark?.range?.from?.blockId;
19887
- const offset = bookmark?.range?.from?.offset ?? 0;
19888
- if (typeof blockId !== "string" || !Number.isInteger(offset) || offset < 0) return false;
19889
- if (placeCaret) await placeCaretAtBookmark(blockId, offset);
19897
+ let position = await readBodyBookmark();
19898
+ if (!position) return false;
19899
+ if (placeCaret && !revalidateCaretAfterReveal) await placeCaretAtBookmark(position.blockId, position.offset);
19890
19900
  const viewport = getUi()?.viewport;
19891
19901
  const scrollIntoView = viewport?.scrollIntoView;
19892
19902
  if (typeof scrollIntoView !== "function") return false;
19893
- const target = {
19894
- kind: "text",
19895
- blockId,
19896
- range: {
19897
- start: offset,
19898
- end: offset
19899
- }
19900
- };
19901
19903
  for (let step = 0; step < MAX_ANCHOR_NAVIGATION_STEPS; step += 1) try {
19904
+ const target = {
19905
+ kind: "text",
19906
+ blockId: position.blockId,
19907
+ range: {
19908
+ start: position.offset,
19909
+ end: position.offset
19910
+ }
19911
+ };
19902
19912
  const result = await Promise.resolve(scrollIntoView.call(viewport, {
19903
19913
  target,
19904
19914
  block: "start",
19905
19915
  behavior: "instant"
19906
19916
  }));
19907
19917
  if (editor !== getActiveEditor() || generation !== openGeneration) return false;
19908
- if (result?.success !== false) return true;
19918
+ if (result?.success !== false) {
19919
+ if (revalidateCaretAfterReveal) {
19920
+ const current = await readBodyBookmark();
19921
+ if (!current) return false;
19922
+ if (current.blockId !== position.blockId || current.offset !== position.offset) {
19923
+ position = current;
19924
+ continue;
19925
+ }
19926
+ if (placeCaret) await placeCaretAtBookmark(current.blockId, current.offset);
19927
+ if (editor !== getActiveEditor() || generation !== openGeneration) return false;
19928
+ }
19929
+ return true;
19930
+ }
19909
19931
  } catch {
19910
19932
  return false;
19911
19933
  }
@@ -20031,8 +20053,13 @@ function useLinkPopover({ getSurfaceManager, getActiveEditor, getUi, getActivati
20031
20053
  return;
20032
20054
  }
20033
20055
  if (ctx.defaultAction === "navigate") {
20034
- if (ctx.isAnchorLink) navigateToAnchor(ctx.href);
20035
- else if (ctx.href) {
20056
+ if (ctx.isAnchorLink) {
20057
+ const noteReference = isNoteCrossReferenceLinkElement(ctx.element);
20058
+ navigateToAnchor(ctx.href, {
20059
+ placeCaret: noteReference && ctx.documentMode !== "viewing",
20060
+ revalidateCaretAfterReveal: noteReference && ctx.documentMode !== "viewing"
20061
+ });
20062
+ } else if (ctx.href) {
20036
20063
  const target = ctx.target || "_self";
20037
20064
  const features = linkOpenFeaturesForTarget(ctx.rel, target);
20038
20065
  if (features) window.open(ctx.href, target, features);
@@ -46493,7 +46520,7 @@ var SuperDoc = class extends import_eventemitter3.default {
46493
46520
  }
46494
46521
  this.userColorMap = /* @__PURE__ */ new Map();
46495
46522
  this.colorIndex = 0;
46496
- this.version = "2.24.0-next.4";
46523
+ this.version = "2.24.0-next.5";
46497
46524
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
46498
46525
  this.superdocId = config.superdocId || v4();
46499
46526
  this.colors = this.config.colors ?? [];