superdoc 2.4.0-next.4 → 2.4.0-next.41
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 +13 -13
- package/README.md +19 -22
- package/dist/chunks/{FindReplaceSurface-Dx0llWqP.cjs → FindReplaceSurface-0p7EtMZh.cjs} +4 -4
- package/dist/chunks/{FindReplaceSurface-BEW-1NhM.es.js → FindReplaceSurface-40AnrqWk.es.js} +5 -4
- package/dist/chunks/{PasswordPromptSurface-BUUVC2ee.cjs → PasswordPromptSurface-31lYPcCK.cjs} +4 -3
- package/dist/chunks/{PasswordPromptSurface-BA6HHqEa.es.js → PasswordPromptSurface-CwYeO3iQ.es.js} +4 -2
- package/dist/chunks/{PdfViewer-CNOtyS-I.es.js → PdfViewer-D8h7LRZy.es.js} +103 -19
- package/dist/chunks/{PdfViewer-qpvzwYMz.cjs → PdfViewer-Dug6yDRC.cjs} +105 -20
- package/dist/chunks/_plugin-vue_export-helper-BOaGB7Aw.es.js +8 -0
- package/dist/chunks/_plugin-vue_export-helper-SDR04tiH.cjs +13 -0
- package/dist/chunks/{blank-docx-DP8RUPW-.cjs → blank-docx-BuFAbRjs.cjs} +2 -0
- package/dist/chunks/{blank-docx-XRX6Ker2.es.js → blank-docx-DzQccOlW.es.js} +2 -0
- package/dist/chunks/constants-B6VBlmKp.es.js +4 -0
- package/dist/chunks/constants-DpXuDx_g.cjs +9 -0
- package/dist/chunks/{create-super-doc-ui-Dli6Wq70.es.js → create-super-doc-ui-B5SqT0gL.es.js} +2114 -1146
- package/dist/chunks/{create-super-doc-ui-BHMQEL2y.cjs → create-super-doc-ui-Dmv8Hjs6.cjs} +1924 -1190
- package/dist/chunks/{eventemitter3-Bt2s0X0a.es.js → eventemitter3-CMOjDs74.es.js} +124 -16
- package/dist/chunks/{eventemitter3-DqY4aSMf.cjs → eventemitter3-D38u8ta_.cjs} +125 -16
- package/dist/chunks/jszip-RC64TPzL.cjs +4758 -0
- package/dist/chunks/jszip-VxCFV9YS.es.js +4717 -0
- package/dist/chunks/{rolldown-runtime-D7PMmH3s.es.js → rolldown-runtime-B5TtN50X.es.js} +13 -4
- package/dist/chunks/{rolldown-runtime-1Y-nnZJ3.cjs → rolldown-runtime-DtsSbkrh.cjs} +12 -3
- package/dist/chunks/{uuid-CFp0WGVU.cjs → uuid-BhG0ngwk.cjs} +10 -6
- package/dist/chunks/{uuid-B2Sqk-3p.es.js → uuid-H0Xcmmhy.es.js} +8 -3
- package/dist/collaboration-upgrade-engine.cjs +34 -9
- package/dist/collaboration-upgrade-engine.es.js +30 -5
- package/dist/document-api/src/citations/citations.types.d.ts +9 -0
- package/dist/document-api/src/comments/comments.types.d.ts +7 -0
- package/dist/document-api/src/types/receipt.d.ts +9 -5
- package/dist/document-api/src/types/track-changes.types.d.ts +18 -3
- package/dist/layout-engine/contracts/src/incremental-dependency.d.ts +22 -2
- package/dist/layout-engine/contracts/src/index.d.ts +83 -2
- package/dist/layout-engine/contracts/src/inline-box.d.ts +19 -0
- package/dist/layout-engine/contracts/src/paragraph-visible-text.d.ts +19 -0
- package/dist/layout-engine/layout-bridge/src/hydrateTableTextboxMeasures.d.ts +9 -0
- package/dist/layout-engine/layout-bridge/src/incrementalLayout.d.ts +28 -10
- package/dist/layout-engine/layout-bridge/src/index.d.ts +4 -2
- package/dist/layout-engine/layout-bridge/src/inline-box-key.d.ts +3 -0
- package/dist/layout-engine/layout-bridge/src/layoutHeaderFooter.d.ts +10 -3
- package/dist/layout-engine/layout-bridge/src/run-visual-marks.d.ts +2 -0
- package/dist/layout-engine/layout-bridge/src/text-measurement.d.ts +0 -12
- package/dist/layout-engine/layout-engine/src/anchors.d.ts +4 -0
- package/dist/layout-engine/layout-engine/src/execution.d.ts +21 -0
- package/dist/layout-engine/layout-engine/src/floating-table-anchor.d.ts +2 -0
- package/dist/layout-engine/layout-engine/src/footnote-anchor-index.d.ts +17 -0
- package/dist/layout-engine/layout-engine/src/index.d.ts +10 -7
- package/dist/layout-engine/layout-engine/src/pageNumbering.d.ts +3 -41
- package/dist/layout-engine/layout-engine/src/resolvePageTokens.d.ts +2 -0
- package/dist/layout-engine/layout-engine/src/section-props.d.ts +5 -0
- package/dist/layout-engine/painters/dom/src/runs/inline-box.d.ts +8 -0
- package/dist/layout-engine/painters/dom/src/runs/text-run.d.ts +6 -4
- package/dist/layout-engine/style-engine/src/ooxml/word-style-model/parse-theme.d.ts +6 -0
- package/dist/public/ui-react.cjs +66 -2
- package/dist/public/ui-react.es.js +66 -1
- package/dist/public/ui.cjs +1 -1
- package/dist/public/ui.es.js +1 -1
- package/dist/style.css +174 -138
- package/dist/style.layered.css +174 -138
- package/dist/superdoc/src/components/CommentsLayer/CommentDialog.vue.d.ts +2 -0
- package/dist/superdoc/src/components/CommentsLayer/commentsList/ReviewDirectoryListItem.vue.d.ts +16 -0
- package/dist/superdoc/src/components/CommentsLayer/commentsList/commentsList.vue.d.ts +3 -1
- package/dist/superdoc/src/components/CommentsLayer/commentsList/super-comments-list.d.ts +12 -0
- package/dist/superdoc/src/core/SuperDoc.d.ts +10 -7
- package/dist/superdoc/src/core/extensions/index.d.ts +1 -1
- package/dist/superdoc/src/core/extensions/types.d.ts +63 -5
- package/dist/superdoc/src/core/types/index.d.ts +535 -42
- package/dist/superdoc/src/core/v2-integration/v2-integration.d.ts +3 -3
- package/dist/superdoc/src/helpers/comment-small-screen.d.ts +10 -0
- package/dist/superdoc/src/helpers/v2-review-mutation-impact.d.ts +3 -5
- package/dist/superdoc/src/internal/toolbar/built-in/ToolbarButton.vue.d.ts +4 -4
- package/dist/superdoc/src/internal/toolbar/built-in-toolbar.d.ts +11 -0
- package/dist/superdoc/src/internal/toolbar/compatibility-catalog.d.ts +1 -1
- package/dist/superdoc/src/public/index.d.cts +28 -0
- package/dist/superdoc/src/public/index.d.ts +14 -0
- package/dist/superdoc/src/public/ui/types.d.ts +30 -6
- package/dist/superdoc/src/stores/comments-store.d.ts +81 -78
- package/dist/superdoc/src/stores/superdoc-store.d.ts +243 -234
- package/dist/superdoc.cjs +6790 -2159
- package/dist/superdoc.es.js +6663 -2032
- 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 +14 -14
- package/dist/chunks/_plugin-vue_export-helper-BTwbGDKw.cjs +0 -11
- package/dist/chunks/_plugin-vue_export-helper-CInC0bKI.es.js +0 -6
- package/dist/chunks/constants-CY3R3_kF.es.js +0 -3
- package/dist/chunks/constants-sbCZ2O_A.cjs +0 -14
- package/dist/chunks/jszip-C8srOKAO.es.js +0 -4650
- package/dist/chunks/jszip-Cs9JBLlJ.cjs +0 -4691
- package/dist/superdoc/src/helpers/v2-remote-review-hydration.d.ts +0 -12
- package/dist/superdoc/src/helpers/v2-review-mutation-reconciler.d.ts +0 -19
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { PageCheckpointDependencyClass, FlowBlock, Layout, Measure, HeaderFooterLayout,
|
|
1
|
+
import { NonFlowingPageRelativeAnchorDependencyProof, PageCheckpointDependencyClass, FlowBlock, Layout, Measure, HeaderFooterLayout, ColumnLayout } from '../../contracts/src/index.js';
|
|
2
2
|
import { FontMeasureContext } from '../../../shared/font-system/src/index.js';
|
|
3
|
-
import { LayoutOptions, HeaderFooterConstraints } from '../../layout-engine/src/index.js';
|
|
3
|
+
import { LayoutOptions, HeaderFooterConstraints, LayoutExecutionCheckpoint } from '../../layout-engine/src/index.js';
|
|
4
4
|
import { computeDirtyRegions } from './diff.js';
|
|
5
5
|
import { MeasureCache } from './cache.js';
|
|
6
6
|
import { HeaderFooterBatch } from './layoutHeaderFooter.js';
|
|
@@ -52,6 +52,8 @@ export type FootnoteReserveSeed = {
|
|
|
52
52
|
};
|
|
53
53
|
export type IncrementalLayoutResult = {
|
|
54
54
|
layout: Layout;
|
|
55
|
+
/** Pass-owned block plane after derived layout annotations are attached. */
|
|
56
|
+
blocks: FlowBlock[];
|
|
55
57
|
measures: Measure[];
|
|
56
58
|
dirty: ReturnType<typeof computeDirtyRegions>;
|
|
57
59
|
headers?: HeaderFooterLayoutResult[];
|
|
@@ -117,6 +119,16 @@ export type IncrementalLayoutBridgeTiming = {
|
|
|
117
119
|
measuresAdopted: number;
|
|
118
120
|
pagesPaginated: number | null;
|
|
119
121
|
pagesSplicedByReuse: number;
|
|
122
|
+
paginationPasses: number;
|
|
123
|
+
pageTokenRelayouts: number;
|
|
124
|
+
footnoteRelayouts: number;
|
|
125
|
+
footnoteReserveRelayouts: number;
|
|
126
|
+
footnoteGrowRelayouts: number;
|
|
127
|
+
footnoteTightenRelayouts: number;
|
|
128
|
+
footnotePreferredRelayouts: number;
|
|
129
|
+
footnoteWidowRelayouts: number;
|
|
130
|
+
footnoteRevertRelayouts: number;
|
|
131
|
+
footnoteOtherRelayouts: number;
|
|
120
132
|
};
|
|
121
133
|
};
|
|
122
134
|
/**
|
|
@@ -168,6 +180,13 @@ export type IncrementalSectionPageNumberTransform = {
|
|
|
168
180
|
/** Difference between target and source section-relative page positions. */
|
|
169
181
|
delta: number;
|
|
170
182
|
};
|
|
183
|
+
export type IncrementalDisplayPageNumberTransform = {
|
|
184
|
+
/** First section whose retained display-page values inherit the local page delta. */
|
|
185
|
+
startSectionIndex: number;
|
|
186
|
+
/** First later section with an explicit numbering restart. */
|
|
187
|
+
endSectionIndexExclusive: number;
|
|
188
|
+
delta: number;
|
|
189
|
+
};
|
|
171
190
|
export type IncrementalLayoutTailAdoption = {
|
|
172
191
|
startPageIndex: number;
|
|
173
192
|
endPageIndexExclusive: number;
|
|
@@ -175,6 +194,7 @@ export type IncrementalLayoutTailAdoption = {
|
|
|
175
194
|
sourcePageEndIndexExclusive: number;
|
|
176
195
|
pageIndexDelta: number;
|
|
177
196
|
sectionPageNumberTransform: IncrementalSectionPageNumberTransform | null;
|
|
197
|
+
displayPageNumberTransform?: IncrementalDisplayPageNumberTransform | null;
|
|
178
198
|
sourceLayoutEpoch: number | null;
|
|
179
199
|
positionTransforms: readonly LayoutPositionTransform[];
|
|
180
200
|
/** Lazy old->current block-id rekeys for an ordinal-changing structural splice. */
|
|
@@ -207,6 +227,7 @@ export type IncrementalPaginationProof = IncrementalPaginationProofBase & ({
|
|
|
207
227
|
globalDependenciesAbsent: false;
|
|
208
228
|
globalDependenciesFencedByPageCheckpoint: true;
|
|
209
229
|
admittedDependencyClasses: readonly PageCheckpointDependencyClass[];
|
|
230
|
+
nonFlowingPageRelativeAnchorDependency?: NonFlowingPageRelativeAnchorDependencyProof;
|
|
210
231
|
localKeepDependencyClosure?: {
|
|
211
232
|
checkpointPageIndex: number;
|
|
212
233
|
checkpointBlockId: string | null;
|
|
@@ -276,10 +297,13 @@ export declare const measureCache: MeasureCache<Measure>;
|
|
|
276
297
|
*/
|
|
277
298
|
export declare function clearIncrementalModuleState(): void;
|
|
278
299
|
export interface IncrementalLayoutExecutionControl {
|
|
300
|
+
signal?: AbortSignal;
|
|
279
301
|
/** Budget-aware host-task yield; may resolve immediately. */
|
|
280
|
-
yieldToHost?: () => Promise<void>;
|
|
281
|
-
/**
|
|
302
|
+
yieldToHost?: (checkpoint?: LayoutExecutionCheckpoint) => Promise<void>;
|
|
303
|
+
/** Measurement checkpoints default to 32 blocks; nested layout checkpoints default to 16. */
|
|
282
304
|
yieldEveryBlocks?: number;
|
|
305
|
+
/** Time-aware mounted probe. Null is the allocation-free under-budget path. */
|
|
306
|
+
checkpointIfDue?: (checkpoint?: LayoutExecutionCheckpoint) => Promise<void> | null;
|
|
283
307
|
}
|
|
284
308
|
export declare function incrementalLayout(previousBlocks: FlowBlock[], _previousLayout: Layout | null, nextBlocks: FlowBlock[], options: LayoutOptions, measureBlock: (block: FlowBlock, constraints: {
|
|
285
309
|
maxWidth: number;
|
|
@@ -325,12 +349,6 @@ export declare function incrementalLayout(previousBlocks: FlowBlock[], _previous
|
|
|
325
349
|
* @returns The normalized margin value (guaranteed to be finite)
|
|
326
350
|
*/
|
|
327
351
|
export declare const normalizeMargin: (value: number | undefined, fallback: number) => number;
|
|
328
|
-
/**
|
|
329
|
-
* Walks table blocks (including nested tables) and computes `contentMeasures` for any
|
|
330
|
-
* `textboxShape` drawings found in table cells. Stores results directly on the block so
|
|
331
|
-
* the painter can read them without a `DrawingFragment` (table-cell drawings have none).
|
|
332
|
-
*/
|
|
333
|
-
export declare function hydrateTableTextboxMeasures(blocks: FlowBlock[], remeasure: (block: ParagraphBlock, maxWidth: number) => ParagraphMeasure): void;
|
|
334
352
|
/**
|
|
335
353
|
* Resolves the maximum measurement constraints (width and height) needed for measuring blocks
|
|
336
354
|
* across all sections in a document.
|
|
@@ -11,8 +11,10 @@ export { findWordBoundaries, findParagraphBoundaries } from './text-boundaries.j
|
|
|
11
11
|
export type { BoundaryRange } from './text-boundaries.js';
|
|
12
12
|
export { buildSectionAwareHeaderFooterLayoutKey, buildSectionContentWidth, buildEffectiveHeaderFooterRefsBySection, collectReferencedHeaderFooterRIds, buildSectionAwareHeaderFooterMeasurementGroups, } from './sectionAwareHeaderFooter.js';
|
|
13
13
|
export type { HeaderFooterSectionKind, HeaderFooterRefs, SectionAwareHeaderFooterMeasurementGroup, } from './sectionAwareHeaderFooter.js';
|
|
14
|
-
export { clearIncrementalModuleState, incrementalLayout, measureCache, normalizeMargin
|
|
15
|
-
export
|
|
14
|
+
export { clearIncrementalModuleState, incrementalLayout, measureCache, normalizeMargin } from './incrementalLayout.js';
|
|
15
|
+
export { hydrateTableTextboxMeasures } from './hydrateTableTextboxMeasures.js';
|
|
16
|
+
export { hashMeasureContent } from './cache.js';
|
|
17
|
+
export type { HeaderFooterLayoutResult, IncrementalLayoutBridgeTiming, IncrementalLayoutResult, IncrementalLayoutExecutionControl, IncrementalMeasureReuseProof, IncrementalLayoutReuseOptions, IncrementalLayoutReuseSummary, IncrementalSectionPageNumberTransform, IncrementalLayoutTailAdoption, IncrementalLayoutTailDisposition, IncrementalPaginationProof, LayoutPositionTransform, FootnoteReserveSeed, } from './incrementalLayout.js';
|
|
16
18
|
export { collectFootnoteLedgers, getPreferredReserveCandidates, getPreferredReserveTrialTargets, isMandatoryOnlyFootnotePage, scoreFootnoteWindow, summarizeFootnoteWindow, } from './footnote-scorer.js';
|
|
17
19
|
export type { FootnotePreferredReserveCandidate, FootnoteWindowScoreInput, FootnoteWindowScoreReason, FootnoteWindowScoreResult, FootnoteWindowStats, } from './footnote-scorer.js';
|
|
18
20
|
export { computeDisplayPageNumber } from '../../layout-engine/src/index.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FlowBlock, HeaderFooterLayout, Measure, PageNumberChapterSeparator, PageNumberFormat, ParagraphBlock, ParagraphMeasure } from '../../contracts/src/index.js';
|
|
2
|
-
import { HeaderFooterConstraints } from '../../layout-engine/src/index.js';
|
|
2
|
+
import { HeaderFooterConstraints, LayoutExecutionCheckpoint, LayoutExecutionControl } from '../../layout-engine/src/index.js';
|
|
3
3
|
import { MeasureCache } from './cache.js';
|
|
4
4
|
import { ResolveHeaderFooterTokensOptions } from './resolveHeaderFooterTokens.js';
|
|
5
5
|
export type HeaderFooterBatch = Partial<Record<'default' | 'first' | 'even' | 'odd', FlowBlock[]>>;
|
|
@@ -28,6 +28,13 @@ export type PageResolver = (pageNumber: number) => {
|
|
|
28
28
|
chapterNumberText?: string;
|
|
29
29
|
chapterSeparator?: PageNumberChapterSeparator;
|
|
30
30
|
};
|
|
31
|
+
/** Optional cooperative execution hooks for browser-owned furniture builds. */
|
|
32
|
+
export interface HeaderFooterLayoutExecution extends LayoutExecutionControl {
|
|
33
|
+
/** Time-aware mounted probe. Null is the allocation-free under-budget path. */
|
|
34
|
+
checkpointIfDue?: (checkpoint?: LayoutExecutionCheckpoint) => Promise<void> | null;
|
|
35
|
+
/** Exact physical pages whose PAGE contexts are missing from a retained layout entry. */
|
|
36
|
+
pageNumbers?: readonly number[];
|
|
37
|
+
}
|
|
31
38
|
/**
|
|
32
39
|
* Digit bucket for page number caching strategy.
|
|
33
40
|
* Different digit lengths require different measurements due to width changes.
|
|
@@ -85,7 +92,7 @@ export declare class HeaderFooterLayoutCache {
|
|
|
85
92
|
measureBlocks(blocks: FlowBlock[], constraints: {
|
|
86
93
|
width: number;
|
|
87
94
|
height: number;
|
|
88
|
-
}, measureBlock: MeasureResolver, fontSignature?: string): Promise<Measure[]>;
|
|
95
|
+
}, measureBlock: MeasureResolver, fontSignature?: string, execution?: LayoutExecutionControl): Promise<Measure[]>;
|
|
89
96
|
invalidate(blockIds: string[]): void;
|
|
90
97
|
/**
|
|
91
98
|
* Gets cache statistics for monitoring and debugging.
|
|
@@ -120,4 +127,4 @@ export declare function invalidateHeaderFooterMeasureCache(blockIds: string[]):
|
|
|
120
127
|
* @param pageResolver - Callback to resolve display page info for a physical page number
|
|
121
128
|
* @returns Batch result with layouts, blocks, and measures for each variant
|
|
122
129
|
*/
|
|
123
|
-
export declare function layoutHeaderFooterWithCache(sections: HeaderFooterBatch, constraints: HeaderFooterConstraints, measureBlock: MeasureResolver, cache?: HeaderFooterLayoutCache, totalPages?: number, pageResolver?: PageResolver, kind?: 'header' | 'footer', fontSignature?: string, remeasureParagraph?: (block: ParagraphBlock, maxWidth: number, firstLineIndent?: number) => ParagraphMeasure, options?: ResolveHeaderFooterTokensOptions): Promise<HeaderFooterBatchResult>;
|
|
130
|
+
export declare function layoutHeaderFooterWithCache(sections: HeaderFooterBatch, constraints: HeaderFooterConstraints, measureBlock: MeasureResolver, cache?: HeaderFooterLayoutCache, totalPages?: number, pageResolver?: PageResolver, kind?: 'header' | 'footer', fontSignature?: string, remeasureParagraph?: (block: ParagraphBlock, maxWidth: number, firstLineIndent?: number) => ParagraphMeasure, options?: ResolveHeaderFooterTokensOptions, execution?: HeaderFooterLayoutExecution): Promise<HeaderFooterBatchResult>;
|
|
@@ -5,6 +5,8 @@ import { Run } from '../../contracts/src/index.js';
|
|
|
5
5
|
* Include every run property that affects text measurement or painted output but is not
|
|
6
6
|
* covered elsewhere (e.g. tracked-change / comment keys). When adding a new visual
|
|
7
7
|
* property, update this function only — `cache.ts` and `diff.ts` both depend on it.
|
|
8
|
+
* Paragraph-scoped inline boxes are deliberately keyed by `inline-box-key.ts`,
|
|
9
|
+
* not by this run-scoped helper.
|
|
8
10
|
*
|
|
9
11
|
* @param run - Flow run (text, tab, image, etc.); unknown fields are ignored safely.
|
|
10
12
|
* @returns Stable string encoding bold/italic/underline/strike/color/font/highlight/link.
|
|
@@ -7,18 +7,6 @@ import { FontMeasureContext } from '../../../shared/font-system/src/index.js';
|
|
|
7
7
|
* @returns CSS font string (e.g., "italic bold 16px Arial")
|
|
8
8
|
*/
|
|
9
9
|
export declare function getRunFontString(run: Run, fontContext?: FontMeasureContext): string;
|
|
10
|
-
/**
|
|
11
|
-
* Measure the X position for a specific character offset within a line.
|
|
12
|
-
* Uses Canvas measureText for pixel-perfect accuracy.
|
|
13
|
-
*
|
|
14
|
-
* @param block - The paragraph block containing the line
|
|
15
|
-
* @param line - The line to measure within
|
|
16
|
-
* @param charOffset - Character offset from the start of the line (0-based)
|
|
17
|
-
* @param availableWidthOverride - Optional override for available width
|
|
18
|
-
* @param alignmentOverride - Optional override for text alignment (e.g., 'left' for list items
|
|
19
|
-
* which are always rendered left-aligned in the DOM regardless of paragraph alignment)
|
|
20
|
-
* @returns The X coordinate (in pixels) from the start of the line
|
|
21
|
-
*/
|
|
22
10
|
export declare function measureCharacterX(block: FlowBlock, line: Line, charOffset: number, availableWidthOverride?: number, alignmentOverride?: string, fontContext?: FontMeasureContext): number;
|
|
23
11
|
/**
|
|
24
12
|
* Convert a character offset within a line back to a ProseMirror position.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FlowBlock, ImageBlock, ImageMeasure, Measure, DrawingBlock, DrawingMeasure, TableBlock, TableMeasure, isPageRelativeAnchor } from '../../contracts/src/index.js';
|
|
2
2
|
import { resolveFloatingTableAnchorResolution } from './floating-table-anchor.js';
|
|
3
|
+
import { LayoutWorkCheckpoint } from './execution.js';
|
|
3
4
|
export type { FloatingTableAnchorResolution } from './floating-table-anchor.js';
|
|
4
5
|
export { resolveFloatingTableAnchorResolution };
|
|
5
6
|
export { isPageRelativeAnchor };
|
|
@@ -39,14 +40,17 @@ export type AnchoredTableCollection = {
|
|
|
39
40
|
* @param measures - Corresponding measures for each block
|
|
40
41
|
* @returns Array of anchored drawings that should be pre-registered
|
|
41
42
|
*/
|
|
43
|
+
export declare function collectPreRegisteredAnchorsSteps(blocks: FlowBlock[], measures: Measure[], checkpointEveryBlocks?: number | null): Generator<LayoutWorkCheckpoint, AnchoredDrawing[], void>;
|
|
42
44
|
export declare function collectPreRegisteredAnchors(blocks: FlowBlock[], measures: Measure[]): AnchoredDrawing[];
|
|
43
45
|
/**
|
|
44
46
|
* Collect anchored drawings (images/drawings) mapped to their anchor paragraph index.
|
|
45
47
|
* Map of paragraph block index -> anchored images/drawings associated with that paragraph.
|
|
46
48
|
*/
|
|
49
|
+
export declare function collectAnchoredDrawingsSteps(blocks: FlowBlock[], measures: Measure[], checkpointEveryBlocks?: number | null): Generator<LayoutWorkCheckpoint, AnchoredDrawingCollection, void>;
|
|
47
50
|
export declare function collectAnchoredDrawings(blocks: FlowBlock[], measures: Measure[]): AnchoredDrawingCollection;
|
|
48
51
|
/**
|
|
49
52
|
* Collect anchored/floating tables mapped to their anchor paragraph index.
|
|
50
53
|
* Also returns anchored tables that have no paragraph to attach to.
|
|
51
54
|
*/
|
|
55
|
+
export declare function collectAnchoredTablesSteps(blocks: FlowBlock[], measures: Measure[], checkpointEveryBlocks?: number | null): Generator<LayoutWorkCheckpoint, AnchoredTableCollection, void>;
|
|
52
56
|
export declare function collectAnchoredTables(blocks: FlowBlock[], measures: Measure[]): AnchoredTableCollection;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type LayoutExecutionPhase = 'measure:block' | 'layout-document:prepare' | 'layout-document:preflight-section' | 'layout-document:preflight-footnote' | 'layout-document:preflight-anchor' | 'layout-document:preflight-keep-next' | 'layout-document:block' | 'layout-document:finalize-page' | 'layout-document:finalize-section' | 'page-token:prepare' | 'page-token:page' | 'numbering-context:chapter' | 'numbering-context:page' | 'footnote:phase' | 'header-footer:variant' | 'header-footer:block' | 'header-footer:page';
|
|
2
|
+
export type LayoutExecutionCheckpoint = {
|
|
3
|
+
phase: LayoutExecutionPhase;
|
|
4
|
+
index?: number;
|
|
5
|
+
total?: number;
|
|
6
|
+
};
|
|
7
|
+
/** Phase-agnostic progress emitted by resumable layout helpers. */
|
|
8
|
+
export type LayoutWorkCheckpoint = {
|
|
9
|
+
index: number;
|
|
10
|
+
total?: number;
|
|
11
|
+
};
|
|
12
|
+
export interface LayoutExecutionControl {
|
|
13
|
+
signal?: AbortSignal;
|
|
14
|
+
/** Host-owned task boundary. It may resolve immediately while the current budget remains. */
|
|
15
|
+
yieldToHost?: (checkpoint: LayoutExecutionCheckpoint) => Promise<void>;
|
|
16
|
+
/** Work cadence for document/block loops. Defaults to 16. */
|
|
17
|
+
checkpointEveryBlocks?: number;
|
|
18
|
+
}
|
|
19
|
+
export declare function layoutExecutionCheckpointEveryBlocks(execution: LayoutExecutionControl | undefined): number;
|
|
20
|
+
export declare function throwIfLayoutExecutionAborted(execution: LayoutExecutionControl | undefined): void;
|
|
21
|
+
export declare function checkpointLayoutExecution(execution: LayoutExecutionControl | undefined, checkpoint: LayoutExecutionCheckpoint): Promise<void>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { FlowBlock, Measure, TableBlock, TableMeasure } from '../../contracts/src/index.js';
|
|
2
|
+
import { LayoutWorkCheckpoint } from './execution.js';
|
|
2
3
|
export type FloatingTableAnchorResolution = {
|
|
3
4
|
paragraphIndex: number;
|
|
4
5
|
offsetV: number;
|
|
@@ -18,4 +19,5 @@ export declare function isAnchoredTableFullWidth(block: TableBlock, measure: Tab
|
|
|
18
19
|
/**
|
|
19
20
|
* Resolve anchor paragraph + vertical offset for a block-level floating table.
|
|
20
21
|
*/
|
|
22
|
+
export declare function resolveFloatingTableAnchorResolutionSteps(blocks: FlowBlock[], measures: Measure[], len: number, tableIndex: number, tableBlock: TableBlock, paragraphIndexById: Map<string, number>, checkpointEveryBlocks?: number | null): Generator<LayoutWorkCheckpoint, FloatingTableAnchorResolution | null, void>;
|
|
21
23
|
export declare function resolveFloatingTableAnchorResolution(blocks: FlowBlock[], measures: Measure[], len: number, tableIndex: number, tableBlock: TableBlock, paragraphIndexById: Map<string, number>): FloatingTableAnchorResolution | null;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { FlowBlock } from '../../contracts/src/index.js';
|
|
2
|
+
import { LayoutWorkCheckpoint } from './execution.js';
|
|
3
|
+
import { FootnoteAnchorRef } from './layout-paragraph.js';
|
|
4
|
+
export type FootnoteAnchorIndexInput = {
|
|
5
|
+
refs?: Array<{
|
|
6
|
+
id: string;
|
|
7
|
+
pos: number;
|
|
8
|
+
}>;
|
|
9
|
+
bodyHeightById?: Map<string, number>;
|
|
10
|
+
firstLineHeightById?: Map<string, number>;
|
|
11
|
+
};
|
|
12
|
+
export type FootnoteAnchorIndexDiagnostics = {
|
|
13
|
+
rangeComparisons: number;
|
|
14
|
+
lowerBoundComparisons: number;
|
|
15
|
+
legacyComparisons: number;
|
|
16
|
+
};
|
|
17
|
+
export declare function buildFootnoteAnchorIndexSteps(blocks: FlowBlock[], footnotes: FootnoteAnchorIndexInput | undefined, checkpointEveryBlocks: number | null, diagnostics?: FootnoteAnchorIndexDiagnostics): Generator<LayoutWorkCheckpoint, Map<string, FootnoteAnchorRef[]>, void>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ColumnLayout, FlowBlock, HeaderFooterLayout, Layout, Measure, Page, ParagraphBlock, ParagraphMeasure, SectionMetadata, FlowMode, DocumentBackground } from '../../contracts/src/index.js';
|
|
2
2
|
import { PageState, ConstraintBoundary } from './paginator.js';
|
|
3
|
+
import { LayoutExecutionControl } from './execution.js';
|
|
3
4
|
type PageSize = {
|
|
4
5
|
w: number;
|
|
5
6
|
h: number;
|
|
@@ -258,13 +259,12 @@ export type HeaderFooterConstraints = {
|
|
|
258
259
|
overflowBaseHeight?: number;
|
|
259
260
|
};
|
|
260
261
|
/**
|
|
261
|
-
*
|
|
262
|
-
*
|
|
263
|
-
*
|
|
264
|
-
* FlowBlocks in order, consumes their Measure objects (same index),
|
|
265
|
-
* and greedily stacks fragments inside the content box of each page/column.
|
|
262
|
+
* The synchronous API drains the same resumable state machine without host
|
|
263
|
+
* turns. Mounted orchestration uses `layoutDocumentCooperatively`; keeping one
|
|
264
|
+
* algorithm prevents cancellation support from becoming a second paginator.
|
|
266
265
|
*/
|
|
267
266
|
export declare function layoutDocument(blocks: FlowBlock[], measures: Measure[], options?: LayoutOptions): Layout;
|
|
267
|
+
export declare function layoutDocumentCooperatively(blocks: FlowBlock[], measures: Measure[], options?: LayoutOptions, execution?: LayoutExecutionControl): Promise<Layout>;
|
|
268
268
|
export type LayoutRangeBoundaryPolicy = 'conservative-context' | 'overscan' | 'degraded-on-incomplete-state';
|
|
269
269
|
export type LayoutRangeExactness = 'exact' | 'pending-layout' | 'degraded-unsupported' | 'stale';
|
|
270
270
|
export type LayoutRangeSourceRange = {
|
|
@@ -338,12 +338,15 @@ export declare function layoutDocumentRange(input: LayoutRangeInput): LayoutRang
|
|
|
338
338
|
* (for overlay shift). See the Coordinate Contract in the fix plan for details.
|
|
339
339
|
*/
|
|
340
340
|
export declare function layoutHeaderFooter(blocks: FlowBlock[], measures: Measure[], constraints: HeaderFooterConstraints, kind?: 'header' | 'footer', remeasureParagraph?: (block: ParagraphBlock, maxWidth: number, firstLineIndent?: number) => ParagraphMeasure): HeaderFooterLayout;
|
|
341
|
+
export declare function layoutHeaderFooterCooperatively(blocks: FlowBlock[], measures: Measure[], constraints: HeaderFooterConstraints, kind?: 'header' | 'footer', remeasureParagraph?: (block: ParagraphBlock, maxWidth: number, firstLineIndent?: number) => ParagraphMeasure, execution?: LayoutExecutionControl): Promise<HeaderFooterLayout>;
|
|
341
342
|
export { buildAnchorMap, resolvePageRefTokens, getTocBlocksForRemeasurement } from './resolvePageRefs.js';
|
|
342
|
-
export { buildChapterContextByPage, computeDisplayPageNumber, formatPageNumber, formatPageNumberFieldValue, formatSectionPageNumberText, normalizeChapterMarkerText, } from './pageNumbering.js';
|
|
343
|
+
export { buildChapterContextByPage, buildChapterContextByPageCooperatively, computeDisplayPageNumber, computeDisplayPageNumberCooperatively, formatPageNumber, formatPageNumberFieldValue, formatSectionPageNumberText, normalizeChapterMarkerText, } from './pageNumbering.js';
|
|
343
344
|
export type { ChapterPageInfo, DisplayPageInfo, PageNumberFormat } from './pageNumbering.js';
|
|
344
|
-
export { resolvePageNumberTokens } from './resolvePageTokens.js';
|
|
345
|
+
export { resolvePageNumberTokens, resolvePageNumberTokensCooperatively } from './resolvePageTokens.js';
|
|
345
346
|
export type { NumberingContext, ResolvePageTokensResult, ResolvePageTokensOptions } from './resolvePageTokens.js';
|
|
346
347
|
export { getCellLines, getEmbeddedRowLines, resolveTableFrame, resolveRenderedTableWidth } from './layout-table.js';
|
|
347
348
|
export { describeCellRenderBlocks, computeCellSliceContentHeight } from './table-cell-slice.js';
|
|
348
349
|
export { layoutTextboxContent, resolveTextboxContentMeasures } from './layout-textbox.js';
|
|
349
350
|
export { SINGLE_COLUMN_DEFAULT } from './section-breaks.js';
|
|
351
|
+
export { checkpointLayoutExecution, throwIfLayoutExecutionAborted } from './execution.js';
|
|
352
|
+
export type { LayoutExecutionCheckpoint, LayoutExecutionControl, LayoutExecutionPhase } from './execution.js';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { formatPageNumber, formatPageNumberFieldValue, formatSectionPageNumberText, FlowBlock, Layout, Page, PageNumberChapterSeparator, PageNumberFormat, SectionMetadata } from '../../contracts/src/index.js';
|
|
2
|
+
import { LayoutExecutionControl } from './execution.js';
|
|
2
3
|
export { formatPageNumber, formatPageNumberFieldValue, formatSectionPageNumberText };
|
|
3
4
|
export type { PageNumberFormat };
|
|
4
5
|
export interface ChapterPageInfo {
|
|
@@ -29,45 +30,6 @@ export interface DisplayPageInfo {
|
|
|
29
30
|
}
|
|
30
31
|
export declare function normalizeChapterMarkerText(markerText: unknown): string | undefined;
|
|
31
32
|
export declare function buildChapterContextByPage(layout: Layout, blocks: FlowBlock[] | ReadonlyMap<string, FlowBlock>, sections: SectionMetadata[]): Map<number, ChapterPageInfo>;
|
|
32
|
-
|
|
33
|
-
* Computes section-aware display page numbers for all pages in a document.
|
|
34
|
-
*
|
|
35
|
-
* This function implements MS Word's section numbering behavior:
|
|
36
|
-
* - Each section can have its own page number format
|
|
37
|
-
* - Sections can restart numbering at a specific value
|
|
38
|
-
* - Continuous sections inherit the previous section's running count unless restart is set
|
|
39
|
-
* - Display numbers are calculated as: pageIndexWithinSection + offset (or restart value)
|
|
40
|
-
* - Display numbers are never less than 1
|
|
41
|
-
*
|
|
42
|
-
* Algorithm:
|
|
43
|
-
* 1. Map each page to its owning section
|
|
44
|
-
* 2. For each section:
|
|
45
|
-
* - If restart/start is set, begin counting from that value
|
|
46
|
-
* - Otherwise, continue from previous section's count
|
|
47
|
-
* 3. For each page within a section:
|
|
48
|
-
* - Calculate displayIndex = pageIndexWithinSection + offset
|
|
49
|
-
* - Clamp displayNumber = max(1, displayIndex)
|
|
50
|
-
* - Format displayText using the section's number format
|
|
51
|
-
*
|
|
52
|
-
* @param pages - Array of pages from the layout (with page.number 1-indexed)
|
|
53
|
-
* @param sections - Array of section metadata (aligned by sectionIndex)
|
|
54
|
-
* @returns Array of display page information for each page
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* ```typescript
|
|
58
|
-
* const pages = [
|
|
59
|
-
* { number: 1, ... },
|
|
60
|
-
* { number: 2, ... },
|
|
61
|
-
* { number: 3, ... },
|
|
62
|
-
* ];
|
|
63
|
-
* const sections = [
|
|
64
|
-
* { sectionIndex: 0, numbering: { format: 'lowerRoman', start: 1 } },
|
|
65
|
-
* { sectionIndex: 1, numbering: { format: 'decimal', start: 1 } },
|
|
66
|
-
* ];
|
|
67
|
-
* const displayInfo = computeDisplayPageNumber(pages, sections);
|
|
68
|
-
* // displayInfo[0]: { physicalPage: 1, displayNumber: 1, displayText: "i", sectionIndex: 0 }
|
|
69
|
-
* // displayInfo[1]: { physicalPage: 2, displayNumber: 2, displayText: "ii", sectionIndex: 0 }
|
|
70
|
-
* // displayInfo[2]: { physicalPage: 3, displayNumber: 1, displayText: "1", sectionIndex: 1 }
|
|
71
|
-
* ```
|
|
72
|
-
*/
|
|
33
|
+
export declare function buildChapterContextByPageCooperatively(layout: Layout, blocks: FlowBlock[] | ReadonlyMap<string, FlowBlock>, sections: SectionMetadata[], execution?: LayoutExecutionControl): Promise<Map<number, ChapterPageInfo>>;
|
|
73
34
|
export declare function computeDisplayPageNumber(pages: Page[], sections: SectionMetadata[], chapterInfoByPage?: ReadonlyMap<number, ChapterPageInfo>): DisplayPageInfo[];
|
|
35
|
+
export declare function computeDisplayPageNumberCooperatively(pages: Page[], sections: SectionMetadata[], chapterInfoByPage: ReadonlyMap<number, ChapterPageInfo> | undefined, execution?: LayoutExecutionControl): Promise<DisplayPageInfo[]>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Layout, FlowBlock, ParagraphBlock, Measure } from '../../contracts/src/index.js';
|
|
2
2
|
import { DisplayPageInfo } from './pageNumbering.js';
|
|
3
|
+
import { LayoutExecutionControl } from './execution.js';
|
|
3
4
|
/**
|
|
4
5
|
* Numbering context for page token resolution.
|
|
5
6
|
* Contains display page information for each physical page in the document.
|
|
@@ -59,6 +60,7 @@ export interface ResolvePageTokensOptions {
|
|
|
59
60
|
pageCountFieldsExact?: boolean;
|
|
60
61
|
}
|
|
61
62
|
export declare function resolvePageNumberTokens(layout: Layout, blocks: FlowBlock[], measures: Measure[], numberingCtx: NumberingContext, options?: ResolvePageTokensOptions): ResolvePageTokensResult;
|
|
63
|
+
export declare function resolvePageNumberTokensCooperatively(layout: Layout, blocks: FlowBlock[], measures: Measure[], numberingCtx: NumberingContext, options?: ResolvePageTokensOptions, execution?: LayoutExecutionControl): Promise<ResolvePageTokensResult>;
|
|
62
64
|
/**
|
|
63
65
|
* Resolves page number tokens in paragraph blocks.
|
|
64
66
|
*
|
|
@@ -62,4 +62,9 @@ export type SectionProps = {
|
|
|
62
62
|
* }
|
|
63
63
|
* ```
|
|
64
64
|
*/
|
|
65
|
+
export type SectionPropsScanCheckpoint = {
|
|
66
|
+
index: number;
|
|
67
|
+
total: number;
|
|
68
|
+
};
|
|
69
|
+
export declare function computeNextSectionPropsAtBreakSteps(blocks: FlowBlock[], checkpointEveryBlocks?: number | null): Generator<SectionPropsScanCheckpoint, Map<number, SectionProps>, void>;
|
|
65
70
|
export declare function computeNextSectionPropsAtBreak(blocks: FlowBlock[]): Map<number, SectionProps>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Line, LineInlineBox, ParagraphBlock, Run, TextRun } from '../../../../contracts/src/index.js';
|
|
2
|
+
export declare const markInlineBoxRun: (run: TextRun, lineFrom: number, lineTo: number) => TextRun;
|
|
3
|
+
/** Splits text runs at the segment boundaries emitted for inline-box edges. */
|
|
4
|
+
export declare const splitInlineBoxRuns: (block: ParagraphBlock, line: Line) => Run[] | null;
|
|
5
|
+
/** Returns the resolved inline advance preceding an explicitly positioned text segment. */
|
|
6
|
+
export declare const inlineBoxAdvanceBeforeOffset: (boxes: readonly LineInlineBox[] | undefined, offset: number) => number;
|
|
7
|
+
/** Paints measured LTR inline-box slices on the canonical text leaves. */
|
|
8
|
+
export declare const paintInlineBoxes: (boxes: readonly LineInlineBox[] | undefined, lineElement: HTMLElement, isRtl: boolean) => void;
|
|
@@ -15,6 +15,11 @@ import { RunRenderContext, TrackedChangesRenderConfig } from './types.js';
|
|
|
15
15
|
* makes the tab border and the text underline rasterize to the same line weight.
|
|
16
16
|
*/
|
|
17
17
|
export declare const underlineThicknessPx: (fontSize: number) => number;
|
|
18
|
+
type ResolvePhysicalFont = (cssFontFamily: string, face: {
|
|
19
|
+
weight: '400' | '700';
|
|
20
|
+
style: 'normal' | 'italic';
|
|
21
|
+
}) => string;
|
|
22
|
+
export declare const applyRunTypographyStyles: (element: HTMLElement, run: TextRun, resolvePhysical?: ResolvePhysicalFont) => void;
|
|
18
23
|
/**
|
|
19
24
|
* Applies run styling properties to a DOM element.
|
|
20
25
|
*
|
|
@@ -25,10 +30,7 @@ export declare const underlineThicknessPx: (fontSize: number) => number;
|
|
|
25
30
|
* inline colors are now applied to all runs (including links) to
|
|
26
31
|
* ensure OOXML hyperlink character styles appear correctly.
|
|
27
32
|
*/
|
|
28
|
-
export declare const applyRunStyles: (element: HTMLElement, run: Run, _isLink?: boolean, resolvePhysical?:
|
|
29
|
-
weight: "400" | "700";
|
|
30
|
-
style: "normal" | "italic";
|
|
31
|
-
}) => string) => void;
|
|
33
|
+
export declare const applyRunStyles: (element: HTMLElement, run: Run, _isLink?: boolean, resolvePhysical?: ResolvePhysicalFont) => void;
|
|
32
34
|
export declare const resolveRunText: (run: Run, context: FragmentRenderContext) => string;
|
|
33
35
|
export declare const extractLinkData: (run: Run) => import('./types.js').LinkRenderData | null;
|
|
34
36
|
export declare const renderTextRun: (run: TextRun, context: FragmentRenderContext, renderContext: RunRenderContext, trackedConfig?: TrackedChangesRenderConfig) => HTMLElement | null;
|
|
@@ -11,11 +11,17 @@ export interface WordThemeFontFamily {
|
|
|
11
11
|
readonly ea?: string;
|
|
12
12
|
readonly cs?: string;
|
|
13
13
|
}
|
|
14
|
+
/** Authored DrawingML fill definitions, indexed by `a:fillRef/@idx`. */
|
|
15
|
+
export interface WordThemeFormatScheme {
|
|
16
|
+
readonly fillStyles: readonly string[];
|
|
17
|
+
readonly backgroundFillStyles: readonly string[];
|
|
18
|
+
}
|
|
14
19
|
export declare const DEFAULT_WORD_THEME_PALETTE: WordThemeColorPalette;
|
|
15
20
|
export declare const DEFAULT_WORD_THEME_FONT_SCHEME: WordThemeFontScheme;
|
|
16
21
|
export interface ThemeParseResult {
|
|
17
22
|
palette?: WordThemeColorPalette;
|
|
18
23
|
fontScheme?: WordThemeFontScheme;
|
|
24
|
+
formatScheme?: WordThemeFormatScheme;
|
|
19
25
|
}
|
|
20
26
|
/**
|
|
21
27
|
* Parse the theme root (`a:theme`) into colors + font scheme. Returns an
|
package/dist/public/ui-react.cjs
CHANGED
|
@@ -1,17 +1,45 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const
|
|
3
|
-
const require_create_super_doc_ui = require("../chunks/create-super-doc-ui-BHMQEL2y.cjs");
|
|
2
|
+
const require_create_super_doc_ui = require("../chunks/create-super-doc-ui-Dmv8Hjs6.cjs");
|
|
4
3
|
let react = require("react");
|
|
4
|
+
//#region src/public/ui/react.ts
|
|
5
|
+
/**
|
|
6
|
+
* v2-native React bindings for the `superdoc/ui` controller.
|
|
7
|
+
*
|
|
8
|
+
* Provider + hooks over the SuperDoc-owned controller (`superdoc.ui`). For a
|
|
9
|
+
* real `SuperDoc` this layer never creates or destroys a controller; it binds
|
|
10
|
+
* to the one the instance already owns. It falls back to building (and then
|
|
11
|
+
* owning) one only for a structural host that carries no `ui`, since
|
|
12
|
+
* `SuperDocHost` leaves that property optional. Authored with
|
|
13
|
+
* `React.createElement` (no JSX) so the
|
|
14
|
+
* library build needs no JSX transform, and `react` stays an external/optional
|
|
15
|
+
* peer. No v1 editor or private v2 runtime imports.
|
|
16
|
+
*/
|
|
5
17
|
var SuperDocUIContext = (0, react.createContext)(null);
|
|
18
|
+
/**
|
|
19
|
+
* Destroy a controller this provider built itself. Controllers read off
|
|
20
|
+
* `superdoc.ui` are never passed here: the instance owns those.
|
|
21
|
+
*/
|
|
6
22
|
function disposeOwnedUi(ref) {
|
|
7
23
|
const ui = ref.current;
|
|
8
24
|
if (!ui) return;
|
|
9
25
|
ui.destroy();
|
|
10
26
|
ref.current = null;
|
|
11
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Root provider. Call {@link useSetSuperDoc} from your editor-mount
|
|
30
|
+
* component's ready callback to bind a running SuperDoc instance; the hooks
|
|
31
|
+
* below then read that instance's own controller (`superdoc.ui`).
|
|
32
|
+
*
|
|
33
|
+
* The provider is a consumer, not an owner. SuperDoc creates the controller
|
|
34
|
+
* and destroys it in `superdoc.destroy()`, so unmounting or rebinding the
|
|
35
|
+
* provider leaves it running for the built-in toolbar and any other consumer
|
|
36
|
+
* of the same instance. Every React hook therefore observes the same command
|
|
37
|
+
* state the rest of the application sees.
|
|
38
|
+
*/
|
|
12
39
|
function SuperDocUIProvider(props) {
|
|
13
40
|
const [ui, setUi] = (0, react.useState)(null);
|
|
14
41
|
const [host, setHost] = (0, react.useState)(null);
|
|
42
|
+
/** Only ever holds a controller this provider created for a host lacking one. */
|
|
15
43
|
const ownedUiRef = (0, react.useRef)(null);
|
|
16
44
|
const setSuperDoc = (0, react.useCallback)((superdoc) => {
|
|
17
45
|
const hostUi = superdoc.ui;
|
|
@@ -37,15 +65,33 @@ function useContextValue() {
|
|
|
37
65
|
if (!value) throw new Error("[superdoc/ui/react] hooks must be used within <SuperDocUIProvider>.");
|
|
38
66
|
return value;
|
|
39
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* Read the controller, or `null` until a SuperDoc instance is bound.
|
|
70
|
+
*
|
|
71
|
+
* Borrowed: the bound instance owns teardown, so the returned type omits
|
|
72
|
+
* `destroy()`. A provider-built fallback controller is disposed by the provider.
|
|
73
|
+
*/
|
|
40
74
|
function useSuperDocUI() {
|
|
41
75
|
return useContextValue().ui;
|
|
42
76
|
}
|
|
77
|
+
/** Read the raw bound SuperDoc host, or `null` until one is bound. */
|
|
43
78
|
function useSuperDocHost() {
|
|
44
79
|
return useContextValue().host;
|
|
45
80
|
}
|
|
81
|
+
/** Get the stable callback used to bind a running SuperDoc instance. */
|
|
46
82
|
function useSetSuperDoc() {
|
|
47
83
|
return useContextValue().setSuperDoc;
|
|
48
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Normalize a `pick` result into a {@link SliceSource}. Domain handles and the
|
|
87
|
+
* command/font hooks already expose the snapshot-shaped contract
|
|
88
|
+
* (`getSnapshot` + `observe`) and pass through unchanged. A raw `ui.select(...)`
|
|
89
|
+
* {@link Subscribable} (`get` + `subscribe`) is adapted: it `subscribe`s FIRST,
|
|
90
|
+
* then emits the current value, so a synchronous recompute triggered by the
|
|
91
|
+
* first listener is not missed (the substrate's `subscribe` does not emit on
|
|
92
|
+
* attach). Exported for unit tests; not re-exported by the `superdoc/ui/react`
|
|
93
|
+
* facade, so it stays off the public surface.
|
|
94
|
+
*/
|
|
49
95
|
function toSliceSource(source) {
|
|
50
96
|
const candidate = source;
|
|
51
97
|
if (typeof candidate.getSnapshot === "function" && typeof candidate.observe === "function") return source;
|
|
@@ -59,6 +105,13 @@ function toSliceSource(source) {
|
|
|
59
105
|
}
|
|
60
106
|
};
|
|
61
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Subscribe to a derived slice of controller state. `pick` selects a value
|
|
110
|
+
* source from the controller: a domain handle / snapshot source
|
|
111
|
+
* ({@link SliceSource}) or a raw `ui.select(...)` {@link Subscribable}, both
|
|
112
|
+
* normalized via {@link toSliceSource}. `initial` is returned until the
|
|
113
|
+
* controller is bound.
|
|
114
|
+
*/
|
|
62
115
|
function useSuperDocSlice(pick, initial) {
|
|
63
116
|
const ui = useSuperDocUI();
|
|
64
117
|
const [value, setValue] = (0, react.useState)(() => ui ? toSliceSource(pick(ui)).getSnapshot() : initial);
|
|
@@ -83,9 +136,11 @@ var EMPTY_SELECTION = {
|
|
|
83
136
|
activeChangeIds: [],
|
|
84
137
|
quotedText: ""
|
|
85
138
|
};
|
|
139
|
+
/** Subscribe to the selection slice. */
|
|
86
140
|
function useSuperDocSelection() {
|
|
87
141
|
return useSuperDocSlice((ui) => ui.selection, EMPTY_SELECTION);
|
|
88
142
|
}
|
|
143
|
+
/** Subscribe to the comments slice. */
|
|
89
144
|
function useSuperDocComments() {
|
|
90
145
|
return useSuperDocSlice((ui) => ui.comments, {
|
|
91
146
|
status: "pending",
|
|
@@ -96,6 +151,7 @@ function useSuperDocComments() {
|
|
|
96
151
|
activeId: null
|
|
97
152
|
});
|
|
98
153
|
}
|
|
154
|
+
/** Subscribe to the content-controls slice. */
|
|
99
155
|
function useSuperDocContentControls() {
|
|
100
156
|
return useSuperDocSlice((ui) => ui.contentControls, {
|
|
101
157
|
status: "pending",
|
|
@@ -105,6 +161,7 @@ function useSuperDocContentControls() {
|
|
|
105
161
|
activeIds: []
|
|
106
162
|
});
|
|
107
163
|
}
|
|
164
|
+
/** Subscribe to the track-changes slice. */
|
|
108
165
|
function useSuperDocTrackChanges() {
|
|
109
166
|
return useSuperDocSlice((ui) => ui.trackChanges, {
|
|
110
167
|
status: "pending",
|
|
@@ -114,6 +171,7 @@ function useSuperDocTrackChanges() {
|
|
|
114
171
|
authors: []
|
|
115
172
|
});
|
|
116
173
|
}
|
|
174
|
+
/** Subscribe to the toolbar snapshot slice. */
|
|
117
175
|
function useSuperDocToolbar() {
|
|
118
176
|
return useSuperDocSlice((ui) => ui.toolbar, {
|
|
119
177
|
context: null,
|
|
@@ -121,6 +179,7 @@ function useSuperDocToolbar() {
|
|
|
121
179
|
copyFormatActive: false
|
|
122
180
|
});
|
|
123
181
|
}
|
|
182
|
+
/** Subscribe to a single command's enable/active state. */
|
|
124
183
|
function useSuperDocCommand(id) {
|
|
125
184
|
return useSuperDocSlice((ui) => ({
|
|
126
185
|
getSnapshot: () => ui.commands.get(id).getState(),
|
|
@@ -131,6 +190,7 @@ function useSuperDocCommand(id) {
|
|
|
131
190
|
supported: false
|
|
132
191
|
});
|
|
133
192
|
}
|
|
193
|
+
/** Subscribe to the document slice. */
|
|
134
194
|
function useSuperDocDocument() {
|
|
135
195
|
return useSuperDocSlice((ui) => ui.document, {
|
|
136
196
|
ready: false,
|
|
@@ -138,18 +198,21 @@ function useSuperDocDocument() {
|
|
|
138
198
|
dirty: false
|
|
139
199
|
});
|
|
140
200
|
}
|
|
201
|
+
/** Subscribe to available font-family options. */
|
|
141
202
|
function useSuperDocFontOptions() {
|
|
142
203
|
return useSuperDocSlice((ui) => ({
|
|
143
204
|
getSnapshot: () => ui.fonts.getFamilyOptions(),
|
|
144
205
|
observe: (cb) => ui.fonts.observe((slice) => cb(slice.options))
|
|
145
206
|
}), []);
|
|
146
207
|
}
|
|
208
|
+
/** Subscribe to available font-size options. */
|
|
147
209
|
function useSuperDocFontSizeOptions() {
|
|
148
210
|
return useSuperDocSlice((ui) => ({
|
|
149
211
|
getSnapshot: () => ui.fonts.getSizeOptions(),
|
|
150
212
|
observe: (cb) => ui.fonts.observe((slice) => cb(slice.sizeOptions))
|
|
151
213
|
}), []);
|
|
152
214
|
}
|
|
215
|
+
/** Subscribe to the zoom slice. */
|
|
153
216
|
function useSuperDocZoom() {
|
|
154
217
|
return useSuperDocSlice((ui) => ui.zoom, {
|
|
155
218
|
mode: null,
|
|
@@ -158,6 +221,7 @@ function useSuperDocZoom() {
|
|
|
158
221
|
max: 100
|
|
159
222
|
});
|
|
160
223
|
}
|
|
224
|
+
//#endregion
|
|
161
225
|
exports.SuperDocUIProvider = SuperDocUIProvider;
|
|
162
226
|
exports.useSetSuperDoc = useSetSuperDoc;
|
|
163
227
|
exports.useSuperDocCommand = useSuperDocCommand;
|