superdoc 2.0.0-next.49 → 2.0.0-next.50
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 +31 -10
- package/dist/chunks/{create-super-doc-ui-BmtUtDDR.es.js → create-super-doc-ui-D4UDePxr.es.js} +126 -28
- package/dist/chunks/{create-super-doc-ui-BNo2DvD1.cjs → create-super-doc-ui-DlSN0ENQ.cjs} +126 -28
- package/dist/collaboration-upgrade-engine.cjs +1 -1
- package/dist/collaboration-upgrade-engine.es.js +1 -1
- package/dist/document-api/src/contract/operation-definitions.d.ts +1 -1
- package/dist/public/ui-react.cjs +1 -1
- package/dist/public/ui-react.es.js +1 -1
- package/dist/public/ui.cjs +1 -1
- package/dist/public/ui.es.js +1 -1
- package/dist/shared/font-system/src/font-offerings.d.ts +1 -1
- package/dist/style.css +28 -28
- package/dist/style.layered.css +28 -28
- package/dist/superdoc/src/core/SuperDoc.d.ts +43 -1
- package/dist/superdoc/src/core/config/merge-defined.d.ts +35 -0
- package/dist/superdoc/src/core/config/normalize-interaction-config.d.ts +15 -0
- package/dist/superdoc/src/core/config/normalize-surfaces-config.d.ts +23 -0
- package/dist/superdoc/src/core/config/normalize-ui-config.d.ts +62 -0
- package/dist/superdoc/src/core/types/index.d.ts +209 -2
- package/dist/superdoc/src/public/index.d.cts +6 -0
- package/dist/superdoc/src/public/index.d.ts +3 -0
- package/dist/superdoc/src/public/ui.d.cts +2 -0
- package/dist/superdoc/src/public/ui.d.ts +1 -1
- package/dist/superdoc.cjs +211 -37
- package/dist/superdoc.es.js +211 -37
- 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
package/dist/style.layered.css
CHANGED
|
@@ -1368,28 +1368,28 @@ img[data-v-c95b2073] {
|
|
|
1368
1368
|
background-color: #1355ff7f;
|
|
1369
1369
|
}
|
|
1370
1370
|
|
|
1371
|
-
.comment-placeholder[data-v-
|
|
1371
|
+
.comment-placeholder[data-v-b5be33eb] {
|
|
1372
1372
|
position: absolute;
|
|
1373
1373
|
width: 300px;
|
|
1374
1374
|
transition: top 0.3s ease;
|
|
1375
1375
|
}
|
|
1376
|
-
.comment-placeholder.is-direct-decision-continuity-target[data-v-
|
|
1376
|
+
.comment-placeholder.is-direct-decision-continuity-target[data-v-b5be33eb] .overflow-menu {
|
|
1377
1377
|
opacity: 1;
|
|
1378
1378
|
pointer-events: auto;
|
|
1379
1379
|
}
|
|
1380
|
-
.floating-comment[data-v-
|
|
1380
|
+
.floating-comment[data-v-b5be33eb] {
|
|
1381
1381
|
position: relative;
|
|
1382
1382
|
display: block;
|
|
1383
1383
|
min-width: 300px;
|
|
1384
1384
|
}
|
|
1385
|
-
.sidebar-container[data-v-
|
|
1385
|
+
.sidebar-container[data-v-b5be33eb] {
|
|
1386
1386
|
position: absolute;
|
|
1387
1387
|
width: 300px;
|
|
1388
1388
|
min-height: 300px;
|
|
1389
1389
|
transition: transform 0.3s ease;
|
|
1390
1390
|
will-change: transform;
|
|
1391
1391
|
}
|
|
1392
|
-
.section-wrapper[data-v-
|
|
1392
|
+
.section-wrapper[data-v-b5be33eb] {
|
|
1393
1393
|
position: relative;
|
|
1394
1394
|
min-height: 100%;
|
|
1395
1395
|
width: 300px;
|
|
@@ -1727,11 +1727,11 @@ img[data-v-c95b2073] {
|
|
|
1727
1727
|
pointer-events: auto;
|
|
1728
1728
|
}
|
|
1729
1729
|
|
|
1730
|
-
.superdoc[data-v-
|
|
1730
|
+
.superdoc[data-v-2a7bfa95] {
|
|
1731
1731
|
display: flex;
|
|
1732
1732
|
position: relative;
|
|
1733
1733
|
}
|
|
1734
|
-
.sd-visually-hidden[data-v-
|
|
1734
|
+
.sd-visually-hidden[data-v-2a7bfa95] {
|
|
1735
1735
|
position: absolute;
|
|
1736
1736
|
width: 1px;
|
|
1737
1737
|
height: 1px;
|
|
@@ -1742,30 +1742,30 @@ img[data-v-c95b2073] {
|
|
|
1742
1742
|
white-space: nowrap;
|
|
1743
1743
|
border: 0;
|
|
1744
1744
|
}
|
|
1745
|
-
.right-sidebar[data-v-
|
|
1745
|
+
.right-sidebar[data-v-2a7bfa95] {
|
|
1746
1746
|
min-width: 320px;
|
|
1747
1747
|
height: 100%;
|
|
1748
1748
|
}
|
|
1749
|
-
.floating-comments[data-v-
|
|
1749
|
+
.floating-comments[data-v-2a7bfa95] {
|
|
1750
1750
|
min-width: 300px;
|
|
1751
1751
|
width: 300px;
|
|
1752
1752
|
height: 100%;
|
|
1753
1753
|
overflow: visible;
|
|
1754
1754
|
}
|
|
1755
|
-
.superdoc__layers[data-v-
|
|
1755
|
+
.superdoc__layers[data-v-2a7bfa95] {
|
|
1756
1756
|
height: 100%;
|
|
1757
1757
|
position: relative;
|
|
1758
1758
|
box-sizing: border-box;
|
|
1759
1759
|
}
|
|
1760
|
-
.superdoc__document[data-v-
|
|
1760
|
+
.superdoc__document[data-v-2a7bfa95] {
|
|
1761
1761
|
width: 100%;
|
|
1762
1762
|
position: relative;
|
|
1763
1763
|
}
|
|
1764
|
-
.superdoc__sub-document[data-v-
|
|
1764
|
+
.superdoc__sub-document[data-v-2a7bfa95] {
|
|
1765
1765
|
width: 100%;
|
|
1766
1766
|
position: relative;
|
|
1767
1767
|
}
|
|
1768
|
-
.superdoc__selection-layer[data-v-
|
|
1768
|
+
.superdoc__selection-layer[data-v-2a7bfa95] {
|
|
1769
1769
|
position: absolute;
|
|
1770
1770
|
min-width: 100%;
|
|
1771
1771
|
min-height: 100%;
|
|
@@ -1776,13 +1776,13 @@ img[data-v-c95b2073] {
|
|
|
1776
1776
|
/* SD-3497: PDF whiteboard overlay sits above the rendered PDF canvas but below
|
|
1777
1777
|
the PDF comment anchors (z-index 6 in PdfCommentsLayer) so anchors stay
|
|
1778
1778
|
clickable, and below the selection layer (z-index 10). */
|
|
1779
|
-
.superdoc__whiteboard-layer[data-v-
|
|
1779
|
+
.superdoc__whiteboard-layer[data-v-2a7bfa95] {
|
|
1780
1780
|
z-index: 4;
|
|
1781
1781
|
}
|
|
1782
|
-
.superdoc__temp-selection[data-v-
|
|
1782
|
+
.superdoc__temp-selection[data-v-2a7bfa95] {
|
|
1783
1783
|
position: absolute;
|
|
1784
1784
|
}
|
|
1785
|
-
.superdoc__right-sidebar[data-v-
|
|
1785
|
+
.superdoc__right-sidebar[data-v-2a7bfa95] {
|
|
1786
1786
|
width: 320px;
|
|
1787
1787
|
min-width: 320px;
|
|
1788
1788
|
padding: 0 10px;
|
|
@@ -1790,7 +1790,7 @@ img[data-v-c95b2073] {
|
|
|
1790
1790
|
position: relative;
|
|
1791
1791
|
z-index: 2;
|
|
1792
1792
|
}
|
|
1793
|
-
.superdoc__compact-comment-popover[data-v-
|
|
1793
|
+
.superdoc__compact-comment-popover[data-v-2a7bfa95] {
|
|
1794
1794
|
position: absolute;
|
|
1795
1795
|
top: 12px;
|
|
1796
1796
|
right: 12px;
|
|
@@ -1799,14 +1799,14 @@ img[data-v-c95b2073] {
|
|
|
1799
1799
|
}
|
|
1800
1800
|
|
|
1801
1801
|
/* Tools styles */
|
|
1802
|
-
.tools[data-v-
|
|
1802
|
+
.tools[data-v-2a7bfa95] {
|
|
1803
1803
|
position: absolute;
|
|
1804
1804
|
z-index: 3;
|
|
1805
1805
|
display: flex;
|
|
1806
1806
|
flex-direction: column;
|
|
1807
1807
|
gap: var(--sd-ui-tools-gap, 6px);
|
|
1808
1808
|
}
|
|
1809
|
-
.tools-item[data-v-
|
|
1809
|
+
.tools-item[data-v-2a7bfa95] {
|
|
1810
1810
|
display: flex;
|
|
1811
1811
|
align-items: center;
|
|
1812
1812
|
justify-content: center;
|
|
@@ -1817,10 +1817,10 @@ img[data-v-c95b2073] {
|
|
|
1817
1817
|
cursor: pointer;
|
|
1818
1818
|
position: relative;
|
|
1819
1819
|
}
|
|
1820
|
-
.tools-item i[data-v-
|
|
1820
|
+
.tools-item i[data-v-2a7bfa95] {
|
|
1821
1821
|
cursor: pointer;
|
|
1822
1822
|
}
|
|
1823
|
-
.superdoc__tools-icon[data-v-
|
|
1823
|
+
.superdoc__tools-icon[data-v-2a7bfa95] {
|
|
1824
1824
|
width: var(--sd-ui-tools-icon-size, 20px);
|
|
1825
1825
|
height: var(--sd-ui-tools-icon-size, 20px);
|
|
1826
1826
|
flex-shrink: 0;
|
|
@@ -1835,22 +1835,22 @@ img[data-v-c95b2073] {
|
|
|
1835
1835
|
|
|
1836
1836
|
/* 834px is iPad screen size in portrait orientation */
|
|
1837
1837
|
@media (max-width: 834px) {
|
|
1838
|
-
.superdoc .superdoc__layers[data-v-
|
|
1838
|
+
.superdoc .superdoc__layers[data-v-2a7bfa95] {
|
|
1839
1839
|
margin: 0;
|
|
1840
1840
|
border: 0 !important;
|
|
1841
1841
|
box-shadow: none;
|
|
1842
1842
|
}
|
|
1843
|
-
.superdoc__sub-document[data-v-
|
|
1843
|
+
.superdoc__sub-document[data-v-2a7bfa95] {
|
|
1844
1844
|
max-width: 100%;
|
|
1845
1845
|
}
|
|
1846
|
-
.superdoc__right-sidebar[data-v-
|
|
1846
|
+
.superdoc__right-sidebar[data-v-2a7bfa95] {
|
|
1847
1847
|
padding: 10px;
|
|
1848
1848
|
position: relative;
|
|
1849
1849
|
}
|
|
1850
1850
|
}
|
|
1851
1851
|
|
|
1852
1852
|
/* AI Writer styles */
|
|
1853
|
-
.ai-writer-container[data-v-
|
|
1853
|
+
.ai-writer-container[data-v-2a7bfa95] {
|
|
1854
1854
|
position: fixed;
|
|
1855
1855
|
z-index: 1000;
|
|
1856
1856
|
background: white;
|
|
@@ -1866,10 +1866,10 @@ img[data-v-c95b2073] {
|
|
|
1866
1866
|
transform: translateY(-50%);
|
|
1867
1867
|
z-index: 50;
|
|
1868
1868
|
} */
|
|
1869
|
-
.ai-tool > svg[data-v-
|
|
1869
|
+
.ai-tool > svg[data-v-2a7bfa95] {
|
|
1870
1870
|
fill: transparent;
|
|
1871
1871
|
}
|
|
1872
|
-
.ai-tool[data-v-
|
|
1872
|
+
.ai-tool[data-v-2a7bfa95]::before {
|
|
1873
1873
|
content: '';
|
|
1874
1874
|
position: absolute;
|
|
1875
1875
|
width: 20px;
|
|
@@ -1890,7 +1890,7 @@ img[data-v-c95b2073] {
|
|
|
1890
1890
|
filter: brightness(1.2);
|
|
1891
1891
|
transition: filter 0.2s ease;
|
|
1892
1892
|
}
|
|
1893
|
-
.ai-tool[data-v-
|
|
1893
|
+
.ai-tool[data-v-2a7bfa95]:hover::before {
|
|
1894
1894
|
filter: brightness(1.3);
|
|
1895
1895
|
}
|
|
1896
1896
|
|
|
@@ -2,9 +2,12 @@ import { EventEmitter } from 'eventemitter3';
|
|
|
2
2
|
import { HocuspocusProviderWebsocket } from '@hocuspocus/provider';
|
|
3
3
|
import { createSuperdocVueApp } from './create-app.js';
|
|
4
4
|
import { Whiteboard } from './whiteboard/Whiteboard.js';
|
|
5
|
+
import { normalizeUiConfig } from './config/normalize-ui-config.js';
|
|
6
|
+
import { normalizeInteractionConfig } from './config/normalize-interaction-config.js';
|
|
7
|
+
import { normalizeSurfacesConfig } from './config/normalize-surfaces-config.js';
|
|
5
8
|
import { EditorRuntimeFocusOptions } from './editor-runtime/types.js';
|
|
6
9
|
import { BorrowedSuperDocUI } from '../public/ui/types.js';
|
|
7
|
-
import { AwarenessUser, CanPerformPermissionParams, CollaborationProvider, Config, ContentControlActiveChangePayload, ContentControlClickPayload, DocumentMode, Editor, EditorUpdateEvent, ExportParams, FontsChangedPayload, FontsResolvedPayload, InternalConfig, ListDefinitionsPayload, NavigableAddress, DocumentRendererRuntime, SearchMatch, SuperDocAwarenessUpdatePayload, SuperDocCommentsUpdatePayload, SuperDocEditorPayload, SuperDocExceptionPayload, SuperDocFontsApi, SuperDocLockedPayload, SuperDocMeasurementUnit, SuperDocMeasurementUnitChangePayload, SuperDocReadyPayload, SuperDocState, SuperDocViewportChangePayload, SuperDocViewportMetrics, SuperDocZoomMode, SuperDocZoomPayload, SuperDocZoomState, SurfaceHandle, SurfaceRequest, UpgradeToCollaborationOptions, User } from './types/index.js';
|
|
10
|
+
import { AwarenessUser, CanPerformPermissionParams, CollaborationProvider, Config, ContentControlActiveChangePayload, ContentControlClickPayload, DocumentMode, Editor, EditorUpdateEvent, ExportParams, FontsChangedPayload, FontsResolvedPayload, InternalConfig, ListDefinitionsPayload, NavigableAddress, DocumentRendererRuntime, SearchMatch, SuperDocAwarenessUpdatePayload, SuperDocCommentsUpdatePayload, SuperDocDocumentReplacedPayload, SuperDocEditorPayload, SuperDocExceptionPayload, SuperDocFontsApi, SuperDocLockedPayload, SuperDocMeasurementUnit, SuperDocMeasurementUnitChangePayload, SuperDocReadyPayload, SuperDocState, SuperDocViewportChangePayload, SuperDocViewportMetrics, SuperDocZoomMode, SuperDocZoomPayload, SuperDocZoomState, SurfaceHandle, SurfaceRequest, UpgradeToCollaborationOptions, User } from './types/index.js';
|
|
8
11
|
import { WhiteboardData } from './whiteboard/Whiteboard.js';
|
|
9
12
|
type ToolbarLike = {
|
|
10
13
|
activeEditor?: unknown;
|
|
@@ -61,6 +64,21 @@ interface SuperDocEventMap {
|
|
|
61
64
|
* neither a pre-ready read nor a clear would refresh without this.
|
|
62
65
|
*/
|
|
63
66
|
'active-editor-change': [];
|
|
67
|
+
/**
|
|
68
|
+
* `replaceFile()` swapped the content under a stable editor identity.
|
|
69
|
+
*
|
|
70
|
+
* Deliberately distinct from `active-editor-change`: the editor object and its
|
|
71
|
+
* host both survive a replace, so anything bound to the HOST — geometry
|
|
72
|
+
* observers, for one — is still attached to the thing now rendering the
|
|
73
|
+
* replacement and must not be torn down. Only state describing the previous
|
|
74
|
+
* document's content is stale.
|
|
75
|
+
*
|
|
76
|
+
* Emitted only after the replacement is confirmed, and carrying the editor
|
|
77
|
+
* whose replacement completed: a replace is asynchronous, so the active editor
|
|
78
|
+
* can move while it is in flight, and a consumer must ignore an event naming an
|
|
79
|
+
* editor it is not bound to.
|
|
80
|
+
*/
|
|
81
|
+
'document-replaced': [SuperDocDocumentReplacedPayload];
|
|
64
82
|
'editor-update': [EditorUpdateEvent];
|
|
65
83
|
'content-error': [SuperDocContentErrorPayload];
|
|
66
84
|
'fonts-resolved': [FontsResolvedPayload];
|
|
@@ -92,6 +110,30 @@ interface SuperDocEventMap {
|
|
|
92
110
|
export declare class SuperDoc extends EventEmitter<SuperDocEventMap> {
|
|
93
111
|
#private;
|
|
94
112
|
static allowedTypes: ("application/vnd.openxmlformats-officedocument.wordprocessingml.document" | "application/pdf" | "text/html")[];
|
|
113
|
+
/**
|
|
114
|
+
* Which built-in surfaces this instance renders.
|
|
115
|
+
*
|
|
116
|
+
* Resolved from {@link Config.ui}, falling back to the historical defaults
|
|
117
|
+
* when it is omitted. Read-only: changing what SuperDoc renders after mount
|
|
118
|
+
* is a per-surface concern, not a config swap.
|
|
119
|
+
*/
|
|
120
|
+
get uiConfig(): ReturnType<typeof normalizeUiConfig>;
|
|
121
|
+
/**
|
|
122
|
+
* What the user is permitted to do, as distinct from what SuperDoc draws.
|
|
123
|
+
*
|
|
124
|
+
* Resolved from {@link Config.interaction}. Stays meaningful when the
|
|
125
|
+
* application renders its own UI: `ui: false` removes the built-in comment
|
|
126
|
+
* dialog but not the policy that rejects a mutation.
|
|
127
|
+
*/
|
|
128
|
+
get interactionConfig(): ReturnType<typeof normalizeInteractionConfig>;
|
|
129
|
+
/**
|
|
130
|
+
* Shared plumbing for dialogs and floating overlays, including ones the
|
|
131
|
+
* application opens itself through `openSurface()`.
|
|
132
|
+
*
|
|
133
|
+
* Resolved from {@link Config.surfaces}. Unaffected by `ui: false`, which
|
|
134
|
+
* turns off SuperDoc's own surfaces without disabling the mechanism.
|
|
135
|
+
*/
|
|
136
|
+
get surfacesConfig(): ReturnType<typeof normalizeSurfacesConfig>;
|
|
95
137
|
/**
|
|
96
138
|
* Build-time SuperDoc version string. Initialized to `'0.0.0'` so the
|
|
97
139
|
* field is structurally assigned before the constructor runs, then
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Merge config layers without letting an explicit `undefined` erase a value.
|
|
3
|
+
*
|
|
4
|
+
* Object spread treats a present-but-undefined key as a real assignment, so
|
|
5
|
+
* `{ ...legacy, ...next }` clobbers `legacy.closeOnEscape` whenever `next`
|
|
6
|
+
* carries `closeOnEscape: undefined`. That shape is common and unintentional:
|
|
7
|
+
* configs assembled from optional properties, spreads, or destructured
|
|
8
|
+
* arguments routinely carry keys whose value is undefined without the consumer
|
|
9
|
+
* meaning anything by it.
|
|
10
|
+
*
|
|
11
|
+
* Everywhere this migration merges a new spelling over a legacy one, the rule
|
|
12
|
+
* is the same as the single-value case: `undefined` means "unset, fall
|
|
13
|
+
* through", and only an explicit value overrides.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Merge sources left to right, skipping keys whose value is `undefined`.
|
|
17
|
+
*
|
|
18
|
+
* Later sources win, as with spread. Non-object sources are ignored so callers
|
|
19
|
+
* can pass a possibly-absent block without guarding first.
|
|
20
|
+
*
|
|
21
|
+
* @param {...(Record<string, unknown> | undefined)} sources
|
|
22
|
+
* @returns {Record<string, unknown>}
|
|
23
|
+
*/
|
|
24
|
+
export function mergeDefined(...sources: (Record<string, unknown> | undefined)[]): Record<string, unknown>;
|
|
25
|
+
/**
|
|
26
|
+
* Pick the first defined value, so `undefined` falls through but `null`,
|
|
27
|
+
* `false`, and `0` are honored as deliberate choices.
|
|
28
|
+
*
|
|
29
|
+
* `??` already does this for null and undefined together, which is wrong when
|
|
30
|
+
* `null` carries meaning — clearing an inherited resolver, for instance.
|
|
31
|
+
*
|
|
32
|
+
* @param {...unknown} values
|
|
33
|
+
* @returns {unknown}
|
|
34
|
+
*/
|
|
35
|
+
export function firstDefined(...values: unknown[]): unknown;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve the effective interaction policy.
|
|
3
|
+
*
|
|
4
|
+
* Reads `interaction.comments` first, then the legacy fields on
|
|
5
|
+
* `modules.comments`, so both spellings work while the migration lands.
|
|
6
|
+
*
|
|
7
|
+
* @param {Record<string, any>} [config] Raw consumer config.
|
|
8
|
+
* @returns {{ comments: { readOnly: boolean, allowResolve: boolean } }}
|
|
9
|
+
*/
|
|
10
|
+
export function normalizeInteractionConfig(config?: Record<string, any>): {
|
|
11
|
+
comments: {
|
|
12
|
+
readOnly: boolean;
|
|
13
|
+
allowResolve: boolean;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve the generic surface infrastructure config.
|
|
3
|
+
*
|
|
4
|
+
* Reads top-level `surfaces` first, then the legacy `modules.surfaces` block,
|
|
5
|
+
* so both spellings work while the migration lands. Built-in surface intents
|
|
6
|
+
* are deliberately not read here; they belong to the UI profile.
|
|
7
|
+
*
|
|
8
|
+
* The resolved shape mirrors the public `SurfacesConfig`, with every member
|
|
9
|
+
* present: the presets are merged objects rather than optional, and `resolver`
|
|
10
|
+
* is a function or `null` once a non-function value has been rejected.
|
|
11
|
+
*
|
|
12
|
+
* @param {Record<string, any>} [config] Raw consumer config.
|
|
13
|
+
* @returns {{
|
|
14
|
+
* resolver: import('../types/index.js').SurfaceResolver | null,
|
|
15
|
+
* dialog: NonNullable<import('../types/index.js').SurfacesConfig['dialog']>,
|
|
16
|
+
* floating: NonNullable<import('../types/index.js').SurfacesConfig['floating']>,
|
|
17
|
+
* }}
|
|
18
|
+
*/
|
|
19
|
+
export function normalizeSurfacesConfig(config?: Record<string, any>): {
|
|
20
|
+
resolver: import('../types/index.js').SurfaceResolver | null;
|
|
21
|
+
dialog: NonNullable<import('../types/index.js').SurfacesConfig["dialog"]>;
|
|
22
|
+
floating: NonNullable<import('../types/index.js').SurfacesConfig["floating"]>;
|
|
23
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collapse a consumer config into the effective built-in UI profile.
|
|
3
|
+
*
|
|
4
|
+
* @param {Record<string, any>} [config] Raw consumer config.
|
|
5
|
+
* @returns {{
|
|
6
|
+
* enabled: boolean,
|
|
7
|
+
* toolbar: { enabled: boolean, container: string | HTMLElement | null, options: Record<string, unknown> },
|
|
8
|
+
* comments: { enabled: boolean, options: Record<string, unknown> },
|
|
9
|
+
* contextMenu: { enabled: boolean, suppressed: boolean, options: Record<string, unknown> },
|
|
10
|
+
* search: { enabled: boolean, options: Record<string, unknown> },
|
|
11
|
+
* linkPopover: { enabled: boolean, suppressed: boolean, options: Record<string, unknown> },
|
|
12
|
+
* ruler: { enabled: boolean, suppressed: boolean, container: string | HTMLElement | null },
|
|
13
|
+
* contentControls: { enabled: boolean, options: Record<string, unknown> },
|
|
14
|
+
* }}
|
|
15
|
+
*/
|
|
16
|
+
export function normalizeUiConfig(config?: Record<string, any>): {
|
|
17
|
+
enabled: boolean;
|
|
18
|
+
toolbar: {
|
|
19
|
+
enabled: boolean;
|
|
20
|
+
container: string | HTMLElement | null;
|
|
21
|
+
options: Record<string, unknown>;
|
|
22
|
+
};
|
|
23
|
+
comments: {
|
|
24
|
+
enabled: boolean;
|
|
25
|
+
options: Record<string, unknown>;
|
|
26
|
+
};
|
|
27
|
+
contextMenu: {
|
|
28
|
+
enabled: boolean;
|
|
29
|
+
suppressed: boolean;
|
|
30
|
+
options: Record<string, unknown>;
|
|
31
|
+
};
|
|
32
|
+
search: {
|
|
33
|
+
enabled: boolean;
|
|
34
|
+
options: Record<string, unknown>;
|
|
35
|
+
};
|
|
36
|
+
linkPopover: {
|
|
37
|
+
enabled: boolean;
|
|
38
|
+
suppressed: boolean;
|
|
39
|
+
options: Record<string, unknown>;
|
|
40
|
+
};
|
|
41
|
+
ruler: {
|
|
42
|
+
enabled: boolean;
|
|
43
|
+
suppressed: boolean;
|
|
44
|
+
container: string | HTMLElement | null;
|
|
45
|
+
};
|
|
46
|
+
contentControls: {
|
|
47
|
+
enabled: boolean;
|
|
48
|
+
options: Record<string, unknown>;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
/** Every built-in surface `ui: false` turns off. */
|
|
52
|
+
export const BUILT_IN_SURFACES: readonly string[];
|
|
53
|
+
/** Surfaces that render when the consumer says nothing at all. */
|
|
54
|
+
export const HISTORICAL_DEFAULTS: Readonly<{
|
|
55
|
+
toolbar: true;
|
|
56
|
+
comments: true;
|
|
57
|
+
contextMenu: true;
|
|
58
|
+
search: false;
|
|
59
|
+
linkPopover: false;
|
|
60
|
+
ruler: false;
|
|
61
|
+
contentControls: true;
|
|
62
|
+
}>;
|
|
@@ -995,8 +995,14 @@ export interface ExternalSurfaceRenderContext {
|
|
|
995
995
|
}
|
|
996
996
|
/** Module-level configuration for the surface system. */
|
|
997
997
|
export interface SurfacesModuleConfig {
|
|
998
|
-
/**
|
|
999
|
-
|
|
998
|
+
/**
|
|
999
|
+
* Global surface resolver.
|
|
1000
|
+
*
|
|
1001
|
+
* `null` is the resolved "no resolver" value the normalizer produces after
|
|
1002
|
+
* rejecting a non-function; SurfaceManager guards with `typeof === 'function'`
|
|
1003
|
+
* either way.
|
|
1004
|
+
*/
|
|
1005
|
+
resolver?: SurfaceResolver | null;
|
|
1000
1006
|
/** Default dialog options. */
|
|
1001
1007
|
dialog?: {
|
|
1002
1008
|
/** Default escape behavior for dialogs (default: true). */
|
|
@@ -1961,6 +1967,32 @@ export interface SuperDocReadyPayload {
|
|
|
1961
1967
|
export interface SuperDocEditorPayload {
|
|
1962
1968
|
editor: Editor;
|
|
1963
1969
|
}
|
|
1970
|
+
/**
|
|
1971
|
+
* Payload emitted with `document-replaced`.
|
|
1972
|
+
*
|
|
1973
|
+
* `editor` is the editor whose replacement completed, not necessarily the one
|
|
1974
|
+
* active when the event is received: a replace is asynchronous, so the active
|
|
1975
|
+
* editor can move while it is in flight. A consumer must compare this against
|
|
1976
|
+
* the editor it is bound to and ignore anything else.
|
|
1977
|
+
*
|
|
1978
|
+
* Typed `unknown` rather than `Editor`: the active editor can be a v2 facade
|
|
1979
|
+
* that does not satisfy `Editor` (`getHTML` is required there and absent on the
|
|
1980
|
+
* facade), so annotating it as `Editor` would promise methods that are not
|
|
1981
|
+
* present. It is an identity token to compare, not an object to call.
|
|
1982
|
+
*/
|
|
1983
|
+
export interface SuperDocDocumentReplacedPayload {
|
|
1984
|
+
editor: unknown;
|
|
1985
|
+
/**
|
|
1986
|
+
* The host that rendered the replaced document.
|
|
1987
|
+
*
|
|
1988
|
+
* Carried because `editor` alone cannot be matched in the V2 browser path: a
|
|
1989
|
+
* successful replace emits its ready payload before `replaceFile()` resolves,
|
|
1990
|
+
* so the shell has already installed a NEW facade by the time this event
|
|
1991
|
+
* fires, and the captured facade is one the controller no longer holds. The
|
|
1992
|
+
* host survives that swap, so it is the identity that still lines up.
|
|
1993
|
+
*/
|
|
1994
|
+
host: unknown;
|
|
1995
|
+
}
|
|
1964
1996
|
/**
|
|
1965
1997
|
* Payload emitted with the `locked` event and passed to
|
|
1966
1998
|
* `Config.onLocked`. `lockedBy` is non-optional because the runtime
|
|
@@ -2333,6 +2365,134 @@ export interface SuperDocZoomConfig {
|
|
|
2333
2365
|
/** Bounds and padding for the `fit-width` policy. */
|
|
2334
2366
|
fitWidth?: SuperDocFitWidthOptions;
|
|
2335
2367
|
}
|
|
2368
|
+
/**
|
|
2369
|
+
* Per-surface built-in UI configuration. Every field is optional; an omitted
|
|
2370
|
+
* field keeps that surface's historical default rather than inheriting from
|
|
2371
|
+
* its siblings, so a partial config only changes what it names.
|
|
2372
|
+
*
|
|
2373
|
+
* `false` disables a surface, `true` enables it with defaults, and an options
|
|
2374
|
+
* object both enables and configures it.
|
|
2375
|
+
*
|
|
2376
|
+
* @see {@link Config.ui}
|
|
2377
|
+
*/
|
|
2378
|
+
export interface UIConfig {
|
|
2379
|
+
/**
|
|
2380
|
+
* Built-in toolbar. Enabled by default, but a toolbar only appears once
|
|
2381
|
+
* `container` resolves to an element — enabling it without one creates the
|
|
2382
|
+
* `superdoc.toolbar` handle and renders nothing.
|
|
2383
|
+
*/
|
|
2384
|
+
toolbar?: boolean | {
|
|
2385
|
+
/**
|
|
2386
|
+
* Where to render the toolbar: an element, an id selector
|
|
2387
|
+
* (`#toolbar`), a class selector (`.toolbar`), or a bare element id.
|
|
2388
|
+
* Other CSS selector syntax resolves to nothing.
|
|
2389
|
+
*/
|
|
2390
|
+
container?: string | HTMLElement;
|
|
2391
|
+
/**
|
|
2392
|
+
* Which groups render, or what goes in them. The shape decides which
|
|
2393
|
+
* of the two it means, so both v1 spellings have somewhere to land.
|
|
2394
|
+
*
|
|
2395
|
+
* An array selects which groups render, e.g.
|
|
2396
|
+
* `['left', 'center', 'right']`. This is where `Config.toolbarGroups`
|
|
2397
|
+
* moves to. It is a membership list, not a sort order: the built-in
|
|
2398
|
+
* toolbar lays groups out left, center, right, and renders center
|
|
2399
|
+
* whether or not it is listed.
|
|
2400
|
+
*
|
|
2401
|
+
* An object is composition: a group id mapped to the item ids inside
|
|
2402
|
+
* it, e.g. `{ right: ['bold'] }`. This is where
|
|
2403
|
+
* `modules.toolbar.groups` moves to. Supplying both an ordering array
|
|
2404
|
+
* here and a legacy composition map keeps the composition and applies
|
|
2405
|
+
* the ordering as a filter.
|
|
2406
|
+
*/
|
|
2407
|
+
groups?: string[] | Record<string, string[]>;
|
|
2408
|
+
/** Toolbar item ids to hide from the default set. */
|
|
2409
|
+
excludeItems?: string[];
|
|
2410
|
+
/** Icon overrides, merged over the built-in set. */
|
|
2411
|
+
icons?: Record<string, unknown>;
|
|
2412
|
+
/** Text overrides, merged over the built-in set. */
|
|
2413
|
+
texts?: Record<string, unknown>;
|
|
2414
|
+
/** Size the toolbar to its container rather than the viewport. */
|
|
2415
|
+
responsiveToContainer?: boolean;
|
|
2416
|
+
};
|
|
2417
|
+
/** Built-in comments UI. Enabled by default. */
|
|
2418
|
+
comments?: boolean | Record<string, unknown>;
|
|
2419
|
+
/** Built-in right-click and slash context menu. Enabled by default. */
|
|
2420
|
+
contextMenu?: boolean | Record<string, unknown>;
|
|
2421
|
+
/**
|
|
2422
|
+
* Built-in find/replace surface. Disabled by default. Enabling it lets
|
|
2423
|
+
* SuperDoc intercept Cmd+F / Ctrl+F; `editor.ui.search` stays available to
|
|
2424
|
+
* custom UI either way.
|
|
2425
|
+
*/
|
|
2426
|
+
search?: boolean | Record<string, unknown>;
|
|
2427
|
+
/** Built-in popover shown when a link is selected. Disabled by default. */
|
|
2428
|
+
linkPopover?: boolean | Record<string, unknown>;
|
|
2429
|
+
/** Built-in ruler. Disabled by default. */
|
|
2430
|
+
ruler?: boolean | {
|
|
2431
|
+
/** Element or selector to render the ruler into. */
|
|
2432
|
+
container?: string | HTMLElement;
|
|
2433
|
+
};
|
|
2434
|
+
/** Built-in chrome drawn around content controls. Enabled by default. */
|
|
2435
|
+
contentControls?: boolean | Record<string, unknown>;
|
|
2436
|
+
}
|
|
2437
|
+
/**
|
|
2438
|
+
* What the user is permitted to do, as distinct from what SuperDoc draws.
|
|
2439
|
+
*
|
|
2440
|
+
* Policy outlives presentation: `ui: false` removes the built-in comment
|
|
2441
|
+
* dialog, but an application rendering its own still needs `readOnly`
|
|
2442
|
+
* enforced. Keeping the two apart means a custom UI does not have to hold a
|
|
2443
|
+
* `modules.comments` object alive purely to carry policy.
|
|
2444
|
+
*/
|
|
2445
|
+
export interface InteractionConfig {
|
|
2446
|
+
/** Comment and tracked-change interaction policy. */
|
|
2447
|
+
comments?: {
|
|
2448
|
+
/** Reject every comment and tracked-change mutation (default: false). */
|
|
2449
|
+
readOnly?: boolean;
|
|
2450
|
+
/** Offer resolve/reopen actions when writable (default: true). */
|
|
2451
|
+
allowResolve?: boolean;
|
|
2452
|
+
};
|
|
2453
|
+
}
|
|
2454
|
+
/**
|
|
2455
|
+
* Shared plumbing for dialogs and floating overlays, including surfaces the
|
|
2456
|
+
* application opens itself through `superdoc.openSurface()`.
|
|
2457
|
+
*
|
|
2458
|
+
* Unaffected by `ui: false`: turning off SuperDoc's own surfaces does not
|
|
2459
|
+
* disable the mechanism an application uses to render its own.
|
|
2460
|
+
*/
|
|
2461
|
+
export interface SurfacesConfig {
|
|
2462
|
+
/**
|
|
2463
|
+
* Resolver for intent-based surface requests.
|
|
2464
|
+
*
|
|
2465
|
+
* `null` explicitly clears a resolver inherited from the legacy
|
|
2466
|
+
* `modules.surfaces.resolver`, which omitting the key does not do.
|
|
2467
|
+
*/
|
|
2468
|
+
resolver?: SurfaceResolver | null;
|
|
2469
|
+
/** Defaults applied to dialog surfaces. */
|
|
2470
|
+
dialog?: {
|
|
2471
|
+
/** Close on Escape (default: true). */
|
|
2472
|
+
closeOnEscape?: boolean;
|
|
2473
|
+
/** Close on backdrop click (default: true). */
|
|
2474
|
+
closeOnBackdrop?: boolean;
|
|
2475
|
+
/** Default max width. */
|
|
2476
|
+
maxWidth?: string | number;
|
|
2477
|
+
};
|
|
2478
|
+
/** Defaults applied to floating surfaces. */
|
|
2479
|
+
floating?: {
|
|
2480
|
+
/** Placement preset (default: 'top-right'). */
|
|
2481
|
+
placement?: SurfaceFloatingPlacement;
|
|
2482
|
+
/** Default width. */
|
|
2483
|
+
width?: string | number;
|
|
2484
|
+
/** Default max width. */
|
|
2485
|
+
maxWidth?: string | number;
|
|
2486
|
+
/** Default max height. */
|
|
2487
|
+
maxHeight?: string | number;
|
|
2488
|
+
/** Close on Escape (default: true). */
|
|
2489
|
+
closeOnEscape?: boolean;
|
|
2490
|
+
/** Close on outside pointer down (default: false). */
|
|
2491
|
+
closeOnOutsidePointerDown?: boolean;
|
|
2492
|
+
/** Focus the surface on open (default: true). */
|
|
2493
|
+
autoFocus?: boolean;
|
|
2494
|
+
};
|
|
2495
|
+
}
|
|
2336
2496
|
export interface Config {
|
|
2337
2497
|
/** The ID of the SuperDoc. */
|
|
2338
2498
|
superdocId?: string;
|
|
@@ -2380,6 +2540,53 @@ export interface Config {
|
|
|
2380
2540
|
users?: User[];
|
|
2381
2541
|
/** Colors to use for user awareness. */
|
|
2382
2542
|
colors?: string[];
|
|
2543
|
+
/**
|
|
2544
|
+
* Which built-in interface SuperDoc renders.
|
|
2545
|
+
*
|
|
2546
|
+
* Omit it to keep SuperDoc's historical rendering: comments, the context
|
|
2547
|
+
* menu, and content-control chrome are on; search, the link popover, and
|
|
2548
|
+
* the ruler are opt-in; and the toolbar renders once it has somewhere to
|
|
2549
|
+
* mount. That profile is not symmetrical, and omitting this field
|
|
2550
|
+
* reproduces it exactly.
|
|
2551
|
+
*
|
|
2552
|
+
* Pass `false` when the application owns the interface. SuperDoc then
|
|
2553
|
+
* renders no controls, chrome, dialogs, or popovers, while the document,
|
|
2554
|
+
* the Document API, and `editor.ui` keep working — so a custom UI drives
|
|
2555
|
+
* the same commands the built-in one would have.
|
|
2556
|
+
*
|
|
2557
|
+
* Pass an object to choose per surface. An omitted key keeps that
|
|
2558
|
+
* surface's default rather than following its siblings, so
|
|
2559
|
+
* `{ comments: false }` disables comments and changes nothing else.
|
|
2560
|
+
*
|
|
2561
|
+
* @example
|
|
2562
|
+
* // Application owns the interface.
|
|
2563
|
+
* new SuperDoc({ selector: '#editor', document: file, ui: false });
|
|
2564
|
+
*
|
|
2565
|
+
* @example
|
|
2566
|
+
* // Built-in toolbar and search, no comments or context menu.
|
|
2567
|
+
* new SuperDoc({
|
|
2568
|
+
* selector: '#editor',
|
|
2569
|
+
* document: file,
|
|
2570
|
+
* ui: {
|
|
2571
|
+
* toolbar: { container: '#toolbar' },
|
|
2572
|
+
* search: true,
|
|
2573
|
+
* comments: false,
|
|
2574
|
+
* contextMenu: false,
|
|
2575
|
+
* },
|
|
2576
|
+
* });
|
|
2577
|
+
*/
|
|
2578
|
+
ui?: false | UIConfig;
|
|
2579
|
+
/**
|
|
2580
|
+
* What the user is permitted to do. Independent of {@link Config.ui}: a
|
|
2581
|
+
* `readOnly` policy still applies when the application renders its own
|
|
2582
|
+
* comment UI.
|
|
2583
|
+
*/
|
|
2584
|
+
interaction?: InteractionConfig;
|
|
2585
|
+
/**
|
|
2586
|
+
* Shared configuration for dialogs and floating overlays, including ones
|
|
2587
|
+
* opened through `superdoc.openSurface()`. Stays active under `ui: false`.
|
|
2588
|
+
*/
|
|
2589
|
+
surfaces?: SurfacesConfig;
|
|
2383
2590
|
/** Modules to load. */
|
|
2384
2591
|
modules?: Modules;
|
|
2385
2592
|
/** Top-level override for permission checks. */
|