superdoc 2.12.0-next.9 → 2.12.0
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/{FindReplaceSurface-40AnrqWk.es.js → FindReplaceSurface-CVKgivXi.es.js} +8 -2
- package/dist/chunks/{FindReplaceSurface-0p7EtMZh.cjs → FindReplaceSurface-qi9OhbwN.cjs} +8 -2
- package/dist/chunks/{create-super-doc-ui-CBFGggZ2.cjs → create-super-doc-ui-BWWWNPP8.cjs} +180 -84
- package/dist/chunks/{create-super-doc-ui-C-AuEM9F.es.js → create-super-doc-ui-FnwgTkUv.es.js} +180 -84
- package/dist/collaboration-upgrade-engine.cjs +1 -1
- package/dist/collaboration-upgrade-engine.es.js +1 -1
- package/dist/layout-engine/contracts/src/column-layout.d.ts +58 -1
- package/dist/layout-engine/contracts/src/graphic-placement.d.ts +3 -0
- package/dist/layout-engine/contracts/src/index.d.ts +16 -2
- package/dist/layout-engine/layout-engine/src/column-balancing.d.ts +11 -7
- package/dist/layout-engine/layout-engine/src/layout-paragraph.d.ts +2 -6
- package/dist/layout-engine/painters/dom/src/derived-run-text-plane.d.ts +9 -0
- package/dist/layout-engine/painters/dom/src/index.d.ts +1 -0
- package/dist/layout-engine/painters/dom/src/page-content.d.ts +3 -1
- package/dist/layout-engine/painters/dom/src/persistent-page-surface.d.ts +2 -0
- package/dist/layout-engine/painters/dom/src/renderer.d.ts +9 -16
- package/dist/public/ui-react.cjs +18 -1
- package/dist/public/ui-react.es.js +18 -2
- package/dist/public/ui-vue.cjs +18 -1
- package/dist/public/ui-vue.es.js +18 -2
- package/dist/public/ui.cjs +1 -1
- package/dist/public/ui.es.js +1 -1
- package/dist/style.css +40 -40
- package/dist/style.layered.css +40 -40
- package/dist/superdoc/src/core/types/index.d.ts +20 -12
- package/dist/superdoc/src/public/ui/react.d.ts +3 -1
- package/dist/superdoc/src/public/ui/types.d.ts +67 -9
- package/dist/superdoc/src/public/ui/vue.d.ts +3 -1
- package/dist/superdoc/src/public/ui-react.d.cts +1 -0
- package/dist/superdoc/src/public/ui-react.d.ts +1 -1
- package/dist/superdoc/src/public/ui-vue.d.cts +1 -0
- package/dist/superdoc/src/public/ui-vue.d.ts +1 -1
- package/dist/superdoc.cjs +138 -12
- package/dist/superdoc.es.js +138 -12
- package/dist-cdn/style.layered.css +1 -1
- package/dist-cdn/superdoc.min.css +1 -1
- package/dist-cdn/superdoc.min.js +37 -37
- package/package.json +2 -2
|
@@ -920,33 +920,49 @@ export interface TrackChangesHandle extends SnapshotSubscribable<TrackChangesSli
|
|
|
920
920
|
* already identifies one occurrence, anywhere in the document). A
|
|
921
921
|
* `{ id, story }` record (e.g. a {@link getAt}/{@link setActive} hit) is
|
|
922
922
|
* also accepted for convenience, so a hit can be passed straight through.
|
|
923
|
-
*
|
|
923
|
+
* Returns the immediate routed result. Use {@link acceptAsync} when later UI
|
|
924
|
+
* depends on the settled document operation.
|
|
924
925
|
*/
|
|
925
926
|
accept(changeId: string | {
|
|
926
927
|
id: string;
|
|
927
928
|
story?: unknown;
|
|
928
929
|
}): CommandExecutionResult;
|
|
930
|
+
/** Accept a change and resolve after the document operation settles. */
|
|
931
|
+
acceptAsync(changeId: string | {
|
|
932
|
+
id: string;
|
|
933
|
+
story?: unknown;
|
|
934
|
+
}): Promise<CommandExecutionResult>;
|
|
929
935
|
/**
|
|
930
936
|
* Reject a change. The id is sufficient on its own (a tracked-change id
|
|
931
937
|
* already identifies one occurrence, anywhere in the document). A
|
|
932
938
|
* `{ id, story }` record (e.g. a {@link getAt}/{@link setActive} hit) is
|
|
933
939
|
* also accepted for convenience, so a hit can be passed straight through.
|
|
934
|
-
*
|
|
940
|
+
* Returns the immediate routed result. Use {@link rejectAsync} when later UI
|
|
941
|
+
* depends on the settled document operation.
|
|
935
942
|
*/
|
|
936
943
|
reject(changeId: string | {
|
|
937
944
|
id: string;
|
|
938
945
|
story?: unknown;
|
|
939
946
|
}): CommandExecutionResult;
|
|
947
|
+
/** Reject a change and resolve after the document operation settles. */
|
|
948
|
+
rejectAsync(changeId: string | {
|
|
949
|
+
id: string;
|
|
950
|
+
story?: unknown;
|
|
951
|
+
}): Promise<CommandExecutionResult>;
|
|
940
952
|
/**
|
|
941
953
|
* Accept every active tracked change. Returns the Document API receipt, or
|
|
942
954
|
* `false` when bulk decisions are unavailable / disabled on the host.
|
|
943
955
|
*/
|
|
944
956
|
acceptAll(): CommandExecutionResult;
|
|
957
|
+
/** Accept every active tracked change and resolve after the operation settles. */
|
|
958
|
+
acceptAllAsync(): Promise<CommandExecutionResult>;
|
|
945
959
|
/**
|
|
946
960
|
* Reject every active tracked change. Returns the Document API receipt, or
|
|
947
961
|
* `false` when bulk decisions are unavailable / disabled on the host.
|
|
948
962
|
*/
|
|
949
963
|
rejectAll(): CommandExecutionResult;
|
|
964
|
+
/** Reject every active tracked change and resolve after the operation settles. */
|
|
965
|
+
rejectAllAsync(): Promise<CommandExecutionResult>;
|
|
950
966
|
/**
|
|
951
967
|
* Move focus to the next tracked change in document order (relative to the
|
|
952
968
|
* active change). Returns the id that became active, or `null` when there are
|
|
@@ -1005,12 +1021,33 @@ export interface TrackChangesHandle extends SnapshotSubscribable<TrackChangesSli
|
|
|
1005
1021
|
/**
|
|
1006
1022
|
* Scroll the tracked-change anchor into view through the host navigation
|
|
1007
1023
|
* surface. Resolves with both v1/main `{ success }` and v2 `{ ok, reason? }`
|
|
1008
|
-
* fields.
|
|
1024
|
+
* fields. A bare id resolves its story from the loaded rows; a
|
|
1025
|
+
* `{ id, story }` record pins the occurrence when the same id repeats across
|
|
1026
|
+
* the body and a footnote, header, or footer.
|
|
1009
1027
|
*/
|
|
1010
|
-
scrollTo(
|
|
1028
|
+
scrollTo(input: string | {
|
|
1029
|
+
id: string;
|
|
1030
|
+
story?: unknown;
|
|
1031
|
+
}): Promise<WorkflowScrollResult>;
|
|
1011
1032
|
}
|
|
1012
1033
|
/** Content-controls handle. */
|
|
1013
1034
|
export interface ContentControlsHandle extends SnapshotSubscribable<ContentControlsSlice> {
|
|
1035
|
+
/**
|
|
1036
|
+
* Observe the document-wide content-control catalog and active field IDs.
|
|
1037
|
+
* The catalog remains requested until the returned disposer runs.
|
|
1038
|
+
*/
|
|
1039
|
+
observe(listener: (snapshot: ContentControlsSlice) => void): () => void;
|
|
1040
|
+
/**
|
|
1041
|
+
* Observe the passive content-controls slice without requesting the
|
|
1042
|
+
* document-wide catalog. Meant for consumers that only need the active
|
|
1043
|
+
* field path, such as the core active-change event bridge; a field panel
|
|
1044
|
+
* should use {@link observe}.
|
|
1045
|
+
*/
|
|
1046
|
+
observeActivePath(listener: (snapshot: ContentControlsSlice) => void): () => void;
|
|
1047
|
+
/** Event-shaped alias of {@link observe}. */
|
|
1048
|
+
subscribe(listener: (event: {
|
|
1049
|
+
snapshot: ContentControlsSlice;
|
|
1050
|
+
}) => void): () => void;
|
|
1014
1051
|
/** Read the current content-controls snapshot. */
|
|
1015
1052
|
getSnapshot(): ContentControlsSlice;
|
|
1016
1053
|
/** Read the current content-controls snapshot. */
|
|
@@ -1220,11 +1257,21 @@ export interface SearchSlice {
|
|
|
1220
1257
|
/** Whether the query is a regular expression (V2 runtime only). */
|
|
1221
1258
|
regex: boolean;
|
|
1222
1259
|
/**
|
|
1223
|
-
* Whether replace
|
|
1224
|
-
* read-only mode
|
|
1225
|
-
* truncated and cannot be fully enumerated.
|
|
1260
|
+
* Whether `replace()` can mutate the active match right now. False in
|
|
1261
|
+
* viewing / read-only mode or when replace is host-unavailable.
|
|
1226
1262
|
*/
|
|
1227
1263
|
canReplace: boolean;
|
|
1264
|
+
/**
|
|
1265
|
+
* Whether `replaceAll()` can mutate right now. Everything that disables
|
|
1266
|
+
* `canReplace` disables this too. It also requires at least one match, and
|
|
1267
|
+
* it is false for a truncated match set: when more matches exist than the
|
|
1268
|
+
* session enumerates, replacing all of them cannot be applied, while
|
|
1269
|
+
* replacing the active match still can.
|
|
1270
|
+
*
|
|
1271
|
+
* Optional here so existing implementations of the deprecated
|
|
1272
|
+
* {@link SearchHandle} keep compiling; {@link SearchSnapshot} requires it.
|
|
1273
|
+
*/
|
|
1274
|
+
canReplaceAll?: boolean;
|
|
1228
1275
|
/** Stable reason when the surface (or an action) is unavailable. */
|
|
1229
1276
|
reason?: SuperDocUIReason;
|
|
1230
1277
|
}
|
|
@@ -1232,8 +1279,10 @@ export interface SearchSlice {
|
|
|
1232
1279
|
export interface SearchSnapshot extends SearchSlice {
|
|
1233
1280
|
/** Whether the session includes pending tracked deletions in match discovery. */
|
|
1234
1281
|
includeTrackedDeletions: boolean;
|
|
1282
|
+
/** Whether `replaceAll()` can mutate right now. See {@link SearchSlice.canReplaceAll}. */
|
|
1283
|
+
canReplaceAll: boolean;
|
|
1235
1284
|
}
|
|
1236
|
-
/** Options for `
|
|
1285
|
+
/** Options for `superdoc.ui.search.find()`. */
|
|
1237
1286
|
export interface SearchQueryOptions {
|
|
1238
1287
|
/** Match uppercase and lowercase letters exactly (default: false). */
|
|
1239
1288
|
caseSensitive?: boolean;
|
|
@@ -1306,12 +1355,21 @@ export interface SearchController extends Omit<SearchHandle, keyof SnapshotSubsc
|
|
|
1306
1355
|
*/
|
|
1307
1356
|
search(query: string, options?: SearchQueryOptions): SearchSnapshot;
|
|
1308
1357
|
}
|
|
1309
|
-
/** Runtime control
|
|
1358
|
+
/** Runtime control and document context for context menus. */
|
|
1310
1359
|
export interface ContextMenuHandle {
|
|
1311
1360
|
/** Open the menu at the active selection or caret. */
|
|
1312
1361
|
open(): WorkflowActionResult;
|
|
1313
1362
|
/** Close the menu when it is open. */
|
|
1314
1363
|
close(): void;
|
|
1364
|
+
/**
|
|
1365
|
+
* Resolve the public document context at a viewport point. Coordinates use
|
|
1366
|
+
* `MouseEvent.clientX` and `MouseEvent.clientY`. This remains available when
|
|
1367
|
+
* the built-in context menu is disabled.
|
|
1368
|
+
*/
|
|
1369
|
+
contextAt(input: {
|
|
1370
|
+
x: number;
|
|
1371
|
+
y: number;
|
|
1372
|
+
}): ViewportContext;
|
|
1315
1373
|
}
|
|
1316
1374
|
/**
|
|
1317
1375
|
* Structural shape of the active editor the controller reads. Every member is
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ComputedRef, MaybeRefOrGetter, ShallowRef } from 'vue';
|
|
2
2
|
import { SliceSource } from './slice-source.js';
|
|
3
|
-
import { BorrowedSuperDocUI, CommandExecutionResult, CommandId, CommandState, CommentsSlice, ContentControlsSlice, DocumentSlice, FontFamilyOption, FontSizeOption, SelectionSlice, Subscribable, SuperDocLike, ToolbarSnapshotSlice, TrackChangesSlice, ZoomSlice } from './types.js';
|
|
3
|
+
import { BorrowedSuperDocUI, CommandExecutionResult, CommandId, CommandState, CommentsSlice, ContentControlsSlice, DocumentSlice, FontFamilyOption, FontSizeOption, SearchSnapshot, SelectionSlice, Subscribable, SuperDocLike, ToolbarSnapshotSlice, TrackChangesSlice, ZoomSlice } from './types.js';
|
|
4
4
|
/** The raw SuperDoc instance (or host stub) handed to the provider. */
|
|
5
5
|
export type SuperDocHost = SuperDocLike;
|
|
6
6
|
/**
|
|
@@ -84,6 +84,8 @@ export declare function useClearSuperDoc(): (expectedHost: SuperDocHost) => bool
|
|
|
84
84
|
export declare function useSuperDocSlice<T>(pick: (ui: BorrowedSuperDocUI) => SliceSource<T> | Subscribable<T>, initial: T): Readonly<ShallowRef<T>>;
|
|
85
85
|
/** Subscribe to the selection slice. */
|
|
86
86
|
export declare function useSuperDocSelection(): Readonly<ShallowRef<SelectionSlice>>;
|
|
87
|
+
/** Subscribe to the current Search session. */
|
|
88
|
+
export declare function useSuperDocSearch(): Readonly<ShallowRef<SearchSnapshot>>;
|
|
87
89
|
/** Subscribe to the comments slice. */
|
|
88
90
|
export declare function useSuperDocComments(): Readonly<ShallowRef<CommentsSlice>>;
|
|
89
91
|
/** Subscribe to the content-controls slice. */
|
|
@@ -14,6 +14,7 @@ export declare const useSuperDocDocument: typeof import('./ui-react.js', { with:
|
|
|
14
14
|
export declare const useSuperDocFontOptions: typeof import('./ui-react.js', { with: { "resolution-mode": "import" } }).useSuperDocFontOptions;
|
|
15
15
|
export declare const useSuperDocFontSizeOptions: typeof import('./ui-react.js', { with: { "resolution-mode": "import" } }).useSuperDocFontSizeOptions;
|
|
16
16
|
export declare const useSuperDocHost: typeof import('./ui-react.js', { with: { "resolution-mode": "import" } }).useSuperDocHost;
|
|
17
|
+
export declare const useSuperDocSearch: typeof import('./ui-react.js', { with: { "resolution-mode": "import" } }).useSuperDocSearch;
|
|
17
18
|
export declare const useSuperDocSelection: typeof import('./ui-react.js', { with: { "resolution-mode": "import" } }).useSuperDocSelection;
|
|
18
19
|
export declare const useSuperDocSlice: typeof import('./ui-react.js', { with: { "resolution-mode": "import" } }).useSuperDocSlice;
|
|
19
20
|
export declare const useSuperDocToolbar: typeof import('./ui-react.js', { with: { "resolution-mode": "import" } }).useSuperDocToolbar;
|
|
@@ -16,5 +16,5 @@
|
|
|
16
16
|
* - AIDEV-NOTE: `verify-public-facade-emit.cjs` parses this file and verifies
|
|
17
17
|
* the emitted declarations expose exactly these named exports.
|
|
18
18
|
*/
|
|
19
|
-
export { SuperDocUIProvider, useSuperDocUI, useSuperDocHost, useSetSuperDoc, useSuperDocSlice, useSuperDocSelection, useSuperDocComments, useSuperDocContentControls, useSuperDocTrackChanges, useSuperDocToolbar, useSuperDocCommand, useSuperDocDocument, useSuperDocFontOptions, useSuperDocFontSizeOptions, useSuperDocZoom, } from './ui/react.js';
|
|
19
|
+
export { SuperDocUIProvider, useSuperDocUI, useSuperDocHost, useSetSuperDoc, useSuperDocSlice, useSuperDocSelection, useSuperDocSearch, useSuperDocComments, useSuperDocContentControls, useSuperDocTrackChanges, useSuperDocToolbar, useSuperDocCommand, useSuperDocDocument, useSuperDocFontOptions, useSuperDocFontSizeOptions, useSuperDocZoom, } from './ui/react.js';
|
|
20
20
|
export type { SuperDocHost, SuperDocUIProviderProps, UseSuperDocCommandResult } from './ui/react.js';
|
|
@@ -15,6 +15,7 @@ export declare const useSuperDocDocument: typeof import('./ui-vue.js', { with: {
|
|
|
15
15
|
export declare const useSuperDocFontOptions: typeof import('./ui-vue.js', { with: { "resolution-mode": "import" } }).useSuperDocFontOptions;
|
|
16
16
|
export declare const useSuperDocFontSizeOptions: typeof import('./ui-vue.js', { with: { "resolution-mode": "import" } }).useSuperDocFontSizeOptions;
|
|
17
17
|
export declare const useSuperDocHost: typeof import('./ui-vue.js', { with: { "resolution-mode": "import" } }).useSuperDocHost;
|
|
18
|
+
export declare const useSuperDocSearch: typeof import('./ui-vue.js', { with: { "resolution-mode": "import" } }).useSuperDocSearch;
|
|
18
19
|
export declare const useSuperDocSelection: typeof import('./ui-vue.js', { with: { "resolution-mode": "import" } }).useSuperDocSelection;
|
|
19
20
|
export declare const useSuperDocSlice: typeof import('./ui-vue.js', { with: { "resolution-mode": "import" } }).useSuperDocSlice;
|
|
20
21
|
export declare const useSuperDocToolbar: typeof import('./ui-vue.js', { with: { "resolution-mode": "import" } }).useSuperDocToolbar;
|
|
@@ -16,5 +16,5 @@
|
|
|
16
16
|
* - AIDEV-NOTE: `verify-public-facade-emit.cjs` parses this file and verifies
|
|
17
17
|
* the emitted declarations expose exactly these named exports.
|
|
18
18
|
*/
|
|
19
|
-
export { provideSuperDocUI, useSuperDocUI, useSuperDocHost, useSetSuperDoc, useClearSuperDoc, useSuperDocSlice, useSuperDocSelection, useSuperDocComments, useSuperDocContentControls, useSuperDocTrackChanges, useSuperDocToolbar, useSuperDocCommand, useSuperDocDocument, useSuperDocFontOptions, useSuperDocFontSizeOptions, useSuperDocZoom, } from './ui/vue.js';
|
|
19
|
+
export { provideSuperDocUI, useSuperDocUI, useSuperDocHost, useSetSuperDoc, useClearSuperDoc, useSuperDocSlice, useSuperDocSelection, useSuperDocSearch, useSuperDocComments, useSuperDocContentControls, useSuperDocTrackChanges, useSuperDocToolbar, useSuperDocCommand, useSuperDocDocument, useSuperDocFontOptions, useSuperDocFontSizeOptions, useSuperDocZoom, } from './ui/vue.js';
|
|
20
20
|
export type { SuperDocHost, SuperDocUIBinding, UseSuperDocCommandResult } from './ui/vue.js';
|
package/dist/superdoc.cjs
CHANGED
|
@@ -4,7 +4,7 @@ const require_blank_docx = require("./chunks/blank-docx-BuFAbRjs.cjs");
|
|
|
4
4
|
const require_eventemitter3 = require("./chunks/eventemitter3-C_TAnXOl.cjs");
|
|
5
5
|
const require_uuid = require("./chunks/uuid-BhG0ngwk.cjs");
|
|
6
6
|
const require_jszip = require("./chunks/jszip-D8mAFF-r.cjs");
|
|
7
|
-
const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-
|
|
7
|
+
const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-BWWWNPP8.cjs");
|
|
8
8
|
const require__plugin_vue_export_helper = require("./chunks/_plugin-vue_export-helper-SDR04tiH.cjs");
|
|
9
9
|
const require_constants = require("./chunks/constants-DpXuDx_g.cjs");
|
|
10
10
|
let vue = require("vue");
|
|
@@ -316,7 +316,7 @@ var shuffleArray = (array) => {
|
|
|
316
316
|
var DEFAULT_ENDPOINT = "https://ingest.superdoc.dev/v1/collect";
|
|
317
317
|
function getSuperdocVersion() {
|
|
318
318
|
try {
|
|
319
|
-
return "2.12.0
|
|
319
|
+
return "2.12.0";
|
|
320
320
|
} catch {
|
|
321
321
|
return "unknown";
|
|
322
322
|
}
|
|
@@ -10188,6 +10188,115 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10188
10188
|
const type = normalizeTrackedChangeDecisionType(comment?.trackedChangeDisplayType) ?? normalizeTrackedChangeDecisionType(comment?.trackedChangeType);
|
|
10189
10189
|
return normalizedDecision === "accept" && type === "insertion" || normalizedDecision === "reject" && type === "deletion";
|
|
10190
10190
|
};
|
|
10191
|
+
const getBodyTrackedChangeIdentityIds = (comment) => {
|
|
10192
|
+
const commentId = normalizeCommentId(comment.commentId);
|
|
10193
|
+
const canonicalId = normalizeCommentId(comment.trackedChangeCanonicalId);
|
|
10194
|
+
return [commentId, ...!(canonicalId && canonicalId !== commentId) ? [
|
|
10195
|
+
comment.importedId,
|
|
10196
|
+
canonicalId,
|
|
10197
|
+
comment.trackedChangeAnchorKey,
|
|
10198
|
+
...normalizeTrackedChangePositionAliases(comment.trackedChangePositionAliases)
|
|
10199
|
+
] : []].map((id) => normalizeCommentId(id)).filter(Boolean);
|
|
10200
|
+
};
|
|
10201
|
+
const groupBodyTrackedChangeCommentsByIdentity = (comments) => {
|
|
10202
|
+
const parents = comments.map((_, index) => index);
|
|
10203
|
+
const findRoot = (index) => {
|
|
10204
|
+
let root = index;
|
|
10205
|
+
while (parents[root] !== root) root = parents[root];
|
|
10206
|
+
while (parents[index] !== index) {
|
|
10207
|
+
const next = parents[index];
|
|
10208
|
+
parents[index] = root;
|
|
10209
|
+
index = next;
|
|
10210
|
+
}
|
|
10211
|
+
return root;
|
|
10212
|
+
};
|
|
10213
|
+
const join = (left, right) => {
|
|
10214
|
+
const leftRoot = findRoot(left);
|
|
10215
|
+
const rightRoot = findRoot(right);
|
|
10216
|
+
if (leftRoot === rightRoot) return;
|
|
10217
|
+
parents[Math.max(leftRoot, rightRoot)] = Math.min(leftRoot, rightRoot);
|
|
10218
|
+
};
|
|
10219
|
+
const identityOwner = /* @__PURE__ */ new Map();
|
|
10220
|
+
comments.forEach((comment, index) => {
|
|
10221
|
+
getBodyTrackedChangeIdentityIds(comment).forEach((identityId) => {
|
|
10222
|
+
const owner = identityOwner.get(identityId);
|
|
10223
|
+
if (owner === void 0) identityOwner.set(identityId, index);
|
|
10224
|
+
else join(index, owner);
|
|
10225
|
+
});
|
|
10226
|
+
});
|
|
10227
|
+
const groups = /* @__PURE__ */ new Map();
|
|
10228
|
+
comments.forEach((comment, index) => {
|
|
10229
|
+
const root = findRoot(index);
|
|
10230
|
+
const group = groups.get(root) ?? [];
|
|
10231
|
+
group.push(comment);
|
|
10232
|
+
groups.set(root, group);
|
|
10233
|
+
});
|
|
10234
|
+
return groups;
|
|
10235
|
+
};
|
|
10236
|
+
const mergeDuplicateBodyTrackedChangeComments = (groups) => {
|
|
10237
|
+
const duplicates = /* @__PURE__ */ new Map();
|
|
10238
|
+
groups.forEach(([survivor, ...duplicateRows]) => {
|
|
10239
|
+
if (!survivor || duplicateRows.length === 0) return;
|
|
10240
|
+
const resolvedDuplicate = duplicateRows.find((comment) => comment.resolvedTime != null);
|
|
10241
|
+
if (survivor.resolvedTime == null && resolvedDuplicate) {
|
|
10242
|
+
survivor.resolvedTime = resolvedDuplicate.resolvedTime;
|
|
10243
|
+
survivor.resolvedById = resolvedDuplicate.resolvedById;
|
|
10244
|
+
survivor.resolvedByEmail = resolvedDuplicate.resolvedByEmail;
|
|
10245
|
+
survivor.resolvedByName = resolvedDuplicate.resolvedByName;
|
|
10246
|
+
survivor.trackedChangeDecision = resolvedDuplicate.trackedChangeDecision;
|
|
10247
|
+
}
|
|
10248
|
+
survivor.trackedChangePositionAliases = normalizeTrackedChangePositionAliases([...normalizeTrackedChangePositionAliases(survivor.trackedChangePositionAliases), ...duplicateRows.flatMap((comment) => [
|
|
10249
|
+
comment.commentId,
|
|
10250
|
+
comment.importedId,
|
|
10251
|
+
comment.trackedChangeCanonicalId,
|
|
10252
|
+
...normalizeTrackedChangePositionAliases(comment.trackedChangePositionAliases)
|
|
10253
|
+
])]);
|
|
10254
|
+
duplicateRows.forEach((comment) => duplicates.set(comment, survivor));
|
|
10255
|
+
});
|
|
10256
|
+
return duplicates;
|
|
10257
|
+
};
|
|
10258
|
+
const createDroppedCommentIdMap = (duplicates) => {
|
|
10259
|
+
const droppedCommentIds = /* @__PURE__ */ new Map();
|
|
10260
|
+
duplicates.forEach((survivor, duplicate) => {
|
|
10261
|
+
const fromId = normalizeCommentId(duplicate.commentId);
|
|
10262
|
+
const toId = normalizeCommentId(survivor.commentId);
|
|
10263
|
+
if (fromId && toId) droppedCommentIds.set(fromId, toId);
|
|
10264
|
+
});
|
|
10265
|
+
return droppedCommentIds;
|
|
10266
|
+
};
|
|
10267
|
+
const remapTrackedChangeReferences = (droppedCommentIds, activeDocumentId) => {
|
|
10268
|
+
const remapSelection = (selection) => {
|
|
10269
|
+
const selectedId = normalizeCommentId(selection.value);
|
|
10270
|
+
if (selectedId && droppedCommentIds.has(selectedId)) selection.value = droppedCommentIds.get(selectedId);
|
|
10271
|
+
};
|
|
10272
|
+
remapSelection(activeComment);
|
|
10273
|
+
remapSelection(activeFloatingCommentInstanceId);
|
|
10274
|
+
commentsList.value.forEach((row) => {
|
|
10275
|
+
if (!belongsToTrackedChangeSyncDocument(row, activeDocumentId)) return;
|
|
10276
|
+
const rowIdentityUpdates = {};
|
|
10277
|
+
for (const field of [
|
|
10278
|
+
"trackedChangeThreadParentId",
|
|
10279
|
+
"trackedChangeParentId",
|
|
10280
|
+
"threadingParentCommentId",
|
|
10281
|
+
"parentCommentId"
|
|
10282
|
+
]) {
|
|
10283
|
+
const replacementId = droppedCommentIds.get(normalizeCommentId(row?.[field]));
|
|
10284
|
+
if (!replacementId) continue;
|
|
10285
|
+
row[field] = replacementId;
|
|
10286
|
+
rowIdentityUpdates[field] = replacementId;
|
|
10287
|
+
}
|
|
10288
|
+
if (Object.keys(rowIdentityUpdates).length && typeof row.updateIdentityValues === "function") row.updateIdentityValues(rowIdentityUpdates);
|
|
10289
|
+
});
|
|
10290
|
+
};
|
|
10291
|
+
const compactDuplicateBodyTrackedChangeComments = (activeDocumentId) => {
|
|
10292
|
+
const candidates = commentsList.value.filter((comment) => isBodyTrackedChangeComment(comment) && belongsToTrackedChangeSyncDocument(comment, activeDocumentId));
|
|
10293
|
+
const groups = groupBodyTrackedChangeCommentsByIdentity(candidates);
|
|
10294
|
+
const duplicates = mergeDuplicateBodyTrackedChangeComments(groups);
|
|
10295
|
+
if (!duplicates.size) return 0;
|
|
10296
|
+
commentsList.value = commentsList.value.filter((comment) => !duplicates.has(comment));
|
|
10297
|
+
remapTrackedChangeReferences(createDroppedCommentIdMap(duplicates), activeDocumentId);
|
|
10298
|
+
return duplicates.size;
|
|
10299
|
+
};
|
|
10191
10300
|
/**
|
|
10192
10301
|
* Remove tracked-change comments that no longer have a corresponding mark in the editor.
|
|
10193
10302
|
* Also removes any replies linked to those removed tracked-change threads.
|
|
@@ -10233,7 +10342,9 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10233
10342
|
if (importedId) removedIds.add(importedId);
|
|
10234
10343
|
return false;
|
|
10235
10344
|
});
|
|
10345
|
+
compactDuplicateBodyTrackedChangeComments(activeDocumentId);
|
|
10236
10346
|
restoredComments.forEach((comment) => {
|
|
10347
|
+
if (!commentsList.value.includes(comment)) return;
|
|
10237
10348
|
const payload = getCommentEventPayload(comment);
|
|
10238
10349
|
const event = {
|
|
10239
10350
|
type: COMMENT_EVENTS.UPDATE,
|
|
@@ -10823,11 +10934,14 @@ var useCommentsStore = defineStore("comments", () => {
|
|
|
10823
10934
|
} finally {
|
|
10824
10935
|
endInteractionSpan(identitySpan, trackedChangeIdentityIndex.work());
|
|
10825
10936
|
}
|
|
10826
|
-
if (!effectiveDocumentId || !pruneStale)
|
|
10827
|
-
|
|
10828
|
-
|
|
10829
|
-
|
|
10830
|
-
|
|
10937
|
+
if (!effectiveDocumentId || !pruneStale) {
|
|
10938
|
+
if (effectiveDocumentId) compactDuplicateBodyTrackedChangeComments(String(effectiveDocumentId));
|
|
10939
|
+
return {
|
|
10940
|
+
liveIds,
|
|
10941
|
+
liveAnchorKeys,
|
|
10942
|
+
appliedCount
|
|
10943
|
+
};
|
|
10944
|
+
}
|
|
10831
10945
|
pruneStaleTrackedChangeComments(liveIds, liveAnchorKeys, String(effectiveDocumentId), superdoc, { broadcastChanges: false });
|
|
10832
10946
|
return {
|
|
10833
10947
|
liveIds,
|
|
@@ -17263,6 +17377,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
|
|
|
17263
17377
|
const matchCount = (0, vue.ref)(0);
|
|
17264
17378
|
const activeMatchIndex = (0, vue.ref)(-1);
|
|
17265
17379
|
const canReplaceState = (0, vue.ref)(true);
|
|
17380
|
+
const canReplaceAllState = (0, vue.ref)(true);
|
|
17266
17381
|
const replacePending = (0, vue.ref)(false);
|
|
17267
17382
|
const ignoreDiacriticsSupported = (0, vue.ref)(true);
|
|
17268
17383
|
const regexSupported = (0, vue.ref)(false);
|
|
@@ -17277,6 +17392,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
|
|
|
17277
17392
|
});
|
|
17278
17393
|
const hasMatches = (0, vue.computed)(() => matchCount.value > 0);
|
|
17279
17394
|
const canReplaceComputed = (0, vue.computed)(() => hasMatches.value && !replacePending.value && canReplaceState.value);
|
|
17395
|
+
const canReplaceAllComputed = (0, vue.computed)(() => canReplaceComputed.value && canReplaceAllState.value);
|
|
17280
17396
|
/** @type {ReturnType<typeof setTimeout> | null} */
|
|
17281
17397
|
let debounceTimer = null;
|
|
17282
17398
|
/** @type {ReturnType<typeof setInterval> | null} */
|
|
@@ -17311,6 +17427,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
|
|
|
17311
17427
|
matchCount.value = typeof slice.total === "number" ? slice.total : 0;
|
|
17312
17428
|
activeMatchIndex.value = typeof slice.activeIndex === "number" ? slice.activeIndex : -1;
|
|
17313
17429
|
canReplaceState.value = slice.canReplace === true;
|
|
17430
|
+
canReplaceAllState.value = typeof slice.canReplaceAll === "boolean" ? slice.canReplaceAll : slice.canReplace === true;
|
|
17314
17431
|
searchError.value = slice.reason === "search-invalid-pattern" ? currentTexts.invalidPatternLabel : null;
|
|
17315
17432
|
}
|
|
17316
17433
|
function runSearch() {
|
|
@@ -17447,7 +17564,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
|
|
|
17447
17564
|
if (replacePending.value) return;
|
|
17448
17565
|
if (!hasMatches.value) return;
|
|
17449
17566
|
if (currentV2Search) {
|
|
17450
|
-
if (!canReplaceState.value) return;
|
|
17567
|
+
if (!canReplaceState.value || !canReplaceAllState.value) return;
|
|
17451
17568
|
const search = currentV2Search;
|
|
17452
17569
|
replacePending.value = true;
|
|
17453
17570
|
const finish = createReplaceContinuation(search, {
|
|
@@ -17508,6 +17625,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
|
|
|
17508
17625
|
matchCount.value = 0;
|
|
17509
17626
|
activeMatchIndex.value = -1;
|
|
17510
17627
|
canReplaceState.value = true;
|
|
17628
|
+
canReplaceAllState.value = true;
|
|
17511
17629
|
replacePending.value = false;
|
|
17512
17630
|
}
|
|
17513
17631
|
/**
|
|
@@ -17612,6 +17730,11 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
|
|
|
17612
17730
|
hasMatches,
|
|
17613
17731
|
canReplace: canReplaceComputed,
|
|
17614
17732
|
/**
|
|
17733
|
+
* `canReplace` plus the session enumerating every match. A truncated V2
|
|
17734
|
+
* session keeps Replace enabled and disables Replace all.
|
|
17735
|
+
*/
|
|
17736
|
+
canReplaceAll: canReplaceAllComputed,
|
|
17737
|
+
/**
|
|
17615
17738
|
* Runtime mutability of the active session (viewing/read-only mode sets
|
|
17616
17739
|
* this false). Distinct from the static `replaceEnabled` config and from
|
|
17617
17740
|
* `canReplace`, which also requires matches: surfaces hide replace
|
|
@@ -17701,6 +17824,9 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
|
|
|
17701
17824
|
get canReplace() {
|
|
17702
17825
|
return handle.canReplace.value;
|
|
17703
17826
|
},
|
|
17827
|
+
get canReplaceAll() {
|
|
17828
|
+
return handle.canReplaceAll ? handle.canReplaceAll.value : handle.canReplace.value;
|
|
17829
|
+
},
|
|
17704
17830
|
get replacePending() {
|
|
17705
17831
|
return handle.replacePending.value;
|
|
17706
17832
|
},
|
|
@@ -17851,7 +17977,7 @@ function useFindReplace({ getSurfaceManager, getActiveEditor, activeEditorRef, g
|
|
|
17851
17977
|
/** @type {object | undefined} */
|
|
17852
17978
|
let FindReplaceSurface;
|
|
17853
17979
|
try {
|
|
17854
|
-
FindReplaceSurface = (await Promise.resolve().then(() => require("./chunks/FindReplaceSurface-
|
|
17980
|
+
FindReplaceSurface = (await Promise.resolve().then(() => require("./chunks/FindReplaceSurface-qi9OhbwN.cjs"))).default;
|
|
17855
17981
|
} catch {
|
|
17856
17982
|
opening = false;
|
|
17857
17983
|
return;
|
|
@@ -37442,7 +37568,7 @@ var TOOLBAR_ITEM_ALIASES = Object.freeze({
|
|
|
37442
37568
|
* - `ui: false` renders no built-in chrome. It is an explicit
|
|
37443
37569
|
* no-built-in-UI profile, not the inverse of a hypothetical `ui: true`,
|
|
37444
37570
|
* and it never disables document content, the Document API, or
|
|
37445
|
-
* `
|
|
37571
|
+
* `superdoc.ui`.
|
|
37446
37572
|
* - `ui: { ... }` opts in per surface. An omitted key keeps that surface's
|
|
37447
37573
|
* historical default rather than inheriting from its siblings.
|
|
37448
37574
|
*
|
|
@@ -45214,7 +45340,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
|
|
|
45214
45340
|
this.config.colors = shuffleArray(this.config.colors);
|
|
45215
45341
|
this.userColorMap = /* @__PURE__ */ new Map();
|
|
45216
45342
|
this.colorIndex = 0;
|
|
45217
|
-
this.version = "2.12.0
|
|
45343
|
+
this.version = "2.12.0";
|
|
45218
45344
|
this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
|
|
45219
45345
|
this.superdocId = config.superdocId || require_uuid.v4();
|
|
45220
45346
|
this.colors = this.config.colors ?? [];
|
|
@@ -45383,7 +45509,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
|
|
|
45383
45509
|
this.#pendingContentControlInputSource = null;
|
|
45384
45510
|
this.#pendingContentControlInputExpiresAt = null;
|
|
45385
45511
|
});
|
|
45386
|
-
contentControlsUnsub = this.#ui.contentControls.
|
|
45512
|
+
contentControlsUnsub = this.#ui.contentControls.observeActivePath((snapshot) => {
|
|
45387
45513
|
const editor = this.activeEditor;
|
|
45388
45514
|
const activePath = snapshot.activeIds.map((id) => toContentControlRef(snapshot.items.find((item) => item.id === id)));
|
|
45389
45515
|
if (activePath.some((item) => item === null)) return;
|