superdoc 2.0.0-next.26 → 2.0.0-next.27
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/chunks/{create-super-doc-ui-CBs8xQUw.es.js → create-super-doc-ui-Dvl3EZsv.es.js} +480 -81
- package/dist/chunks/{create-super-doc-ui-CHZKlLiH.cjs → create-super-doc-ui-pYMthdDn.cjs} +480 -81
- package/dist/collaboration-upgrade-engine.cjs +1 -1
- package/dist/collaboration-upgrade-engine.es.js +1 -1
- package/dist/document-api/src/comments/comments.types.d.ts +9 -0
- package/dist/document-api/src/content-controls/content-controls.types.d.ts +13 -1
- package/dist/document-api/src/contract/operation-definitions.d.ts +1 -1
- package/dist/layout-engine/contracts/src/index.d.ts +1 -0
- package/dist/layout-engine/style-engine/src/normalize/types.d.ts +1 -0
- package/dist/public/ui-react.cjs +1 -1
- 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 +37 -37
- package/dist/style.layered.css +37 -37
- package/dist/superdoc/src/components/CommentsLayer/collect-removed-comment-ids.d.ts +1 -0
- package/dist/superdoc/src/components/CommentsLayer/collect-tracked-change-thread.d.ts +1 -1
- package/dist/superdoc/src/components/CommentsLayer/tracked-change-threading.d.ts +2 -0
- package/dist/superdoc/src/helpers/v2-remote-review-hydration.d.ts +12 -0
- package/dist/superdoc.cjs +151 -55
- package/dist/superdoc.es.js +151 -55
- 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 +3 -2
package/dist/chunks/{create-super-doc-ui-CBs8xQUw.es.js → create-super-doc-ui-Dvl3EZsv.es.js}
RENAMED
|
@@ -1393,6 +1393,17 @@ function readEntityId(row) {
|
|
|
1393
1393
|
const id = record.id ?? record.commentId ?? record.changeId;
|
|
1394
1394
|
return typeof id === "string" && id.length > 0 ? id : null;
|
|
1395
1395
|
}
|
|
1396
|
+
function readCollapsedHostTrackChangeId(snapshot) {
|
|
1397
|
+
if (!snapshot || typeof snapshot !== "object") return null;
|
|
1398
|
+
const record = snapshot;
|
|
1399
|
+
const anchor = record.anchor;
|
|
1400
|
+
const focus = record.focus;
|
|
1401
|
+
const anchorVisual = anchor?.visualCaret;
|
|
1402
|
+
const focusVisual = focus?.visualCaret;
|
|
1403
|
+
const anchorId = anchorVisual?.trackChangeId;
|
|
1404
|
+
const focusId = focusVisual?.trackChangeId;
|
|
1405
|
+
return typeof anchorId === "string" && anchorId.length > 0 && anchorId === focusId ? anchorId : null;
|
|
1406
|
+
}
|
|
1396
1407
|
var trackedChangeIdContextCache = /* @__PURE__ */ new WeakMap();
|
|
1397
1408
|
function readTrackChangeProvenanceIds(item) {
|
|
1398
1409
|
const out = [];
|
|
@@ -1543,12 +1554,11 @@ function paragraphTarget(blockId, story) {
|
|
|
1543
1554
|
...story && typeof story === "object" ? { story } : {}
|
|
1544
1555
|
};
|
|
1545
1556
|
}
|
|
1546
|
-
function listsBlockTarget(blockId
|
|
1557
|
+
function listsBlockTarget(blockId) {
|
|
1547
1558
|
return {
|
|
1548
1559
|
kind: "block",
|
|
1549
1560
|
nodeType: "paragraph",
|
|
1550
|
-
nodeId: blockId
|
|
1551
|
-
...story && typeof story === "object" ? { story } : {}
|
|
1561
|
+
nodeId: blockId
|
|
1552
1562
|
};
|
|
1553
1563
|
}
|
|
1554
1564
|
function listItemTarget(blockId, story) {
|
|
@@ -2295,6 +2305,40 @@ function createSuperDocUI(options) {
|
|
|
2295
2305
|
const host = getEditor()?.host;
|
|
2296
2306
|
return host && typeof host === "object" ? host : null;
|
|
2297
2307
|
};
|
|
2308
|
+
const resolveActiveHeaderFooterSlot = (story) => {
|
|
2309
|
+
if (story.storyType !== "headerFooterPart" || typeof story.refId !== "string") return null;
|
|
2310
|
+
const editor = getEditor();
|
|
2311
|
+
const host = getHost();
|
|
2312
|
+
const pageLayout = editor?.pageLayout ?? host?.pageLayout;
|
|
2313
|
+
if (!pageLayout || typeof pageLayout !== "object") return null;
|
|
2314
|
+
const getActiveRulerContext = pageLayout.getActiveRulerContext;
|
|
2315
|
+
const resolveEditTarget = host?.resolveHeaderFooterEditTarget;
|
|
2316
|
+
if (typeof getActiveRulerContext !== "function" || typeof resolveEditTarget !== "function") return null;
|
|
2317
|
+
const active = safeCall(() => getActiveRulerContext.call(pageLayout), null);
|
|
2318
|
+
if (!active || typeof active.pageIndex !== "number") return null;
|
|
2319
|
+
for (const headerFooterKind of ["header", "footer"]) {
|
|
2320
|
+
const resolved = safeCall(() => resolveEditTarget.call(host, {
|
|
2321
|
+
pageIndex: active.pageIndex,
|
|
2322
|
+
kind: headerFooterKind
|
|
2323
|
+
}), null);
|
|
2324
|
+
if (resolved?.status !== "ready" || resolved.refId !== story.refId || typeof resolved.sectionId !== "string" || ![
|
|
2325
|
+
"default",
|
|
2326
|
+
"first",
|
|
2327
|
+
"even"
|
|
2328
|
+
].includes(String(resolved.slotVariant))) continue;
|
|
2329
|
+
return {
|
|
2330
|
+
kind: "story",
|
|
2331
|
+
storyType: "headerFooterSlot",
|
|
2332
|
+
section: {
|
|
2333
|
+
kind: "section",
|
|
2334
|
+
sectionId: resolved.sectionId
|
|
2335
|
+
},
|
|
2336
|
+
headerFooterKind,
|
|
2337
|
+
variant: resolved.slotVariant
|
|
2338
|
+
};
|
|
2339
|
+
}
|
|
2340
|
+
return null;
|
|
2341
|
+
};
|
|
2298
2342
|
const readPendingInlineFormat = () => {
|
|
2299
2343
|
const host = getHost();
|
|
2300
2344
|
const fn = host?.getPendingInlineFormat;
|
|
@@ -2653,7 +2697,7 @@ function createSuperDocUI(options) {
|
|
|
2653
2697
|
recompute();
|
|
2654
2698
|
}
|
|
2655
2699
|
});
|
|
2656
|
-
const selectionReadToken = () => `${contentToken()}|s${selectionEpoch}`;
|
|
2700
|
+
const selectionReadToken = () => `${contentToken()}|m${readDocumentMode()}|s${selectionEpoch}`;
|
|
2657
2701
|
const selectionSignature = (selection$1) => JSON.stringify({
|
|
2658
2702
|
t: selection$1.target ?? null,
|
|
2659
2703
|
s: selection$1.selectionTarget ?? null
|
|
@@ -3094,14 +3138,15 @@ function createSuperDocUI(options) {
|
|
|
3094
3138
|
const end = target?.end;
|
|
3095
3139
|
return start?.kind === "text" && end?.kind === "text" && typeof start.blockId === "string" && start.blockId === end.blockId && typeof start.offset === "number" && start.offset === end.offset;
|
|
3096
3140
|
};
|
|
3097
|
-
const seedCaretSelectionFromHost = () => {
|
|
3141
|
+
const seedCaretSelectionFromHost = (hostSelectionSnapshot) => {
|
|
3098
3142
|
const host = getHost();
|
|
3099
3143
|
const read = host?.readLiveSelectionSyncSnapshot;
|
|
3100
3144
|
if (typeof read !== "function") return;
|
|
3101
3145
|
const seed = normalizeSelectionInfo(safeCall(() => read.call(host), null));
|
|
3102
3146
|
if (!seed || !isCollapsedCaretSnapshot(seed)) return;
|
|
3103
3147
|
const token = selectionReadToken();
|
|
3104
|
-
const
|
|
3148
|
+
const foreground = foregroundMutationState();
|
|
3149
|
+
const deferAuthoritativeRead = Boolean(foreground && (foreground.active > 0 || foreground.pending > 0));
|
|
3105
3150
|
if (!deferAuthoritativeRead) {
|
|
3106
3151
|
pendingSelectionSeedValidationToken = null;
|
|
3107
3152
|
if (issueAsyncRead("selection", token, selectionCurrentRun, normalizeSelectionInfo)) return;
|
|
@@ -3111,11 +3156,22 @@ function createSuperDocUI(options) {
|
|
|
3111
3156
|
}
|
|
3112
3157
|
const prev = asyncReads.get("selection");
|
|
3113
3158
|
const seedMarks = Array.isArray(seed.activeMarks) && seed.activeMarks.length > 0 ? seed.activeMarks : Array.isArray(state.selection.activeMarks) ? state.selection.activeMarks : [];
|
|
3159
|
+
const seedCommentIds = Array.isArray(seed.activeCommentIds) ? seed.activeCommentIds : [];
|
|
3160
|
+
const paintedTrackChangeId = readCollapsedHostTrackChangeId(hostSelectionSnapshot);
|
|
3161
|
+
const previousCaret = collapsedTextAddressFromSelection(state.selection);
|
|
3162
|
+
const nextCaret = collapsedTextAddressFromTarget(seed.selectionTarget) ?? collapsedTextAddressFromTarget(seed.target);
|
|
3163
|
+
const previousRange = previousCaret?.range;
|
|
3164
|
+
const nextRange = nextCaret?.range;
|
|
3165
|
+
const sameActiveTypingCaret = Boolean(foreground && foreground.active > 0 && previousCaret && nextCaret && previousCaret.blockId === nextCaret.blockId && storyLocatorSignature(previousCaret.story) === storyLocatorSignature(nextCaret.story) && typeof previousRange?.start === "number" && typeof nextRange?.start === "number" && Math.abs(nextRange.start - previousRange.start) <= 2);
|
|
3166
|
+
const carriedChangeIds = paintedTrackChangeId != null || sameActiveTypingCaret ? state.selection.activeChangeIds.filter((id) => paintedTrackChangeId == null || buildTrackedChangeIdContext(state.trackChanges.items).aliasesFor(id).includes(paintedTrackChangeId)) : [];
|
|
3167
|
+
const seedChangeIds = Array.isArray(seed.activeChangeIds) && seed.activeChangeIds.length > 0 ? seed.activeChangeIds : carriedChangeIds;
|
|
3114
3168
|
asyncReads.set("selection", {
|
|
3115
3169
|
token,
|
|
3116
3170
|
value: {
|
|
3117
3171
|
...seed,
|
|
3118
|
-
activeMarks: seedMarks
|
|
3172
|
+
activeMarks: seedMarks,
|
|
3173
|
+
activeCommentIds: seedCommentIds,
|
|
3174
|
+
activeChangeIds: seedChangeIds
|
|
3119
3175
|
},
|
|
3120
3176
|
hasSettled: true,
|
|
3121
3177
|
inflightToken: deferAuthoritativeRead ? null : prev?.inflightToken ?? null
|
|
@@ -3706,6 +3762,7 @@ function createSuperDocUI(options) {
|
|
|
3706
3762
|
const active = commandActiveState(descriptor, doc, selection$1);
|
|
3707
3763
|
const value = routedCommandValue(descriptor, doc, selection$1, projectedInlineValues);
|
|
3708
3764
|
if (descriptor.list?.mode === "indent" || descriptor.list?.mode === "outdent") return computeHybridIndentCommandState(descriptor, doc, readonly, selection$1, active, value);
|
|
3765
|
+
if (descriptor.list?.mode === "toggle-seed") return computeListToggleCommandState(descriptor, doc, readonly, selection$1, active, value);
|
|
3709
3766
|
if (descriptor.mutates && readonly) return normalizeCommandState({
|
|
3710
3767
|
enabled: false,
|
|
3711
3768
|
active,
|
|
@@ -3822,47 +3879,81 @@ function createSuperDocUI(options) {
|
|
|
3822
3879
|
}
|
|
3823
3880
|
if (descriptor.id === "link") return readActiveLinkHref(doc, selection$1) ?? void 0;
|
|
3824
3881
|
};
|
|
3825
|
-
const
|
|
3882
|
+
const readListStateSnapshotForBlock = (doc, blockId, story) => {
|
|
3826
3883
|
const listsApi = doc?.lists;
|
|
3827
|
-
if (!listsApi
|
|
3828
|
-
|
|
3829
|
-
|
|
3884
|
+
if (!listsApi) return {
|
|
3885
|
+
value: null,
|
|
3886
|
+
status: "ready"
|
|
3887
|
+
};
|
|
3888
|
+
const isBodyStory = story.storyType === "body";
|
|
3889
|
+
const readState = typeof listsApi.getStateInStory === "function" ? () => listsApi.getStateInStory({
|
|
3890
|
+
target: listsBlockTarget(blockId),
|
|
3891
|
+
story
|
|
3892
|
+
}) : isBodyStory && typeof listsApi.getState === "function" ? () => listsApi.getState({ target: listsBlockTarget(blockId) }) : null;
|
|
3893
|
+
if (!readState) return {
|
|
3894
|
+
value: null,
|
|
3895
|
+
status: "ready"
|
|
3896
|
+
};
|
|
3897
|
+
const { value: result, status } = readAsync(`lists:${storyLocatorSignature(story)}:${blockId}`, contentToken(), readState, (raw) => raw && typeof raw === "object" ? raw : null);
|
|
3898
|
+
return {
|
|
3899
|
+
value: result?.success === true ? result : null,
|
|
3900
|
+
status
|
|
3901
|
+
};
|
|
3830
3902
|
};
|
|
3831
|
-
const
|
|
3832
|
-
|
|
3903
|
+
const readListStateForBlock = (doc, blockId, story) => {
|
|
3904
|
+
return readListStateSnapshotForBlock(doc, blockId, story).value;
|
|
3905
|
+
};
|
|
3906
|
+
const readListSeedForBlock = (doc, blockId, story) => {
|
|
3907
|
+
const result = readListStateForBlock(doc, blockId, story);
|
|
3833
3908
|
if (!result || result.isListItem !== true) return null;
|
|
3834
3909
|
return result.seed === "bullet" || result.seed === "ordered" ? result.seed : null;
|
|
3835
3910
|
};
|
|
3836
|
-
const
|
|
3837
|
-
const
|
|
3838
|
-
|
|
3911
|
+
const readListMembershipSnapshotForBlock = (doc, blockId, story) => {
|
|
3912
|
+
const snapshot = readListStateSnapshotForBlock(doc, blockId, story);
|
|
3913
|
+
const result = snapshot.value;
|
|
3914
|
+
return {
|
|
3915
|
+
value: result && typeof result.isListItem === "boolean" ? result.isListItem : null,
|
|
3916
|
+
status: snapshot.status
|
|
3917
|
+
};
|
|
3839
3918
|
};
|
|
3840
3919
|
const readListSeed = (doc, selection$1) => {
|
|
3841
3920
|
const blockIds = selectionBlockIds(selection$1);
|
|
3842
3921
|
if (blockIds.length === 0 || !canProbeEverySelectedBlock(blockIds)) return null;
|
|
3843
|
-
const
|
|
3922
|
+
const story = selectionStory(selection$1);
|
|
3923
|
+
const firstSeed = readListSeedForBlock(doc, blockIds[0], story);
|
|
3844
3924
|
if (firstSeed !== "bullet" && firstSeed !== "ordered") return null;
|
|
3845
|
-
for (const blockId of blockIds.slice(1)) if (readListSeedForBlock(doc, blockId) !== firstSeed) return null;
|
|
3925
|
+
for (const blockId of blockIds.slice(1)) if (readListSeedForBlock(doc, blockId, story) !== firstSeed) return null;
|
|
3846
3926
|
return firstSeed;
|
|
3847
3927
|
};
|
|
3848
|
-
const readNodeById = (doc, blockId) => {
|
|
3849
|
-
if (!doc
|
|
3928
|
+
const readNodeById = (doc, blockId, story) => {
|
|
3929
|
+
if (!doc) return {
|
|
3850
3930
|
value: null,
|
|
3851
3931
|
status: "ready"
|
|
3852
3932
|
};
|
|
3853
|
-
|
|
3933
|
+
const storySignature = storyLocatorSignature(story);
|
|
3934
|
+
const isBodyStory = storySignature === "story:body";
|
|
3935
|
+
if (isBodyStory && typeof doc.getNodeById !== "function") return {
|
|
3936
|
+
value: null,
|
|
3937
|
+
status: "ready"
|
|
3938
|
+
};
|
|
3939
|
+
if (!isBodyStory && typeof doc.getNode !== "function") return {
|
|
3940
|
+
value: null,
|
|
3941
|
+
status: "ready"
|
|
3942
|
+
};
|
|
3943
|
+
return readAsync(`node:${storySignature}:${blockId}`, contentToken(), () => isBodyStory ? doc.getNodeById({
|
|
3854
3944
|
nodeId: blockId,
|
|
3855
3945
|
nodeType: "paragraph"
|
|
3856
|
-
}), (raw) => raw && typeof raw === "object" ? raw : null);
|
|
3946
|
+
}) : doc.getNode(paragraphTarget(blockId, story)), (raw) => raw && typeof raw === "object" ? raw : null);
|
|
3857
3947
|
};
|
|
3858
3948
|
const resolveListMembershipForBlockAsync = async (doc, blockId, story) => {
|
|
3859
3949
|
const listsApi = doc?.lists;
|
|
3860
3950
|
if (!listsApi) return null;
|
|
3861
3951
|
try {
|
|
3952
|
+
const isBodyStory = story.storyType === "body";
|
|
3862
3953
|
const raw = typeof listsApi.getStateInStory === "function" ? await listsApi.getStateInStory({
|
|
3863
3954
|
target: listsBlockTarget(blockId),
|
|
3864
3955
|
story
|
|
3865
|
-
}) : typeof listsApi.getState === "function" ? await listsApi.getState({ target: listsBlockTarget(blockId) }) : null;
|
|
3956
|
+
}) : isBodyStory && typeof listsApi.getState === "function" ? await listsApi.getState({ target: listsBlockTarget(blockId) }) : null;
|
|
3866
3957
|
const result = raw && typeof raw === "object" ? raw : null;
|
|
3867
3958
|
if (!result || result.success !== true || typeof result.isListItem !== "boolean") return null;
|
|
3868
3959
|
return result.isListItem;
|
|
@@ -3870,13 +3961,42 @@ function createSuperDocUI(options) {
|
|
|
3870
3961
|
return null;
|
|
3871
3962
|
}
|
|
3872
3963
|
};
|
|
3873
|
-
const
|
|
3874
|
-
|
|
3964
|
+
const resolveListSeedForBlock = (doc, blockId, story) => {
|
|
3965
|
+
const unavailable = {
|
|
3966
|
+
resolved: false,
|
|
3967
|
+
seed: null
|
|
3968
|
+
};
|
|
3969
|
+
const listsApi = doc?.lists;
|
|
3970
|
+
if (!listsApi) return unavailable;
|
|
3971
|
+
const isBodyStory = story.storyType === "body";
|
|
3972
|
+
const readState = typeof listsApi.getStateInStory === "function" ? () => listsApi.getStateInStory({
|
|
3973
|
+
target: listsBlockTarget(blockId),
|
|
3974
|
+
story
|
|
3975
|
+
}) : isBodyStory && typeof listsApi.getState === "function" ? () => listsApi.getState({ target: listsBlockTarget(blockId) }) : null;
|
|
3976
|
+
if (!readState) return unavailable;
|
|
3977
|
+
const normalize = (raw) => {
|
|
3978
|
+
const result = raw && typeof raw === "object" ? raw : null;
|
|
3979
|
+
if (!result || result.success !== true || typeof result.isListItem !== "boolean") return unavailable;
|
|
3980
|
+
return {
|
|
3981
|
+
resolved: true,
|
|
3982
|
+
seed: result.isListItem === true && (result.seed === "bullet" || result.seed === "ordered") ? result.seed : null
|
|
3983
|
+
};
|
|
3984
|
+
};
|
|
3985
|
+
try {
|
|
3986
|
+
const raw = readState();
|
|
3987
|
+
return isPromiseLike(raw) ? Promise.resolve(raw).then(normalize, () => unavailable) : normalize(raw);
|
|
3988
|
+
} catch {
|
|
3989
|
+
return unavailable;
|
|
3990
|
+
}
|
|
3991
|
+
};
|
|
3992
|
+
const resolveParagraphIndentationForBlockAsync = async (doc, blockId, story) => {
|
|
3993
|
+
if (!doc) return null;
|
|
3875
3994
|
try {
|
|
3876
|
-
const
|
|
3995
|
+
const isBodyStory = !story || story.storyType === "body";
|
|
3996
|
+
const raw = story && typeof doc.getNode === "function" ? await doc.getNode(paragraphTarget(blockId, story)) : isBodyStory && typeof doc.getNodeById === "function" ? await doc.getNodeById({
|
|
3877
3997
|
nodeId: blockId,
|
|
3878
3998
|
nodeType: "paragraph"
|
|
3879
|
-
});
|
|
3999
|
+
}) : null;
|
|
3880
4000
|
return readParagraphIndentationFromResult(raw && typeof raw === "object" ? raw : null);
|
|
3881
4001
|
} catch {
|
|
3882
4002
|
return null;
|
|
@@ -3901,9 +4021,50 @@ function createSuperDocUI(options) {
|
|
|
3901
4021
|
const listOp = descriptor.docRoute ? resolveDocOperation(doc, descriptor.docRoute) : null;
|
|
3902
4022
|
const paragraphSetIndent = resolveDocOperation(doc, "format.paragraph.setIndentation");
|
|
3903
4023
|
const paragraphClearIndent = resolveDocOperation(doc, "format.paragraph.clearIndentation");
|
|
3904
|
-
const
|
|
3905
|
-
|
|
3906
|
-
|
|
4024
|
+
const mode = descriptor.list?.mode;
|
|
4025
|
+
const paragraphOpAvailable = mode === "indent" ? paragraphSetIndent != null : paragraphSetIndent != null || paragraphClearIndent != null;
|
|
4026
|
+
const story = selectionStory(selection$1);
|
|
4027
|
+
let listMembership = null;
|
|
4028
|
+
if (story.storyType !== "body") {
|
|
4029
|
+
listMembership = [];
|
|
4030
|
+
for (const blockId of blockIds) {
|
|
4031
|
+
const { value: isListItem, status } = readListMembershipSnapshotForBlock(doc, blockId, story);
|
|
4032
|
+
if (isListItem === null) {
|
|
4033
|
+
if (status !== "ready" && (listOp != null || paragraphOpAvailable)) return normalizeCommandState({
|
|
4034
|
+
enabled: true,
|
|
4035
|
+
active,
|
|
4036
|
+
supported: true,
|
|
4037
|
+
value
|
|
4038
|
+
}, "builtin");
|
|
4039
|
+
return normalizeCommandState({
|
|
4040
|
+
enabled: false,
|
|
4041
|
+
active,
|
|
4042
|
+
supported: false,
|
|
4043
|
+
value,
|
|
4044
|
+
reason: unavailableRouteReason(doc)
|
|
4045
|
+
}, "builtin");
|
|
4046
|
+
}
|
|
4047
|
+
listMembership.push(isListItem);
|
|
4048
|
+
}
|
|
4049
|
+
}
|
|
4050
|
+
if (listMembership?.some((isListItem) => isListItem === true)) {
|
|
4051
|
+
const rangeRoute = mode === "indent" ? "lists.indentRange" : "lists.outdentRange";
|
|
4052
|
+
const canUseRange = readDocumentMode() !== "suggesting" && listMembership.every((isListItem) => isListItem === true) && resolveDocOperation(doc, rangeRoute) != null;
|
|
4053
|
+
const canUseStoryOutdent = mode === "outdent" && resolveDocOperation(doc, "lists.outdentInStory") != null;
|
|
4054
|
+
if (!canUseRange && !canUseStoryOutdent) return normalizeCommandState({
|
|
4055
|
+
enabled: false,
|
|
4056
|
+
active,
|
|
4057
|
+
supported: false,
|
|
4058
|
+
value,
|
|
4059
|
+
reason: unavailableRouteReason(doc)
|
|
4060
|
+
}, "builtin");
|
|
4061
|
+
}
|
|
4062
|
+
for (const [index, blockId] of blockIds.entries()) {
|
|
4063
|
+
const membership = listMembership ? {
|
|
4064
|
+
value: listMembership[index] ?? null,
|
|
4065
|
+
status: "ready"
|
|
4066
|
+
} : readListMembershipSnapshotForBlock(doc, blockId, story);
|
|
4067
|
+
const isListItem = membership.value;
|
|
3907
4068
|
if (isListItem === true) {
|
|
3908
4069
|
if (listOp != null) return normalizeCommandState({
|
|
3909
4070
|
enabled: true,
|
|
@@ -3913,18 +4074,30 @@ function createSuperDocUI(options) {
|
|
|
3913
4074
|
}, "builtin");
|
|
3914
4075
|
continue;
|
|
3915
4076
|
}
|
|
3916
|
-
if (isListItem === false && paragraphOpAvailable)
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
4077
|
+
if (isListItem === false && paragraphOpAvailable) {
|
|
4078
|
+
if (story.storyType !== "body" && typeof doc?.getNode !== "function") continue;
|
|
4079
|
+
return normalizeCommandState({
|
|
4080
|
+
enabled: true,
|
|
4081
|
+
active,
|
|
4082
|
+
supported: true,
|
|
4083
|
+
value
|
|
4084
|
+
}, "builtin");
|
|
4085
|
+
}
|
|
4086
|
+
if (isListItem === null) {
|
|
4087
|
+
if (membership.status !== "ready" && (listOp != null || paragraphOpAvailable)) return normalizeCommandState({
|
|
4088
|
+
enabled: true,
|
|
4089
|
+
active,
|
|
4090
|
+
supported: true,
|
|
4091
|
+
value
|
|
4092
|
+
}, "builtin");
|
|
4093
|
+
return normalizeCommandState({
|
|
4094
|
+
enabled: false,
|
|
4095
|
+
active,
|
|
4096
|
+
supported: false,
|
|
4097
|
+
value,
|
|
4098
|
+
reason: unavailableRouteReason(doc)
|
|
4099
|
+
}, "builtin");
|
|
4100
|
+
}
|
|
3928
4101
|
}
|
|
3929
4102
|
return normalizeCommandState({
|
|
3930
4103
|
enabled: false,
|
|
@@ -3934,6 +4107,86 @@ function createSuperDocUI(options) {
|
|
|
3934
4107
|
reason: unavailableRouteReason(doc)
|
|
3935
4108
|
}, "builtin");
|
|
3936
4109
|
};
|
|
4110
|
+
const computeListToggleCommandState = (descriptor, doc, readonly, selection$1, active, value) => {
|
|
4111
|
+
if (descriptor.mutates && readonly) return normalizeCommandState({
|
|
4112
|
+
enabled: false,
|
|
4113
|
+
active,
|
|
4114
|
+
supported: true,
|
|
4115
|
+
value,
|
|
4116
|
+
reason: SUPERDOC_UI_REASONS.documentReadonly
|
|
4117
|
+
}, "builtin");
|
|
4118
|
+
const blockIds = selectionBlockIds(selection$1);
|
|
4119
|
+
if (blockIds.length === 0) return normalizeCommandState({
|
|
4120
|
+
enabled: false,
|
|
4121
|
+
active,
|
|
4122
|
+
supported: true,
|
|
4123
|
+
value,
|
|
4124
|
+
reason: SUPERDOC_UI_REASONS.selectionRequired
|
|
4125
|
+
}, "builtin");
|
|
4126
|
+
const story = selectionStory(selection$1);
|
|
4127
|
+
const listsApi = doc?.lists;
|
|
4128
|
+
if (!(typeof listsApi?.getStateInStory === "function" || story.storyType === "body" && typeof listsApi?.getState === "function")) return normalizeCommandState({
|
|
4129
|
+
enabled: false,
|
|
4130
|
+
active,
|
|
4131
|
+
supported: false,
|
|
4132
|
+
value,
|
|
4133
|
+
reason: SUPERDOC_UI_REASONS.operationUnavailable
|
|
4134
|
+
}, "builtin");
|
|
4135
|
+
if (!canProbeEverySelectedBlock(blockIds)) return normalizeCommandState(story.storyType === "body" && resolveDocOperation(doc, "lists.remove") != null ? {
|
|
4136
|
+
enabled: true,
|
|
4137
|
+
active,
|
|
4138
|
+
supported: true,
|
|
4139
|
+
value
|
|
4140
|
+
} : {
|
|
4141
|
+
enabled: false,
|
|
4142
|
+
active,
|
|
4143
|
+
supported: false,
|
|
4144
|
+
value,
|
|
4145
|
+
reason: SUPERDOC_UI_REASONS.operationUnavailable
|
|
4146
|
+
}, "builtin");
|
|
4147
|
+
const snapshots = blockIds.map((blockId) => readListStateSnapshotForBlock(doc, blockId, story));
|
|
4148
|
+
if (snapshots.some(({ status }) => status !== "ready")) return normalizeCommandState({
|
|
4149
|
+
enabled: true,
|
|
4150
|
+
active,
|
|
4151
|
+
supported: true,
|
|
4152
|
+
value
|
|
4153
|
+
}, "builtin");
|
|
4154
|
+
if (snapshots.some(({ value: state$1 }) => state$1 === null)) return normalizeCommandState({
|
|
4155
|
+
enabled: false,
|
|
4156
|
+
active,
|
|
4157
|
+
supported: false,
|
|
4158
|
+
value,
|
|
4159
|
+
reason: SUPERDOC_UI_REASONS.operationUnavailable
|
|
4160
|
+
}, "builtin");
|
|
4161
|
+
const seed = descriptor.list?.seed;
|
|
4162
|
+
const shouldRemove = snapshots.every(({ value: state$1 }) => state$1?.isListItem === true && state$1.seed === seed);
|
|
4163
|
+
if (story.storyType === "body") return normalizeCommandState(!shouldRemove || resolveDocOperation(doc, "lists.remove") != null ? {
|
|
4164
|
+
enabled: true,
|
|
4165
|
+
active,
|
|
4166
|
+
supported: true,
|
|
4167
|
+
value
|
|
4168
|
+
} : {
|
|
4169
|
+
enabled: false,
|
|
4170
|
+
active,
|
|
4171
|
+
supported: false,
|
|
4172
|
+
value,
|
|
4173
|
+
reason: SUPERDOC_UI_REASONS.operationUnavailable
|
|
4174
|
+
}, "builtin");
|
|
4175
|
+
const removeInStory = resolveDocOperation(doc, "lists.removeInStory");
|
|
4176
|
+
if (shouldRemove && removeInStory) return normalizeCommandState({
|
|
4177
|
+
enabled: true,
|
|
4178
|
+
active,
|
|
4179
|
+
supported: true,
|
|
4180
|
+
value
|
|
4181
|
+
}, "builtin");
|
|
4182
|
+
return normalizeCommandState({
|
|
4183
|
+
enabled: false,
|
|
4184
|
+
active,
|
|
4185
|
+
supported: false,
|
|
4186
|
+
value,
|
|
4187
|
+
reason: SUPERDOC_UI_REASONS.operationUnavailable
|
|
4188
|
+
}, "builtin");
|
|
4189
|
+
};
|
|
3937
4190
|
const readActiveLinkHref = (doc, selection$1) => {
|
|
3938
4191
|
const href = (resolveCurrentHyperlink(doc, selection$1)?.properties)?.href;
|
|
3939
4192
|
return typeof href === "string" ? href : null;
|
|
@@ -4048,8 +4301,8 @@ function createSuperDocUI(options) {
|
|
|
4048
4301
|
status: combineStatus(full.status, quickResult.status)
|
|
4049
4302
|
};
|
|
4050
4303
|
};
|
|
4051
|
-
const readBlockStyleRef = (doc, blockId) => {
|
|
4052
|
-
const { value: result, status } = readNodeById(doc, blockId);
|
|
4304
|
+
const readBlockStyleRef = (doc, blockId, story) => {
|
|
4305
|
+
const { value: result, status } = readNodeById(doc, blockId, story);
|
|
4053
4306
|
if (!result) return {
|
|
4054
4307
|
ok: false,
|
|
4055
4308
|
styleRef: null,
|
|
@@ -4128,8 +4381,9 @@ function createSuperDocUI(options) {
|
|
|
4128
4381
|
let blockReadFailures = 0;
|
|
4129
4382
|
let defaultReadFailures = 0;
|
|
4130
4383
|
let readStatus = "ready";
|
|
4384
|
+
const story = selectionStory(selection$1);
|
|
4131
4385
|
for (const blockId of blockIds) {
|
|
4132
|
-
const read = readBlockStyleRef(doc, blockId);
|
|
4386
|
+
const read = readBlockStyleRef(doc, blockId, story);
|
|
4133
4387
|
readStatus = combineStatus(readStatus, read.status);
|
|
4134
4388
|
if (!read.ok) {
|
|
4135
4389
|
blockReadFailures += 1;
|
|
@@ -4273,9 +4527,9 @@ function createSuperDocUI(options) {
|
|
|
4273
4527
|
currentHostSelectionSource = next;
|
|
4274
4528
|
if (!next) return;
|
|
4275
4529
|
try {
|
|
4276
|
-
const unsubscribe = next.subscribe(() => {
|
|
4530
|
+
const unsubscribe = next.subscribe((snapshot) => {
|
|
4277
4531
|
selectionEpoch += 1;
|
|
4278
|
-
seedCaretSelectionFromHost();
|
|
4532
|
+
seedCaretSelectionFromHost(snapshot);
|
|
4279
4533
|
recompute();
|
|
4280
4534
|
});
|
|
4281
4535
|
if (typeof unsubscribe === "function") detachHostSelection = unsubscribe;
|
|
@@ -4428,6 +4682,39 @@ function createSuperDocUI(options) {
|
|
|
4428
4682
|
function readTrackDecisionTargetId(target) {
|
|
4429
4683
|
return target && typeof target === "object" && typeof target.id === "string" ? String(target.id) : null;
|
|
4430
4684
|
}
|
|
4685
|
+
function trackDecisionRangeFromSelection(selection$1) {
|
|
4686
|
+
if (selection$1.empty) return null;
|
|
4687
|
+
const explicit = selection$1.selectionTarget;
|
|
4688
|
+
const start = explicit?.start;
|
|
4689
|
+
const end = explicit?.end;
|
|
4690
|
+
if (explicit?.kind !== "selection" || start?.kind !== "text" || end?.kind !== "text" || typeof start.blockId !== "string" || start.blockId !== end.blockId || !Number.isInteger(start.offset) || !Number.isInteger(end.offset) || start.offset < 0 || end.offset < 0 || start.offset === end.offset) return null;
|
|
4691
|
+
const rangeStart = Math.min(start.offset, end.offset);
|
|
4692
|
+
const rangeEnd = Math.max(start.offset, end.offset);
|
|
4693
|
+
const story = selectionStoryLocator(selection$1);
|
|
4694
|
+
return {
|
|
4695
|
+
kind: "text",
|
|
4696
|
+
...story ? { story } : {},
|
|
4697
|
+
segments: [{
|
|
4698
|
+
blockId: start.blockId,
|
|
4699
|
+
range: {
|
|
4700
|
+
start: rangeStart,
|
|
4701
|
+
end: rangeEnd
|
|
4702
|
+
}
|
|
4703
|
+
}]
|
|
4704
|
+
};
|
|
4705
|
+
}
|
|
4706
|
+
function activeChangePartialDecisionRoute() {
|
|
4707
|
+
const activeId = state.selection.activeChangeIds[0];
|
|
4708
|
+
if (!activeId) return "unavailable";
|
|
4709
|
+
const items = readAllStoryTrackChanges();
|
|
4710
|
+
if (!items) return "unavailable";
|
|
4711
|
+
const story = selectionStoryLocator(state.selection);
|
|
4712
|
+
const item = items.find((candidate) => entityRowMatchesRequest(candidate, activeId, story));
|
|
4713
|
+
if (!item) return "unavailable";
|
|
4714
|
+
const type = trackChangesItemPayload(item).type;
|
|
4715
|
+
const grouping = trackChangesItemPayload(item).grouping;
|
|
4716
|
+
return (type === "insertion" || type === "deletion" || type === "insert" || type === "delete") && grouping === "standalone" ? "range" : "id";
|
|
4717
|
+
}
|
|
4431
4718
|
function resolveTrackDecisionTarget(command, payload) {
|
|
4432
4719
|
if (command.scope === "all") return {
|
|
4433
4720
|
target: { scope: "all" },
|
|
@@ -4465,6 +4752,20 @@ function createSuperDocUI(options) {
|
|
|
4465
4752
|
} : null;
|
|
4466
4753
|
}
|
|
4467
4754
|
function executeTrackDecisionCommand(command, payload) {
|
|
4755
|
+
if (command.scope === "id" && payload == null) {
|
|
4756
|
+
if (state.selection.activeChangeIds.length > 1) return executeTrackDecisionTargets(command.kind, state.selection.activeChangeIds);
|
|
4757
|
+
if (state.selection.activeChangeIds.length === 1 && !state.selection.empty && state.selection.selectionTarget) {
|
|
4758
|
+
const route = activeChangePartialDecisionRoute();
|
|
4759
|
+
if (route === "unavailable") return false;
|
|
4760
|
+
if (route === "range") {
|
|
4761
|
+
const range = trackDecisionRangeFromSelection(state.selection);
|
|
4762
|
+
return range ? executeTrackDecisionTarget(command.kind, {
|
|
4763
|
+
kind: "range",
|
|
4764
|
+
range
|
|
4765
|
+
}, null) : false;
|
|
4766
|
+
}
|
|
4767
|
+
}
|
|
4768
|
+
}
|
|
4468
4769
|
const resolved = resolveTrackDecisionTarget(command, payload);
|
|
4469
4770
|
if (!resolved) return false;
|
|
4470
4771
|
return executeTrackDecisionTarget(command.kind, resolved.target, resolved.changeId);
|
|
@@ -4653,8 +4954,8 @@ function createSuperDocUI(options) {
|
|
|
4653
4954
|
offsetSpace: "selection"
|
|
4654
4955
|
});
|
|
4655
4956
|
};
|
|
4656
|
-
const buildBlockParagraphInput = (spec, blockId, payload) => {
|
|
4657
|
-
const target = paragraphTarget(blockId);
|
|
4957
|
+
const buildBlockParagraphInput = (spec, blockId, payload, story) => {
|
|
4958
|
+
const target = paragraphTarget(blockId, story);
|
|
4658
4959
|
switch (spec.kind) {
|
|
4659
4960
|
case "alignment": {
|
|
4660
4961
|
const alignment = payload;
|
|
@@ -4755,13 +5056,19 @@ function createSuperDocUI(options) {
|
|
|
4755
5056
|
}
|
|
4756
5057
|
}
|
|
4757
5058
|
const resetOp = resolveDocOperation(doc, "format.paragraph.resetDirectFormatting");
|
|
4758
|
-
const listsRemoveOp = resolveDocOperation(doc, "lists.remove");
|
|
4759
5059
|
const setStyleRefOp = resolveDocOperation(doc, "styles.paragraph.setStyleRef");
|
|
5060
|
+
const story = selectionStoryLocator(state.selection);
|
|
5061
|
+
const isBodyStory = !story || story.storyType === "body";
|
|
5062
|
+
const listsRemoveOp = resolveDocOperation(doc, isBodyStory ? "lists.remove" : "lists.removeInStory");
|
|
4760
5063
|
for (const blockId of selectionBlockIds(state.selection)) {
|
|
4761
|
-
const target = paragraphTarget(blockId);
|
|
5064
|
+
const target = paragraphTarget(blockId, story);
|
|
4762
5065
|
if (resetOp) run(resetOp, { target });
|
|
4763
5066
|
if (listsRemoveOp) try {
|
|
4764
|
-
const
|
|
5067
|
+
const listTarget = listsBlockTarget(blockId);
|
|
5068
|
+
const r = settleOperationResult(listsRemoveOp(isBodyStory ? { target: listTarget } : {
|
|
5069
|
+
target: listTarget,
|
|
5070
|
+
story
|
|
5071
|
+
}));
|
|
4765
5072
|
settledResults.push(r.settled.then((s) => commandResultSucceeded(s) ? s : true));
|
|
4766
5073
|
} catch {}
|
|
4767
5074
|
if (setStyleRefOp) run(setStyleRefOp, {
|
|
@@ -4772,7 +5079,7 @@ function createSuperDocUI(options) {
|
|
|
4772
5079
|
if (!rangeTarget && readDocumentMode() !== "suggesting") {
|
|
4773
5080
|
const setMarkRunPropsOp = resolveDocOperation(doc, "format.paragraph.setMarkRunProps");
|
|
4774
5081
|
if (setMarkRunPropsOp) for (const blockId of selectionBlockIds(state.selection)) run(setMarkRunPropsOp, {
|
|
4775
|
-
target: paragraphTarget(blockId),
|
|
5082
|
+
target: paragraphTarget(blockId, story),
|
|
4776
5083
|
markRunProps: {
|
|
4777
5084
|
bold: false,
|
|
4778
5085
|
italic: false,
|
|
@@ -4790,7 +5097,8 @@ function createSuperDocUI(options) {
|
|
|
4790
5097
|
const executeBlockParagraph = (descriptor, op, payload) => {
|
|
4791
5098
|
const blockIds = selectionBlockIds(state.selection);
|
|
4792
5099
|
if (blockIds.length === 0) return false;
|
|
4793
|
-
|
|
5100
|
+
const story = selectionStoryLocator(state.selection);
|
|
5101
|
+
return applyPerBlock(descriptor.docRoute, op, blockIds, (blockId) => buildBlockParagraphInput(descriptor.blockParagraph, blockId, payload, story));
|
|
4794
5102
|
};
|
|
4795
5103
|
const executeHybridIndentCommand = (descriptor, listOp, blockIds) => {
|
|
4796
5104
|
const doc = getDoc();
|
|
@@ -4798,6 +5106,7 @@ function createSuperDocUI(options) {
|
|
|
4798
5106
|
const paragraphClearIndent = resolveDocOperation(doc, "format.paragraph.clearIndentation");
|
|
4799
5107
|
const mode = descriptor.list?.mode;
|
|
4800
5108
|
const story = selectionStory(state.selection);
|
|
5109
|
+
const targetStory = selectionStoryLocator(state.selection);
|
|
4801
5110
|
const planBlock = async (blockId) => {
|
|
4802
5111
|
const isListItem = await resolveListMembershipForBlockAsync(doc, blockId, story);
|
|
4803
5112
|
if (isListItem === true) return {
|
|
@@ -4807,7 +5116,8 @@ function createSuperDocUI(options) {
|
|
|
4807
5116
|
input: { target: listItemTarget(blockId) }
|
|
4808
5117
|
};
|
|
4809
5118
|
if (isListItem === null) return null;
|
|
4810
|
-
|
|
5119
|
+
if (targetStory && targetStory.storyType !== "body" && typeof doc?.getNode !== "function") return null;
|
|
5120
|
+
const current = await resolveParagraphIndentationForBlockAsync(doc, blockId, targetStory);
|
|
4811
5121
|
const preserved = {};
|
|
4812
5122
|
if (current?.right != null) preserved.right = current.right;
|
|
4813
5123
|
if (current?.firstLine != null) preserved.firstLine = current.firstLine;
|
|
@@ -4819,7 +5129,7 @@ function createSuperDocUI(options) {
|
|
|
4819
5129
|
routeToCall: "format.paragraph.setIndentation",
|
|
4820
5130
|
opToCall: paragraphSetIndent,
|
|
4821
5131
|
input: {
|
|
4822
|
-
target: paragraphTarget(blockId),
|
|
5132
|
+
target: paragraphTarget(blockId, targetStory),
|
|
4823
5133
|
left: Math.max(0, current?.left ?? 0) + PARAGRAPH_INDENT_STEP_TWIPS,
|
|
4824
5134
|
...preserved
|
|
4825
5135
|
}
|
|
@@ -4832,14 +5142,14 @@ function createSuperDocUI(options) {
|
|
|
4832
5142
|
kind: "paragraph",
|
|
4833
5143
|
routeToCall: "format.paragraph.clearIndentation",
|
|
4834
5144
|
opToCall: paragraphClearIndent,
|
|
4835
|
-
input: { target: paragraphTarget(blockId) }
|
|
5145
|
+
input: { target: paragraphTarget(blockId, targetStory) }
|
|
4836
5146
|
};
|
|
4837
5147
|
if (paragraphSetIndent) return {
|
|
4838
5148
|
kind: "paragraph",
|
|
4839
5149
|
routeToCall: "format.paragraph.setIndentation",
|
|
4840
5150
|
opToCall: paragraphSetIndent,
|
|
4841
5151
|
input: {
|
|
4842
|
-
target: paragraphTarget(blockId),
|
|
5152
|
+
target: paragraphTarget(blockId, targetStory),
|
|
4843
5153
|
left: 0
|
|
4844
5154
|
}
|
|
4845
5155
|
};
|
|
@@ -4850,7 +5160,7 @@ function createSuperDocUI(options) {
|
|
|
4850
5160
|
routeToCall: "format.paragraph.setIndentation",
|
|
4851
5161
|
opToCall: paragraphSetIndent,
|
|
4852
5162
|
input: {
|
|
4853
|
-
target: paragraphTarget(blockId),
|
|
5163
|
+
target: paragraphTarget(blockId, targetStory),
|
|
4854
5164
|
...preserved
|
|
4855
5165
|
}
|
|
4856
5166
|
};
|
|
@@ -4870,9 +5180,16 @@ function createSuperDocUI(options) {
|
|
|
4870
5180
|
return false;
|
|
4871
5181
|
}
|
|
4872
5182
|
}
|
|
5183
|
+
const nonBodyListPlans = story.storyType !== "body" && plans.some((plan) => plan?.kind === "list");
|
|
5184
|
+
const outdentInStory = nonBodyListPlans && mode === "outdent" ? resolveDocOperation(doc, "lists.outdentInStory") : null;
|
|
5185
|
+
if (nonBodyListPlans && !outdentInStory) return false;
|
|
4873
5186
|
const settledResults = plans.map((plan) => {
|
|
4874
5187
|
if (!plan) return Promise.resolve(false);
|
|
4875
5188
|
try {
|
|
5189
|
+
if (plan.kind === "list" && outdentInStory) return settleOperationResult(callEditorMutation("lists.outdentInStory", outdentInStory, {
|
|
5190
|
+
target: plan.input.target,
|
|
5191
|
+
story
|
|
5192
|
+
})).settled;
|
|
4876
5193
|
return settleOperationResult(callEditorMutation(plan.routeToCall, plan.opToCall, plan.input)).settled;
|
|
4877
5194
|
} catch {
|
|
4878
5195
|
return Promise.resolve(false);
|
|
@@ -4887,17 +5204,62 @@ function createSuperDocUI(options) {
|
|
|
4887
5204
|
const doc = getDoc();
|
|
4888
5205
|
const blockIds = selectionBlockIds(state.selection);
|
|
4889
5206
|
if (blockIds.length === 0) return false;
|
|
5207
|
+
const story = selectionStory(state.selection);
|
|
5208
|
+
const isBodyStory = story.storyType === "body";
|
|
4890
5209
|
if (spec.mode === "indent" || spec.mode === "outdent") return executeHybridIndentCommand(descriptor, op, blockIds);
|
|
4891
5210
|
const seed = spec.seed;
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
5211
|
+
const executeResolved = (states) => {
|
|
5212
|
+
if (states.some((listState) => !listState.resolved)) return {
|
|
5213
|
+
immediate: false,
|
|
5214
|
+
settled: null
|
|
5215
|
+
};
|
|
5216
|
+
const shouldRemove = states.every((listState) => listState.seed === seed);
|
|
5217
|
+
if (!shouldRemove && !isBodyStory) return {
|
|
5218
|
+
immediate: false,
|
|
5219
|
+
settled: null
|
|
5220
|
+
};
|
|
5221
|
+
const route = shouldRemove ? isBodyStory ? "lists.remove" : "lists.removeInStory" : descriptor.docRoute;
|
|
5222
|
+
const operation = shouldRemove ? resolveDocOperation(doc, route) : op;
|
|
5223
|
+
if (!operation) return {
|
|
5224
|
+
immediate: false,
|
|
5225
|
+
settled: null
|
|
5226
|
+
};
|
|
5227
|
+
const immediateResults = [];
|
|
5228
|
+
const settledResults = [];
|
|
5229
|
+
blockIds.forEach((blockId, index) => {
|
|
5230
|
+
if (!shouldRemove && states[index]?.seed === seed) return;
|
|
5231
|
+
const input = shouldRemove ? {
|
|
5232
|
+
target: listsBlockTarget(blockId),
|
|
5233
|
+
...!isBodyStory ? { story } : {}
|
|
5234
|
+
} : {
|
|
5235
|
+
target: listsBlockTarget(blockId),
|
|
5236
|
+
seed
|
|
5237
|
+
};
|
|
5238
|
+
try {
|
|
5239
|
+
const result$1 = settleOperationResult(callEditorMutation(route, operation, input));
|
|
5240
|
+
immediateResults.push(result$1.immediate);
|
|
5241
|
+
settledResults.push(result$1.settled);
|
|
5242
|
+
} catch {
|
|
5243
|
+
immediateResults.push(false);
|
|
5244
|
+
settledResults.push(Promise.resolve(false));
|
|
5245
|
+
}
|
|
5246
|
+
});
|
|
5247
|
+
return {
|
|
5248
|
+
immediate: combineCommandResults(immediateResults),
|
|
5249
|
+
settled: settledResults.length ? Promise.all(settledResults).then((results) => combineCommandResults(results)) : null
|
|
5250
|
+
};
|
|
5251
|
+
};
|
|
5252
|
+
const stateReads = blockIds.map((blockId) => resolveListSeedForBlock(doc, blockId, story));
|
|
5253
|
+
if (stateReads.some(isPromiseLike)) {
|
|
5254
|
+
pendingCommandSettlement = Promise.all(stateReads).then(async (states) => {
|
|
5255
|
+
const result$1 = executeResolved(states);
|
|
5256
|
+
return result$1.settled ? await result$1.settled : result$1.immediate;
|
|
5257
|
+
});
|
|
5258
|
+
return true;
|
|
4896
5259
|
}
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
});
|
|
5260
|
+
const result = executeResolved(stateReads);
|
|
5261
|
+
pendingCommandSettlement = result.settled;
|
|
5262
|
+
return result.immediate;
|
|
4901
5263
|
};
|
|
4902
5264
|
function readLinkPayloadRecord(payload) {
|
|
4903
5265
|
return payload && typeof payload === "object" ? payload : {};
|
|
@@ -5104,14 +5466,29 @@ function createSuperDocUI(options) {
|
|
|
5104
5466
|
const src = record.src ?? record.value;
|
|
5105
5467
|
if (typeof src !== "string" || src.trim() === "") return false;
|
|
5106
5468
|
const caret = collapsedTextAddressFromSelection(state.selection);
|
|
5469
|
+
const story = selectionStory(state.selection);
|
|
5470
|
+
const nonBodyStory = story.storyType === "body" ? null : story;
|
|
5471
|
+
let at;
|
|
5472
|
+
if (caret && typeof caret.blockId === "string") at = {
|
|
5473
|
+
kind: "inParagraph",
|
|
5474
|
+
target: paragraphTarget(caret.blockId, nonBodyStory),
|
|
5475
|
+
offset: caret.range?.start ?? 0
|
|
5476
|
+
};
|
|
5477
|
+
else {
|
|
5478
|
+
at = createLocationAt(state.selection, "target");
|
|
5479
|
+
if (nonBodyStory && at.kind === "after") at = {
|
|
5480
|
+
...at,
|
|
5481
|
+
target: {
|
|
5482
|
+
...at.target,
|
|
5483
|
+
story: nonBodyStory
|
|
5484
|
+
}
|
|
5485
|
+
};
|
|
5486
|
+
}
|
|
5107
5487
|
const input$1 = {
|
|
5108
5488
|
src,
|
|
5109
|
-
at
|
|
5110
|
-
kind: "inParagraph",
|
|
5111
|
-
target: paragraphTarget(caret.blockId),
|
|
5112
|
-
offset: caret.range?.start ?? 0
|
|
5113
|
-
} : createLocationAt(state.selection, "target")
|
|
5489
|
+
at
|
|
5114
5490
|
};
|
|
5491
|
+
if (nonBodyStory) input$1.in = at.kind === "inParagraph" ? resolveActiveHeaderFooterSlot(nonBodyStory) ?? nonBodyStory : nonBodyStory;
|
|
5115
5492
|
if (typeof record.alt === "string") input$1.alt = record.alt;
|
|
5116
5493
|
if (typeof record.title === "string") input$1.title = record.title;
|
|
5117
5494
|
if (record.size && typeof record.size === "object") input$1.size = record.size;
|
|
@@ -6123,24 +6500,46 @@ function createSuperDocUI(options) {
|
|
|
6123
6500
|
}, id, story);
|
|
6124
6501
|
};
|
|
6125
6502
|
const executeTrackDecisionTarget = (kind, target, changeId, story) => {
|
|
6503
|
+
try {
|
|
6504
|
+
return settleCommandExecution(callTrackDecisionTarget(kind, target, changeId, story));
|
|
6505
|
+
} catch {
|
|
6506
|
+
return false;
|
|
6507
|
+
}
|
|
6508
|
+
};
|
|
6509
|
+
const callTrackDecisionTarget = (kind, target, changeId, story) => {
|
|
6126
6510
|
if (reviewMutationsAreReadOnly()) return false;
|
|
6127
6511
|
const tcApi = getDoc()?.trackChanges;
|
|
6512
|
+
const isAllTarget = target.scope === "all";
|
|
6513
|
+
const isRangeTarget = target.kind === "range";
|
|
6128
6514
|
if (bulkTrackDecisionBlockedReason({
|
|
6129
6515
|
kind,
|
|
6130
|
-
scope:
|
|
6516
|
+
scope: isAllTarget ? "all" : "id"
|
|
6131
6517
|
}, tcApi)) return false;
|
|
6132
|
-
const legacyName =
|
|
6133
|
-
const op = !story && tcApi && typeof tcApi[legacyName] === "function" ? tcApi[legacyName] : null;
|
|
6518
|
+
const legacyName = isAllTarget ? `${kind}All` : kind;
|
|
6519
|
+
const op = !isRangeTarget && !story && tcApi && typeof tcApi[legacyName] === "function" ? tcApi[legacyName] : null;
|
|
6134
6520
|
const decide = tcApi && typeof tcApi.decide === "function" ? tcApi.decide : null;
|
|
6135
6521
|
if (!op && !decide) return false;
|
|
6136
|
-
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
|
|
6140
|
-
|
|
6522
|
+
return op ? op.call(tcApi, changeId ?? {}) : decide.call(tcApi, {
|
|
6523
|
+
decision: kind,
|
|
6524
|
+
target
|
|
6525
|
+
});
|
|
6526
|
+
};
|
|
6527
|
+
const executeTrackDecisionTargets = (kind, changeIds) => {
|
|
6528
|
+
const immediateResults = [];
|
|
6529
|
+
const settledResults = [];
|
|
6530
|
+
for (const changeId of changeIds) try {
|
|
6531
|
+
const result = settleOperationResult(callTrackDecisionTarget(kind, {
|
|
6532
|
+
kind: "id",
|
|
6533
|
+
id: changeId
|
|
6534
|
+
}, changeId));
|
|
6535
|
+
immediateResults.push(result.immediate);
|
|
6536
|
+
settledResults.push(result.settled);
|
|
6141
6537
|
} catch {
|
|
6142
|
-
|
|
6538
|
+
immediateResults.push(false);
|
|
6539
|
+
settledResults.push(Promise.resolve(false));
|
|
6143
6540
|
}
|
|
6541
|
+
pendingCommandSettlement = Promise.all(settledResults).then((results) => combineCommandResults(results));
|
|
6542
|
+
return settleCommandExecution(combineCommandResults(immediateResults));
|
|
6144
6543
|
};
|
|
6145
6544
|
const contentControlsSub = sliceHandle((s) => s.contentControls);
|
|
6146
6545
|
const findContentControl = (id) => {
|