superdoc 2.0.0-next.44 → 2.0.0-next.46
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/AGENTS.md +15 -8
- package/dist/chunks/{create-super-doc-ui-DYky1UEo.cjs → create-super-doc-ui-6FUZ9d-y.cjs} +204 -159
- package/dist/chunks/{create-super-doc-ui-BFz0iim0.es.js → create-super-doc-ui-DCFTmVRK.es.js} +205 -160
- package/dist/collaboration-upgrade-engine.cjs +1 -1
- package/dist/collaboration-upgrade-engine.es.js +1 -1
- package/dist/document-api/src/contract/command-catalog.d.ts +1 -1
- package/dist/document-api/src/contract/operation-definitions.d.ts +1 -1
- package/dist/public/ui-react.cjs +17 -14
- package/dist/public/ui-react.es.js +17 -14
- package/dist/public/ui.cjs +1 -1
- package/dist/public/ui.es.js +1 -1
- package/dist/style.css +28 -28
- package/dist/style.layered.css +28 -28
- package/dist/superdoc/src/components/surfaces/FindReplaceSurface.vue.d.ts +2 -2
- package/dist/superdoc/src/components/surfaces/PasswordPromptSurface.vue.d.ts +2 -2
- package/dist/superdoc/src/components/surfaces/SurfaceExternalMount.vue.d.ts +2 -2
- package/dist/superdoc/src/composables/use-find-replace.d.ts +2 -2
- package/dist/superdoc/src/core/SuperDoc.d.ts +41 -0
- package/dist/superdoc/src/core/types/index.d.ts +76 -30
- package/dist/superdoc/src/internal/toolbar/built-in-toolbar.d.ts +5 -5
- package/dist/superdoc/src/public/browser-document-api.d.ts +53 -0
- package/dist/superdoc/src/public/index.d.cts +4 -0
- package/dist/superdoc/src/public/index.d.ts +2 -0
- package/dist/superdoc/src/public/ui/react.d.ts +18 -7
- package/dist/superdoc/src/public/ui/types.d.ts +81 -12
- package/dist/superdoc/src/public/ui-react.d.ts +4 -3
- package/dist/superdoc/src/public/ui.d.cts +8 -0
- package/dist/superdoc/src/public/ui.d.ts +1 -1
- package/dist/superdoc.cjs +85 -141
- package/dist/superdoc.es.js +85 -141
- package/dist-cdn/style.layered.css +1 -1
- package/dist-cdn/superdoc.min.css +1 -1
- package/dist-cdn/superdoc.min.js +36 -36
- package/package.json +2 -2
package/AGENTS.md
CHANGED
|
@@ -179,7 +179,14 @@ For building your own browser UI (toolbars, selection popovers, comment panels,
|
|
|
179
179
|
citation cards) around a live SuperDoc editor, use the v2-native public custom-UI
|
|
180
180
|
entrypoints. They are the supported subpath exports for custom UI:
|
|
181
181
|
|
|
182
|
-
- `superdoc
|
|
182
|
+
- `superdoc.ui` — the framework-agnostic controller every instance owns. Read it;
|
|
183
|
+
do not build one. `superdoc.destroy()` tears it down. The property is typed
|
|
184
|
+
`BorrowedSuperDocUI`, which omits `destroy()`, so you cannot tear down state
|
|
185
|
+
the built-in toolbar and other consumers of that instance are still reading.
|
|
186
|
+
Only a controller you created yourself is yours to destroy.
|
|
187
|
+
- `superdoc/ui` — the controller's types, plus `createSuperDocUI({ superdoc })`
|
|
188
|
+
for the rare case you want a **second, independently owned** controller that
|
|
189
|
+
you create and destroy yourself.
|
|
183
190
|
- `superdoc/ui/react` — React bindings: `SuperDocUIProvider`, `useSetSuperDoc`,
|
|
184
191
|
`useSuperDocUI`, `useSuperDocHost`, and slice hooks.
|
|
185
192
|
|
|
@@ -207,14 +214,14 @@ painted output or reach into editor internals for coordinates.
|
|
|
207
214
|
**Supported / unsupported.**
|
|
208
215
|
|
|
209
216
|
- There is **no public headless path.** Backend / external Document API access uses
|
|
210
|
-
the SDK (`@superdoc-dev/sdk`) — see *Document Engine* above. Browser custom UI
|
|
211
|
-
`superdoc/ui`.
|
|
217
|
+
the SDK (`@superdoc-dev/sdk`) — see *Document Engine* above. Browser custom UI
|
|
218
|
+
reads `superdoc.ui`, typed by `superdoc/ui`.
|
|
212
219
|
- **Migrating from v1 `superdoc/headless-toolbar*`?** Those package subpaths are
|
|
213
220
|
intentionally removed in v2 (migration-only posture). Move v1 custom toolbar /
|
|
214
|
-
headless-toolbar code to `superdoc
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
221
|
+
headless-toolbar code to `superdoc.ui` and `superdoc/ui/react`. Unsupported or
|
|
222
|
+
not-yet-migrated commands stay visible in the toolbar snapshot as disabled with
|
|
223
|
+
a stable `reason` (the `SuperDocUIReason` taxonomy on `CommandState`) instead
|
|
224
|
+
of silently disappearing.
|
|
218
225
|
- The SuperDoc shell may import only the supported `@superdoc/docx-engine`
|
|
219
226
|
package entries. Do **not** import internal implementation packages such as
|
|
220
227
|
`@superdoc/v2-host`, `@superdoc/document-api-v2-adapter`, or
|
|
@@ -241,7 +248,7 @@ painted output or reach into editor internals for coordinates.
|
|
|
241
248
|
| Format text (programmatic) | Use Document API: `editor.doc.format.bold(...)`, `.italic(...)`, etc. |
|
|
242
249
|
| Real-time collab | Configure `modules.collaboration` with a Yjs provider |
|
|
243
250
|
| Custom built-in toolbar | Use `modules.toolbar.customButtons` array |
|
|
244
|
-
| Build your own UI |
|
|
251
|
+
| Build your own UI | Read `superdoc.ui`, or use `superdoc/ui/react` — see *Custom UI* above |
|
|
245
252
|
| Anchor citations to inserted text | Read the Document API receipt's `effects.insertedText[]` |
|
|
246
253
|
| Listen to events | `superdoc.on('ready', ({ superdoc }) => { ... })` |
|
|
247
254
|
|
|
@@ -539,118 +539,6 @@ const isV2EditableTextMutationEvent = (event) => {
|
|
|
539
539
|
if (event?.type !== "mutation:committed" || event.origin !== "command") return false;
|
|
540
540
|
return V2_TYPING_COMMAND_KINDS.has(event.editableCommandKind);
|
|
541
541
|
};
|
|
542
|
-
function shallowEqual(a, b) {
|
|
543
|
-
if (Object.is(a, b)) return true;
|
|
544
|
-
if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) return false;
|
|
545
|
-
if (Array.isArray(a) !== Array.isArray(b)) return false;
|
|
546
|
-
const aKeys = Object.keys(a);
|
|
547
|
-
const bKeys = Object.keys(b);
|
|
548
|
-
if (aKeys.length !== bKeys.length) return false;
|
|
549
|
-
for (const key of aKeys) {
|
|
550
|
-
if (!Object.prototype.hasOwnProperty.call(b, key)) return false;
|
|
551
|
-
if (!Object.is(a[key], b[key])) return false;
|
|
552
|
-
}
|
|
553
|
-
return true;
|
|
554
|
-
}
|
|
555
|
-
function sdRunPropsToInlineRunPatch(props) {
|
|
556
|
-
if (!props || typeof props !== "object") return {};
|
|
557
|
-
const patch = {};
|
|
558
|
-
if (props.fonts) patch.rFonts = {
|
|
559
|
-
ascii: props.fonts.ascii,
|
|
560
|
-
hAnsi: props.fonts.hAnsi,
|
|
561
|
-
eastAsia: props.fonts.eastAsia,
|
|
562
|
-
cs: props.fonts.cs,
|
|
563
|
-
asciiTheme: props.fonts.asciiTheme,
|
|
564
|
-
hAnsiTheme: props.fonts.hAnsiTheme,
|
|
565
|
-
eastAsiaTheme: props.fonts.eastAsiaTheme,
|
|
566
|
-
csTheme: props.fonts.csTheme,
|
|
567
|
-
hint: props.fonts.hint
|
|
568
|
-
};
|
|
569
|
-
if (props.fontFamily != null) patch.fontFamily = props.fontFamily;
|
|
570
|
-
if (props.lang) patch.lang = {
|
|
571
|
-
val: props.lang.val,
|
|
572
|
-
eastAsia: props.lang.eastAsia,
|
|
573
|
-
bidi: props.lang.bidi
|
|
574
|
-
};
|
|
575
|
-
if (props.fontSize != null) patch.fontSize = props.fontSize;
|
|
576
|
-
if (props.fontSizeCs != null) patch.fontSizeCs = props.fontSizeCs;
|
|
577
|
-
const color = projectColorRefToInlineColor(props.color);
|
|
578
|
-
if (color != null) patch.color = color;
|
|
579
|
-
if (props.highlight != null) patch.highlight = props.highlight;
|
|
580
|
-
const shading = projectShadingToInlinePatch(props.shading);
|
|
581
|
-
if (shading) patch.shading = shading;
|
|
582
|
-
if (props.cs != null) patch.cs = props.cs;
|
|
583
|
-
if (props.rtl != null) patch.rtl = props.rtl;
|
|
584
|
-
if (props.bold != null) patch.bold = props.bold;
|
|
585
|
-
if (props.boldCs != null) patch.bCs = props.boldCs;
|
|
586
|
-
if (props.italic != null) patch.italic = props.italic;
|
|
587
|
-
if (props.italicCs != null) patch.iCs = props.italicCs;
|
|
588
|
-
const underline = projectUnderlineToInlinePatch(props.underline);
|
|
589
|
-
if (underline !== void 0) patch.underline = underline;
|
|
590
|
-
if (props.strikethrough != null) patch.strike = props.strikethrough;
|
|
591
|
-
if (props.doubleStrikethrough != null) patch.dstrike = props.doubleStrikethrough;
|
|
592
|
-
if (props.caps != null) patch.caps = props.caps;
|
|
593
|
-
if (props.smallCaps != null) patch.smallCaps = props.smallCaps;
|
|
594
|
-
if (props.outline != null) patch.outline = props.outline;
|
|
595
|
-
if (props.shadow != null) patch.shadow = props.shadow;
|
|
596
|
-
if (props.emboss != null) patch.emboss = props.emboss;
|
|
597
|
-
if (props.imprint != null) patch.imprint = props.imprint;
|
|
598
|
-
if (props.verticalAlign != null) patch.vertAlign = props.verticalAlign;
|
|
599
|
-
if (props.characterSpacing != null) patch.letterSpacing = props.characterSpacing;
|
|
600
|
-
if (props.characterScale != null) patch.charScale = props.characterScale;
|
|
601
|
-
if (props.kern != null) patch.kerning = props.kern;
|
|
602
|
-
if (props.baselineShift != null) patch.position = props.baselineShift;
|
|
603
|
-
if (props.fitTextWidth != null) patch.fitText = { val: props.fitTextWidth };
|
|
604
|
-
if (props.vanish != null) patch.vanish = props.vanish;
|
|
605
|
-
if (props.webHidden != null) patch.webHidden = props.webHidden;
|
|
606
|
-
if (props.specVanish != null) patch.specVanish = props.specVanish;
|
|
607
|
-
const border = projectBorderToInlinePatch(props.border);
|
|
608
|
-
if (border) patch.border = border;
|
|
609
|
-
return patch;
|
|
610
|
-
}
|
|
611
|
-
function projectColorRefToInlineColor(color) {
|
|
612
|
-
if (!color) return void 0;
|
|
613
|
-
if (typeof color === "string") return color;
|
|
614
|
-
if (color.model === "rgb") return color.value;
|
|
615
|
-
if (color.model === "auto") return "auto";
|
|
616
|
-
}
|
|
617
|
-
function projectUnderlineToInlinePatch(underline) {
|
|
618
|
-
if (underline == null) return void 0;
|
|
619
|
-
const patch = {};
|
|
620
|
-
if (underline.style != null) patch.style = underline.style;
|
|
621
|
-
if (underline.color?.model === "rgb") patch.color = underline.color.value;
|
|
622
|
-
if (underline.color?.model === "theme") patch.themeColor = underline.color.theme;
|
|
623
|
-
return Object.keys(patch).length > 0 ? patch : true;
|
|
624
|
-
}
|
|
625
|
-
function projectShadingToInlinePatch(shading) {
|
|
626
|
-
if (!shading) return void 0;
|
|
627
|
-
const patch = {};
|
|
628
|
-
const fill = projectColorRefToInlineColor(shading.fill);
|
|
629
|
-
if (fill != null) patch.fill = fill;
|
|
630
|
-
const color = projectColorRefToInlineColor(shading.color);
|
|
631
|
-
if (color != null) patch.color = color;
|
|
632
|
-
if (shading.pattern != null) patch.val = shading.pattern;
|
|
633
|
-
return Object.keys(patch).length > 0 ? patch : void 0;
|
|
634
|
-
}
|
|
635
|
-
function projectBorderToInlinePatch(border) {
|
|
636
|
-
if (!border) return void 0;
|
|
637
|
-
const patch = {};
|
|
638
|
-
if (border.style != null) patch.val = border.style;
|
|
639
|
-
if (border.width != null) patch.sz = border.width;
|
|
640
|
-
if (border.space != null) patch.space = border.space;
|
|
641
|
-
const color = projectColorRefToInlineColor(border.color);
|
|
642
|
-
if (color != null) patch.color = color;
|
|
643
|
-
return Object.keys(patch).length > 0 ? patch : void 0;
|
|
644
|
-
}
|
|
645
|
-
function selectionKey(selection) {
|
|
646
|
-
const target = selection?.selectionTarget ?? selection?.target;
|
|
647
|
-
if (!selection || !target) return "";
|
|
648
|
-
try {
|
|
649
|
-
return JSON.stringify(target);
|
|
650
|
-
} catch {
|
|
651
|
-
return String(target);
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
542
|
const SUPERDOC_UI_REASONS = {
|
|
655
543
|
notReady: "not-ready",
|
|
656
544
|
documentApiUnavailable: "document-api-unavailable",
|
|
@@ -1313,6 +1201,118 @@ const ALL_BUILT_IN_COMMAND_IDS = COMMAND_CATALOG.map((d) => d.id);
|
|
|
1313
1201
|
function getCommandDescriptor(id) {
|
|
1314
1202
|
return CATALOG_BY_ID.get(id) ?? null;
|
|
1315
1203
|
}
|
|
1204
|
+
function shallowEqual(a, b) {
|
|
1205
|
+
if (Object.is(a, b)) return true;
|
|
1206
|
+
if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) return false;
|
|
1207
|
+
if (Array.isArray(a) !== Array.isArray(b)) return false;
|
|
1208
|
+
const aKeys = Object.keys(a);
|
|
1209
|
+
const bKeys = Object.keys(b);
|
|
1210
|
+
if (aKeys.length !== bKeys.length) return false;
|
|
1211
|
+
for (const key of aKeys) {
|
|
1212
|
+
if (!Object.prototype.hasOwnProperty.call(b, key)) return false;
|
|
1213
|
+
if (!Object.is(a[key], b[key])) return false;
|
|
1214
|
+
}
|
|
1215
|
+
return true;
|
|
1216
|
+
}
|
|
1217
|
+
function sdRunPropsToInlineRunPatch(props) {
|
|
1218
|
+
if (!props || typeof props !== "object") return {};
|
|
1219
|
+
const patch = {};
|
|
1220
|
+
if (props.fonts) patch.rFonts = {
|
|
1221
|
+
ascii: props.fonts.ascii,
|
|
1222
|
+
hAnsi: props.fonts.hAnsi,
|
|
1223
|
+
eastAsia: props.fonts.eastAsia,
|
|
1224
|
+
cs: props.fonts.cs,
|
|
1225
|
+
asciiTheme: props.fonts.asciiTheme,
|
|
1226
|
+
hAnsiTheme: props.fonts.hAnsiTheme,
|
|
1227
|
+
eastAsiaTheme: props.fonts.eastAsiaTheme,
|
|
1228
|
+
csTheme: props.fonts.csTheme,
|
|
1229
|
+
hint: props.fonts.hint
|
|
1230
|
+
};
|
|
1231
|
+
if (props.fontFamily != null) patch.fontFamily = props.fontFamily;
|
|
1232
|
+
if (props.lang) patch.lang = {
|
|
1233
|
+
val: props.lang.val,
|
|
1234
|
+
eastAsia: props.lang.eastAsia,
|
|
1235
|
+
bidi: props.lang.bidi
|
|
1236
|
+
};
|
|
1237
|
+
if (props.fontSize != null) patch.fontSize = props.fontSize;
|
|
1238
|
+
if (props.fontSizeCs != null) patch.fontSizeCs = props.fontSizeCs;
|
|
1239
|
+
const color = projectColorRefToInlineColor(props.color);
|
|
1240
|
+
if (color != null) patch.color = color;
|
|
1241
|
+
if (props.highlight != null) patch.highlight = props.highlight;
|
|
1242
|
+
const shading = projectShadingToInlinePatch(props.shading);
|
|
1243
|
+
if (shading) patch.shading = shading;
|
|
1244
|
+
if (props.cs != null) patch.cs = props.cs;
|
|
1245
|
+
if (props.rtl != null) patch.rtl = props.rtl;
|
|
1246
|
+
if (props.bold != null) patch.bold = props.bold;
|
|
1247
|
+
if (props.boldCs != null) patch.bCs = props.boldCs;
|
|
1248
|
+
if (props.italic != null) patch.italic = props.italic;
|
|
1249
|
+
if (props.italicCs != null) patch.iCs = props.italicCs;
|
|
1250
|
+
const underline = projectUnderlineToInlinePatch(props.underline);
|
|
1251
|
+
if (underline !== void 0) patch.underline = underline;
|
|
1252
|
+
if (props.strikethrough != null) patch.strike = props.strikethrough;
|
|
1253
|
+
if (props.doubleStrikethrough != null) patch.dstrike = props.doubleStrikethrough;
|
|
1254
|
+
if (props.caps != null) patch.caps = props.caps;
|
|
1255
|
+
if (props.smallCaps != null) patch.smallCaps = props.smallCaps;
|
|
1256
|
+
if (props.outline != null) patch.outline = props.outline;
|
|
1257
|
+
if (props.shadow != null) patch.shadow = props.shadow;
|
|
1258
|
+
if (props.emboss != null) patch.emboss = props.emboss;
|
|
1259
|
+
if (props.imprint != null) patch.imprint = props.imprint;
|
|
1260
|
+
if (props.verticalAlign != null) patch.vertAlign = props.verticalAlign;
|
|
1261
|
+
if (props.characterSpacing != null) patch.letterSpacing = props.characterSpacing;
|
|
1262
|
+
if (props.characterScale != null) patch.charScale = props.characterScale;
|
|
1263
|
+
if (props.kern != null) patch.kerning = props.kern;
|
|
1264
|
+
if (props.baselineShift != null) patch.position = props.baselineShift;
|
|
1265
|
+
if (props.fitTextWidth != null) patch.fitText = { val: props.fitTextWidth };
|
|
1266
|
+
if (props.vanish != null) patch.vanish = props.vanish;
|
|
1267
|
+
if (props.webHidden != null) patch.webHidden = props.webHidden;
|
|
1268
|
+
if (props.specVanish != null) patch.specVanish = props.specVanish;
|
|
1269
|
+
const border = projectBorderToInlinePatch(props.border);
|
|
1270
|
+
if (border) patch.border = border;
|
|
1271
|
+
return patch;
|
|
1272
|
+
}
|
|
1273
|
+
function projectColorRefToInlineColor(color) {
|
|
1274
|
+
if (!color) return void 0;
|
|
1275
|
+
if (typeof color === "string") return color;
|
|
1276
|
+
if (color.model === "rgb") return color.value;
|
|
1277
|
+
if (color.model === "auto") return "auto";
|
|
1278
|
+
}
|
|
1279
|
+
function projectUnderlineToInlinePatch(underline) {
|
|
1280
|
+
if (underline == null) return void 0;
|
|
1281
|
+
const patch = {};
|
|
1282
|
+
if (underline.style != null) patch.style = underline.style;
|
|
1283
|
+
if (underline.color?.model === "rgb") patch.color = underline.color.value;
|
|
1284
|
+
if (underline.color?.model === "theme") patch.themeColor = underline.color.theme;
|
|
1285
|
+
return Object.keys(patch).length > 0 ? patch : true;
|
|
1286
|
+
}
|
|
1287
|
+
function projectShadingToInlinePatch(shading) {
|
|
1288
|
+
if (!shading) return void 0;
|
|
1289
|
+
const patch = {};
|
|
1290
|
+
const fill = projectColorRefToInlineColor(shading.fill);
|
|
1291
|
+
if (fill != null) patch.fill = fill;
|
|
1292
|
+
const color = projectColorRefToInlineColor(shading.color);
|
|
1293
|
+
if (color != null) patch.color = color;
|
|
1294
|
+
if (shading.pattern != null) patch.val = shading.pattern;
|
|
1295
|
+
return Object.keys(patch).length > 0 ? patch : void 0;
|
|
1296
|
+
}
|
|
1297
|
+
function projectBorderToInlinePatch(border) {
|
|
1298
|
+
if (!border) return void 0;
|
|
1299
|
+
const patch = {};
|
|
1300
|
+
if (border.style != null) patch.val = border.style;
|
|
1301
|
+
if (border.width != null) patch.sz = border.width;
|
|
1302
|
+
if (border.space != null) patch.space = border.space;
|
|
1303
|
+
const color = projectColorRefToInlineColor(border.color);
|
|
1304
|
+
if (color != null) patch.color = color;
|
|
1305
|
+
return Object.keys(patch).length > 0 ? patch : void 0;
|
|
1306
|
+
}
|
|
1307
|
+
function selectionKey(selection) {
|
|
1308
|
+
const target = selection?.selectionTarget ?? selection?.target;
|
|
1309
|
+
if (!selection || !target) return "";
|
|
1310
|
+
try {
|
|
1311
|
+
return JSON.stringify(target);
|
|
1312
|
+
} catch {
|
|
1313
|
+
return String(target);
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
1316
|
function parseCommaSeparatedIds(value) {
|
|
1317
1317
|
return value.split(",").map((id) => id.trim()).filter(Boolean);
|
|
1318
1318
|
}
|
|
@@ -1703,12 +1703,6 @@ const INLINE_PROPERTY_KEYS_BY_STORAGE = {
|
|
|
1703
1703
|
mark: INLINE_PROPERTY_REGISTRY.filter((entry) => entry.storage === "mark").map((entry) => entry.key),
|
|
1704
1704
|
runAttribute: INLINE_PROPERTY_REGISTRY.filter((entry) => entry.storage === "runAttribute").map((entry) => entry.key)
|
|
1705
1705
|
};
|
|
1706
|
-
var POST_DECISION_TRACKED_CHANGES_LIST_OPTIONS = Object.freeze({
|
|
1707
|
-
mode: "background-reconcile",
|
|
1708
|
-
refreshReason: "post-decision-background",
|
|
1709
|
-
blocking: false
|
|
1710
|
-
});
|
|
1711
|
-
var POST_DECISION_TRACKED_CHANGES_RECONCILE_DELAY_MS = 3e3;
|
|
1712
1706
|
var SUPERDOC_UI_REASON_VALUES = new Set(Object.values(SUPERDOC_UI_REASONS));
|
|
1713
1707
|
function coerceSuperDocUIReason(reason, fallback) {
|
|
1714
1708
|
return typeof reason === "string" && SUPERDOC_UI_REASON_VALUES.has(reason) ? reason : fallback;
|
|
@@ -1731,6 +1725,7 @@ function normalizeHostSelectionApplyResult(result) {
|
|
|
1731
1725
|
}
|
|
1732
1726
|
var HOST_EVENTS = [
|
|
1733
1727
|
"editorCreate",
|
|
1728
|
+
"active-editor-change",
|
|
1734
1729
|
"document-mode-change",
|
|
1735
1730
|
"zoomChange",
|
|
1736
1731
|
"measurement-unit-change",
|
|
@@ -3133,7 +3128,6 @@ function createSuperDocUI(options) {
|
|
|
3133
3128
|
let foregroundAsyncRetryTimer = null;
|
|
3134
3129
|
let pendingSelectionSeedValidationToken = null;
|
|
3135
3130
|
let typingContentInvalidationTimer = null;
|
|
3136
|
-
let postDecisionTrackChangesReconcileTimer = null;
|
|
3137
3131
|
const scheduleAsyncRefresh = () => {
|
|
3138
3132
|
if (asyncRefreshScheduled || disposed) return;
|
|
3139
3133
|
asyncRefreshScheduled = true;
|
|
@@ -3180,14 +3174,12 @@ function createSuperDocUI(options) {
|
|
|
3180
3174
|
};
|
|
3181
3175
|
let scheduleAuthoritativeTrackChangesRetry = (_reconcileToken) => void 0;
|
|
3182
3176
|
let postDecisionTrackChangesToken = null;
|
|
3183
|
-
let postDecisionTrackChangesReconcileToken = null;
|
|
3184
3177
|
let postDecisionTrackChangeIds = /* @__PURE__ */ new Set();
|
|
3185
3178
|
let selectionEpoch = 0;
|
|
3186
3179
|
let lastCoordinatorEditor = null;
|
|
3187
3180
|
const contentToken = () => `${editorIdentityId(getEditor())}|m${documentMutationRevision}`;
|
|
3188
3181
|
const clearPostDecisionTrackChanges = () => {
|
|
3189
3182
|
postDecisionTrackChangesToken = null;
|
|
3190
|
-
postDecisionTrackChangesReconcileToken = null;
|
|
3191
3183
|
postDecisionTrackChangeIds = /* @__PURE__ */ new Set();
|
|
3192
3184
|
};
|
|
3193
3185
|
const applyPostDecisionTrackChangesToCache = (ids) => {
|
|
@@ -3205,25 +3197,6 @@ function createSuperDocUI(options) {
|
|
|
3205
3197
|
});
|
|
3206
3198
|
}
|
|
3207
3199
|
};
|
|
3208
|
-
const schedulePostDecisionTrackChangesReconcile = () => {
|
|
3209
|
-
if (disposed || postDecisionTrackChangesReconcileTimer) return;
|
|
3210
|
-
postDecisionTrackChangesReconcileTimer = setTimeout(() => {
|
|
3211
|
-
postDecisionTrackChangesReconcileTimer = null;
|
|
3212
|
-
const run = () => {
|
|
3213
|
-
if (disposed || postDecisionTrackChangeIds.size === 0) return;
|
|
3214
|
-
invalidateDocumentContent({ preservePostDecisionTrackChanges: true });
|
|
3215
|
-
postDecisionTrackChangesToken = contentToken();
|
|
3216
|
-
postDecisionTrackChangesReconcileToken = postDecisionTrackChangesToken;
|
|
3217
|
-
recompute();
|
|
3218
|
-
};
|
|
3219
|
-
const requestIdle = globalThis.requestIdleCallback;
|
|
3220
|
-
if (typeof requestIdle === "function") {
|
|
3221
|
-
requestIdle(run, { timeout: 2e3 });
|
|
3222
|
-
return;
|
|
3223
|
-
}
|
|
3224
|
-
run();
|
|
3225
|
-
}, POST_DECISION_TRACKED_CHANGES_RECONCILE_DELAY_MS);
|
|
3226
|
-
};
|
|
3227
3200
|
const notifyPostDecisionTrackChanges = (receipt) => {
|
|
3228
3201
|
const notify = () => {
|
|
3229
3202
|
if (disposed) return;
|
|
@@ -3289,7 +3262,6 @@ function createSuperDocUI(options) {
|
|
|
3289
3262
|
postDecisionTrackChangesToken = token;
|
|
3290
3263
|
postDecisionTrackChangeIds = new Set([...alreadyRemoved, ...newlyRemoved]);
|
|
3291
3264
|
applyPostDecisionTrackChangesToCache(postDecisionTrackChangeIds);
|
|
3292
|
-
schedulePostDecisionTrackChangesReconcile();
|
|
3293
3265
|
publishPostDecisionTrackChanges(newlyRemoved, receipt);
|
|
3294
3266
|
};
|
|
3295
3267
|
const postDecisionTrackChangeIdsForToken = (token) => postDecisionTrackChangesToken === token && postDecisionTrackChangeIds.size > 0 ? postDecisionTrackChangeIds : null;
|
|
@@ -3958,11 +3930,11 @@ function createSuperDocUI(options) {
|
|
|
3958
3930
|
sourceLoadingSubscriptionHost = null;
|
|
3959
3931
|
clearPostDecisionTrackChanges();
|
|
3960
3932
|
};
|
|
3961
|
-
const invalidateDocumentContent = (
|
|
3933
|
+
const invalidateDocumentContent = () => {
|
|
3962
3934
|
const carryAuthoritativeTrackChangesHold = authoritativeTrackChangesPendingToken !== null;
|
|
3963
3935
|
documentMutationRevision += 1;
|
|
3964
3936
|
if (carryAuthoritativeTrackChangesHold) authoritativeTrackChangesPendingToken = contentToken();
|
|
3965
|
-
|
|
3937
|
+
clearPostDecisionTrackChanges();
|
|
3966
3938
|
};
|
|
3967
3939
|
const insertText = (text) => {
|
|
3968
3940
|
if (typeof text !== "string" || text.length === 0) return failedReceipt("insertText requires a non-empty string.", "INVALID_INPUT");
|
|
@@ -4173,10 +4145,9 @@ function createSuperDocUI(options) {
|
|
|
4173
4145
|
value: heldEntry?.hasSettled ? heldEntry.value : null,
|
|
4174
4146
|
status: heldEntry?.hasSettled ? "stale" : "pending"
|
|
4175
4147
|
} : readAsync("trackChanges", token, () => {
|
|
4176
|
-
if (listTrackedChanges) return
|
|
4148
|
+
if (listTrackedChanges) return listTrackedChanges.call(v2TrackedChanges);
|
|
4177
4149
|
return tcApi?.list ? tcApi.list() : void 0;
|
|
4178
4150
|
}, (raw) => raw && Array.isArray(raw.items) ? raw.items : []);
|
|
4179
|
-
if (listStatus === "ready" && postDecisionTrackChangesReconcileToken === token) clearPostDecisionTrackChanges();
|
|
4180
4151
|
const items = (value ?? []).map(projectTrackChangesItem).filter((item) => item != null).filter((item) => {
|
|
4181
4152
|
const id = readEntityId(item);
|
|
4182
4153
|
return !id || !postDecisionIds?.has(id);
|
|
@@ -5980,11 +5951,20 @@ function createSuperDocUI(options) {
|
|
|
5980
5951
|
state = nextState;
|
|
5981
5952
|
for (const listener of [...listeners]) listener(state);
|
|
5982
5953
|
};
|
|
5954
|
+
const activeEditorResetHooks = [];
|
|
5955
|
+
const runActiveEditorResetHooks = () => {
|
|
5956
|
+
for (const reset of activeEditorResetHooks) try {
|
|
5957
|
+
reset();
|
|
5958
|
+
} catch {}
|
|
5959
|
+
};
|
|
5983
5960
|
const detachers = [];
|
|
5984
5961
|
const attach = (source, events) => {
|
|
5985
5962
|
if (!source || typeof source.on !== "function") return;
|
|
5986
5963
|
for (const event of events) {
|
|
5987
|
-
const handler = () =>
|
|
5964
|
+
const handler = event === "active-editor-change" ? () => {
|
|
5965
|
+
runActiveEditorResetHooks();
|
|
5966
|
+
recompute();
|
|
5967
|
+
} : () => recompute();
|
|
5988
5968
|
try {
|
|
5989
5969
|
source.on(event, handler);
|
|
5990
5970
|
detachers.push(() => {
|
|
@@ -8288,6 +8268,28 @@ function createSuperDocUI(options) {
|
|
|
8288
8268
|
if (typeof xOrInput === "object") return pointEntityHits(xOrInput?.x, xOrInput?.y);
|
|
8289
8269
|
return null;
|
|
8290
8270
|
}
|
|
8271
|
+
const geometryObservers = /* @__PURE__ */ new Set();
|
|
8272
|
+
const bindGeometryObserver = (entry) => {
|
|
8273
|
+
const host = getHost();
|
|
8274
|
+
if (typeof host?.observeGeometry !== "function") return;
|
|
8275
|
+
const off = safeCall(() => host.observeGeometry(() => entry.schedule()), null);
|
|
8276
|
+
entry.detach = typeof off === "function" ? off : null;
|
|
8277
|
+
};
|
|
8278
|
+
const detachGeometryObserver = (entry) => {
|
|
8279
|
+
if (!entry.detach) return;
|
|
8280
|
+
try {
|
|
8281
|
+
entry.detach();
|
|
8282
|
+
} catch {}
|
|
8283
|
+
entry.detach = null;
|
|
8284
|
+
};
|
|
8285
|
+
const rebindGeometryObservers = () => {
|
|
8286
|
+
for (const entry of geometryObservers) {
|
|
8287
|
+
detachGeometryObserver(entry);
|
|
8288
|
+
bindGeometryObserver(entry);
|
|
8289
|
+
entry.schedule();
|
|
8290
|
+
}
|
|
8291
|
+
};
|
|
8292
|
+
activeEditorResetHooks.push(rebindGeometryObservers);
|
|
8291
8293
|
const viewport = {
|
|
8292
8294
|
getRect: (input) => {
|
|
8293
8295
|
const host = getHost();
|
|
@@ -8323,12 +8325,15 @@ function createSuperDocUI(options) {
|
|
|
8323
8325
|
zoom: s.zoom
|
|
8324
8326
|
}));
|
|
8325
8327
|
unsubs.push(sub.subscribe(() => schedule()));
|
|
8326
|
-
const
|
|
8327
|
-
|
|
8328
|
-
|
|
8329
|
-
|
|
8330
|
-
|
|
8328
|
+
const entry = {
|
|
8329
|
+
schedule,
|
|
8330
|
+
detach: null
|
|
8331
|
+
};
|
|
8332
|
+
bindGeometryObserver(entry);
|
|
8333
|
+
geometryObservers.add(entry);
|
|
8331
8334
|
return () => {
|
|
8335
|
+
geometryObservers.delete(entry);
|
|
8336
|
+
detachGeometryObserver(entry);
|
|
8332
8337
|
if (frame && typeof cancelAnimationFrame === "function") cancelAnimationFrame(frame);
|
|
8333
8338
|
for (const unsub of unsubs.splice(0)) try {
|
|
8334
8339
|
unsub();
|
|
@@ -8502,6 +8507,28 @@ function createSuperDocUI(options) {
|
|
|
8502
8507
|
return searchState;
|
|
8503
8508
|
};
|
|
8504
8509
|
let searchRequestGeneration = 0;
|
|
8510
|
+
let releaseActiveSearchSession = null;
|
|
8511
|
+
const releaseSearchSession = () => {
|
|
8512
|
+
const release = releaseActiveSearchSession;
|
|
8513
|
+
releaseActiveSearchSession = null;
|
|
8514
|
+
if (!release) return;
|
|
8515
|
+
safeCall(() => {
|
|
8516
|
+
release();
|
|
8517
|
+
return null;
|
|
8518
|
+
}, null);
|
|
8519
|
+
};
|
|
8520
|
+
const resetSearchForActiveEditorChange = () => {
|
|
8521
|
+
searchRequestGeneration += 1;
|
|
8522
|
+
releaseSearchSession();
|
|
8523
|
+
const available = searchIsAvailable();
|
|
8524
|
+
searchState = {
|
|
8525
|
+
...SEARCH_UNAVAILABLE_SLICE,
|
|
8526
|
+
available,
|
|
8527
|
+
reason: available ? void 0 : SUPERDOC_UI_REASONS.searchUnavailable
|
|
8528
|
+
};
|
|
8529
|
+
emitSearch();
|
|
8530
|
+
};
|
|
8531
|
+
activeEditorResetHooks.push(resetSearchForActiveEditorChange);
|
|
8505
8532
|
const readSearchQueryError = (record) => {
|
|
8506
8533
|
if (!record) return false;
|
|
8507
8534
|
const queryError = record.queryError;
|
|
@@ -8653,11 +8680,14 @@ function createSuperDocUI(options) {
|
|
|
8653
8680
|
},
|
|
8654
8681
|
close: () => {
|
|
8655
8682
|
searchRequestGeneration += 1;
|
|
8656
|
-
|
|
8657
|
-
if (host && typeof host.clear === "function") safeCall(() => host.clear(), null);
|
|
8683
|
+
if (releaseActiveSearchSession) releaseSearchSession();
|
|
8658
8684
|
else {
|
|
8659
|
-
const
|
|
8660
|
-
if (
|
|
8685
|
+
const host = getHostSearch();
|
|
8686
|
+
if (host && typeof host.clear === "function") safeCall(() => host.clear(), null);
|
|
8687
|
+
else {
|
|
8688
|
+
const editSearch = getEditCommandSearch();
|
|
8689
|
+
if (editSearch && typeof editSearch.query === "function") safeCall(() => editSearch.query({ query: "" }), null);
|
|
8690
|
+
}
|
|
8661
8691
|
}
|
|
8662
8692
|
searchState = {
|
|
8663
8693
|
...SEARCH_UNAVAILABLE_SLICE,
|
|
@@ -8685,6 +8715,9 @@ function createSuperDocUI(options) {
|
|
|
8685
8715
|
open: true,
|
|
8686
8716
|
reason: void 0
|
|
8687
8717
|
});
|
|
8718
|
+
releaseActiveSearchSession = () => {
|
|
8719
|
+
editSearch.query({ query: "" });
|
|
8720
|
+
};
|
|
8688
8721
|
const result = safeCall(() => editSearch.query({
|
|
8689
8722
|
query,
|
|
8690
8723
|
caseSensitive,
|
|
@@ -8725,6 +8758,9 @@ function createSuperDocUI(options) {
|
|
|
8725
8758
|
open: true,
|
|
8726
8759
|
reason: void 0
|
|
8727
8760
|
});
|
|
8761
|
+
releaseActiveSearchSession = () => {
|
|
8762
|
+
if (typeof host.clear === "function") host.clear();
|
|
8763
|
+
};
|
|
8728
8764
|
applyHostSearchResult(safeCall(() => host.setSession(query, {
|
|
8729
8765
|
caseSensitive,
|
|
8730
8766
|
includeDeletedText,
|
|
@@ -8734,6 +8770,11 @@ function createSuperDocUI(options) {
|
|
|
8734
8770
|
if (query.length > 0 && searchState.total === 0 && searchState.reason !== SUPERDOC_UI_REASONS.searchInvalidPattern) {
|
|
8735
8771
|
const editSearch = getEditCommandSearch();
|
|
8736
8772
|
if (editSearch && typeof editSearch.query === "function" && typeof editSearch.getState === "function") {
|
|
8773
|
+
const releaseHostSession = releaseActiveSearchSession;
|
|
8774
|
+
releaseActiveSearchSession = () => {
|
|
8775
|
+
releaseHostSession?.();
|
|
8776
|
+
editSearch.query({ query: "" });
|
|
8777
|
+
};
|
|
8737
8778
|
const commandResult = safeCall(() => editSearch.query({
|
|
8738
8779
|
query,
|
|
8739
8780
|
caseSensitive,
|
|
@@ -8974,10 +9015,6 @@ function createSuperDocUI(options) {
|
|
|
8974
9015
|
clearTimeout(typingContentInvalidationTimer);
|
|
8975
9016
|
typingContentInvalidationTimer = null;
|
|
8976
9017
|
}
|
|
8977
|
-
if (postDecisionTrackChangesReconcileTimer) {
|
|
8978
|
-
clearTimeout(postDecisionTrackChangesReconcileTimer);
|
|
8979
|
-
postDecisionTrackChangesReconcileTimer = null;
|
|
8980
|
-
}
|
|
8981
9018
|
if (heavyReadCompletionRecomputeTimer) {
|
|
8982
9019
|
clearTimeout(heavyReadCompletionRecomputeTimer);
|
|
8983
9020
|
heavyReadCompletionRecomputeTimer = null;
|
|
@@ -9002,6 +9039,8 @@ function createSuperDocUI(options) {
|
|
|
9002
9039
|
currentDocumentSelectionSource = null;
|
|
9003
9040
|
listeners.clear();
|
|
9004
9041
|
searchListeners.clear();
|
|
9042
|
+
painterCaptureEpoch += 1;
|
|
9043
|
+
painterModeListeners.clear();
|
|
9005
9044
|
customCommands.clear();
|
|
9006
9045
|
};
|
|
9007
9046
|
const controller = {
|
|
@@ -9025,12 +9064,14 @@ function createSuperDocUI(options) {
|
|
|
9025
9064
|
styles,
|
|
9026
9065
|
formatPainter: {
|
|
9027
9066
|
setPointerSelecting(flag) {
|
|
9067
|
+
if (disposed) return;
|
|
9028
9068
|
painter = {
|
|
9029
9069
|
...painter,
|
|
9030
9070
|
pointerSelecting: flag
|
|
9031
9071
|
};
|
|
9032
9072
|
},
|
|
9033
9073
|
notifyPointerUp() {
|
|
9074
|
+
if (disposed) return;
|
|
9034
9075
|
painter = {
|
|
9035
9076
|
...painter,
|
|
9036
9077
|
pointerSelecting: false
|
|
@@ -9038,12 +9079,14 @@ function createSuperDocUI(options) {
|
|
|
9038
9079
|
maybeApply();
|
|
9039
9080
|
},
|
|
9040
9081
|
setKeyboardSelecting(flag) {
|
|
9082
|
+
if (disposed) return;
|
|
9041
9083
|
painter = {
|
|
9042
9084
|
...painter,
|
|
9043
9085
|
keyboardSelecting: flag
|
|
9044
9086
|
};
|
|
9045
9087
|
},
|
|
9046
9088
|
notifyKeyUp() {
|
|
9089
|
+
if (disposed) return;
|
|
9047
9090
|
painter = {
|
|
9048
9091
|
...painter,
|
|
9049
9092
|
keyboardSelecting: false
|
|
@@ -9051,9 +9094,11 @@ function createSuperDocUI(options) {
|
|
|
9051
9094
|
maybeApply();
|
|
9052
9095
|
},
|
|
9053
9096
|
cancel() {
|
|
9097
|
+
if (disposed) return;
|
|
9054
9098
|
exitFormatPainter();
|
|
9055
9099
|
},
|
|
9056
9100
|
onModeChange(cb) {
|
|
9101
|
+
if (disposed) return () => {};
|
|
9057
9102
|
painterModeListeners.add(cb);
|
|
9058
9103
|
return () => painterModeListeners.delete(cb);
|
|
9059
9104
|
}
|