superdoc 2.4.0-next.5 → 2.4.0-next.51

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.
Files changed (101) hide show
  1. package/AGENTS.md +13 -13
  2. package/README.md +19 -22
  3. package/dist/chunks/{FindReplaceSurface-C-I4GcRE.cjs → FindReplaceSurface-0p7EtMZh.cjs} +4 -4
  4. package/dist/chunks/{FindReplaceSurface-B_1Ksbr0.es.js → FindReplaceSurface-40AnrqWk.es.js} +5 -4
  5. package/dist/chunks/{PasswordPromptSurface-Bu5xHm91.cjs → PasswordPromptSurface-31lYPcCK.cjs} +4 -3
  6. package/dist/chunks/{PasswordPromptSurface-Bz9_sKhX.es.js → PasswordPromptSurface-CwYeO3iQ.es.js} +4 -2
  7. package/dist/chunks/{PdfViewer-CdVGB6Fe.es.js → PdfViewer-D8h7LRZy.es.js} +103 -19
  8. package/dist/chunks/{PdfViewer-D4eD2dV1.cjs → PdfViewer-Dug6yDRC.cjs} +105 -20
  9. package/dist/chunks/_plugin-vue_export-helper-BOaGB7Aw.es.js +8 -0
  10. package/dist/chunks/_plugin-vue_export-helper-SDR04tiH.cjs +13 -0
  11. package/dist/chunks/{blank-docx-DP8RUPW-.cjs → blank-docx-BuFAbRjs.cjs} +2 -0
  12. package/dist/chunks/{blank-docx-XRX6Ker2.es.js → blank-docx-DzQccOlW.es.js} +2 -0
  13. package/dist/chunks/constants-B6VBlmKp.es.js +4 -0
  14. package/dist/chunks/constants-DpXuDx_g.cjs +9 -0
  15. package/dist/chunks/{create-super-doc-ui-BquF8bnZ.es.js → create-super-doc-ui-B_1l545i.es.js} +2134 -1099
  16. package/dist/chunks/{create-super-doc-ui-sMXbYzhs.cjs → create-super-doc-ui-DNtHxzz_.cjs} +1945 -1150
  17. package/dist/chunks/{eventemitter3-Bt2s0X0a.es.js → eventemitter3-CMOjDs74.es.js} +124 -16
  18. package/dist/chunks/{eventemitter3-DqY4aSMf.cjs → eventemitter3-D38u8ta_.cjs} +125 -16
  19. package/dist/chunks/jszip-RC64TPzL.cjs +4758 -0
  20. package/dist/chunks/jszip-VxCFV9YS.es.js +4717 -0
  21. package/dist/chunks/{rolldown-runtime-D7PMmH3s.es.js → rolldown-runtime-B5TtN50X.es.js} +13 -4
  22. package/dist/chunks/{rolldown-runtime-1Y-nnZJ3.cjs → rolldown-runtime-DtsSbkrh.cjs} +12 -3
  23. package/dist/chunks/{uuid-CFp0WGVU.cjs → uuid-BhG0ngwk.cjs} +10 -6
  24. package/dist/chunks/{uuid-B2Sqk-3p.es.js → uuid-H0Xcmmhy.es.js} +8 -3
  25. package/dist/collaboration-upgrade-engine.cjs +34 -9
  26. package/dist/collaboration-upgrade-engine.es.js +30 -5
  27. package/dist/document-api/src/citations/citations.types.d.ts +9 -0
  28. package/dist/document-api/src/comments/comments.types.d.ts +7 -0
  29. package/dist/document-api/src/types/receipt.d.ts +9 -5
  30. package/dist/document-api/src/types/track-changes.types.d.ts +18 -3
  31. package/dist/layout-engine/contracts/src/graphic-placement.d.ts +35 -6
  32. package/dist/layout-engine/contracts/src/incremental-dependency.d.ts +22 -2
  33. package/dist/layout-engine/contracts/src/index.d.ts +164 -8
  34. package/dist/layout-engine/contracts/src/inline-box.d.ts +19 -0
  35. package/dist/layout-engine/contracts/src/paragraph-visible-text.d.ts +19 -0
  36. package/dist/layout-engine/contracts/src/resolved-layout.d.ts +5 -0
  37. package/dist/layout-engine/dom-contract/src/class-names.d.ts +2 -0
  38. package/dist/layout-engine/layout-bridge/src/footnote-scorer.d.ts +1 -1
  39. package/dist/layout-engine/layout-bridge/src/hydrateTableTextboxMeasures.d.ts +9 -0
  40. package/dist/layout-engine/layout-bridge/src/incrementalLayout.d.ts +28 -10
  41. package/dist/layout-engine/layout-bridge/src/index.d.ts +4 -2
  42. package/dist/layout-engine/layout-bridge/src/inline-box-key.d.ts +3 -0
  43. package/dist/layout-engine/layout-bridge/src/layoutHeaderFooter.d.ts +11 -4
  44. package/dist/layout-engine/layout-bridge/src/remeasure.d.ts +2 -2
  45. package/dist/layout-engine/layout-bridge/src/run-visual-marks.d.ts +2 -0
  46. package/dist/layout-engine/layout-bridge/src/text-measurement.d.ts +0 -12
  47. package/dist/layout-engine/layout-engine/src/anchors.d.ts +4 -0
  48. package/dist/layout-engine/layout-engine/src/execution.d.ts +21 -0
  49. package/dist/layout-engine/layout-engine/src/floating-objects.d.ts +15 -2
  50. package/dist/layout-engine/layout-engine/src/floating-table-anchor.d.ts +2 -0
  51. package/dist/layout-engine/layout-engine/src/footnote-anchor-index.d.ts +17 -0
  52. package/dist/layout-engine/layout-engine/src/index.d.ts +13 -10
  53. package/dist/layout-engine/layout-engine/src/inline-drawing-alignment.d.ts +9 -0
  54. package/dist/layout-engine/layout-engine/src/layout-paragraph.d.ts +2 -2
  55. package/dist/layout-engine/layout-engine/src/pageNumbering.d.ts +3 -41
  56. package/dist/layout-engine/layout-engine/src/resolvePageTokens.d.ts +2 -0
  57. package/dist/layout-engine/layout-engine/src/section-props.d.ts +5 -0
  58. package/dist/layout-engine/painters/dom/src/renderer.d.ts +6 -0
  59. package/dist/layout-engine/painters/dom/src/runs/inline-box.d.ts +8 -0
  60. package/dist/layout-engine/painters/dom/src/runs/text-run.d.ts +6 -4
  61. package/dist/layout-engine/painters/dom/src/table/border-utils.d.ts +20 -27
  62. package/dist/layout-engine/style-engine/src/ooxml/word-style-model/parse-theme.d.ts +6 -0
  63. package/dist/public/ui-react.cjs +66 -2
  64. package/dist/public/ui-react.es.js +66 -1
  65. package/dist/public/ui.cjs +1 -1
  66. package/dist/public/ui.es.js +1 -1
  67. package/dist/style.css +174 -138
  68. package/dist/style.layered.css +174 -138
  69. package/dist/superdoc/src/components/CommentsLayer/CommentDialog.vue.d.ts +2 -0
  70. package/dist/superdoc/src/components/CommentsLayer/commentsList/ReviewDirectoryListItem.vue.d.ts +16 -0
  71. package/dist/superdoc/src/components/CommentsLayer/commentsList/commentsList.vue.d.ts +3 -1
  72. package/dist/superdoc/src/components/CommentsLayer/commentsList/super-comments-list.d.ts +12 -0
  73. package/dist/superdoc/src/core/SuperDoc.d.ts +10 -7
  74. package/dist/superdoc/src/core/extensions/index.d.ts +1 -1
  75. package/dist/superdoc/src/core/extensions/types.d.ts +63 -5
  76. package/dist/superdoc/src/core/types/index.d.ts +535 -42
  77. package/dist/superdoc/src/core/v2-integration/v2-integration.d.ts +3 -3
  78. package/dist/superdoc/src/helpers/comment-small-screen.d.ts +10 -0
  79. package/dist/superdoc/src/helpers/v2-review-mutation-impact.d.ts +3 -5
  80. package/dist/superdoc/src/internal/toolbar/built-in/ToolbarButton.vue.d.ts +4 -4
  81. package/dist/superdoc/src/internal/toolbar/built-in-toolbar.d.ts +11 -0
  82. package/dist/superdoc/src/internal/toolbar/compatibility-catalog.d.ts +1 -1
  83. package/dist/superdoc/src/public/index.d.cts +28 -0
  84. package/dist/superdoc/src/public/index.d.ts +14 -0
  85. package/dist/superdoc/src/public/ui/types.d.ts +30 -6
  86. package/dist/superdoc/src/stores/comments-store.d.ts +81 -78
  87. package/dist/superdoc/src/stores/superdoc-store.d.ts +243 -234
  88. package/dist/superdoc.cjs +6743 -2169
  89. package/dist/superdoc.es.js +6616 -2042
  90. package/dist-cdn/style.layered.css +1 -1
  91. package/dist-cdn/superdoc.min.css +1 -1
  92. package/dist-cdn/superdoc.min.js +37 -37
  93. package/package.json +14 -17
  94. package/dist/chunks/_plugin-vue_export-helper-CZ1Nl59K.cjs +0 -11
  95. package/dist/chunks/_plugin-vue_export-helper-DSMAhhwD.es.js +0 -6
  96. package/dist/chunks/constants-BfH0br5u.es.js +0 -3
  97. package/dist/chunks/constants-D7TNtyJd.cjs +0 -14
  98. package/dist/chunks/jszip-C8srOKAO.es.js +0 -4650
  99. package/dist/chunks/jszip-Cs9JBLlJ.cjs +0 -4691
  100. package/dist/superdoc/src/helpers/v2-remote-review-hydration.d.ts +0 -12
  101. package/dist/superdoc/src/helpers/v2-review-mutation-reconciler.d.ts +0 -19
@@ -1,4 +1,4 @@
1
- import { ImageBlock, ImageMeasure, ExclusionZone, DrawingBlock, DrawingMeasure, TableBlock, TableMeasure, ColumnLayoutForAnchor } from '../../contracts/src/index.js';
1
+ import { ImageBlock, ImageMeasure, ExclusionZone, DrawingBlock, DrawingMeasure, TableBlock, TableMeasure, ColumnLayoutForAnchor, ResolveAnchoredGraphicXContext } from '../../contracts/src/index.js';
2
2
  type FloatBlock = ImageBlock | DrawingBlock;
3
3
  type FloatMeasure = ImageMeasure | DrawingMeasure;
4
4
  export type FloatingObjectManager = {
@@ -31,6 +31,19 @@ export type FloatingObjectManager = {
31
31
  width: number;
32
32
  offsetX: number;
33
33
  };
34
+ /**
35
+ * Compute every contiguous horizontal region available to a line.
36
+ * Unlike computeAvailableWidth, this preserves both sides of a centered
37
+ * `wrapText="bothSides"` object instead of collapsing them to one side.
38
+ */
39
+ computeAvailableRegions(lineY: number, lineHeight: number, baseWidth: number, columnIndex: number, pageNumber: number): Array<{
40
+ offsetX: number;
41
+ width: number;
42
+ }>;
43
+ /**
44
+ * Return the first Y coordinate below every overlapping TopAndBottom float.
45
+ */
46
+ computeVerticalClearance(lineY: number, lineHeight: number, columnIndex: number, pageNumber: number): number | null;
34
47
  /**
35
48
  * Get all floating images for a page (for debugging/painting).
36
49
  */
@@ -56,5 +69,5 @@ export declare function createFloatingObjectManager(columns: ColumnLayout, margi
56
69
  export declare function computeAnchorX(anchor: NonNullable<ImageBlock['anchor']>, columnIndex: number, columns: ColumnLayout, imageWidth: number, margins?: {
57
70
  left?: number;
58
71
  right?: number;
59
- }, pageWidth?: number): number;
72
+ }, pageWidth?: number, context?: ResolveAnchoredGraphicXContext): number;
60
73
  export {};
@@ -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
- import { ColumnLayout, FlowBlock, HeaderFooterLayout, Layout, Measure, Page, ParagraphBlock, ParagraphMeasure, SectionMetadata, FlowMode, DocumentBackground } from '../../contracts/src/index.js';
1
+ import { ColumnLayout, FlowBlock, HeaderFooterLayout, Layout, Measure, Page, ParagraphBlock, ParagraphMeasure, SectionMetadata, FlowMode, DocumentBackground, ParagraphLineRegion } 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;
@@ -30,7 +31,7 @@ export type LayoutOptions = {
30
31
  marginTop?: number;
31
32
  marginBottom?: number;
32
33
  };
33
- remeasureParagraph?: (block: ParagraphBlock, maxWidth: number, firstLineIndent?: number) => ParagraphMeasure;
34
+ remeasureParagraph?: (block: ParagraphBlock, maxWidth: number, firstLineIndent?: number, lineRegions?: readonly (readonly ParagraphLineRegion[])[]) => ParagraphMeasure;
34
35
  /** @internal Positioned paragraph frames that render without advancing the story cursor. */
35
36
  nonFlowPositionedParagraphFrameIds?: ReadonlySet<string>;
36
37
  sectionMetadata?: SectionMetadata[];
@@ -258,13 +259,12 @@ export type HeaderFooterConstraints = {
258
259
  overflowBaseHeight?: number;
259
260
  };
260
261
  /**
261
- * Layout FlowBlocks into paginated fragments using measured line data.
262
- *
263
- * The function is intentionally deterministic: it walks the provided
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 = {
@@ -337,13 +337,16 @@ export declare function layoutDocumentRange(input: LayoutRangeInput): LayoutRang
337
337
  * Returns separate measurement bounds (for pagination) and render bounds
338
338
  * (for overlay shift). See the Coordinate Contract in the fix plan for details.
339
339
  */
340
- export declare function layoutHeaderFooter(blocks: FlowBlock[], measures: Measure[], constraints: HeaderFooterConstraints, kind?: 'header' | 'footer', remeasureParagraph?: (block: ParagraphBlock, maxWidth: number, firstLineIndent?: number) => ParagraphMeasure): HeaderFooterLayout;
340
+ export declare function layoutHeaderFooter(blocks: FlowBlock[], measures: Measure[], constraints: HeaderFooterConstraints, kind?: 'header' | 'footer', remeasureParagraph?: LayoutOptions['remeasureParagraph']): HeaderFooterLayout;
341
+ export declare function layoutHeaderFooterCooperatively(blocks: FlowBlock[], measures: Measure[], constraints: HeaderFooterConstraints, kind?: 'header' | 'footer', remeasureParagraph?: LayoutOptions['remeasureParagraph'], 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';
@@ -0,0 +1,9 @@
1
+ import { FlowBlock, Measure, Page } from '../../contracts/src/index.js';
2
+ /**
3
+ * Word baseline-aligns an inline zero-height connector with the run that owns
4
+ * it. Projection keeps vector drawings as sibling blocks, so the connector has
5
+ * already reserved its authored flow height before the empty carrier paragraph
6
+ * is laid out. Reposition only its paint fragment once that carrier's measured
7
+ * baseline is known; later flow remains untouched.
8
+ */
9
+ export declare function alignInlineZeroHeightDrawingFragments(pages: Page[], blocks: FlowBlock[], measures: Measure[]): void;
@@ -1,6 +1,6 @@
1
1
  import { FloatingObjectManager } from './floating-objects.js';
2
2
  import { PageState } from './paginator.js';
3
- import { PageMargins, ParagraphBlock, ParagraphMeasure, ImageBlock, ImageMeasure, DrawingBlock, DrawingMeasure } from '../../contracts/src/index.js';
3
+ import { PageMargins, ParagraphBlock, ParagraphMeasure, ImageBlock, ImageMeasure, DrawingBlock, DrawingMeasure, ParagraphLineRegion } from '../../contracts/src/index.js';
4
4
  import { AnchoredTable } from './anchors.js';
5
5
  /**
6
6
  * SD-2656: ordered footnote anchor entry. The body slicer reads the candidate
@@ -21,7 +21,7 @@ export type ParagraphLayoutContext = {
21
21
  advanceColumn: (state: PageState) => PageState;
22
22
  columnX: (state: PageState, columnIndex?: number) => number;
23
23
  floatManager: FloatingObjectManager;
24
- remeasureParagraph?: (block: ParagraphBlock, maxWidth: number, firstLineIndent?: number) => ParagraphMeasure;
24
+ remeasureParagraph?: (block: ParagraphBlock, maxWidth: number, firstLineIndent?: number, lineRegions?: readonly (readonly ParagraphLineRegion[])[]) => ParagraphMeasure;
25
25
  /**
26
26
  * Override the paragraph's spacing-after value. Used when contextual spacing
27
27
  * should suppress spacing between this paragraph and the next (same-style) paragraph.
@@ -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>;
@@ -600,6 +600,12 @@ export declare class DomPainter {
600
600
  * Uses resolved data for spatial properties and delegates PM attributes to the legacy path.
601
601
  */
602
602
  private isAnchoredMediaFragment;
603
+ /**
604
+ * Marks fragments whose paint coordinates are independent from body flow.
605
+ * DOM consumers such as header/footer hit-testing must not infer page margins
606
+ * from floating objects that happen to paint above the first flow block.
607
+ */
608
+ private applyFragmentFlowClass;
603
609
  private shouldRenderBehindPageContent;
604
610
  private isHeaderWordArtWatermark;
605
611
  private isVmlTextWatermarkImage;
@@ -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?: (cssFontFamily: string, face: {
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;
@@ -1,5 +1,20 @@
1
1
  import { BorderSpec, CellBorders, TableBorderValue, TableBorders, TableFragment } from '../../../../contracts/src/index.js';
2
2
  import { TableCellGridPosition } from './grid-geometry.js';
3
+ type BorderSide = 'Top' | 'Right' | 'Bottom' | 'Left';
4
+ type ThinDoubleBorderOverlayGeometry = {
5
+ left: string;
6
+ top: string;
7
+ width: string;
8
+ height: string;
9
+ };
10
+ /**
11
+ * Paints thin double borders in an unclipped sibling SVG. CSS gradients are
12
+ * clipped at cell seams and cannot form Word's continuous rectangular rings.
13
+ * The SVG preserves authored geometry once it is large enough, while the V2
14
+ * wrapper's inverse-zoom variable keeps sub-pixel components at Word's
15
+ * one-screen-pixel minimum across editor zoom levels.
16
+ */
17
+ export declare const createThinDoubleBorderOverlay: (doc: Document, source: HTMLElement, geometry: ThinDoubleBorderOverlayGeometry) => SVGSVGElement | null;
3
18
  /**
4
19
  * Applies a border specification to one side of an HTML element.
5
20
  *
@@ -18,7 +33,7 @@ import { TableCellGridPosition } from './grid-geometry.js';
18
33
  * // Sets cell.style.borderTop = '2px solid #FF0000'
19
34
  * ```
20
35
  */
21
- export declare const applyBorder: (element: HTMLElement, side: "Top" | "Right" | "Bottom" | "Left", border?: BorderSpec) => void;
36
+ export declare const applyBorder: (element: HTMLElement, side: BorderSide, border?: BorderSpec) => void;
22
37
  /**
23
38
  * Applies border specifications to all four sides of a table cell element.
24
39
  *
@@ -79,32 +94,9 @@ export declare const borderValueToSpec: (value?: TableBorderValue | null) => Bor
79
94
  * ```
80
95
  */
81
96
  export declare const resolveTableBorderValue: (explicit: TableBorderValue | undefined | null, fallback?: TableBorderValue | undefined | null) => BorderSpec | undefined;
82
- export declare const isPresentBorder: (b?: BorderSpec) => b is BorderSpec;
83
- /**
84
- * True when a border is EXPLICITLY set to none/nil (`w:val="nil"`/`"none"`), as opposed to
85
- * simply unset/absent. The distinction matters for shared interior edges (§17.4.66): an
86
- * explicit none on BOTH adjacent cells suppresses the divider, while an unset side inherits
87
- * the table's insideH/insideV. Accepts either a CellBorders BorderSpec (`{style:'none'}`) or
88
- * a TableBorderValue (`{none:true}`).
89
- */
90
- export declare const isExplicitNoneBorder: (b?: unknown) => boolean;
91
- /**
92
- * OOXML cell-border conflict resolution (ECMA-376 §17.4.66).
93
- *
94
- * With zero cell spacing, two cells sharing an edge each specify a border; the spec
95
- * collapses them to a SINGLE displayed border:
96
- * 1. If either side is nil/none/absent, the opposing (present) border is displayed.
97
- * 2. Otherwise the border with greater weight wins, where
98
- * weight = (#lines in the style) × (style number).
99
- * 3. Equal weight → the style higher on the precedence list (single first) wins.
100
- * 4. Identical style → the color with the smaller brightness (R+B+2G, then B+2G, then
101
- * G) wins; finally the first border (reading order) wins.
102
- *
103
- * @param a - One side's border (the owning cell's, e.g. the lower/right cell)
104
- * @param b - The opposing side's border (e.g. the upper/left neighbor)
105
- * @returns The single BorderSpec to display, or undefined if neither is present.
106
- */
107
- export declare const resolveBorderConflict: (a?: BorderSpec, b?: BorderSpec) => BorderSpec | undefined;
97
+ export declare const isPresentBorder: (border?: BorderSpec) => border is BorderSpec;
98
+ export declare const isExplicitNoneBorder: (border?: unknown) => boolean;
99
+ export declare const resolveBorderConflict: (first?: BorderSpec, second?: BorderSpec) => BorderSpec | undefined;
108
100
  /**
109
101
  * Creates a border overlay element for a table fragment.
110
102
  *
@@ -183,3 +175,4 @@ export declare const swapTableBordersLR: (borders: TableBorders | undefined) =>
183
175
  * Swap left↔right on cell borders for RTL tables (ECMA-376 Part 4 §14.3.1, §14.3.5).
184
176
  */
185
177
  export declare const swapCellBordersLR: (borders: CellBorders | undefined) => CellBorders | undefined;
178
+ export {};
@@ -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
@@ -1,17 +1,45 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_rolldown_runtime = require("../chunks/rolldown-runtime-1Y-nnZJ3.cjs");
3
- const require_create_super_doc_ui = require("../chunks/create-super-doc-ui-sMXbYzhs.cjs");
2
+ const require_create_super_doc_ui = require("../chunks/create-super-doc-ui-DNtHxzz_.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;