superdoc 2.28.0-next.1 → 2.28.0-next.11
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-D1eOhAjv.cjs → create-super-doc-ui-8dttPeGi.cjs} +431 -85
- package/dist/chunks/{create-super-doc-ui-B29zw5qD.es.js → create-super-doc-ui-B6Va_J_0.es.js} +426 -86
- package/dist/collaboration-upgrade-engine.cjs +1 -1
- package/dist/collaboration-upgrade-engine.es.js +1 -1
- package/dist/document-api/src/content-controls/content-controls.types.d.ts +11 -0
- package/dist/document-api/src/contract/command-catalog.d.ts +1 -1
- package/dist/document-api/src/contract/operation-definitions.d.ts +44 -44
- package/dist/document-api/src/contract/operation-registry.d.ts +4 -0
- package/dist/document-api/src/export/export.d.ts +3 -1
- package/dist/document-api/src/export/export.types.d.ts +8 -0
- package/dist/document-api/src/get-node/get-node.d.ts +10 -4
- package/dist/document-api/src/hyperlinks/hyperlinks.types.d.ts +2 -0
- package/dist/document-api/src/index.d.ts +2 -1
- package/dist/document-api/src/replace/replace.d.ts +4 -1
- package/dist/document-api/src/types/mutation-plan.types.d.ts +2 -0
- package/dist/document-api/src/types/track-changes.types.d.ts +10 -2
- package/dist/layout-engine/contracts/src/index.d.ts +2 -0
- package/dist/layout-engine/contracts/src/resolved-layout.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-vue.cjs +1 -1
- package/dist/public/ui-vue.es.js +1 -1
- package/dist/public/ui.cjs +1 -1
- package/dist/public/ui.es.js +1 -1
- package/dist/shared/common/list-marker-utils.d.ts +3 -0
- package/dist/style.css +1 -1
- package/dist/style.layered.css +1 -1
- package/dist/superdoc/src/core/SuperDoc.d.ts +2 -6
- package/dist/superdoc/src/core/collaboration/resolve-v2-collaboration-target.d.ts +2 -0
- package/dist/superdoc/src/core/config/normalize-ui-config.d.ts +1 -0
- package/dist/superdoc/src/core/editor-runtime/types.d.ts +1 -0
- package/dist/superdoc/src/core/editor-runtime/v2/v2-editor-runtime-adapter.d.ts +2 -2
- package/dist/superdoc/src/core/extensions/types.d.ts +14 -3
- package/dist/superdoc/src/core/helpers/resolve-docx-export.d.ts +6 -0
- package/dist/superdoc/src/core/types/index.d.ts +35 -1
- package/dist/superdoc/src/core/v2-integration/v2-integration.d.ts +0 -8
- package/dist/superdoc/src/internal/toolbar/built-in/color-dropdown-helpers.d.ts +0 -1
- package/dist/superdoc/src/internal/toolbar/built-in/constants.d.ts +0 -2
- package/dist/superdoc/src/public/export-types.d.ts +3 -0
- package/dist/superdoc/src/public/ui/entity-at.d.ts +1 -0
- package/dist/superdoc/src/public/ui/format-painter-helpers.d.ts +0 -13
- package/dist/superdoc/src/public/ui/types.d.ts +16 -2
- package/dist/superdoc/src/public/ui.d.cts +14 -0
- package/dist/superdoc/src/public/ui.d.ts +1 -1
- package/dist/superdoc/src/stores/comments-store.d.ts +3 -57
- package/dist/superdoc/src/stores/superdoc-store.d.ts +9 -171
- package/dist/superdoc.cjs +363 -159
- package/dist/superdoc.es.js +363 -159
- package/dist/word-layout/src/types.d.ts +1 -0
- package/dist-cdn/style.layered.css +1 -1
- package/dist-cdn/superdoc.min.css +1 -1
- package/dist-cdn/superdoc.min.js +42 -42
- package/package.json +2 -2
- package/dist/footnote-table-order.docx +0 -0
- package/dist/images/altText_add.svg +0 -3
- package/dist/images/altText_disclaimer.svg +0 -3
- package/dist/images/altText_done.svg +0 -3
- package/dist/images/altText_spinner.svg +0 -30
- package/dist/images/altText_warning.svg +0 -3
- package/dist/images/annotation-check.svg +0 -11
- package/dist/images/annotation-comment.svg +0 -16
- package/dist/images/annotation-help.svg +0 -26
- package/dist/images/annotation-insert.svg +0 -10
- package/dist/images/annotation-key.svg +0 -11
- package/dist/images/annotation-newparagraph.svg +0 -11
- package/dist/images/annotation-noicon.svg +0 -7
- package/dist/images/annotation-note.svg +0 -42
- package/dist/images/annotation-paperclip.svg +0 -6
- package/dist/images/annotation-paragraph.svg +0 -16
- package/dist/images/annotation-pushpin.svg +0 -7
- package/dist/images/checkmark.svg +0 -5
- package/dist/images/comment-actionsButton.svg +0 -3
- package/dist/images/comment-closeButton.svg +0 -3
- package/dist/images/comment-editButton.svg +0 -8
- package/dist/images/comment-popup-editButton.svg +0 -5
- package/dist/images/cursor-editorFreeHighlight.svg +0 -6
- package/dist/images/cursor-editorFreeText.svg +0 -3
- package/dist/images/cursor-editorInk.svg +0 -4
- package/dist/images/cursor-editorTextHighlight.svg +0 -8
- package/dist/images/editor-toolbar-delete.svg +0 -5
- package/dist/images/editor-toolbar-edit.svg +0 -3
- package/dist/images/findbarButton-next.svg +0 -3
- package/dist/images/findbarButton-previous.svg +0 -3
- package/dist/images/gv-toolbarButton-download.svg +0 -3
- package/dist/images/loading-icon.gif +0 -0
- package/dist/images/loading.svg +0 -1
- package/dist/images/messageBar_closingButton.svg +0 -3
- package/dist/images/messageBar_info.svg +0 -3
- package/dist/images/messageBar_warning.svg +0 -3
- package/dist/images/pages_closeButton.svg +0 -3
- package/dist/images/pages_selected.svg +0 -7
- package/dist/images/pages_viewArrow.svg +0 -3
- package/dist/images/pages_viewButton.svg +0 -3
- package/dist/images/secondaryToolbarButton-documentProperties.svg +0 -3
- package/dist/images/secondaryToolbarButton-firstPage.svg +0 -3
- package/dist/images/secondaryToolbarButton-handTool.svg +0 -3
- package/dist/images/secondaryToolbarButton-lastPage.svg +0 -3
- package/dist/images/secondaryToolbarButton-rotateCcw.svg +0 -3
- package/dist/images/secondaryToolbarButton-rotateCw.svg +0 -3
- package/dist/images/secondaryToolbarButton-scrollHorizontal.svg +0 -3
- package/dist/images/secondaryToolbarButton-scrollPage.svg +0 -3
- package/dist/images/secondaryToolbarButton-scrollVertical.svg +0 -3
- package/dist/images/secondaryToolbarButton-scrollWrapped.svg +0 -3
- package/dist/images/secondaryToolbarButton-selectTool.svg +0 -3
- package/dist/images/secondaryToolbarButton-spreadEven.svg +0 -3
- package/dist/images/secondaryToolbarButton-spreadNone.svg +0 -3
- package/dist/images/secondaryToolbarButton-spreadOdd.svg +0 -3
- package/dist/images/toolbarButton-bookmark.svg +0 -3
- package/dist/images/toolbarButton-currentOutlineItem.svg +0 -3
- package/dist/images/toolbarButton-download.svg +0 -4
- package/dist/images/toolbarButton-editorFreeText.svg +0 -5
- package/dist/images/toolbarButton-editorHighlight.svg +0 -6
- package/dist/images/toolbarButton-editorInk.svg +0 -4
- package/dist/images/toolbarButton-editorSignature.svg +0 -6
- package/dist/images/toolbarButton-editorStamp.svg +0 -8
- package/dist/images/toolbarButton-menuArrow.svg +0 -3
- package/dist/images/toolbarButton-openFile.svg +0 -3
- package/dist/images/toolbarButton-pageDown.svg +0 -3
- package/dist/images/toolbarButton-pageUp.svg +0 -3
- package/dist/images/toolbarButton-presentationMode.svg +0 -3
- package/dist/images/toolbarButton-print.svg +0 -3
- package/dist/images/toolbarButton-search.svg +0 -3
- package/dist/images/toolbarButton-secondaryToolbarToggle.svg +0 -3
- package/dist/images/toolbarButton-viewAttachments.svg +0 -3
- package/dist/images/toolbarButton-viewLayers.svg +0 -3
- package/dist/images/toolbarButton-viewOutline.svg +0 -3
- package/dist/images/toolbarButton-viewThumbnail.svg +0 -3
- package/dist/images/toolbarButton-viewsManagerToggle.svg +0 -3
- package/dist/images/toolbarButton-zoomIn.svg +0 -3
- package/dist/images/toolbarButton-zoomOut.svg +0 -3
- package/dist/images/treeitem-collapsed.svg +0 -1
- package/dist/images/treeitem-expanded.svg +0 -1
- package/dist/superdoc/src/helpers/floor.d.ts +0 -1
- package/dist/superdoc/src/index.d.cts +0 -18
- package/dist/superdoc/src/index.d.ts +0 -14
- package/dist-cdn/footnote-table-order.docx +0 -0
package/dist/chunks/{create-super-doc-ui-B29zw5qD.es.js → create-super-doc-ui-B6Va_J_0.es.js}
RENAMED
|
@@ -3691,6 +3691,25 @@ function getCommandDescriptor(id) {
|
|
|
3691
3691
|
}
|
|
3692
3692
|
//#endregion
|
|
3693
3693
|
//#region src/public/ui/entity-at.ts
|
|
3694
|
+
function readDecorationProviders(node) {
|
|
3695
|
+
const encoded = node.getAttribute("data-superdoc-extension-decorations");
|
|
3696
|
+
if (encoded) try {
|
|
3697
|
+
const parsed = JSON.parse(encoded);
|
|
3698
|
+
if (Array.isArray(parsed)) return parsed.filter((id) => typeof id === "string");
|
|
3699
|
+
} catch {
|
|
3700
|
+
return [];
|
|
3701
|
+
}
|
|
3702
|
+
const single = node.getAttribute("data-superdoc-extension-decoration");
|
|
3703
|
+
return single ? [single] : [];
|
|
3704
|
+
}
|
|
3705
|
+
function collectDecorationProvidersFromChain(start, stopAt) {
|
|
3706
|
+
const providers = /* @__PURE__ */ new Set();
|
|
3707
|
+
for (let element = start; element; element = element.parentElement) {
|
|
3708
|
+
for (const provider of readDecorationProviders(element)) providers.add(provider);
|
|
3709
|
+
if (element === stopAt) break;
|
|
3710
|
+
}
|
|
3711
|
+
return [...providers];
|
|
3712
|
+
}
|
|
3694
3713
|
function parseCommaSeparatedIds(value) {
|
|
3695
3714
|
return value.split(",").map((id) => id.trim()).filter(Boolean);
|
|
3696
3715
|
}
|
|
@@ -3762,6 +3781,16 @@ function collectEntityHitsFromChain(start, stopAt) {
|
|
|
3762
3781
|
for (const hit of pendingStory) hit.story = layoutStory;
|
|
3763
3782
|
pendingStory = [];
|
|
3764
3783
|
}
|
|
3784
|
+
for (const decorationProvider of readDecorationProviders(node)) {
|
|
3785
|
+
const key = `decoration:${decorationProvider}`;
|
|
3786
|
+
if (!seen.has(key)) {
|
|
3787
|
+
seen.add(key);
|
|
3788
|
+
hits.push({
|
|
3789
|
+
type: "decoration",
|
|
3790
|
+
id: decorationProvider
|
|
3791
|
+
});
|
|
3792
|
+
}
|
|
3793
|
+
}
|
|
3765
3794
|
const citationId = node.getAttribute("data-citation-id");
|
|
3766
3795
|
if (citationId) {
|
|
3767
3796
|
const key = `citation:${citationId}`;
|
|
@@ -6152,6 +6181,7 @@ function createSuperDocUI(options) {
|
|
|
6152
6181
|
pointerSelecting: false,
|
|
6153
6182
|
keyboardSelecting: false
|
|
6154
6183
|
};
|
|
6184
|
+
const paintedInlineTargets = /* @__PURE__ */ new WeakSet();
|
|
6155
6185
|
let painterCaptureEpoch = 0;
|
|
6156
6186
|
let painterCommandDoc = null;
|
|
6157
6187
|
const painterModeListeners = /* @__PURE__ */ new Set();
|
|
@@ -6248,7 +6278,7 @@ function createSuperDocUI(options) {
|
|
|
6248
6278
|
const readHostSelectionSnapshot = () => {
|
|
6249
6279
|
const handles = safeCall(() => hostMethod(getHost(), "getHandles")?.() ?? null, null);
|
|
6250
6280
|
const editing = isPlainObject(handles) ? handles.editing : void 0;
|
|
6251
|
-
const getSnapshot = hostMethod(isPlainObject(editing) ? editing.selection : void 0, "getSnapshot");
|
|
6281
|
+
const getSnapshot = hostMethod(isPlainObject(editing) ? editing.selection : void 0, "getSnapshot") ?? hostMethod(isPlainObject(handles) ? handles.selection : void 0, "getSnapshot");
|
|
6252
6282
|
if (!getSnapshot) return null;
|
|
6253
6283
|
const snapshot = safeCall(() => getSnapshot(), null);
|
|
6254
6284
|
return snapshot && typeof snapshot === "object" ? snapshot : null;
|
|
@@ -6462,7 +6492,7 @@ function createSuperDocUI(options) {
|
|
|
6462
6492
|
return left.id === right.id && left.paintedEntityId === right.paintedEntityId && storyLocatorSignature(left.story) === storyLocatorSignature(right.story);
|
|
6463
6493
|
};
|
|
6464
6494
|
const hasPendingTrackChangeRevealFocus = (focus) => Array.from(pendingTrackChangeRevealFocuses).some((pendingFocus) => explicitActiveChangesEqual(pendingFocus, focus));
|
|
6465
|
-
const
|
|
6495
|
+
const mirrorReviewFocusToHost = (entityType, next) => {
|
|
6466
6496
|
const readHandles = hostMethod(getHost(), "getHandles");
|
|
6467
6497
|
if (!readHandles) return;
|
|
6468
6498
|
const handles = safeCall(() => readHandles(), null);
|
|
@@ -6473,15 +6503,15 @@ function createSuperDocUI(options) {
|
|
|
6473
6503
|
if (!setActiveReviewTarget) return;
|
|
6474
6504
|
const layout = isPlainObject(handles.layout) ? handles.layout : void 0;
|
|
6475
6505
|
safeCall(() => setActiveReviewTarget({
|
|
6476
|
-
entityType
|
|
6506
|
+
entityType,
|
|
6477
6507
|
entityId: next.id,
|
|
6478
6508
|
...next.paintedEntityId ? { paintedEntityId: next.paintedEntityId } : {},
|
|
6479
6509
|
origin: "panel",
|
|
6480
6510
|
layoutEpoch: typeof layout?.generation === "number" ? layout.generation : 0,
|
|
6481
|
-
story: next.story ?? {
|
|
6511
|
+
...entityType === "trackedChange" ? { story: next.story ?? {
|
|
6482
6512
|
kind: "story",
|
|
6483
6513
|
storyType: "body"
|
|
6484
|
-
}
|
|
6514
|
+
} } : {}
|
|
6485
6515
|
}), null);
|
|
6486
6516
|
return;
|
|
6487
6517
|
}
|
|
@@ -6489,10 +6519,22 @@ function createSuperDocUI(options) {
|
|
|
6489
6519
|
const clearActiveReviewTarget = hostMethod(review, "clearActiveReviewTarget");
|
|
6490
6520
|
if (!getActiveReviewTarget || !clearActiveReviewTarget) return;
|
|
6491
6521
|
const activeTarget = safeCall(() => getActiveReviewTarget(), null);
|
|
6492
|
-
if (isPlainObject(activeTarget) && activeTarget.entityType ===
|
|
6522
|
+
if (isPlainObject(activeTarget) && activeTarget.entityType === entityType) safeCall(() => clearActiveReviewTarget(), void 0);
|
|
6523
|
+
};
|
|
6524
|
+
const mirrorTrackedChangeFocusToHost = (next) => mirrorReviewFocusToHost("trackedChange", next);
|
|
6525
|
+
const readReviewFocus = () => ({
|
|
6526
|
+
change: explicitActiveChange,
|
|
6527
|
+
commentId: explicitActiveCommentId
|
|
6528
|
+
});
|
|
6529
|
+
const restoreReviewFocus = (previous) => {
|
|
6530
|
+
setExplicitActiveChange(previous.change, { invalidateQueuedNavigation: false });
|
|
6531
|
+
explicitActiveCommentId = previous.commentId;
|
|
6532
|
+
if (previous.commentId) mirrorReviewFocusToHost("comment", { id: previous.commentId });
|
|
6533
|
+
else mirrorTrackedChangeFocusToHost(previous.change);
|
|
6493
6534
|
};
|
|
6494
6535
|
const setExplicitActiveChange = (next, options) => {
|
|
6495
6536
|
explicitActiveChange = next;
|
|
6537
|
+
if (next) explicitActiveCommentId = null;
|
|
6496
6538
|
explicitActiveChangeRevision += 1;
|
|
6497
6539
|
trackChangeRevealInvalidation += 1;
|
|
6498
6540
|
if (options?.invalidateQueuedNavigation !== false) queuedTrackChangeNavigationInvalidation += 1;
|
|
@@ -7552,15 +7594,53 @@ function createSuperDocUI(options) {
|
|
|
7552
7594
|
* Explicit whole-table changes have a complete local source range and also
|
|
7553
7595
|
* seed clears, so a delayed worker read cannot retain a cleared table target.
|
|
7554
7596
|
*/
|
|
7555
|
-
|
|
7597
|
+
function captureWholeTableParagraphSeed(host, seed, nativeSelection) {
|
|
7598
|
+
const editor = getEditor();
|
|
7599
|
+
const rawLifetime = safeCall(() => hostMethod(host, "getForegroundInteractionLifetime")?.() ?? null, null);
|
|
7600
|
+
const lifetime = hasAbortedFlag(rawLifetime) ? rawLifetime : null;
|
|
7601
|
+
const mount = safeCall(() => hostMethod(host, "getMountedHandle")?.() ?? null, null);
|
|
7602
|
+
const mode = readDocumentMode();
|
|
7603
|
+
if (!host || !editor || !mount || !lifetime || lifetime.aborted || mode === null || seed.empty || seed.tableSelection?.kind !== "tableCells" || seed.tableSelection.type !== "table" || seed.target?.kind !== "text" || !seed.target.segments.length) return false;
|
|
7604
|
+
if (nativeSelection) {
|
|
7605
|
+
const presentation = safeCall(() => hostMethod(host, "readAppliedSelectionPresentation")?.(), null);
|
|
7606
|
+
const applied = normalizeSelectionInfo(isPlainObject(presentation) ? presentation.selection : null);
|
|
7607
|
+
if (readHostSelectionSnapshot() !== nativeSelection || !isNonCollapsedHostSelection(nativeSelection) || !applied || selectionSignature(selectionSliceFromInfo(applied, "ready")) !== selectionSignature(selectionSliceFromInfo(seed, "ready")) || JSON.stringify(applied.tableSelection) !== JSON.stringify(seed.tableSelection)) return false;
|
|
7608
|
+
const snapshot = nativeSelection;
|
|
7609
|
+
const first = seed.target.segments[0]?.blockId, last = seed.target.segments.at(-1)?.blockId;
|
|
7610
|
+
const matches = (point, blockId) => !!blockId && isPlainObject(point) && point.blockId === blockId && storyLocatorSignature(point.story ?? snapshot.story) === storyLocatorSignature(seed.target?.story);
|
|
7611
|
+
if (!(matches(snapshot.anchor, first) && matches(snapshot.focus, last) || matches(snapshot.focus, first) && matches(snapshot.anchor, last))) return false;
|
|
7612
|
+
}
|
|
7613
|
+
wholeTableParagraphSeed = {
|
|
7614
|
+
editor,
|
|
7615
|
+
host,
|
|
7616
|
+
doc: editor.doc,
|
|
7617
|
+
mount,
|
|
7618
|
+
lifetime,
|
|
7619
|
+
sourceToken: contentToken(),
|
|
7620
|
+
mode,
|
|
7621
|
+
info: seed,
|
|
7622
|
+
nativeSelection
|
|
7623
|
+
};
|
|
7624
|
+
return true;
|
|
7625
|
+
}
|
|
7626
|
+
const refreshSelectionFromHost = (hostSelectionSnapshot, afterTypingPaint = false, wholeTableSelectionChanged = false, initialTableSelection = null) => {
|
|
7627
|
+
const host = getHost();
|
|
7556
7628
|
const foreground = foregroundMutationState();
|
|
7629
|
+
if (isNonCollapsedHostSelection(hostSelectionSnapshot) && readHostSelectionSnapshot() === hostSelectionSnapshot) {
|
|
7630
|
+
const seed = normalizeSelectionInfo(safeCall(() => hostMethod(host, "readLiveSelectionSyncSnapshot")?.(), null));
|
|
7631
|
+
if (seed && !seed.selectionTarget && captureWholeTableParagraphSeed(host, seed, hostSelectionSnapshot)) asyncReads.set("selection", {
|
|
7632
|
+
token: asyncReads.get("selection")?.token ?? null,
|
|
7633
|
+
value: seed,
|
|
7634
|
+
hasSettled: true,
|
|
7635
|
+
inflightToken: null
|
|
7636
|
+
});
|
|
7637
|
+
}
|
|
7557
7638
|
if (isNonCollapsedHostSelection(hostSelectionSnapshot) && !(foreground && foreground.active > 0)) {
|
|
7558
7639
|
typedCaretValidationHeld = false;
|
|
7559
7640
|
pendingSelectionSeedValidationToken = null;
|
|
7560
7641
|
issueAsyncRead("selection", selectionReadToken(), selectionCurrentRun, normalizeSelectionInfo);
|
|
7561
7642
|
return;
|
|
7562
7643
|
}
|
|
7563
|
-
const host = getHost();
|
|
7564
7644
|
const read = host?.readLiveSelectionSyncSnapshot;
|
|
7565
7645
|
if (typeof read !== "function") return;
|
|
7566
7646
|
const seed = normalizeSelectionInfo(safeCall(() => read.call(host), null));
|
|
@@ -7569,21 +7649,7 @@ function createSuperDocUI(options) {
|
|
|
7569
7649
|
typedCaretValidationHeld = false;
|
|
7570
7650
|
pendingSelectionSeedValidationToken = null;
|
|
7571
7651
|
wholeTableParagraphSeed = null;
|
|
7572
|
-
|
|
7573
|
-
const rawLifetime = safeCall(() => hostMethod(host, "getForegroundInteractionLifetime")?.() ?? null, null);
|
|
7574
|
-
const lifetime = hasAbortedFlag(rawLifetime) ? rawLifetime : null;
|
|
7575
|
-
const mount = safeCall(() => hostMethod(host, "getMountedHandle")?.() ?? null, null);
|
|
7576
|
-
const mode = readDocumentMode();
|
|
7577
|
-
if (host && editor && mount && lifetime && !lifetime.aborted && mode !== null && !seed.empty && seed.tableSelection?.kind === "tableCells" && seed.tableSelection.type === "table" && seed.target?.segments.length && seed.selectionTarget) wholeTableParagraphSeed = {
|
|
7578
|
-
editor,
|
|
7579
|
-
host,
|
|
7580
|
-
doc: editor.doc,
|
|
7581
|
-
mount,
|
|
7582
|
-
lifetime,
|
|
7583
|
-
sourceToken: contentToken(),
|
|
7584
|
-
mode,
|
|
7585
|
-
info: seed
|
|
7586
|
-
};
|
|
7652
|
+
captureWholeTableParagraphSeed(host, seed, initialTableSelection);
|
|
7587
7653
|
const token = selectionReadToken();
|
|
7588
7654
|
asyncReads.set("selection", {
|
|
7589
7655
|
token,
|
|
@@ -7741,7 +7807,7 @@ function createSuperDocUI(options) {
|
|
|
7741
7807
|
const directory = asyncReads.get("comments");
|
|
7742
7808
|
const directoryItems = directory?.token === contentToken() && directory.hasSettled && Array.isArray(directory.value) ? directory.value : null;
|
|
7743
7809
|
const activeValidationItems = directoryLeaseCounts.comments > 0 ? directoryItems : items;
|
|
7744
|
-
if (explicitActiveCommentId && activeValidationItems &&
|
|
7810
|
+
if (explicitActiveCommentId && activeValidationItems && (activeValidationItems !== items || listStatus === "ready")) explicitActiveCommentId = resolveActiveCommentId(activeValidationItems, explicitActiveCommentId);
|
|
7745
7811
|
const activeId = explicitActiveCommentId ?? activeIds[0] ?? null;
|
|
7746
7812
|
return {
|
|
7747
7813
|
status: combineStatus(listStatus, selection.status),
|
|
@@ -8386,12 +8452,13 @@ function createSuperDocUI(options) {
|
|
|
8386
8452
|
];
|
|
8387
8453
|
function effectiveInlineUniformityInput(selection) {
|
|
8388
8454
|
const cellTarget = currentCellSelectionTarget();
|
|
8389
|
-
const
|
|
8455
|
+
const paintedTarget = cellTarget ? null : currentUnrepresentableSelectionTarget(selection);
|
|
8456
|
+
const target = cellTarget ?? paintedTarget ?? selection.selectionTarget;
|
|
8390
8457
|
if (!target) return null;
|
|
8391
8458
|
const tableCellSelection = cellTarget ? tableCellSelectionForTarget(cellTarget) : null;
|
|
8392
8459
|
return {
|
|
8393
8460
|
target,
|
|
8394
|
-
offsetSpace: "selection",
|
|
8461
|
+
offsetSpace: cellTarget || paintedTarget ? "selection" : "kernel",
|
|
8395
8462
|
...tableCellSelection ? { tableCellSelection } : {}
|
|
8396
8463
|
};
|
|
8397
8464
|
}
|
|
@@ -8529,7 +8596,11 @@ function createSuperDocUI(options) {
|
|
|
8529
8596
|
const getNodeById = hostMethod(doc, "getNodeById");
|
|
8530
8597
|
const raw = await Promise.resolve(getNode ? getNode(address) : getNodeById?.({
|
|
8531
8598
|
nodeId: address["nodeId"],
|
|
8532
|
-
nodeType: address["nodeType"]
|
|
8599
|
+
nodeType: address["nodeType"],
|
|
8600
|
+
story: address["story"] ?? {
|
|
8601
|
+
kind: "story",
|
|
8602
|
+
storyType: "body"
|
|
8603
|
+
}
|
|
8533
8604
|
}));
|
|
8534
8605
|
return isPlainObject(raw) ? raw : void 0;
|
|
8535
8606
|
};
|
|
@@ -9075,7 +9146,8 @@ function createSuperDocUI(options) {
|
|
|
9075
9146
|
const token = contentToken();
|
|
9076
9147
|
const read = readAsync(key, token, () => isBodyStory ? doc.getNodeById({
|
|
9077
9148
|
nodeId: blockId,
|
|
9078
|
-
nodeType: "paragraph"
|
|
9149
|
+
nodeType: "paragraph",
|
|
9150
|
+
story
|
|
9079
9151
|
}) : doc.getNode(paragraphTarget(blockId, story)), (raw) => raw && typeof raw === "object" ? raw : null);
|
|
9080
9152
|
const entry = asyncReads.get(key);
|
|
9081
9153
|
return {
|
|
@@ -9284,7 +9356,11 @@ function createSuperDocUI(options) {
|
|
|
9284
9356
|
const isBodyStory = !story || story.storyType === "body";
|
|
9285
9357
|
const raw = story && typeof doc.getNode === "function" ? await doc.getNode(paragraphTarget(blockId, story)) : isBodyStory && typeof doc.getNodeById === "function" ? await doc.getNodeById({
|
|
9286
9358
|
nodeId: blockId,
|
|
9287
|
-
nodeType: "paragraph"
|
|
9359
|
+
nodeType: "paragraph",
|
|
9360
|
+
story: {
|
|
9361
|
+
kind: "story",
|
|
9362
|
+
storyType: "body"
|
|
9363
|
+
}
|
|
9288
9364
|
}) : null;
|
|
9289
9365
|
return readParagraphIndentationFromResult(raw && typeof raw === "object" ? raw : null);
|
|
9290
9366
|
} catch {
|
|
@@ -9961,14 +10037,15 @@ function createSuperDocUI(options) {
|
|
|
9961
10037
|
const tableSelection = isPlainObject(handles) ? handles.selection : void 0;
|
|
9962
10038
|
const subscribeWholeTable = hostMethod(tableSelection, "subscribeWholeTable");
|
|
9963
10039
|
if (subscribeWholeTable) {
|
|
9964
|
-
const refreshWholeTable = () => {
|
|
10040
|
+
const refreshWholeTable = (initial = false) => {
|
|
10041
|
+
const native = initial ? readHostSelectionSnapshot() : null;
|
|
9965
10042
|
selectionEpoch += 1;
|
|
9966
|
-
refreshSelectionFromHost(void 0, false, true);
|
|
10043
|
+
refreshSelectionFromHost(void 0, false, true, native);
|
|
9967
10044
|
recompute("host-selection");
|
|
9968
10045
|
};
|
|
9969
|
-
const detach = subscribeWholeTable(refreshWholeTable);
|
|
10046
|
+
const detach = subscribeWholeTable(() => refreshWholeTable());
|
|
9970
10047
|
if (typeof detach === "function") unsubscribeCallbacks.push(() => detach());
|
|
9971
|
-
if (hostMethod(tableSelection, "getWholeTableNodeId")?.()) refreshWholeTable();
|
|
10048
|
+
if (hostMethod(tableSelection, "getWholeTableNodeId")?.()) refreshWholeTable(true);
|
|
9972
10049
|
}
|
|
9973
10050
|
} catch {
|
|
9974
10051
|
currentHostSelectionSource = null;
|
|
@@ -9989,10 +10066,35 @@ function createSuperDocUI(options) {
|
|
|
9989
10066
|
};
|
|
9990
10067
|
let trackedChangeNavigationInFlight = 0;
|
|
9991
10068
|
let lastPublishedHostReviewTarget;
|
|
10069
|
+
const isRepublishedHostReviewTarget = (left, right) => left === right || isPlainObject(left) && isPlainObject(right) && left.layoutEpoch !== right.layoutEpoch && left.origin === right.origin && left.entityType === right.entityType && left.entityId === right.entityId && left.paintedEntityId === right.paintedEntityId && storyLocatorSignature(left.story) === storyLocatorSignature(right.story);
|
|
9992
10070
|
const syncTrackedChangeFocusFromHostReviewTarget = (rawTarget, rawSnapshot) => {
|
|
9993
10071
|
const rejection = (rawSnapshot && typeof rawSnapshot === "object" ? rawSnapshot : null)?.lastInteractionRejection;
|
|
9994
|
-
if (rawTarget == null && rejection && typeof rejection === "object" && rejection.code === "review-target-invalidated" && rejection.detail === "not-painted" && explicitActiveChange) return false;
|
|
10072
|
+
if (rawTarget == null && rejection && typeof rejection === "object" && rejection.code === "review-target-invalidated" && rejection.detail === "not-painted" && (explicitActiveChange || explicitActiveCommentId)) return false;
|
|
9995
10073
|
const target = rawTarget && typeof rawTarget === "object" ? rawTarget : null;
|
|
10074
|
+
if (target?.entityType === "comment" && typeof target.entityId === "string" && target.entityId.length > 0) {
|
|
10075
|
+
const commentId = resolveActiveCommentId(state?.comments.items ?? [], target.entityId) ?? target.entityId;
|
|
10076
|
+
const republished = isRepublishedHostReviewTarget(rawTarget, lastPublishedHostReviewTarget?.raw);
|
|
10077
|
+
lastPublishedHostReviewTarget = {
|
|
10078
|
+
raw: rawTarget,
|
|
10079
|
+
focus: null,
|
|
10080
|
+
origin: target.origin
|
|
10081
|
+
};
|
|
10082
|
+
if (republished || explicitActiveCommentId === commentId && !explicitActiveChange) return false;
|
|
10083
|
+
setExplicitActiveChange(null);
|
|
10084
|
+
explicitActiveCommentId = commentId;
|
|
10085
|
+
return true;
|
|
10086
|
+
}
|
|
10087
|
+
const previousTarget = lastPublishedHostReviewTarget?.raw;
|
|
10088
|
+
if (!target && isPlainObject(previousTarget) && previousTarget.entityType === "comment") {
|
|
10089
|
+
lastPublishedHostReviewTarget = {
|
|
10090
|
+
raw: rawTarget,
|
|
10091
|
+
focus: null,
|
|
10092
|
+
origin: void 0
|
|
10093
|
+
};
|
|
10094
|
+
if (!explicitActiveCommentId) return false;
|
|
10095
|
+
explicitActiveCommentId = null;
|
|
10096
|
+
return true;
|
|
10097
|
+
}
|
|
9996
10098
|
let next = null;
|
|
9997
10099
|
if (target?.entityType === "trackedChange" && typeof target.entityId === "string" && target.entityId.length > 0) {
|
|
9998
10100
|
const targetStory = target.story && typeof target.story === "object" ? target.story : void 0;
|
|
@@ -10017,7 +10119,7 @@ function createSuperDocUI(options) {
|
|
|
10017
10119
|
}
|
|
10018
10120
|
if (rawTarget == null && next == null && explicitActiveChange != null && hasPendingTrackChangeRevealFocus(explicitActiveChange)) return false;
|
|
10019
10121
|
const previousPublication = lastPublishedHostReviewTarget;
|
|
10020
|
-
if (previousPublication && (rawTarget
|
|
10122
|
+
if (previousPublication && (isRepublishedHostReviewTarget(rawTarget, previousPublication.raw) || target?.origin === "panel" && previousPublication.origin === "panel" && next && previousPublication.focus && explicitActiveChangesEqual(previousPublication.focus, next))) return false;
|
|
10021
10123
|
lastPublishedHostReviewTarget = {
|
|
10022
10124
|
raw: rawTarget,
|
|
10023
10125
|
focus: next,
|
|
@@ -10395,11 +10497,16 @@ function createSuperDocUI(options) {
|
|
|
10395
10497
|
* ordinary/insertion selections are visible-space, while a selection that
|
|
10396
10498
|
* reaches painted deleted text is projected in tracked space by the host.
|
|
10397
10499
|
*
|
|
10398
|
-
* Cross-block
|
|
10399
|
-
*
|
|
10500
|
+
* Cross-block and object-containing coverage use the model-backed tracked
|
|
10501
|
+
* target when the explicit text selection cannot represent the range.
|
|
10400
10502
|
*/
|
|
10401
10503
|
function trackDecisionRangeFromSelection(selection) {
|
|
10402
10504
|
if (selection.empty) return null;
|
|
10505
|
+
if (!selection.selectionTarget && selection.trackedTarget) return {
|
|
10506
|
+
kind: "range",
|
|
10507
|
+
coordinateSpace: "tracked",
|
|
10508
|
+
range: selection.trackedTarget
|
|
10509
|
+
};
|
|
10403
10510
|
const explicit = selection.selectionTarget;
|
|
10404
10511
|
const start = explicit?.start;
|
|
10405
10512
|
const end = explicit?.end;
|
|
@@ -10553,7 +10660,7 @@ function createSuperDocUI(options) {
|
|
|
10553
10660
|
kind: "blocked",
|
|
10554
10661
|
reason: SUPERDOC_UI_REASONS.operationUnavailable
|
|
10555
10662
|
};
|
|
10556
|
-
if (!selection.selectionTarget) return null;
|
|
10663
|
+
if (!selection.selectionTarget && !selection.trackedTarget && selection.target?.kind !== "text") return null;
|
|
10557
10664
|
const target = trackDecisionRangeFromSelection(selection);
|
|
10558
10665
|
if (!target && route() !== "id") return {
|
|
10559
10666
|
kind: "blocked",
|
|
@@ -10893,25 +11000,35 @@ function createSuperDocUI(options) {
|
|
|
10893
11000
|
pendingCommandSettlement = settledResults.length ? Promise.all(settledResults).then((results) => combineCommandResults(results)) : null;
|
|
10894
11001
|
return combineCommandResults(immediateResults);
|
|
10895
11002
|
};
|
|
10896
|
-
/**
|
|
10897
|
-
* Call an inline `format.*` operation against the live selection. Mirrors
|
|
10898
|
-
* `callEditorMutation` (suggesting mode adds `changeMode: 'tracked'`), and
|
|
10899
|
-
* when the target is the host's own editable `selectionTarget` it also
|
|
10900
|
-
* carries the PRIVATE V2 option `offsetSpace: 'selection'` (browser
|
|
10901
|
-
* selection offsets count an inline object as one caret position). The
|
|
10902
|
-
* option is not part of public `MutationOptions`; this is the same cast
|
|
10903
|
-
* pattern the delete/replace callers use.
|
|
10904
|
-
*/
|
|
10905
11003
|
function currentCellSelectionTarget() {
|
|
11004
|
+
return captureInputSelectionTarget(true);
|
|
11005
|
+
}
|
|
11006
|
+
function captureInputSelectionTarget(requireTableCells = false) {
|
|
10906
11007
|
const handles = safeCall(() => hostMethod(getHost(), "getHandles")?.(), null);
|
|
10907
11008
|
const selection = isPlainObject(handles) ? handles.selection : void 0;
|
|
10908
11009
|
const held = hostMethod(selection, "getSnapshot")?.();
|
|
10909
|
-
if (!isPlainObject(held) || !held.tableCells) return null;
|
|
11010
|
+
if (requireTableCells && (!isPlainObject(held) || !held.tableCells)) return null;
|
|
10910
11011
|
const resolved = hostMethod(selection, "toSelectionTarget")?.();
|
|
10911
11012
|
return isPlainObject(resolved) && resolved.kind === "ok" && resolved.mode === "range" ? capturedTableCellTarget(resolved.target) : null;
|
|
10912
11013
|
}
|
|
11014
|
+
function currentUnrepresentableSelectionTarget(selection) {
|
|
11015
|
+
if (selection.empty || selection.selectionTarget || selection.target?.kind !== "text") return null;
|
|
11016
|
+
return heldPaintedTextSelectionTarget();
|
|
11017
|
+
}
|
|
11018
|
+
function heldPaintedTextSelectionTarget() {
|
|
11019
|
+
const target = captureInputSelectionTarget();
|
|
11020
|
+
if (target) paintedInlineTargets.add(target);
|
|
11021
|
+
return target;
|
|
11022
|
+
}
|
|
10913
11023
|
function resolveInlineCommandTarget(selection) {
|
|
10914
|
-
|
|
11024
|
+
const cells = currentCellSelectionTarget();
|
|
11025
|
+
if (cells) return cells;
|
|
11026
|
+
if (!selection.empty && !selection.selectionTarget && selection.target?.kind === "text") {
|
|
11027
|
+
const snapshot = readHostSelectionSnapshot();
|
|
11028
|
+
const painted = currentUnrepresentableSelectionTarget(selection);
|
|
11029
|
+
if (painted) return snapshot && appliedSelectionPresentation(selection) && readHostSelectionSnapshot() === snapshot ? painted : null;
|
|
11030
|
+
}
|
|
11031
|
+
return resolveInlineSelectionTarget(selection);
|
|
10915
11032
|
}
|
|
10916
11033
|
function tableCellSelectionForTarget(target) {
|
|
10917
11034
|
const cellTarget = currentCellSelectionTarget();
|
|
@@ -10931,10 +11048,15 @@ function createSuperDocUI(options) {
|
|
|
10931
11048
|
offsetSpace: "selection",
|
|
10932
11049
|
tableCellSelection
|
|
10933
11050
|
});
|
|
11051
|
+
const paintedTarget = input?.target;
|
|
11052
|
+
if (paintedTarget !== null && typeof paintedTarget === "object" && (paintedInlineTargets.has(paintedTarget) || paintedTarget.coordinateSpace === "tracked")) return op(input, {
|
|
11053
|
+
...options,
|
|
11054
|
+
offsetSpace: "selection"
|
|
11055
|
+
});
|
|
10934
11056
|
if (!selection.selectionTarget) return options ? op(input, options) : op(input);
|
|
10935
11057
|
return op(input, {
|
|
10936
11058
|
...options,
|
|
10937
|
-
offsetSpace: "
|
|
11059
|
+
offsetSpace: "kernel"
|
|
10938
11060
|
});
|
|
10939
11061
|
};
|
|
10940
11062
|
/** Build the `format.paragraph.*` / `styles.paragraph.*` input for a block. */
|
|
@@ -11163,13 +11285,16 @@ function createSuperDocUI(options) {
|
|
|
11163
11285
|
};
|
|
11164
11286
|
pendingCommandSettlement = (async () => {
|
|
11165
11287
|
const plans = await Promise.all(blockIds.map((blockId) => planBlock(blockId).catch(() => null)));
|
|
11166
|
-
|
|
11288
|
+
const allListItems = plans.length === blockIds.length && plans.every((plan) => plan?.kind === "list");
|
|
11289
|
+
const preserveFirstItemLevel = blockIds.length === 1 && story.storyType === "body";
|
|
11290
|
+
if (allListItems && (readDocumentMode() !== "suggesting" || preserveFirstItemLevel)) {
|
|
11167
11291
|
const rangeRoute = mode === "indent" ? "lists.indentRange" : "lists.outdentRange";
|
|
11168
11292
|
const rangeOp = resolveDocOperation(doc, rangeRoute);
|
|
11169
11293
|
if (rangeOp) try {
|
|
11170
11294
|
return await settleOperationResult(callEditorMutation(rangeRoute, rangeOp, {
|
|
11171
11295
|
paraIds: blockIds,
|
|
11172
|
-
story
|
|
11296
|
+
story,
|
|
11297
|
+
...preserveFirstItemLevel ? { preserveFirstItemLevel: true } : {}
|
|
11173
11298
|
})).settled;
|
|
11174
11299
|
} catch {
|
|
11175
11300
|
return false;
|
|
@@ -11709,23 +11834,32 @@ function createSuperDocUI(options) {
|
|
|
11709
11834
|
const record = readLinkPayloadRecord(payload);
|
|
11710
11835
|
return Boolean(readLinkPayloadTarget(payload) || isPlainObject(record.hyperlinkTarget) || isPlainObject(record.textTarget));
|
|
11711
11836
|
};
|
|
11712
|
-
const
|
|
11837
|
+
const currentWholeTableParagraphOwner = () => {
|
|
11713
11838
|
const owner = wholeTableParagraphSeed, host = getHost();
|
|
11714
|
-
if (!owner || disposed || owner.lifetime.aborted || owner.host !== host || owner.editor !== getEditor() || owner.editor.doc !== owner.doc || owner.sourceToken !== contentToken() || owner.mode !== readDocumentMode() || safeCall(() => hostMethod(host, "getMountedHandle")?.(), null) !== owner.mount) return
|
|
11839
|
+
if (!owner || disposed || owner.lifetime.aborted || owner.host !== host || owner.editor !== getEditor() || owner.editor.doc !== owner.doc || owner.sourceToken !== contentToken() || owner.mode !== readDocumentMode() || safeCall(() => hostMethod(host, "getMountedHandle")?.(), null) !== owner.mount) return null;
|
|
11715
11840
|
const tableId = owner.info.tableSelection?.tableId;
|
|
11716
11841
|
const activeTable = safeCall(() => {
|
|
11717
11842
|
const handles = hostMethod(host, "getHandles")?.();
|
|
11718
11843
|
return hostMethod(isPlainObject(handles) ? handles.selection : void 0, "getWholeTableNodeId")?.();
|
|
11719
11844
|
}, null);
|
|
11720
|
-
if (!tableId || activeTable !== tableId || state.selection.tableSelection?.type !== "table" || state.selection.tableSelection.tableId !== tableId || selectionSignature(state.selection) !== selectionSignature(selectionSliceFromInfo(owner.info, "ready"))) return
|
|
11845
|
+
if (!tableId || activeTable !== tableId || state.selection.tableSelection?.type !== "table" || state.selection.tableSelection.tableId !== tableId || selectionSignature(state.selection) !== selectionSignature(selectionSliceFromInfo(owner.info, "ready"))) return null;
|
|
11721
11846
|
const applied = appliedSelectionPresentation(state.selection);
|
|
11722
11847
|
const info = normalizeSelectionInfo(applied?.selection);
|
|
11723
|
-
return
|
|
11848
|
+
return info && JSON.stringify(info.tableSelection) === JSON.stringify(owner.info.tableSelection) ? {
|
|
11849
|
+
owner,
|
|
11850
|
+
info
|
|
11851
|
+
} : null;
|
|
11852
|
+
};
|
|
11853
|
+
const currentWholeTableParagraphSelection = () => {
|
|
11854
|
+
const current = currentWholeTableParagraphOwner();
|
|
11855
|
+
if (!current) return false;
|
|
11856
|
+
return current.owner.info.selectionTarget ? selectionInfoMatchesHost(current.info) : current.owner.nativeSelection !== null && readHostSelectionSnapshot() === current.owner.nativeSelection;
|
|
11724
11857
|
};
|
|
11725
11858
|
const commandSelectionIsReady = (id, descriptor, payload) => {
|
|
11726
11859
|
const foreground = foregroundMutationState();
|
|
11727
11860
|
if (foreground && (foreground.active > 0 || foreground.pending > 0)) return false;
|
|
11728
11861
|
if (descriptor?.blockParagraph && currentWholeTableParagraphSelection()) return true;
|
|
11862
|
+
if (descriptor?.blockParagraph && state.selection.tableSelection?.type === "table" && !state.selection.selectionTarget) return false;
|
|
11729
11863
|
if (state.selection.status !== "ready") return false;
|
|
11730
11864
|
if (trackDecisionCommand(id)?.scope === "id") return true;
|
|
11731
11865
|
if (!descriptor || descriptor.disposition !== "routed") return true;
|
|
@@ -12026,6 +12160,12 @@ function createSuperDocUI(options) {
|
|
|
12026
12160
|
keys: [...EFFECTIVE_INLINE_UNIFORMITY_KEYS, "highlight"],
|
|
12027
12161
|
includeCaret: true
|
|
12028
12162
|
} : null);
|
|
12163
|
+
if (effective?.fontFamily?.state === "mixed") {
|
|
12164
|
+
delete inlinePatch.fontFamily;
|
|
12165
|
+
delete inlinePatch.rFonts;
|
|
12166
|
+
mixedInlineKeys.add("fontFamily");
|
|
12167
|
+
mixedInlineKeys.add("rFonts");
|
|
12168
|
+
}
|
|
12029
12169
|
for (const [markName, patchKey] of Object.entries(MARK_TO_PATCH)) {
|
|
12030
12170
|
const entry = effective?.[markName];
|
|
12031
12171
|
if (!entry) continue;
|
|
@@ -12146,10 +12286,23 @@ function createSuperDocUI(options) {
|
|
|
12146
12286
|
const cellTarget = currentCellSelectionTarget();
|
|
12147
12287
|
const tableCellSelection = tableCellSelectionForTarget(cellTarget);
|
|
12148
12288
|
const rawSelection = typeof selectionApi?.["current"] === "function" ? await Promise.resolve(selectionApi["current"]({ includeText: true })) : readSelectionInfoLive().value;
|
|
12289
|
+
const selection = normalizeSelectionInfo(rawSelection);
|
|
12290
|
+
let paintedTarget = null;
|
|
12291
|
+
if (selection && !selection.empty && !selection.selectionTarget && selection.target?.kind === "text" && !cellTarget) {
|
|
12292
|
+
const nativeSelection = readHostSelectionSnapshot();
|
|
12293
|
+
paintedTarget = heldPaintedTextSelectionTarget();
|
|
12294
|
+
if (paintedTarget && (!nativeSelection || !appliedSelectionPresentation(selectionSliceFromInfo(selection, "ready")) || readHostSelectionSnapshot() !== nativeSelection)) return {
|
|
12295
|
+
selection: null,
|
|
12296
|
+
cellTarget: null,
|
|
12297
|
+
tableCellSelection: null,
|
|
12298
|
+
paintedTarget: null
|
|
12299
|
+
};
|
|
12300
|
+
}
|
|
12149
12301
|
return {
|
|
12150
|
-
selection
|
|
12302
|
+
selection,
|
|
12151
12303
|
cellTarget,
|
|
12152
|
-
tableCellSelection
|
|
12304
|
+
tableCellSelection,
|
|
12305
|
+
paintedTarget
|
|
12153
12306
|
};
|
|
12154
12307
|
};
|
|
12155
12308
|
const waitForSelectionSettle = () => new Promise((resolve) => setTimeout(resolve, 16));
|
|
@@ -12167,7 +12320,7 @@ function createSuperDocUI(options) {
|
|
|
12167
12320
|
break;
|
|
12168
12321
|
}
|
|
12169
12322
|
if (selectionRead?.selection && !selectionRead.selection.empty && key !== painter.sourceSelectionKey) {
|
|
12170
|
-
await applyFormatPainter(selectionRead.selection, selectionRead.cellTarget, selectionRead.tableCellSelection);
|
|
12323
|
+
await applyFormatPainter(selectionRead.selection, selectionRead.cellTarget, selectionRead.tableCellSelection, selectionRead.paintedTarget);
|
|
12171
12324
|
return;
|
|
12172
12325
|
}
|
|
12173
12326
|
if (painter.snapshot?.paragraph) {
|
|
@@ -12175,10 +12328,10 @@ function createSuperDocUI(options) {
|
|
|
12175
12328
|
const caretSel = caretRead.selection;
|
|
12176
12329
|
if (!caretSel) return;
|
|
12177
12330
|
if (selectionKey(caretSel) === painter.sourceSelectionKey) return;
|
|
12178
|
-
await applyFormatPainter(caretSel, caretRead.cellTarget, caretRead.tableCellSelection);
|
|
12331
|
+
await applyFormatPainter(caretSel, caretRead.cellTarget, caretRead.tableCellSelection, caretRead.paintedTarget);
|
|
12179
12332
|
}
|
|
12180
12333
|
};
|
|
12181
|
-
const applyFormatPainter = async (selection, cellTarget, tableCellSelection) => {
|
|
12334
|
+
const applyFormatPainter = async (selection, cellTarget, tableCellSelection, paintedTarget) => {
|
|
12182
12335
|
const snap = painter.snapshot;
|
|
12183
12336
|
if (!snap) {
|
|
12184
12337
|
if (painter.mode === "armed") exitFormatPainter();
|
|
@@ -12196,7 +12349,7 @@ function createSuperDocUI(options) {
|
|
|
12196
12349
|
return;
|
|
12197
12350
|
}
|
|
12198
12351
|
const selTarget = selection.target;
|
|
12199
|
-
const selectionTarget = cellTarget ?? selection.selectionTarget;
|
|
12352
|
+
const selectionTarget = cellTarget ?? paintedTarget ?? selection.selectionTarget;
|
|
12200
12353
|
const selectionIsEmpty = selection.empty === true;
|
|
12201
12354
|
const segments = Array.isArray(selTarget?.segments) ? selTarget.segments : [];
|
|
12202
12355
|
const targetStory = selTarget?.story;
|
|
@@ -12206,7 +12359,11 @@ function createSuperDocUI(options) {
|
|
|
12206
12359
|
const node = (await readBlockNode(paragraphTarget(segment.blockId, targetStory)))?.node;
|
|
12207
12360
|
const para = node ? getParagraphLikeData(node) : null;
|
|
12208
12361
|
const runs = Array.isArray(para?.inlines) ? para.inlines : [];
|
|
12209
|
-
for (const props of sliceRunProps(runs, segment.range)) for (const key of Object.keys(sdRunPropsToInlineRunPatch(props)))
|
|
12362
|
+
for (const props of sliceRunProps(runs, segment.range)) for (const key of Object.keys(sdRunPropsToInlineRunPatch(props))) {
|
|
12363
|
+
const fontAlias = key === "rFonts" ? "fontFamily" : key === "fontFamily" ? "rFonts" : null;
|
|
12364
|
+
const capturedFontAlias = fontAlias && (fontAlias in inline || snap.mixedInlineKeys.includes(fontAlias));
|
|
12365
|
+
if (!(key in inline) && !snap.mixedInlineKeys.includes(key) && !capturedFontAlias) inline[key] = FORMAT_PAINTER_BOOLEAN_KEYS.has(key) ? false : null;
|
|
12366
|
+
}
|
|
12210
12367
|
}
|
|
12211
12368
|
if (disposed || painter.snapshot !== snap || getEditor() !== ownerEditor || ownerEditor?.doc !== ownerDoc || readDocumentMode() !== ownerMode) return;
|
|
12212
12369
|
}
|
|
@@ -12434,13 +12591,16 @@ function createSuperDocUI(options) {
|
|
|
12434
12591
|
const snapshot = selectionSub.get();
|
|
12435
12592
|
if (snapshot.empty) return null;
|
|
12436
12593
|
const cells = currentCellSelectionTarget();
|
|
12594
|
+
const painted = cells ? null : currentUnrepresentableSelectionTarget(snapshot);
|
|
12595
|
+
const hostSelection = selectionHostSnapshots.get(snapshot);
|
|
12596
|
+
if ((cells || painted || hostSelection && !snapshot.selectionTarget) && (!hostSelection || readHostSelectionSnapshot() !== hostSelection)) return null;
|
|
12437
12597
|
if (!snapshot.target && !snapshot.selectionTarget && !cells) return null;
|
|
12438
12598
|
const capture = {
|
|
12439
12599
|
...snapshot,
|
|
12440
12600
|
capturedAt: Date.now(),
|
|
12441
|
-
...cells ? { _tableCellSelectionTarget: cells } : {}
|
|
12601
|
+
...cells ? { _tableCellSelectionTarget: cells } : {},
|
|
12602
|
+
...painted ? { _paintedSelectionTarget: painted } : {}
|
|
12442
12603
|
};
|
|
12443
|
-
const hostSelection = selectionHostSnapshots.get(snapshot);
|
|
12444
12604
|
if (hostSelection) selectionHostSnapshots.set(capture, hostSelection);
|
|
12445
12605
|
return capture;
|
|
12446
12606
|
},
|
|
@@ -12466,7 +12626,13 @@ function createSuperDocUI(options) {
|
|
|
12466
12626
|
ok: false,
|
|
12467
12627
|
reason: SUPERDOC_UI_REASONS.targetUnresolved
|
|
12468
12628
|
});
|
|
12469
|
-
const
|
|
12629
|
+
const hasPaintedTarget = "_paintedSelectionTarget" in capture;
|
|
12630
|
+
const paintedTarget = hasPaintedTarget ? capturedTableCellTarget(capture._paintedSelectionTarget) : null;
|
|
12631
|
+
if (hasPaintedTarget && !paintedTarget) return done({
|
|
12632
|
+
ok: false,
|
|
12633
|
+
reason: SUPERDOC_UI_REASONS.targetUnresolved
|
|
12634
|
+
});
|
|
12635
|
+
const target = cellTarget ?? paintedTarget ?? selectionTargetForRestore(capture);
|
|
12470
12636
|
if (!target) return done({
|
|
12471
12637
|
ok: false,
|
|
12472
12638
|
reason: SUPERDOC_UI_REASONS.targetUnresolved
|
|
@@ -12479,7 +12645,7 @@ function createSuperDocUI(options) {
|
|
|
12479
12645
|
reason: resolved.reason
|
|
12480
12646
|
});
|
|
12481
12647
|
try {
|
|
12482
|
-
return done(normalizeHostSelectionApplyResult(hostMethod(resolved.helper, "apply")?.(target, ...cellTarget ? [{ tableCells: true }] : [])));
|
|
12648
|
+
return done(normalizeHostSelectionApplyResult(hostMethod(resolved.helper, "apply")?.(target, ...cellTarget ? [{ tableCells: true }] : paintedTarget ? [{ offsetSpace: "selection" }] : [])));
|
|
12483
12649
|
} catch {
|
|
12484
12650
|
return done({
|
|
12485
12651
|
ok: false,
|
|
@@ -12898,6 +13064,10 @@ function createSuperDocUI(options) {
|
|
|
12898
13064
|
};
|
|
12899
13065
|
const commentsSub = sliceHandle((s) => s.comments);
|
|
12900
13066
|
const commentsSnap = directorySnapshotHandle(commentsSub, select((s) => computeCommentsDirectorySnapshot(s.selection, s.comments)), "comments");
|
|
13067
|
+
documentResetHooks.push(() => {
|
|
13068
|
+
setExplicitActiveChange(null);
|
|
13069
|
+
explicitActiveCommentId = null;
|
|
13070
|
+
});
|
|
12901
13071
|
const comments = {
|
|
12902
13072
|
get: commentsSnap.get,
|
|
12903
13073
|
getSnapshot: commentsSnap.getSnapshot,
|
|
@@ -12991,6 +13161,7 @@ function createSuperDocUI(options) {
|
|
|
12991
13161
|
setActive: (commentId) => {
|
|
12992
13162
|
if (commentId == null) {
|
|
12993
13163
|
explicitActiveCommentId = null;
|
|
13164
|
+
mirrorReviewFocusToHost("comment", null);
|
|
12994
13165
|
recompute();
|
|
12995
13166
|
return true;
|
|
12996
13167
|
}
|
|
@@ -13003,7 +13174,9 @@ function createSuperDocUI(options) {
|
|
|
13003
13174
|
const resolvedId = resolveActiveCommentId(items, commentId);
|
|
13004
13175
|
if (!resolvedId) return false;
|
|
13005
13176
|
if (!items.some((entry) => readEntityId(entry) === resolvedId)) return false;
|
|
13177
|
+
setExplicitActiveChange(null);
|
|
13006
13178
|
explicitActiveCommentId = resolvedId;
|
|
13179
|
+
mirrorReviewFocusToHost("comment", { id: resolvedId });
|
|
13007
13180
|
recompute();
|
|
13008
13181
|
return true;
|
|
13009
13182
|
},
|
|
@@ -13063,7 +13236,7 @@ function createSuperDocUI(options) {
|
|
|
13063
13236
|
};
|
|
13064
13237
|
const navigateAndScrollCurrentRequest = async (step, requestedAtInvalidation) => {
|
|
13065
13238
|
if (queuedTrackChangeNavigationInvalidation !== requestedAtInvalidation) return { success: false };
|
|
13066
|
-
const
|
|
13239
|
+
const previousFocus = readReviewFocus();
|
|
13067
13240
|
const activeId = navigateTrackChange(step, { invalidateQueuedNavigation: false });
|
|
13068
13241
|
if (activeId == null) return { success: false };
|
|
13069
13242
|
const optimisticActiveChange = explicitActiveChange;
|
|
@@ -13071,7 +13244,7 @@ function createSuperDocUI(options) {
|
|
|
13071
13244
|
const isCurrent = () => queuedTrackChangeNavigationInvalidation === requestedAtInvalidation && explicitActiveChange === optimisticActiveChange && explicitActiveChangeRevision === optimisticRevision;
|
|
13072
13245
|
const rollback = () => {
|
|
13073
13246
|
if (!isCurrent()) return;
|
|
13074
|
-
|
|
13247
|
+
restoreReviewFocus(previousFocus);
|
|
13075
13248
|
recompute();
|
|
13076
13249
|
};
|
|
13077
13250
|
if (optimisticActiveChange) pendingTrackChangeRevealFocuses.add(optimisticActiveChange);
|
|
@@ -13091,10 +13264,8 @@ function createSuperDocUI(options) {
|
|
|
13091
13264
|
shouldContinue: isCurrent
|
|
13092
13265
|
});
|
|
13093
13266
|
if (!isCurrent()) return { success: false };
|
|
13094
|
-
if (!result.ok && result.reason !== SUPERDOC_UI_REASONS.targetNotVisible)
|
|
13095
|
-
|
|
13096
|
-
mirrorTrackedChangeFocusToHost(previousActiveChange);
|
|
13097
|
-
} else {
|
|
13267
|
+
if (!result.ok && result.reason !== SUPERDOC_UI_REASONS.targetNotVisible) rollback();
|
|
13268
|
+
else {
|
|
13098
13269
|
if (result.ok) await restampVisibleTrackedChangeCarrierAliases(activeId);
|
|
13099
13270
|
if (!isCurrent()) return { success: false };
|
|
13100
13271
|
mirrorTrackedChangeFocusToHost(optimisticActiveChange);
|
|
@@ -13225,7 +13396,7 @@ function createSuperDocUI(options) {
|
|
|
13225
13396
|
const matchingRow = matchStory ? loadedItems.find((item) => entityRowMatchesRequest(item, publicId, matchStory)) : loadedItems.find((item) => readEntityId(item) === publicId);
|
|
13226
13397
|
const story = matchStory ? requestedStory : readEntityRequestStory(matchingRow);
|
|
13227
13398
|
const importedId = deriveTrackedChangeImportedId(matchingRow);
|
|
13228
|
-
const
|
|
13399
|
+
const previousFocus = readReviewFocus();
|
|
13229
13400
|
const requestedActiveChange = {
|
|
13230
13401
|
id: publicId,
|
|
13231
13402
|
...story ? { story } : {},
|
|
@@ -13253,7 +13424,7 @@ function createSuperDocUI(options) {
|
|
|
13253
13424
|
const isCurrent = () => trackChangeRevealInvalidation === revealInvalidation && explicitActiveChange === optimisticActiveChange && explicitActiveChangeRevision === optimisticRevision;
|
|
13254
13425
|
const rollback = () => {
|
|
13255
13426
|
if (!isCurrent()) return;
|
|
13256
|
-
|
|
13427
|
+
restoreReviewFocus(previousFocus);
|
|
13257
13428
|
recompute();
|
|
13258
13429
|
};
|
|
13259
13430
|
recompute();
|
|
@@ -13267,10 +13438,8 @@ function createSuperDocUI(options) {
|
|
|
13267
13438
|
success: false,
|
|
13268
13439
|
ok: false
|
|
13269
13440
|
};
|
|
13270
|
-
if (!result.ok && result.reason !== SUPERDOC_UI_REASONS.targetNotVisible)
|
|
13271
|
-
|
|
13272
|
-
mirrorTrackedChangeFocusToHost(previousActiveChange);
|
|
13273
|
-
} else {
|
|
13441
|
+
if (!result.ok && result.reason !== SUPERDOC_UI_REASONS.targetNotVisible) rollback();
|
|
13442
|
+
else {
|
|
13274
13443
|
if (result.ok) await restampVisibleTrackedChangeCarrierAliases(publicId);
|
|
13275
13444
|
if (!isCurrent()) return {
|
|
13276
13445
|
success: false,
|
|
@@ -13605,14 +13774,14 @@ function createSuperDocUI(options) {
|
|
|
13605
13774
|
if (root instanceof HTMLElement) return root;
|
|
13606
13775
|
return null;
|
|
13607
13776
|
};
|
|
13608
|
-
const
|
|
13609
|
-
if (typeof x !== "number" || typeof y !== "number" || !Number.isFinite(x) || !Number.isFinite(y)) return
|
|
13777
|
+
const pointHitElements = (x, y) => {
|
|
13778
|
+
if (typeof x !== "number" || typeof y !== "number" || !Number.isFinite(x) || !Number.isFinite(y)) return null;
|
|
13610
13779
|
const dom = globalThis.document;
|
|
13611
|
-
if (!dom || typeof dom.elementFromPoint !== "function") return
|
|
13780
|
+
if (!dom || typeof dom.elementFromPoint !== "function") return null;
|
|
13612
13781
|
const container = resolveVisibleHost();
|
|
13613
|
-
if (!container) return
|
|
13782
|
+
if (!container) return null;
|
|
13614
13783
|
const startEl = dom.elementFromPoint(x, y);
|
|
13615
|
-
if (!startEl || !container.contains(startEl)) return
|
|
13784
|
+
if (!startEl || !container.contains(startEl)) return null;
|
|
13616
13785
|
const primaryEls = [startEl];
|
|
13617
13786
|
const addPrimaryEl = (el) => {
|
|
13618
13787
|
if (el && container.contains(el) && !primaryEls.includes(el)) primaryEls.push(el);
|
|
@@ -13627,6 +13796,17 @@ function createSuperDocUI(options) {
|
|
|
13627
13796
|
}
|
|
13628
13797
|
for (const el of stacked) addPrimaryEl(el);
|
|
13629
13798
|
}
|
|
13799
|
+
return {
|
|
13800
|
+
container,
|
|
13801
|
+
elements: primaryEls,
|
|
13802
|
+
x,
|
|
13803
|
+
y
|
|
13804
|
+
};
|
|
13805
|
+
};
|
|
13806
|
+
const pointEntityHits = (x, y) => {
|
|
13807
|
+
const point = pointHitElements(x, y);
|
|
13808
|
+
if (!point) return [];
|
|
13809
|
+
const { container, elements: primaryEls } = point;
|
|
13630
13810
|
const markerEls = [];
|
|
13631
13811
|
const addMarkerEl = (el) => {
|
|
13632
13812
|
if (el && container.contains(el) && !markerEls.includes(el) && !primaryEls.includes(el)) markerEls.push(el);
|
|
@@ -13640,7 +13820,7 @@ function createSuperDocUI(options) {
|
|
|
13640
13820
|
} catch {
|
|
13641
13821
|
return false;
|
|
13642
13822
|
}
|
|
13643
|
-
return rect != null && x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;
|
|
13823
|
+
return rect != null && point.x >= rect.left && point.x <= rect.right && point.y >= rect.top && point.y <= rect.bottom;
|
|
13644
13824
|
};
|
|
13645
13825
|
for (const el of primaryEls) {
|
|
13646
13826
|
const queryAll = el.querySelectorAll;
|
|
@@ -13664,6 +13844,18 @@ function createSuperDocUI(options) {
|
|
|
13664
13844
|
const seen = /* @__PURE__ */ new Set();
|
|
13665
13845
|
const hits = [];
|
|
13666
13846
|
for (const hit of rawHits) {
|
|
13847
|
+
if (hit.type === "decoration") {
|
|
13848
|
+
const owner = decorationOwnerForProvider(hit.id);
|
|
13849
|
+
if (!owner) continue;
|
|
13850
|
+
const key = `decoration:${owner.id}`;
|
|
13851
|
+
if (seen.has(key)) continue;
|
|
13852
|
+
seen.add(key);
|
|
13853
|
+
hits.push({
|
|
13854
|
+
type: "decoration",
|
|
13855
|
+
id: owner.id
|
|
13856
|
+
});
|
|
13857
|
+
continue;
|
|
13858
|
+
}
|
|
13667
13859
|
if (hit.type !== "trackedChange") {
|
|
13668
13860
|
const layoutStory = hit.type === "contentControl" ? layoutStoryDatasetToStoryLocator(hit.story) : void 0;
|
|
13669
13861
|
const story = hit.type === "contentControl" ? isTextboxStory(layoutStory) ? layoutStory : storyKeyToStoryLocator(hit.storyKey) ?? layoutStory : void 0;
|
|
@@ -13819,6 +14011,149 @@ function createSuperDocUI(options) {
|
|
|
13819
14011
|
if (status !== "ready") return { reason: "not-ready" };
|
|
13820
14012
|
return value ? { target: value } : { reason: "unresolved" };
|
|
13821
14013
|
};
|
|
14014
|
+
const liveDecorations = /* @__PURE__ */ new Map();
|
|
14015
|
+
const decorationOwnerForProvider = (providerId) => {
|
|
14016
|
+
const owner = currentHostVisuals()?.providerOwner?.(providerId);
|
|
14017
|
+
return isPlainObject(owner) && typeof owner.id === "string" ? owner : null;
|
|
14018
|
+
};
|
|
14019
|
+
const currentHostVisuals = () => getEditor()?.visuals ?? null;
|
|
14020
|
+
const decorationListeners = /* @__PURE__ */ new Set();
|
|
14021
|
+
let detachDecorationPointer = null;
|
|
14022
|
+
let hoveredDecorations = [];
|
|
14023
|
+
let lastPointer = {
|
|
14024
|
+
clientX: 0,
|
|
14025
|
+
clientY: 0
|
|
14026
|
+
};
|
|
14027
|
+
const decorationIdsAt = (x, y) => {
|
|
14028
|
+
const point = pointHitElements(x, y);
|
|
14029
|
+
if (!point) return [];
|
|
14030
|
+
const ids = /* @__PURE__ */ new Set();
|
|
14031
|
+
for (const element of point.elements) for (const provider of collectDecorationProvidersFromChain(element, point.container)) {
|
|
14032
|
+
const owner = decorationOwnerForProvider(provider);
|
|
14033
|
+
if (owner) ids.add(owner.id);
|
|
14034
|
+
}
|
|
14035
|
+
return [...ids];
|
|
14036
|
+
};
|
|
14037
|
+
const decorationData = (id) => {
|
|
14038
|
+
const owner = currentHostVisuals()?.ownerById?.(id);
|
|
14039
|
+
return isPlainObject(owner?.data) ? owner.data : void 0;
|
|
14040
|
+
};
|
|
14041
|
+
const emitDecorationEvent = (type, decoration, point) => {
|
|
14042
|
+
const payload = {
|
|
14043
|
+
type,
|
|
14044
|
+
id: decoration.id,
|
|
14045
|
+
...decoration.data ? { data: decoration.data } : {},
|
|
14046
|
+
clientX: point.clientX,
|
|
14047
|
+
clientY: point.clientY
|
|
14048
|
+
};
|
|
14049
|
+
for (const listener of Array.from(decorationListeners)) safeCall(() => listener(payload), void 0);
|
|
14050
|
+
};
|
|
14051
|
+
const leaveHoveredDecorations = (onlyId) => {
|
|
14052
|
+
const leaving = hoveredDecorations.filter((decoration) => onlyId === void 0 || decoration.id === onlyId);
|
|
14053
|
+
hoveredDecorations = hoveredDecorations.filter((decoration) => !leaving.includes(decoration));
|
|
14054
|
+
for (const decoration of leaving) emitDecorationEvent("hover-leave", decoration, lastPointer);
|
|
14055
|
+
};
|
|
14056
|
+
const attachDecorationPointer = () => {
|
|
14057
|
+
if (detachDecorationPointer || decorationListeners.size === 0) return;
|
|
14058
|
+
const host = resolveVisibleHost();
|
|
14059
|
+
if (!host) return;
|
|
14060
|
+
const onClick = (event) => {
|
|
14061
|
+
for (const id of decorationIdsAt(event.clientX, event.clientY)) emitDecorationEvent("click", {
|
|
14062
|
+
id,
|
|
14063
|
+
data: decorationData(id)
|
|
14064
|
+
}, event);
|
|
14065
|
+
};
|
|
14066
|
+
const onMove = (event) => {
|
|
14067
|
+
lastPointer = {
|
|
14068
|
+
clientX: event.clientX,
|
|
14069
|
+
clientY: event.clientY
|
|
14070
|
+
};
|
|
14071
|
+
const nextIds = decorationIdsAt(event.clientX, event.clientY);
|
|
14072
|
+
const leaving = hoveredDecorations.filter((decoration) => !nextIds.includes(decoration.id));
|
|
14073
|
+
const kept = hoveredDecorations.filter((decoration) => nextIds.includes(decoration.id));
|
|
14074
|
+
const entering = nextIds.filter((id) => !kept.some((decoration) => decoration.id === id)).map((id) => ({
|
|
14075
|
+
id,
|
|
14076
|
+
data: decorationData(id)
|
|
14077
|
+
}));
|
|
14078
|
+
hoveredDecorations = [...kept, ...entering];
|
|
14079
|
+
for (const decoration of leaving) emitDecorationEvent("hover-leave", decoration, event);
|
|
14080
|
+
for (const decoration of entering) emitDecorationEvent("hover-enter", decoration, event);
|
|
14081
|
+
};
|
|
14082
|
+
const onLeave = (event) => {
|
|
14083
|
+
lastPointer = {
|
|
14084
|
+
clientX: event.clientX,
|
|
14085
|
+
clientY: event.clientY
|
|
14086
|
+
};
|
|
14087
|
+
leaveHoveredDecorations();
|
|
14088
|
+
};
|
|
14089
|
+
host.addEventListener("click", onClick);
|
|
14090
|
+
host.addEventListener("pointermove", onMove);
|
|
14091
|
+
host.addEventListener("pointerleave", onLeave);
|
|
14092
|
+
detachDecorationPointer = () => {
|
|
14093
|
+
host.removeEventListener("click", onClick);
|
|
14094
|
+
host.removeEventListener("pointermove", onMove);
|
|
14095
|
+
host.removeEventListener("pointerleave", onLeave);
|
|
14096
|
+
leaveHoveredDecorations();
|
|
14097
|
+
detachDecorationPointer = null;
|
|
14098
|
+
};
|
|
14099
|
+
};
|
|
14100
|
+
const subscribeDecorationPointer = (listener) => {
|
|
14101
|
+
if (disposed) throw new Error("ui.decorations.subscribe called on a destroyed UI controller.");
|
|
14102
|
+
decorationListeners.add(listener);
|
|
14103
|
+
attachDecorationPointer();
|
|
14104
|
+
return () => {
|
|
14105
|
+
decorationListeners.delete(listener);
|
|
14106
|
+
if (decorationListeners.size === 0) detachDecorationPointer?.();
|
|
14107
|
+
};
|
|
14108
|
+
};
|
|
14109
|
+
documentResetHooks.push(() => {
|
|
14110
|
+
leaveHoveredDecorations();
|
|
14111
|
+
const current = currentHostVisuals();
|
|
14112
|
+
for (const [handle, owner] of Array.from(liveDecorations)) if (owner.visuals !== current || owner.generation !== current.generation()) handle.dispose();
|
|
14113
|
+
});
|
|
14114
|
+
activeEditorResetHooks.push(() => {
|
|
14115
|
+
detachDecorationPointer?.();
|
|
14116
|
+
attachDecorationPointer();
|
|
14117
|
+
});
|
|
14118
|
+
const createDecorationsHandle = (track) => ({
|
|
14119
|
+
subscribe: (listener) => {
|
|
14120
|
+
const unsubscribe = subscribeDecorationPointer(listener);
|
|
14121
|
+
track?.({ dispose: unsubscribe });
|
|
14122
|
+
return unsubscribe;
|
|
14123
|
+
},
|
|
14124
|
+
highlight: (id, options) => {
|
|
14125
|
+
if (disposed) throw new Error("ui.decorations.highlight called on a destroyed UI controller.");
|
|
14126
|
+
const visuals = currentHostVisuals();
|
|
14127
|
+
if (!visuals) throw new Error("ui.decorations.highlight requires a ready document.");
|
|
14128
|
+
const inner = visuals.highlight(id, options);
|
|
14129
|
+
let handleDisposed = false;
|
|
14130
|
+
const handle = {
|
|
14131
|
+
id: inner.id,
|
|
14132
|
+
replace: (targets) => inner.replace(targets),
|
|
14133
|
+
add: (targets) => inner.add(targets),
|
|
14134
|
+
clear: () => {
|
|
14135
|
+
if (handleDisposed) return;
|
|
14136
|
+
inner.clear();
|
|
14137
|
+
leaveHoveredDecorations(inner.id);
|
|
14138
|
+
},
|
|
14139
|
+
invalidate: () => inner.invalidate(),
|
|
14140
|
+
dispose: () => {
|
|
14141
|
+
if (handleDisposed) return;
|
|
14142
|
+
handleDisposed = true;
|
|
14143
|
+
liveDecorations.delete(handle);
|
|
14144
|
+
inner.dispose();
|
|
14145
|
+
leaveHoveredDecorations(inner.id);
|
|
14146
|
+
}
|
|
14147
|
+
};
|
|
14148
|
+
liveDecorations.set(handle, {
|
|
14149
|
+
visuals,
|
|
14150
|
+
generation: visuals.generation()
|
|
14151
|
+
});
|
|
14152
|
+
track?.(handle);
|
|
14153
|
+
return handle;
|
|
14154
|
+
}
|
|
14155
|
+
});
|
|
14156
|
+
const decorations = createDecorationsHandle();
|
|
13822
14157
|
const viewport = {
|
|
13823
14158
|
getRects: async (input) => {
|
|
13824
14159
|
const initialHost = getHost();
|
|
@@ -14910,6 +15245,7 @@ function createSuperDocUI(options) {
|
|
|
14910
15245
|
const createScope = () => {
|
|
14911
15246
|
const scopeUnsubs = [];
|
|
14912
15247
|
return {
|
|
15248
|
+
decorations: createDecorationsHandle((handle) => scopeUnsubs.push(() => handle.dispose())),
|
|
14913
15249
|
select: (selector, equality) => {
|
|
14914
15250
|
const sub = select(selector, equality);
|
|
14915
15251
|
return {
|
|
@@ -14930,6 +15266,9 @@ function createSuperDocUI(options) {
|
|
|
14930
15266
|
if (disposed) return;
|
|
14931
15267
|
watermark.destroy();
|
|
14932
15268
|
clearContentControlHighlight();
|
|
15269
|
+
for (const handle of Array.from(liveDecorations.keys())) handle.dispose();
|
|
15270
|
+
detachDecorationPointer?.();
|
|
15271
|
+
decorationListeners.clear();
|
|
14933
15272
|
disposed = true;
|
|
14934
15273
|
completedFallbackSearch = null;
|
|
14935
15274
|
if (searchRefreshTimer !== null) clearTimeout(searchRefreshTimer);
|
|
@@ -15012,6 +15351,7 @@ function createSuperDocUI(options) {
|
|
|
15012
15351
|
zoom,
|
|
15013
15352
|
document: documentHandle,
|
|
15014
15353
|
viewport,
|
|
15354
|
+
decorations,
|
|
15015
15355
|
metadata,
|
|
15016
15356
|
tables,
|
|
15017
15357
|
search,
|
|
@@ -15230,4 +15570,4 @@ function commandIsActive(descriptor, selection) {
|
|
|
15230
15570
|
return descriptor.activeMark ? selection.activeMarks.includes(descriptor.activeMark) : false;
|
|
15231
15571
|
}
|
|
15232
15572
|
//#endregion
|
|
15233
|
-
export {
|
|
15573
|
+
export { createInteractionHistory as _, registerFirstPartyCommandMutation as a, recordInteraction as b, applyV2CommentInvalidationFromMutation as c, createImageFilePicker as d, resolveImageSrc as f, closeInteractionHistory as g, DOM_CLASS_NAMES as h, readFirstPartyPageNumbers as i, getV2TrackedChangeMutationImpact as l, isSyntheticTrackedChangeCommentLaneItem as m, executeFirstPartyCommandAsync as n, isRecord as o, shallowEqual as p, executeFirstPartyShortcutAsync as r, BUILT_IN_COMMAND_IDS as s, createSuperDocUI as t, isPlainObject as u, getWorkflowRecording as v, isWorkflowRecordingEnabled as y };
|