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