superdoc 2.3.0 → 2.4.0-next.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/README.md +0 -1
- package/dist/chunks/{FindReplaceSurface-DLxnCQOB.cjs → FindReplaceSurface-Dx0llWqP.cjs} +1 -1
- package/dist/chunks/{PasswordPromptSurface-DMbfDvpQ.cjs → PasswordPromptSurface-BUUVC2ee.cjs} +1 -1
- package/dist/chunks/{PdfViewer-CoFiGAhm.cjs → PdfViewer-qpvzwYMz.cjs} +1 -1
- package/dist/chunks/blank-docx-DP8RUPW-.cjs +7 -0
- package/dist/chunks/blank-docx-XRX6Ker2.es.js +2 -0
- package/dist/chunks/{create-super-doc-ui-fxF2Q8Ib.es.js → create-super-doc-ui-D4kk9AjM.es.js} +331 -102
- package/dist/chunks/{create-super-doc-ui-CXCqHc2m.cjs → create-super-doc-ui-DXdWuTzm.cjs} +331 -102
- package/dist/chunks/{eventemitter3-B60Fsz-a.es.js → eventemitter3-Bt2s0X0a.es.js} +1 -1
- package/dist/chunks/{eventemitter3-DCfwFVNn.cjs → eventemitter3-DqY4aSMf.cjs} +1 -1
- package/dist/chunks/{jszip-DzmwAHr3.es.js → jszip-C8srOKAO.es.js} +2 -2
- package/dist/chunks/{jszip-BdUBlUeG.cjs → jszip-Cs9JBLlJ.cjs} +13 -1
- package/dist/chunks/{rolldown-runtime-_dR15c8t.cjs → rolldown-runtime-1Y-nnZJ3.cjs} +0 -28
- package/dist/chunks/{rolldown-runtime-BJVcqBbz.es.js → rolldown-runtime-D7PMmH3s.es.js} +1 -17
- package/dist/collaboration-upgrade-engine.cjs +1 -1
- package/dist/collaboration-upgrade-engine.es.js +1 -1
- package/dist/document-api/src/comments/comment-create-attribution.d.ts +2 -0
- package/dist/document-api/src/comments/comments.d.ts +13 -4
- package/dist/document-api/src/comments/comments.types.d.ts +39 -0
- package/dist/document-api/src/content-controls/content-controls.types.d.ts +2 -0
- package/dist/document-api/src/contract/metadata-types.d.ts +18 -0
- package/dist/document-api/src/contract/operation-definitions.d.ts +1 -1
- package/dist/document-api/src/index.d.ts +2 -2
- package/dist/layout-engine/painters/dom/src/_test-utils.d.ts +3 -2
- package/dist/layout-engine/painters/dom/src/index.d.ts +24 -19
- package/dist/layout-engine/painters/dom/src/page-content.d.ts +107 -39
- package/dist/layout-engine/painters/dom/src/persistent-page-surface.d.ts +144 -0
- package/dist/layout-engine/painters/dom/src/pm-position-validation.d.ts +1 -1
- package/dist/layout-engine/painters/dom/src/renderer.d.ts +50 -106
- package/dist/layout-engine/painters/dom/src/sdt/boundaries.d.ts +1 -1
- package/dist/public/ui-react.cjs +2 -2
- package/dist/public/ui-react.es.js +1 -1
- package/dist/public/ui.cjs +1 -1
- package/dist/public/ui.es.js +1 -1
- package/dist/style.css +97 -90
- package/dist/style.layered.css +97 -90
- package/dist/superdoc/src/core/types/index.d.ts +258 -11
- package/dist/superdoc/src/helpers/floor.d.ts +1 -1
- package/dist/superdoc/src/helpers/v2-review-mutation-impact.d.ts +4 -0
- package/dist/superdoc/src/internal/toolbar/built-in/constants.d.ts +0 -1
- package/dist/superdoc/src/public/index.d.cts +6 -0
- package/dist/superdoc/src/public/index.d.ts +3 -0
- package/dist/superdoc/src/stores/comments-store.d.ts +34 -10
- package/dist/superdoc/src/stores/superdoc-store.d.ts +102 -30
- package/dist/superdoc.cjs +4581 -608
- package/dist/superdoc.es.js +4581 -612
- package/dist-cdn/style.layered.css +1 -1
- package/dist-cdn/superdoc.min.css +1 -1
- package/dist-cdn/superdoc.min.js +37 -37
- package/package.json +5 -4
- package/dist/chunks/blank-docx-CJAXnJKp.es.js +0 -2
- package/dist/chunks/blank-docx-DA-G-3VB.cjs +0 -7
package/dist/chunks/{create-super-doc-ui-fxF2Q8Ib.es.js → create-super-doc-ui-D4kk9AjM.es.js}
RENAMED
|
@@ -90,24 +90,36 @@ function getV2TrackedChangeMutationImpact(event) {
|
|
|
90
90
|
if (!payload || typeof payload !== "object") return null;
|
|
91
91
|
const upsertIds = /* @__PURE__ */ new Set();
|
|
92
92
|
const removedIds = /* @__PURE__ */ new Set();
|
|
93
|
+
const remappedPairs = [];
|
|
93
94
|
const collectEntity = (entry, into) => {
|
|
94
95
|
if (entry?.kind !== "entity" || entry.entityType !== "trackedChange") return;
|
|
95
96
|
if (typeof entry.entityId === "string" && entry.entityId.length > 0) into.add(entry.entityId);
|
|
96
97
|
};
|
|
98
|
+
const readEntityId$1 = (entry) => {
|
|
99
|
+
if (entry?.kind !== "entity" || entry.entityType !== "trackedChange") return null;
|
|
100
|
+
return typeof entry.entityId === "string" && entry.entityId.length > 0 ? entry.entityId : null;
|
|
101
|
+
};
|
|
97
102
|
if (Array.isArray(payload.inserted)) payload.inserted.forEach((entry) => collectEntity(entry, upsertIds));
|
|
98
103
|
if (Array.isArray(payload.updated)) payload.updated.forEach((entry) => collectEntity(entry, upsertIds));
|
|
99
104
|
if (Array.isArray(payload.trackedChangeRefs)) payload.trackedChangeRefs.forEach((entry) => collectEntity(entry, upsertIds));
|
|
100
105
|
if (Array.isArray(payload.removed)) payload.removed.forEach((entry) => collectEntity(entry, removedIds));
|
|
101
106
|
if (Array.isArray(payload.invalidatedRefs)) payload.invalidatedRefs.forEach((entry) => collectEntity(entry, removedIds));
|
|
102
107
|
if (Array.isArray(payload.remappedRefs)) for (const mapping of payload.remappedRefs) {
|
|
103
|
-
|
|
104
|
-
|
|
108
|
+
const fromId = readEntityId$1(mapping?.from);
|
|
109
|
+
const toId = readEntityId$1(mapping?.to);
|
|
110
|
+
if (fromId) removedIds.add(fromId);
|
|
111
|
+
if (toId) upsertIds.add(toId);
|
|
112
|
+
if (fromId && toId && fromId !== toId) remappedPairs.push({
|
|
113
|
+
from: fromId,
|
|
114
|
+
to: toId
|
|
115
|
+
});
|
|
105
116
|
}
|
|
106
117
|
for (const id of removedIds) upsertIds.delete(id);
|
|
107
118
|
if (upsertIds.size === 0 && removedIds.size === 0) return null;
|
|
108
119
|
return {
|
|
109
120
|
upsertIds,
|
|
110
121
|
removedIds,
|
|
122
|
+
remappedPairs,
|
|
111
123
|
reconcileMode: event.origin === "history" ? "authoritative" : "targeted"
|
|
112
124
|
};
|
|
113
125
|
}
|
|
@@ -217,6 +229,7 @@ function createV2ReviewMutationReconciler({ getContext, reconcile, hydrate, onRe
|
|
|
217
229
|
if (!impact) return;
|
|
218
230
|
const reconcileMode = impact.reconcileMode === "authoritative" ? "authoritative" : "targeted";
|
|
219
231
|
const removedIds = normalizeIds(impact.removedIds);
|
|
232
|
+
const upsertIds = normalizeIds(impact.upsertIds);
|
|
220
233
|
for (const id of removedIds) {
|
|
221
234
|
const existing = pendingUpserts.get(id);
|
|
222
235
|
if (existing?.reconcileMode === "authoritative") pendingUpserts.set(id, {
|
|
@@ -228,13 +241,13 @@ function createV2ReviewMutationReconciler({ getContext, reconcile, hydrate, onRe
|
|
|
228
241
|
else pendingUpserts.delete(id);
|
|
229
242
|
}
|
|
230
243
|
const context = getContext();
|
|
231
|
-
if (removedIds.size > 0 && context?.adapter) try {
|
|
244
|
+
if (removedIds.size > 0 && upsertIds.size === 0 && context?.adapter) try {
|
|
232
245
|
Promise.resolve(reconcile(context, {
|
|
233
246
|
upsertIds: /* @__PURE__ */ new Set(),
|
|
234
247
|
removedIds
|
|
235
248
|
})).catch(() => void 0);
|
|
236
249
|
} catch {}
|
|
237
|
-
for (const id of
|
|
250
|
+
for (const id of upsertIds) if (!removedIds.has(id)) {
|
|
238
251
|
const existing = pendingUpserts.get(id);
|
|
239
252
|
pendingUpserts.set(id, {
|
|
240
253
|
version: ++sequence,
|
|
@@ -1577,7 +1590,7 @@ const HEAVY_DOC_READ_POLICY = [
|
|
|
1577
1590
|
{
|
|
1578
1591
|
key: "trackChanges",
|
|
1579
1592
|
match: "exact",
|
|
1580
|
-
note: "audited:
|
|
1593
|
+
note: "audited: all-story tracked-changes list; stale-served during load"
|
|
1581
1594
|
},
|
|
1582
1595
|
{
|
|
1583
1596
|
key: "trackChanges:all",
|
|
@@ -1664,6 +1677,48 @@ function readEntityTarget(row) {
|
|
|
1664
1677
|
const target = row.target;
|
|
1665
1678
|
return target && typeof target === "object" ? target : null;
|
|
1666
1679
|
}
|
|
1680
|
+
function isHostGeometryTarget(target) {
|
|
1681
|
+
if (!target || typeof target !== "object") return false;
|
|
1682
|
+
const record = target;
|
|
1683
|
+
const isTextPoint = (point) => {
|
|
1684
|
+
if (!point || typeof point !== "object") return false;
|
|
1685
|
+
const candidate = point;
|
|
1686
|
+
return candidate.kind === "text" && typeof candidate.blockId === "string" && typeof candidate.offset === "number";
|
|
1687
|
+
};
|
|
1688
|
+
const isTextSegment = (segment) => {
|
|
1689
|
+
if (!segment || typeof segment !== "object") return false;
|
|
1690
|
+
const candidate = segment;
|
|
1691
|
+
const range$1 = candidate.range;
|
|
1692
|
+
return typeof candidate.blockId === "string" && typeof range$1?.start === "number" && typeof range$1.end === "number";
|
|
1693
|
+
};
|
|
1694
|
+
if (Array.isArray(record.segments)) {
|
|
1695
|
+
const first = record.segments[0];
|
|
1696
|
+
const last = record.segments[record.segments.length - 1];
|
|
1697
|
+
return isTextSegment(first) && isTextSegment(last);
|
|
1698
|
+
}
|
|
1699
|
+
if (record.kind === "selection") return isTextPoint(record.start) && isTextPoint(record.end);
|
|
1700
|
+
if (record.kind !== "text" || typeof record.blockId !== "string") return false;
|
|
1701
|
+
const range = record.range;
|
|
1702
|
+
return typeof range?.start === "number" && typeof range.end === "number";
|
|
1703
|
+
}
|
|
1704
|
+
function readTrackedChangeNavigationTarget(row) {
|
|
1705
|
+
if (!row || typeof row !== "object") return null;
|
|
1706
|
+
const target = readEntityTarget(row);
|
|
1707
|
+
if (isHostGeometryTarget(target)) return target;
|
|
1708
|
+
const record = row;
|
|
1709
|
+
const navigationTarget = record.navigationTarget && typeof record.navigationTarget === "object" ? record.navigationTarget : null;
|
|
1710
|
+
if (navigationTarget?.kind === "block" && typeof navigationTarget.blockId === "string" && navigationTarget.blockId.length > 0) return {
|
|
1711
|
+
kind: "text",
|
|
1712
|
+
blockId: navigationTarget.blockId,
|
|
1713
|
+
range: {
|
|
1714
|
+
start: 0,
|
|
1715
|
+
end: 0
|
|
1716
|
+
},
|
|
1717
|
+
...navigationTarget.story && typeof navigationTarget.story === "object" ? { story: navigationTarget.story } : {},
|
|
1718
|
+
...record.address && typeof record.address === "object" ? { address: record.address } : {}
|
|
1719
|
+
};
|
|
1720
|
+
return target;
|
|
1721
|
+
}
|
|
1667
1722
|
function storyLocatorSignature(story) {
|
|
1668
1723
|
if (!story || typeof story !== "object") return "story:body";
|
|
1669
1724
|
const record = story;
|
|
@@ -1870,6 +1925,7 @@ function buildTrackedChangeIdContext(items) {
|
|
|
1870
1925
|
return context;
|
|
1871
1926
|
}
|
|
1872
1927
|
var storyScopedTrackedChangeIdContextCache = /* @__PURE__ */ new WeakMap();
|
|
1928
|
+
var declaredBodyItemsCache = /* @__PURE__ */ new WeakMap();
|
|
1873
1929
|
function buildStoryScopedTrackedChangeIdContext(items, story) {
|
|
1874
1930
|
const signature = storyLocatorSignature(story);
|
|
1875
1931
|
let byStory = storyScopedTrackedChangeIdContextCache.get(items);
|
|
@@ -1883,6 +1939,56 @@ function buildStoryScopedTrackedChangeIdContext(items, story) {
|
|
|
1883
1939
|
byStory.set(signature, context);
|
|
1884
1940
|
return context;
|
|
1885
1941
|
}
|
|
1942
|
+
function isTextboxStory(story) {
|
|
1943
|
+
return !!story && typeof story === "object" && story.storyType === "textbox";
|
|
1944
|
+
}
|
|
1945
|
+
function resolveStorylessCanonicalTrackedChangeId(items, selectionIds) {
|
|
1946
|
+
const storyless = selectionIds.filter((id) => items.some((item) => readEntityId(item) === id && readEntityStory(item) == null));
|
|
1947
|
+
if (storyless.length === 0) return null;
|
|
1948
|
+
if (storyless.length === 1) return storyless[0];
|
|
1949
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1950
|
+
for (const id of storyless) {
|
|
1951
|
+
const row = items.find((item) => readEntityId(item) === id);
|
|
1952
|
+
if (!row) continue;
|
|
1953
|
+
for (const raw of readTrackChangeProvenanceIds(row)) {
|
|
1954
|
+
if (seen.has(raw)) return null;
|
|
1955
|
+
seen.add(raw);
|
|
1956
|
+
}
|
|
1957
|
+
}
|
|
1958
|
+
return storyless[0];
|
|
1959
|
+
}
|
|
1960
|
+
function declaredBodyItems(items) {
|
|
1961
|
+
const cached = declaredBodyItemsCache.get(items);
|
|
1962
|
+
if (cached) return cached;
|
|
1963
|
+
const declared = items.filter((item) => readEntityStory(item) != null);
|
|
1964
|
+
const result = declared.length === items.length ? items : declared;
|
|
1965
|
+
declaredBodyItemsCache.set(items, result);
|
|
1966
|
+
return result;
|
|
1967
|
+
}
|
|
1968
|
+
function resolveSelectionActiveChangeId(options) {
|
|
1969
|
+
const { selectionIds, publicIds, selection, bodyItems, allStoryItems } = options;
|
|
1970
|
+
if (selectionIds.length === 0) return null;
|
|
1971
|
+
const mapIds = (context) => {
|
|
1972
|
+
for (const id of selectionIds) {
|
|
1973
|
+
const publicId = context.toPublicId(id);
|
|
1974
|
+
if (publicId) return publicId;
|
|
1975
|
+
}
|
|
1976
|
+
return null;
|
|
1977
|
+
};
|
|
1978
|
+
const story = selectionStory(selection);
|
|
1979
|
+
const isBodySelection = storyLocatorSignature(story) === storyLocatorSignature(null);
|
|
1980
|
+
if (allStoryItems) {
|
|
1981
|
+
const scopedItems = isBodySelection ? declaredBodyItems(allStoryItems) : allStoryItems;
|
|
1982
|
+
const fromStory = mapIds(buildStoryScopedTrackedChangeIdContext(scopedItems, story));
|
|
1983
|
+
if (fromStory) return fromStory;
|
|
1984
|
+
const fromPublic = publicIds?.find((id) => scopedItems.some((item) => entityRowMatchesRequest(item, id, story)));
|
|
1985
|
+
if (fromPublic) return fromPublic;
|
|
1986
|
+
if (!isBodySelection) return isTextboxStory(story) ? resolveStorylessCanonicalTrackedChangeId(allStoryItems, selectionIds) : null;
|
|
1987
|
+
return mapIds(buildTrackedChangeIdContext(bodyItems));
|
|
1988
|
+
}
|
|
1989
|
+
if (isBodySelection) return mapIds(buildTrackedChangeIdContext(bodyItems)) ?? selectionIds[0] ?? null;
|
|
1990
|
+
return null;
|
|
1991
|
+
}
|
|
1886
1992
|
function resolveActiveCommentId(items, commentId) {
|
|
1887
1993
|
const item = items.find((candidate) => readEntityId(candidate) === commentId || candidate.importedId === commentId);
|
|
1888
1994
|
if (!item) return null;
|
|
@@ -2860,11 +2966,14 @@ function createSuperDocUI(options) {
|
|
|
2860
2966
|
let explicitActiveChange = null;
|
|
2861
2967
|
let explicitActiveChangeRevision = 0;
|
|
2862
2968
|
let queuedTrackChangeNavigationInvalidation = 0;
|
|
2969
|
+
let trackChangeRevealInvalidation = 0;
|
|
2970
|
+
const pendingTrackChangeRevealFocuses = /* @__PURE__ */ new Set();
|
|
2863
2971
|
const explicitActiveChangesEqual = (left, right) => {
|
|
2864
2972
|
if (left === right) return true;
|
|
2865
2973
|
if (!left || !right) return false;
|
|
2866
2974
|
return left.id === right.id && left.paintedEntityId === right.paintedEntityId && storyLocatorSignature(left.story) === storyLocatorSignature(right.story);
|
|
2867
2975
|
};
|
|
2976
|
+
const hasPendingTrackChangeRevealFocus = (focus) => Array.from(pendingTrackChangeRevealFocuses).some((pendingFocus) => explicitActiveChangesEqual(pendingFocus, focus));
|
|
2868
2977
|
const mirrorTrackedChangeFocusToHost = (next) => {
|
|
2869
2978
|
const host = getHost();
|
|
2870
2979
|
if (typeof host?.getHandles !== "function") return;
|
|
@@ -2893,6 +3002,7 @@ function createSuperDocUI(options) {
|
|
|
2893
3002
|
const setExplicitActiveChange = (next, options$1) => {
|
|
2894
3003
|
explicitActiveChange = next;
|
|
2895
3004
|
explicitActiveChangeRevision += 1;
|
|
3005
|
+
trackChangeRevealInvalidation += 1;
|
|
2896
3006
|
if (options$1?.invalidateQueuedNavigation !== false) queuedTrackChangeNavigationInvalidation += 1;
|
|
2897
3007
|
};
|
|
2898
3008
|
const listeners = /* @__PURE__ */ new Set();
|
|
@@ -3298,7 +3408,7 @@ function createSuperDocUI(options) {
|
|
|
3298
3408
|
const read = host?.getDocumentLoadingSnapshot;
|
|
3299
3409
|
if (typeof read !== "function") return "unknown";
|
|
3300
3410
|
const stage = safeCall(() => read.call(host), null)?.sourceStage;
|
|
3301
|
-
if (stage === "opening" || stage === "ready
|
|
3411
|
+
if (stage === "opening" || stage === "bootstrap-ready" || stage === "source-loading") return "loading";
|
|
3302
3412
|
if (stage === "source-complete" || stage === "source-failed" || stage === "source-cancelled") return "complete";
|
|
3303
3413
|
return "unknown";
|
|
3304
3414
|
};
|
|
@@ -3938,8 +4048,8 @@ function createSuperDocUI(options) {
|
|
|
3938
4048
|
status: heldEntry?.hasSettled ? "stale" : "pending"
|
|
3939
4049
|
} : readAsync("trackChanges", token, () => {
|
|
3940
4050
|
if (listTrackedChanges) return listTrackedChanges.call(v2TrackedChanges);
|
|
3941
|
-
return tcApi?.list ? tcApi.list() : void 0;
|
|
3942
|
-
}, (raw) => raw && Array.isArray(raw.items) ? raw.items
|
|
4051
|
+
return tcApi?.list ? tcApi.list({ in: "all" }) : void 0;
|
|
4052
|
+
}, (raw) => raw && Array.isArray(raw.items) ? raw.items : []);
|
|
3943
4053
|
const items = (value ?? []).map(projectTrackChangesItem).filter((item) => item != null).filter((item) => {
|
|
3944
4054
|
const id = readEntityId(item);
|
|
3945
4055
|
return !id || !postDecisionIds?.has(id);
|
|
@@ -3958,8 +4068,20 @@ function createSuperDocUI(options) {
|
|
|
3958
4068
|
if (allStoryItems && !allStoryItems.some((row) => entityRowMatchesRequest(row, active.id, active.story))) setExplicitActiveChange(null);
|
|
3959
4069
|
} else if (!items.some((item) => readEntityId(item) === active.id)) setExplicitActiveChange(null);
|
|
3960
4070
|
}
|
|
4071
|
+
const publicIdItems = allStoryItems ?? items;
|
|
4072
|
+
const selectionIdContext = buildStoryScopedTrackedChangeIdContext(publicIdItems, selectionStory(selection$1));
|
|
3961
4073
|
const selectionActiveChangeIds = postDecisionIds ? selection$1.activeChangeIds.filter((id) => !postDecisionIds.has(id)) : selection$1.activeChangeIds;
|
|
3962
|
-
const
|
|
4074
|
+
const selectionPublicChangeIds = selectionActiveChangeIds.map((id) => selectionIdContext.toPublicId(id) ?? id);
|
|
4075
|
+
const explicitActiveIdContext = explicitActiveChange?.story ? buildStoryScopedTrackedChangeIdContext(publicIdItems, explicitActiveChange.story) : buildTrackedChangeIdContext(publicIdItems);
|
|
4076
|
+
const explicitActiveId = explicitActiveChange ? explicitActiveIdContext.toPublicId(explicitActiveChange.id) ?? explicitActiveChange.id : null;
|
|
4077
|
+
const selectionActiveId = resolveSelectionActiveChangeId({
|
|
4078
|
+
selectionIds: selectionActiveChangeIds,
|
|
4079
|
+
publicIds: selectionPublicChangeIds,
|
|
4080
|
+
selection: selection$1,
|
|
4081
|
+
bodyItems: items,
|
|
4082
|
+
allStoryItems
|
|
4083
|
+
});
|
|
4084
|
+
const activeId = explicitActiveId ?? selectionActiveId;
|
|
3963
4085
|
return {
|
|
3964
4086
|
status: combineStatus(listStatus, selection$1.status),
|
|
3965
4087
|
items,
|
|
@@ -5623,13 +5745,18 @@ function createSuperDocUI(options) {
|
|
|
5623
5745
|
const target = rawTarget && typeof rawTarget === "object" ? rawTarget : null;
|
|
5624
5746
|
let next = null;
|
|
5625
5747
|
if (target?.entityType === "trackedChange" && typeof target.entityId === "string" && target.entityId.length > 0) {
|
|
5626
|
-
const
|
|
5748
|
+
const paintedEntityId = target.entityId;
|
|
5749
|
+
const targetStory = target.story && typeof target.story === "object" ? target.story : void 0;
|
|
5750
|
+
const allStoryItems = readAllStoryTrackChanges();
|
|
5751
|
+
const entityId = (allStoryItems ? targetStory ? buildStoryScopedTrackedChangeIdContext(allStoryItems, targetStory).toPublicId(paintedEntityId) : buildTrackedChangeIdContext(allStoryItems).toPublicId(paintedEntityId) : null) ?? paintedEntityId;
|
|
5752
|
+
const story = targetStory && storyLocatorSignature(targetStory) !== storyLocatorSignature(null) ? targetStory : void 0;
|
|
5627
5753
|
next = {
|
|
5628
|
-
id:
|
|
5754
|
+
id: entityId,
|
|
5629
5755
|
...story ? { story } : {},
|
|
5630
|
-
...typeof target.paintedEntityId === "string" && target.paintedEntityId.length > 0 ? { paintedEntityId: target.paintedEntityId } : {}
|
|
5756
|
+
...typeof target.paintedEntityId === "string" && target.paintedEntityId.length > 0 ? { paintedEntityId: target.paintedEntityId } : entityId !== paintedEntityId ? { paintedEntityId } : {}
|
|
5631
5757
|
};
|
|
5632
5758
|
}
|
|
5759
|
+
if (rawTarget == null && next == null && explicitActiveChange != null && hasPendingTrackChangeRevealFocus(explicitActiveChange)) return false;
|
|
5633
5760
|
if (explicitActiveChangesEqual(explicitActiveChange, next)) return false;
|
|
5634
5761
|
setExplicitActiveChange(next);
|
|
5635
5762
|
return true;
|
|
@@ -5867,6 +5994,17 @@ function createSuperDocUI(options) {
|
|
|
5867
5994
|
function readTrackDecisionTargetId(target) {
|
|
5868
5995
|
return target && typeof target === "object" && typeof target.id === "string" ? String(target.id) : null;
|
|
5869
5996
|
}
|
|
5997
|
+
function nonBodySelectionStoryLocator(selection$1) {
|
|
5998
|
+
const story = selectionStoryLocator(selection$1);
|
|
5999
|
+
return story && storyLocatorSignature(story) !== storyLocatorSignature(null) ? story : void 0;
|
|
6000
|
+
}
|
|
6001
|
+
function trackDecisionIdTarget(changeId, story) {
|
|
6002
|
+
return {
|
|
6003
|
+
kind: "id",
|
|
6004
|
+
id: changeId,
|
|
6005
|
+
...story ? { story } : {}
|
|
6006
|
+
};
|
|
6007
|
+
}
|
|
5870
6008
|
function trackDecisionRangeFromSelection(selection$1) {
|
|
5871
6009
|
if (selection$1.empty) return null;
|
|
5872
6010
|
const explicit = selection$1.selectionTarget;
|
|
@@ -5892,19 +6030,55 @@ function createSuperDocUI(options) {
|
|
|
5892
6030
|
}
|
|
5893
6031
|
};
|
|
5894
6032
|
}
|
|
6033
|
+
function readBodyTrackChangeForDecision(activeId, story) {
|
|
6034
|
+
if (storyLocatorSignature(story) !== storyLocatorSignature(null)) return void 0;
|
|
6035
|
+
const trackChanges$1 = getDoc()?.trackChanges;
|
|
6036
|
+
const list = trackChanges$1?.list;
|
|
6037
|
+
if (typeof list !== "function") return void 0;
|
|
6038
|
+
const raw = safeCall(() => list.call(trackChanges$1), null);
|
|
6039
|
+
if (isPromiseLike(raw) || !raw || typeof raw !== "object") return void 0;
|
|
6040
|
+
const items = raw.items;
|
|
6041
|
+
if (!Array.isArray(items)) return void 0;
|
|
6042
|
+
return items.map(projectTrackChangesItem).find((item) => item != null && entityRowMatchesRequest(item, activeId, story));
|
|
6043
|
+
}
|
|
6044
|
+
function selectedTextCoversTrackChangeText(selection$1, item) {
|
|
6045
|
+
const selected = normalizeTrackDecisionText(selection$1.quotedText);
|
|
6046
|
+
if (!selected) return false;
|
|
6047
|
+
const payload = trackChangesItemPayload(item);
|
|
6048
|
+
return [
|
|
6049
|
+
payload.insertedText,
|
|
6050
|
+
payload.deletedText,
|
|
6051
|
+
payload.excerpt
|
|
6052
|
+
].some((value) => normalizeTrackDecisionText(value) === selected);
|
|
6053
|
+
}
|
|
6054
|
+
function normalizeTrackDecisionText(value) {
|
|
6055
|
+
return typeof value === "string" ? value.replace(/\s+/g, " ").trim() : "";
|
|
6056
|
+
}
|
|
5895
6057
|
function activeChangePartialDecisionRoute() {
|
|
5896
6058
|
const activeId = state.selection.activeChangeIds[0];
|
|
5897
6059
|
if (!activeId) return "unavailable";
|
|
5898
|
-
const items = readAllStoryTrackChanges();
|
|
5899
|
-
if (!items) return "unavailable";
|
|
5900
6060
|
const story = selectionStoryLocator(state.selection);
|
|
5901
|
-
const item = items.find((candidate) => entityRowMatchesRequest(candidate, activeId, story));
|
|
6061
|
+
const item = (state.trackChanges.status === "ready" ? state.trackChanges.items.find((candidate) => entityRowMatchesRequest(candidate, activeId, story)) : void 0) ?? readBodyTrackChangeForDecision(activeId, story) ?? readAllStoryTrackChanges()?.find((candidate) => entityRowMatchesRequest(candidate, activeId, story));
|
|
5902
6062
|
if (!item) return "unavailable";
|
|
5903
|
-
const
|
|
5904
|
-
const
|
|
6063
|
+
const change = trackChangesItemPayload(item);
|
|
6064
|
+
const type = change.type;
|
|
6065
|
+
const grouping = change.grouping;
|
|
6066
|
+
if (selectedTextCoversTrackChangeText(state.selection, item)) return "id";
|
|
5905
6067
|
if (type === "replacement" && grouping === "replacement-pair") return "range";
|
|
5906
6068
|
return (type === "insertion" || type === "deletion" || type === "insert" || type === "delete") && grouping === "standalone" ? "range" : "id";
|
|
5907
6069
|
}
|
|
6070
|
+
function executeTrackDecisionRangeWithIdFallback(kind, rangeTarget, changeId, story) {
|
|
6071
|
+
const fallback = () => callTrackDecisionTarget(kind, trackDecisionIdTarget(changeId, story), changeId, story);
|
|
6072
|
+
try {
|
|
6073
|
+
const result = callTrackDecisionTarget(kind, rangeTarget, null);
|
|
6074
|
+
if (isPromiseLike(result)) return settleCommandExecution(Promise.resolve(result).then((settled) => {
|
|
6075
|
+
return commandResultSucceeded(commandResultFromOperationResult(settled)) ? settled : fallback();
|
|
6076
|
+
}));
|
|
6077
|
+
return settleCommandExecution(commandResultSucceeded(commandResultFromOperationResult(result)) ? result : fallback());
|
|
6078
|
+
} catch {
|
|
6079
|
+
return false;
|
|
6080
|
+
}
|
|
6081
|
+
}
|
|
5908
6082
|
function resolveTrackDecisionTarget(command, payload) {
|
|
5909
6083
|
if (command.scope === "all") return {
|
|
5910
6084
|
target: { scope: "all" },
|
|
@@ -5919,26 +6093,27 @@ function createSuperDocUI(options) {
|
|
|
5919
6093
|
};
|
|
5920
6094
|
if (payload && typeof payload === "object") {
|
|
5921
6095
|
const record = payload;
|
|
5922
|
-
if (record.target && typeof record.target === "object")
|
|
5923
|
-
target
|
|
5924
|
-
|
|
5925
|
-
|
|
6096
|
+
if (record.target && typeof record.target === "object") {
|
|
6097
|
+
const target = record.target;
|
|
6098
|
+
return {
|
|
6099
|
+
target,
|
|
6100
|
+
changeId: readTrackDecisionTargetId(target),
|
|
6101
|
+
story: target.story
|
|
6102
|
+
};
|
|
6103
|
+
}
|
|
5926
6104
|
const id = typeof record.changeId === "string" ? record.changeId : record.id;
|
|
5927
6105
|
if (typeof id === "string" && id.length > 0) return {
|
|
5928
|
-
target:
|
|
5929
|
-
|
|
5930
|
-
|
|
5931
|
-
},
|
|
5932
|
-
changeId: id
|
|
6106
|
+
target: trackDecisionIdTarget(id, record.story),
|
|
6107
|
+
changeId: id,
|
|
6108
|
+
story: record.story
|
|
5933
6109
|
};
|
|
5934
6110
|
}
|
|
5935
6111
|
const selectedId = state.selection.activeChangeIds[0];
|
|
6112
|
+
const story = nonBodySelectionStoryLocator(state.selection);
|
|
5936
6113
|
return selectedId ? {
|
|
5937
|
-
target:
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
},
|
|
5941
|
-
changeId: selectedId
|
|
6114
|
+
target: trackDecisionIdTarget(selectedId, story),
|
|
6115
|
+
changeId: selectedId,
|
|
6116
|
+
story
|
|
5942
6117
|
} : null;
|
|
5943
6118
|
}
|
|
5944
6119
|
function executeTrackDecisionCommand(command, payload) {
|
|
@@ -5952,13 +6127,23 @@ function createSuperDocUI(options) {
|
|
|
5952
6127
|
if (route === "unavailable") return false;
|
|
5953
6128
|
if (route === "range") {
|
|
5954
6129
|
const target = trackDecisionRangeFromSelection(state.selection);
|
|
5955
|
-
|
|
6130
|
+
const story = nonBodySelectionStoryLocator(state.selection);
|
|
6131
|
+
return target ? executeTrackDecisionRangeWithIdFallback(command.kind, target, state.selection.activeChangeIds[0], story) : false;
|
|
6132
|
+
}
|
|
6133
|
+
if (route === "id") {
|
|
6134
|
+
const activeId = state.selection.activeChangeIds[0];
|
|
6135
|
+
const selectedStory = selectionStoryLocator(state.selection);
|
|
6136
|
+
const story = selectedStory && storyLocatorSignature(selectedStory) !== storyLocatorSignature(null) ? selectedStory : void 0;
|
|
6137
|
+
return executeTrackDecision(command.kind, story ? {
|
|
6138
|
+
id: activeId,
|
|
6139
|
+
story
|
|
6140
|
+
} : activeId);
|
|
5956
6141
|
}
|
|
5957
6142
|
}
|
|
5958
6143
|
}
|
|
5959
6144
|
const resolved = resolveTrackDecisionTarget(command, payload);
|
|
5960
6145
|
if (!resolved) return false;
|
|
5961
|
-
return executeTrackDecisionTarget(command.kind, resolved.target, resolved.changeId);
|
|
6146
|
+
return executeTrackDecisionTarget(command.kind, resolved.target, resolved.changeId, resolved.story);
|
|
5962
6147
|
}
|
|
5963
6148
|
function executeListToggleCommand(kind, payload) {
|
|
5964
6149
|
const lists = getEditCommands()?.lists;
|
|
@@ -7478,11 +7663,12 @@ function createSuperDocUI(options) {
|
|
|
7478
7663
|
reason: SUPERDOC_UI_REASONS.hostCapabilityUnavailable
|
|
7479
7664
|
};
|
|
7480
7665
|
try {
|
|
7481
|
-
const
|
|
7666
|
+
const input = {
|
|
7482
7667
|
target,
|
|
7483
7668
|
block: options$1?.block ?? "center",
|
|
7484
7669
|
behavior: options$1?.behavior ?? "smooth"
|
|
7485
|
-
}
|
|
7670
|
+
};
|
|
7671
|
+
const result = await Promise.resolve(options$1?.shouldContinue ? scroll.call(host, input, options$1.shouldContinue) : scroll.call(host, input));
|
|
7486
7672
|
if (result && typeof result === "object" && result.success === false) return {
|
|
7487
7673
|
success: false,
|
|
7488
7674
|
ok: false,
|
|
@@ -7512,19 +7698,32 @@ function createSuperDocUI(options) {
|
|
|
7512
7698
|
story: requestedStory
|
|
7513
7699
|
};
|
|
7514
7700
|
};
|
|
7515
|
-
const
|
|
7516
|
-
|
|
7701
|
+
const readTarget = namespace === "trackChanges" ? readTrackedChangeNavigationTarget : readEntityTarget;
|
|
7702
|
+
const loadedRow = loaded.find((row) => entityRowMatchesRequest(row, id, requestedStory));
|
|
7703
|
+
const loadedRecord = loadedRow && typeof loadedRow === "object" ? loadedRow : null;
|
|
7704
|
+
const moveSide = namespace === "trackChanges" && loadedRecord?.type === "move" && (loadedRecord.subtype === "move-to" || loadedRecord.subtype === "move-from") ? loadedRecord.subtype : null;
|
|
7705
|
+
const trackedChangeLookupId = moveSide && typeof loadedRecord?.trackedChangeCanonicalId === "string" ? loadedRecord.trackedChangeCanonicalId : id;
|
|
7706
|
+
const readResolvedTarget = (row) => {
|
|
7707
|
+
if (!moveSide) return readTarget(row);
|
|
7708
|
+
const moveTarget = readEntityTarget(row);
|
|
7709
|
+
if (moveTarget?.kind !== "move") return null;
|
|
7710
|
+
const sideTarget = moveSide === "move-to" ? moveTarget.destination : moveTarget.source;
|
|
7711
|
+
return isHostGeometryTarget(sideTarget) ? sideTarget : null;
|
|
7712
|
+
};
|
|
7713
|
+
const fromList = readTarget(loadedRow);
|
|
7714
|
+
const listTargetIsAuthoritative = namespace !== "trackChanges" || !moveSide && isHostGeometryTarget(readEntityTarget(loadedRow));
|
|
7715
|
+
if (fromList && listTargetIsAuthoritative) return withRequestedStory(fromList);
|
|
7517
7716
|
const api = getDoc()?.[namespace];
|
|
7518
7717
|
const input = namespace === "comments" ? { commentId: id } : {
|
|
7519
|
-
id,
|
|
7718
|
+
id: trackedChangeLookupId,
|
|
7520
7719
|
...requestedStory ? { story: requestedStory } : {}
|
|
7521
7720
|
};
|
|
7522
7721
|
const get = api?.get;
|
|
7523
|
-
if (typeof get !== "function") return
|
|
7722
|
+
if (typeof get !== "function") return withRequestedStory(fromList);
|
|
7524
7723
|
try {
|
|
7525
|
-
return withRequestedStory(
|
|
7724
|
+
return withRequestedStory(readResolvedTarget(await Promise.resolve(get.call(api, input))) ?? fromList);
|
|
7526
7725
|
} catch {
|
|
7527
|
-
return
|
|
7726
|
+
return withRequestedStory(fromList);
|
|
7528
7727
|
}
|
|
7529
7728
|
};
|
|
7530
7729
|
function patchCommentStatus(commentId, status) {
|
|
@@ -7658,10 +7857,12 @@ function createSuperDocUI(options) {
|
|
|
7658
7857
|
};
|
|
7659
7858
|
const trackChangesSub = sliceHandle((s) => s.trackChanges);
|
|
7660
7859
|
const navigateTrackChange = (step, options$1) => {
|
|
7661
|
-
const
|
|
7662
|
-
if (
|
|
7860
|
+
const allRows = trackChangesSub.get().items.filter((item) => readEntityId(item) !== null);
|
|
7861
|
+
if (allRows.length === 0) return null;
|
|
7663
7862
|
const currentId = state.trackChanges.activeId;
|
|
7664
7863
|
const currentStory = explicitActiveChange?.id === currentId ? explicitActiveChange.story : void 0;
|
|
7864
|
+
const bodyRows = allRows.filter((row) => readEntityRequestStory(row) == null);
|
|
7865
|
+
const rows = currentStory || bodyRows.length === 0 ? allRows : bodyRows;
|
|
7665
7866
|
let currentIdx = currentId ? rows.findIndex((row) => entityRowMatchesRequest(row, currentId, currentStory)) : -1;
|
|
7666
7867
|
if (currentIdx === -1 && currentId && currentStory) currentIdx = rows.findIndex((row) => entityRowMatchesRequest(row, currentId));
|
|
7667
7868
|
const nextRow = rows[currentIdx === -1 ? step > 0 ? 0 : rows.length - 1 : (currentIdx + step + rows.length) % rows.length];
|
|
@@ -7686,33 +7887,41 @@ function createSuperDocUI(options) {
|
|
|
7686
7887
|
if (activeId == null) return { success: false };
|
|
7687
7888
|
const optimisticActiveChange = explicitActiveChange;
|
|
7688
7889
|
const optimisticRevision = explicitActiveChangeRevision;
|
|
7689
|
-
const isCurrent = () => explicitActiveChange === optimisticActiveChange && explicitActiveChangeRevision === optimisticRevision;
|
|
7890
|
+
const isCurrent = () => queuedTrackChangeNavigationInvalidation === requestedAtInvalidation && explicitActiveChange === optimisticActiveChange && explicitActiveChangeRevision === optimisticRevision;
|
|
7690
7891
|
const rollback = () => {
|
|
7691
7892
|
if (!isCurrent()) return;
|
|
7692
7893
|
setExplicitActiveChange(previousActiveChange, { invalidateQueuedNavigation: false });
|
|
7693
7894
|
recompute();
|
|
7694
7895
|
};
|
|
7695
|
-
|
|
7696
|
-
if (!isCurrent()) return { success: false };
|
|
7697
|
-
if (!target) {
|
|
7698
|
-
rollback();
|
|
7699
|
-
return { success: false };
|
|
7700
|
-
}
|
|
7701
|
-
trackedChangeNavigationInFlight += 1;
|
|
7896
|
+
if (optimisticActiveChange) pendingTrackChangeRevealFocuses.add(optimisticActiveChange);
|
|
7702
7897
|
try {
|
|
7703
|
-
const
|
|
7898
|
+
const target = await resolveEntityTarget("trackChanges", activeId, trackChangesSub.get().items, optimisticActiveChange?.story ? { story: optimisticActiveChange.story } : void 0);
|
|
7704
7899
|
if (!isCurrent()) return { success: false };
|
|
7705
|
-
if (!
|
|
7900
|
+
if (!target) {
|
|
7706
7901
|
rollback();
|
|
7707
|
-
|
|
7708
|
-
} else mirrorTrackedChangeFocusToHost(optimisticActiveChange);
|
|
7709
|
-
return { success: result.ok };
|
|
7710
|
-
} finally {
|
|
7711
|
-
trackedChangeNavigationInFlight = Math.max(0, trackedChangeNavigationInFlight - 1);
|
|
7712
|
-
if (trackedChangeNavigationInFlight === 0) {
|
|
7713
|
-
if (!isCurrent()) mirrorTrackedChangeFocusToHost(explicitActiveChange);
|
|
7714
|
-
else if (currentHostReviewSource) syncTrackedChangeFocusFromHostReviewTarget(readHostActiveReviewTarget(currentHostReviewSource));
|
|
7902
|
+
return { success: false };
|
|
7715
7903
|
}
|
|
7904
|
+
trackedChangeNavigationInFlight += 1;
|
|
7905
|
+
try {
|
|
7906
|
+
const result = await scrollTargetIntoView(target, {
|
|
7907
|
+
behavior: "auto",
|
|
7908
|
+
shouldContinue: isCurrent
|
|
7909
|
+
});
|
|
7910
|
+
if (!isCurrent()) return { success: false };
|
|
7911
|
+
if (!result.ok && result.reason !== SUPERDOC_UI_REASONS.targetNotVisible) {
|
|
7912
|
+
rollback();
|
|
7913
|
+
mirrorTrackedChangeFocusToHost(previousActiveChange);
|
|
7914
|
+
} else mirrorTrackedChangeFocusToHost(optimisticActiveChange);
|
|
7915
|
+
return { success: result.ok };
|
|
7916
|
+
} finally {
|
|
7917
|
+
trackedChangeNavigationInFlight = Math.max(0, trackedChangeNavigationInFlight - 1);
|
|
7918
|
+
if (trackedChangeNavigationInFlight === 0) {
|
|
7919
|
+
if (!isCurrent()) mirrorTrackedChangeFocusToHost(explicitActiveChange);
|
|
7920
|
+
else if (currentHostReviewSource) syncTrackedChangeFocusFromHostReviewTarget(readHostActiveReviewTarget(currentHostReviewSource));
|
|
7921
|
+
}
|
|
7922
|
+
}
|
|
7923
|
+
} finally {
|
|
7924
|
+
if (optimisticActiveChange) pendingTrackChangeRevealFocuses.delete(optimisticActiveChange);
|
|
7716
7925
|
}
|
|
7717
7926
|
};
|
|
7718
7927
|
const navigateAndScroll = (step) => {
|
|
@@ -7754,7 +7963,7 @@ function createSuperDocUI(options) {
|
|
|
7754
7963
|
if (!input || typeof input !== "object" || typeof input.x !== "number" || typeof input.y !== "number") return null;
|
|
7755
7964
|
const hits = entityAt(input);
|
|
7756
7965
|
if (hits.length === 0) return null;
|
|
7757
|
-
const
|
|
7966
|
+
const items = trackChangesSub.get().items;
|
|
7758
7967
|
let allStoryItems;
|
|
7759
7968
|
for (const hit of hits) {
|
|
7760
7969
|
if (hit.type !== "trackedChange") continue;
|
|
@@ -7763,7 +7972,7 @@ function createSuperDocUI(options) {
|
|
|
7763
7972
|
if (allStoryItems === void 0) allStoryItems = readAllStoryTrackChanges();
|
|
7764
7973
|
if (!allStoryItems) continue;
|
|
7765
7974
|
candidates = allStoryItems;
|
|
7766
|
-
} else candidates =
|
|
7975
|
+
} else candidates = items;
|
|
7767
7976
|
const item = candidates.find((candidate) => entityRowMatchesRequest(candidate, hit.id, hit.story));
|
|
7768
7977
|
if (item) return hit.story ? {
|
|
7769
7978
|
id: item.id,
|
|
@@ -7797,10 +8006,12 @@ function createSuperDocUI(options) {
|
|
|
7797
8006
|
if (!allStoryItems.some((row) => entityRowMatchesRequest(row, publicId, requested.story))) return false;
|
|
7798
8007
|
requested.id = publicId;
|
|
7799
8008
|
} else {
|
|
7800
|
-
const
|
|
7801
|
-
const publicId = buildTrackedChangeIdContext(
|
|
7802
|
-
|
|
8009
|
+
const items = trackChangesSub.get().items;
|
|
8010
|
+
const publicId = buildTrackedChangeIdContext(items).toPublicId(requested.id) ?? requested.id;
|
|
8011
|
+
const item = items.find((candidate) => readEntityId(candidate) === publicId);
|
|
8012
|
+
if (!item) return false;
|
|
7803
8013
|
requested.id = publicId;
|
|
8014
|
+
requested.story = readEntityRequestStory(item);
|
|
7804
8015
|
}
|
|
7805
8016
|
if (paintedEntityId !== requested.id) requested.paintedEntityId = paintedEntityId;
|
|
7806
8017
|
setExplicitActiveChange(requested);
|
|
@@ -7814,47 +8025,65 @@ function createSuperDocUI(options) {
|
|
|
7814
8025
|
ok: false,
|
|
7815
8026
|
reason: getEditor() ? SUPERDOC_UI_REASONS.documentApiUnavailable : SUPERDOC_UI_REASONS.notReady
|
|
7816
8027
|
};
|
|
8028
|
+
queuedTrackChangeNavigationInvalidation += 1;
|
|
8029
|
+
trackChangeRevealInvalidation += 1;
|
|
8030
|
+
const requestedAtInvalidation = trackChangeRevealInvalidation;
|
|
7817
8031
|
const loadedItems = trackChangesSub.get().items;
|
|
7818
|
-
const
|
|
7819
|
-
const
|
|
7820
|
-
if (!target) return {
|
|
7821
|
-
success: false,
|
|
7822
|
-
ok: false,
|
|
7823
|
-
reason: SUPERDOC_UI_REASONS.targetUnresolved
|
|
7824
|
-
};
|
|
8032
|
+
const publicId = buildTrackedChangeIdContext(loadedItems).toPublicId(changeId) ?? changeId;
|
|
8033
|
+
const story = readEntityRequestStory(loadedItems.find((item) => readEntityId(item) === publicId));
|
|
7825
8034
|
const previousActiveChange = explicitActiveChange;
|
|
7826
|
-
const requestedActiveChange =
|
|
7827
|
-
id:
|
|
7828
|
-
story
|
|
7829
|
-
|
|
7830
|
-
setExplicitActiveChange(requestedActiveChange);
|
|
7831
|
-
recompute();
|
|
7832
|
-
const optimisticActiveChange = explicitActiveChange;
|
|
7833
|
-
const optimisticRevision = explicitActiveChangeRevision;
|
|
7834
|
-
const isCurrent = () => explicitActiveChange === optimisticActiveChange && explicitActiveChangeRevision === optimisticRevision;
|
|
7835
|
-
const rollback = () => {
|
|
7836
|
-
if (!isCurrent()) return;
|
|
7837
|
-
setExplicitActiveChange(previousActiveChange, { invalidateQueuedNavigation: false });
|
|
7838
|
-
recompute();
|
|
8035
|
+
const requestedActiveChange = {
|
|
8036
|
+
id: publicId,
|
|
8037
|
+
...story ? { story } : {},
|
|
8038
|
+
...publicId !== changeId ? { paintedEntityId: changeId } : {}
|
|
7839
8039
|
};
|
|
7840
|
-
|
|
8040
|
+
pendingTrackChangeRevealFocuses.add(requestedActiveChange);
|
|
7841
8041
|
try {
|
|
7842
|
-
const
|
|
7843
|
-
if (
|
|
8042
|
+
const target = await resolveEntityTarget("trackChanges", publicId, loadedItems, story ? { story } : void 0);
|
|
8043
|
+
if (trackChangeRevealInvalidation !== requestedAtInvalidation) return {
|
|
7844
8044
|
success: false,
|
|
7845
8045
|
ok: false
|
|
7846
8046
|
};
|
|
7847
|
-
if (!
|
|
7848
|
-
|
|
7849
|
-
|
|
7850
|
-
|
|
7851
|
-
|
|
7852
|
-
|
|
7853
|
-
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
|
|
8047
|
+
if (!target) return {
|
|
8048
|
+
success: false,
|
|
8049
|
+
ok: false,
|
|
8050
|
+
reason: SUPERDOC_UI_REASONS.targetUnresolved
|
|
8051
|
+
};
|
|
8052
|
+
setExplicitActiveChange(requestedActiveChange);
|
|
8053
|
+
const revealInvalidation = trackChangeRevealInvalidation;
|
|
8054
|
+
const optimisticActiveChange = explicitActiveChange;
|
|
8055
|
+
const optimisticRevision = explicitActiveChangeRevision;
|
|
8056
|
+
const isCurrent = () => trackChangeRevealInvalidation === revealInvalidation && explicitActiveChange === optimisticActiveChange && explicitActiveChangeRevision === optimisticRevision;
|
|
8057
|
+
const rollback = () => {
|
|
8058
|
+
if (!isCurrent()) return;
|
|
8059
|
+
setExplicitActiveChange(previousActiveChange, { invalidateQueuedNavigation: false });
|
|
8060
|
+
recompute();
|
|
8061
|
+
};
|
|
8062
|
+
recompute();
|
|
8063
|
+
trackedChangeNavigationInFlight += 1;
|
|
8064
|
+
try {
|
|
8065
|
+
const result = await scrollTargetIntoView(target, {
|
|
8066
|
+
behavior: "auto",
|
|
8067
|
+
shouldContinue: isCurrent
|
|
8068
|
+
});
|
|
8069
|
+
if (!isCurrent()) return {
|
|
8070
|
+
success: false,
|
|
8071
|
+
ok: false
|
|
8072
|
+
};
|
|
8073
|
+
if (!result.ok && result.reason !== SUPERDOC_UI_REASONS.targetNotVisible) {
|
|
8074
|
+
rollback();
|
|
8075
|
+
mirrorTrackedChangeFocusToHost(previousActiveChange);
|
|
8076
|
+
} else mirrorTrackedChangeFocusToHost(requestedActiveChange);
|
|
8077
|
+
return result;
|
|
8078
|
+
} finally {
|
|
8079
|
+
trackedChangeNavigationInFlight = Math.max(0, trackedChangeNavigationInFlight - 1);
|
|
8080
|
+
if (trackedChangeNavigationInFlight === 0) {
|
|
8081
|
+
if (!isCurrent()) mirrorTrackedChangeFocusToHost(explicitActiveChange);
|
|
8082
|
+
else if (currentHostReviewSource) syncTrackedChangeFocusFromHostReviewTarget(readHostActiveReviewTarget(currentHostReviewSource));
|
|
8083
|
+
}
|
|
7857
8084
|
}
|
|
8085
|
+
} finally {
|
|
8086
|
+
pendingTrackChangeRevealFocuses.delete(requestedActiveChange);
|
|
7858
8087
|
}
|
|
7859
8088
|
}
|
|
7860
8089
|
};
|
|
@@ -8109,8 +8338,8 @@ function createSuperDocUI(options) {
|
|
|
8109
8338
|
const rawHits = collectEntityHitsFromChain(startEls[0], container);
|
|
8110
8339
|
for (let i = 1; i < startEls.length; i += 1) for (const hit of collectEntityHitsFromChain(startEls[i], container)) rawHits.push(hit);
|
|
8111
8340
|
if (rawHits.length === 0) return rawHits;
|
|
8112
|
-
const
|
|
8113
|
-
const
|
|
8341
|
+
const items = trackChangesSub.get().items;
|
|
8342
|
+
const idContext = buildTrackedChangeIdContext(items);
|
|
8114
8343
|
let allStoryItems;
|
|
8115
8344
|
const seen = /* @__PURE__ */ new Set();
|
|
8116
8345
|
const hits = [];
|
|
@@ -8130,7 +8359,7 @@ function createSuperDocUI(options) {
|
|
|
8130
8359
|
publicId = buildStoryScopedTrackedChangeIdContext(allStoryItems, story).toPublicId(hit.id);
|
|
8131
8360
|
if (!publicId || !allStoryItems.some((item) => entityRowMatchesRequest(item, publicId, story))) continue;
|
|
8132
8361
|
} else {
|
|
8133
|
-
publicId =
|
|
8362
|
+
publicId = idContext.toPublicId(hit.id);
|
|
8134
8363
|
if (!publicId) continue;
|
|
8135
8364
|
}
|
|
8136
8365
|
const key = `trackedChange:${publicId}`;
|