superdoc 2.4.0-next.6 → 2.4.0-next.60

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 (105) hide show
  1. package/README.md +12 -90
  2. package/dist/chunks/{FindReplaceSurface-C-I4GcRE.cjs → FindReplaceSurface-0p7EtMZh.cjs} +4 -4
  3. package/dist/chunks/{FindReplaceSurface-B_1Ksbr0.es.js → FindReplaceSurface-40AnrqWk.es.js} +5 -4
  4. package/dist/chunks/{PasswordPromptSurface-Bu5xHm91.cjs → PasswordPromptSurface-31lYPcCK.cjs} +4 -3
  5. package/dist/chunks/{PasswordPromptSurface-Bz9_sKhX.es.js → PasswordPromptSurface-CwYeO3iQ.es.js} +4 -2
  6. package/dist/chunks/{PdfViewer-CdVGB6Fe.es.js → PdfViewer-D8h7LRZy.es.js} +103 -19
  7. package/dist/chunks/{PdfViewer-D4eD2dV1.cjs → PdfViewer-Dug6yDRC.cjs} +105 -20
  8. package/dist/chunks/_plugin-vue_export-helper-BOaGB7Aw.es.js +8 -0
  9. package/dist/chunks/_plugin-vue_export-helper-SDR04tiH.cjs +13 -0
  10. package/dist/chunks/{blank-docx-DP8RUPW-.cjs → blank-docx-BuFAbRjs.cjs} +2 -0
  11. package/dist/chunks/{blank-docx-XRX6Ker2.es.js → blank-docx-DzQccOlW.es.js} +2 -0
  12. package/dist/chunks/constants-B6VBlmKp.es.js +4 -0
  13. package/dist/chunks/constants-DpXuDx_g.cjs +9 -0
  14. package/dist/chunks/{create-super-doc-ui-BquF8bnZ.es.js → create-super-doc-ui-B_1l545i.es.js} +2134 -1099
  15. package/dist/chunks/{create-super-doc-ui-sMXbYzhs.cjs → create-super-doc-ui-DNtHxzz_.cjs} +1945 -1150
  16. package/dist/chunks/{eventemitter3-Bt2s0X0a.es.js → eventemitter3-CMOjDs74.es.js} +124 -16
  17. package/dist/chunks/{eventemitter3-DqY4aSMf.cjs → eventemitter3-D38u8ta_.cjs} +125 -16
  18. package/dist/chunks/jszip-RC64TPzL.cjs +4758 -0
  19. package/dist/chunks/jszip-VxCFV9YS.es.js +4717 -0
  20. package/dist/chunks/{rolldown-runtime-D7PMmH3s.es.js → rolldown-runtime-B5TtN50X.es.js} +13 -4
  21. package/dist/chunks/{rolldown-runtime-1Y-nnZJ3.cjs → rolldown-runtime-DtsSbkrh.cjs} +12 -3
  22. package/dist/chunks/{uuid-CFp0WGVU.cjs → uuid-BhG0ngwk.cjs} +10 -6
  23. package/dist/chunks/{uuid-B2Sqk-3p.es.js → uuid-H0Xcmmhy.es.js} +8 -3
  24. package/dist/collaboration-upgrade-engine.cjs +34 -9
  25. package/dist/collaboration-upgrade-engine.es.js +30 -5
  26. package/dist/document-api/src/citations/citations.types.d.ts +9 -0
  27. package/dist/document-api/src/comments/comments.types.d.ts +7 -0
  28. package/dist/document-api/src/types/receipt.d.ts +9 -5
  29. package/dist/document-api/src/types/track-changes.types.d.ts +17 -0
  30. package/dist/layout-engine/contracts/src/graphic-placement.d.ts +35 -6
  31. package/dist/layout-engine/contracts/src/incremental-dependency.d.ts +22 -2
  32. package/dist/layout-engine/contracts/src/index.d.ts +208 -14
  33. package/dist/layout-engine/contracts/src/inline-box.d.ts +19 -0
  34. package/dist/layout-engine/contracts/src/paragraph-visible-text.d.ts +19 -0
  35. package/dist/layout-engine/contracts/src/resolved-layout.d.ts +5 -0
  36. package/dist/layout-engine/dom-contract/src/class-names.d.ts +2 -0
  37. package/dist/layout-engine/layout-bridge/src/footnote-scorer.d.ts +1 -1
  38. package/dist/layout-engine/layout-bridge/src/hydrateTableTextboxMeasures.d.ts +9 -0
  39. package/dist/layout-engine/layout-bridge/src/incrementalLayout.d.ts +42 -11
  40. package/dist/layout-engine/layout-bridge/src/index.d.ts +4 -2
  41. package/dist/layout-engine/layout-bridge/src/inline-box-key.d.ts +3 -0
  42. package/dist/layout-engine/layout-bridge/src/layoutHeaderFooter.d.ts +11 -4
  43. package/dist/layout-engine/layout-bridge/src/remeasure.d.ts +2 -2
  44. package/dist/layout-engine/layout-bridge/src/run-visual-marks.d.ts +2 -0
  45. package/dist/layout-engine/layout-bridge/src/text-measurement.d.ts +0 -12
  46. package/dist/layout-engine/layout-engine/src/anchors.d.ts +4 -0
  47. package/dist/layout-engine/layout-engine/src/execution.d.ts +21 -0
  48. package/dist/layout-engine/layout-engine/src/floating-objects.d.ts +15 -2
  49. package/dist/layout-engine/layout-engine/src/floating-table-anchor.d.ts +2 -0
  50. package/dist/layout-engine/layout-engine/src/footnote-anchor-index.d.ts +17 -0
  51. package/dist/layout-engine/layout-engine/src/index.d.ts +13 -10
  52. package/dist/layout-engine/layout-engine/src/inline-drawing-alignment.d.ts +9 -0
  53. package/dist/layout-engine/layout-engine/src/layout-drawing.d.ts +3 -3
  54. package/dist/layout-engine/layout-engine/src/layout-paragraph.d.ts +2 -2
  55. package/dist/layout-engine/layout-engine/src/layout-textbox.d.ts +3 -3
  56. package/dist/layout-engine/layout-engine/src/pageNumbering.d.ts +3 -41
  57. package/dist/layout-engine/layout-engine/src/paginator.d.ts +7 -2
  58. package/dist/layout-engine/layout-engine/src/resolvePageTokens.d.ts +2 -0
  59. package/dist/layout-engine/layout-engine/src/section-props.d.ts +5 -0
  60. package/dist/layout-engine/painters/dom/src/renderer.d.ts +18 -0
  61. package/dist/layout-engine/painters/dom/src/runs/inline-box.d.ts +8 -0
  62. package/dist/layout-engine/painters/dom/src/runs/text-run.d.ts +6 -4
  63. package/dist/layout-engine/painters/dom/src/table/border-utils.d.ts +20 -27
  64. package/dist/layout-engine/painters/dom/src/table/renderTableFragment.d.ts +1 -1
  65. package/dist/layout-engine/style-engine/src/ooxml/word-style-model/parse-theme.d.ts +6 -0
  66. package/dist/public/ui-react.cjs +66 -2
  67. package/dist/public/ui-react.es.js +66 -1
  68. package/dist/public/ui.cjs +1 -1
  69. package/dist/public/ui.es.js +1 -1
  70. package/dist/style.css +174 -138
  71. package/dist/style.layered.css +174 -138
  72. package/dist/superdoc/src/components/CommentsLayer/CommentDialog.vue.d.ts +2 -0
  73. package/dist/superdoc/src/components/CommentsLayer/commentsList/ReviewDirectoryListItem.vue.d.ts +16 -0
  74. package/dist/superdoc/src/components/CommentsLayer/commentsList/commentsList.vue.d.ts +3 -1
  75. package/dist/superdoc/src/components/CommentsLayer/commentsList/super-comments-list.d.ts +12 -0
  76. package/dist/superdoc/src/core/SuperDoc.d.ts +10 -7
  77. package/dist/superdoc/src/core/extensions/index.d.ts +1 -1
  78. package/dist/superdoc/src/core/extensions/types.d.ts +63 -5
  79. package/dist/superdoc/src/core/types/index.d.ts +535 -42
  80. package/dist/superdoc/src/core/v2-integration/v2-integration.d.ts +3 -3
  81. package/dist/superdoc/src/helpers/comment-small-screen.d.ts +10 -0
  82. package/dist/superdoc/src/helpers/v2-review-mutation-impact.d.ts +3 -5
  83. package/dist/superdoc/src/internal/toolbar/built-in/ToolbarButton.vue.d.ts +4 -4
  84. package/dist/superdoc/src/internal/toolbar/built-in-toolbar.d.ts +11 -0
  85. package/dist/superdoc/src/internal/toolbar/compatibility-catalog.d.ts +1 -1
  86. package/dist/superdoc/src/public/index.d.cts +28 -0
  87. package/dist/superdoc/src/public/index.d.ts +14 -0
  88. package/dist/superdoc/src/public/ui/types.d.ts +30 -6
  89. package/dist/superdoc/src/stores/comments-store.d.ts +81 -78
  90. package/dist/superdoc/src/stores/superdoc-store.d.ts +243 -234
  91. package/dist/superdoc.cjs +6735 -2163
  92. package/dist/superdoc.es.js +6608 -2036
  93. package/dist-cdn/style.layered.css +1 -1
  94. package/dist-cdn/superdoc.min.css +1 -1
  95. package/dist-cdn/superdoc.min.js +37 -37
  96. package/package.json +14 -18
  97. package/AGENTS.md +0 -337
  98. package/dist/chunks/_plugin-vue_export-helper-CZ1Nl59K.cjs +0 -11
  99. package/dist/chunks/_plugin-vue_export-helper-DSMAhhwD.es.js +0 -6
  100. package/dist/chunks/constants-BfH0br5u.es.js +0 -3
  101. package/dist/chunks/constants-D7TNtyJd.cjs +0 -14
  102. package/dist/chunks/jszip-C8srOKAO.es.js +0 -4650
  103. package/dist/chunks/jszip-Cs9JBLlJ.cjs +0 -4691
  104. package/dist/superdoc/src/helpers/v2-remote-review-hydration.d.ts +0 -12
  105. package/dist/superdoc/src/helpers/v2-review-mutation-reconciler.d.ts +0 -19
@@ -1,5 +1,5 @@
1
- import { FlowBlock, HeaderFooterLayout, Measure, PageNumberChapterSeparator, PageNumberFormat, ParagraphBlock, ParagraphMeasure } from '../../contracts/src/index.js';
2
- import { HeaderFooterConstraints } from '../../layout-engine/src/index.js';
1
+ import { FlowBlock, HeaderFooterLayout, Measure, PageNumberChapterSeparator, PageNumberFormat, ParagraphBlock, ParagraphLineRegion, ParagraphMeasure } from '../../contracts/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, lineRegions?: readonly (readonly ParagraphLineRegion[])[]) => ParagraphMeasure, options?: ResolveHeaderFooterTokensOptions, execution?: HeaderFooterLayoutExecution): Promise<HeaderFooterBatchResult>;
@@ -1,4 +1,4 @@
1
- import { ParagraphBlock, ParagraphMeasure } from '../../contracts/src/index.js';
1
+ import { ParagraphBlock, ParagraphMeasure, ParagraphLineRegion } from '../../contracts/src/index.js';
2
2
  /** Drop cached text widths and the canvas context. Call when registered font faces may have changed. */
3
3
  export declare function clearRemeasureTextCaches(): void;
4
4
  /**
@@ -72,4 +72,4 @@ export declare function clearRemeasureTextCaches(): void;
72
72
  * // First line has only 170px available (200 - 30), subsequent lines have full 200px
73
73
  * ```
74
74
  */
75
- export declare function remeasureParagraph(block: ParagraphBlock, maxWidth: number, firstLineIndent?: number): ParagraphMeasure;
75
+ export declare function remeasureParagraph(block: ParagraphBlock, maxWidth: number, firstLineIndent?: number, lineRegions?: readonly (readonly ParagraphLineRegion[])[]): ParagraphMeasure;
@@ -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,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,4 +1,4 @@
1
- import { DrawingBlock, DrawingMeasure, ParagraphMeasure } from '../../contracts/src/index.js';
1
+ import { DrawingBlock, DrawingMeasure, TextboxContentMeasure } from '../../contracts/src/index.js';
2
2
  import { NormalizedColumns } from './layout-image.js';
3
3
  import { PageState } from './paginator.js';
4
4
  /**
@@ -21,8 +21,8 @@ export type DrawingLayoutContext = {
21
21
  advanceColumn: (state: PageState) => PageState;
22
22
  /** Computes the X coordinate for a column in the given page state (SD-2629). */
23
23
  columnX: (state: PageState, columnIndex?: number) => number;
24
- /** Optional textbox paragraph measurements carried alongside textbox drawings. */
25
- textboxContentMeasures?: ParagraphMeasure[];
24
+ /** Optional canonical textbox block measurements carried alongside textbox drawings. */
25
+ textboxContentMeasures?: TextboxContentMeasure[];
26
26
  };
27
27
  /**
28
28
  * Layout a drawing block (vector shape) within the document flow.
@@ -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,4 @@
1
- import { DrawingMeasure, ParagraphMeasure, TextboxDrawing } from '../../contracts/src/index.js';
2
- export declare function layoutTextboxContent(block: TextboxDrawing, remeasureParagraph: (block: TextboxDrawing['contentBlocks'][number], maxWidth: number) => ParagraphMeasure): ParagraphMeasure[];
1
+ import { DrawingMeasure, ParagraphBlock, ParagraphMeasure, TextboxContentMeasure, TextboxDrawing } from '../../contracts/src/index.js';
2
+ export declare function layoutTextboxContent(block: TextboxDrawing, remeasureParagraph: (block: ParagraphBlock, maxWidth: number) => ParagraphMeasure): ParagraphMeasure[] | undefined;
3
3
  /** Prefer canonical measurement output, retaining the synchronous bridge as a legacy fallback. */
4
- export declare function resolveTextboxContentMeasures(block: TextboxDrawing, measure: DrawingMeasure, remeasureParagraph?: (block: TextboxDrawing['contentBlocks'][number], maxWidth: number) => ParagraphMeasure): ParagraphMeasure[] | undefined;
4
+ export declare function resolveTextboxContentMeasures(block: TextboxDrawing, measure: DrawingMeasure, remeasureParagraph?: (block: ParagraphBlock, maxWidth: number) => ParagraphMeasure): TextboxContentMeasure[] | undefined;
@@ -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[]>;
@@ -94,7 +94,9 @@ export type PaginatorOptions = {
94
94
  w: number;
95
95
  h: number;
96
96
  }): Page;
97
- onNewPage?: (state: PageState) => void;
97
+ onNewPage?: (state: PageState | undefined, options?: {
98
+ applyPendingSection: boolean;
99
+ }) => void;
98
100
  shouldStopBeforeNewPage?: (input: {
99
101
  completedPageIndex: number;
100
102
  pages: readonly Page[];
@@ -122,7 +124,10 @@ export declare function breakParagraphAdjacency(state: PageState): void;
122
124
  export declare function createPaginator(opts: PaginatorOptions): {
123
125
  readonly pages: Page[];
124
126
  readonly states: PageState[];
125
- readonly startNewPage: () => PageState;
127
+ readonly startNewPage: (options?: {
128
+ applyPendingSection?: boolean;
129
+ replaceCurrentPage?: boolean;
130
+ }) => PageState;
126
131
  readonly ensurePage: () => PageState;
127
132
  readonly advanceColumn: (state: PageState) => PageState;
128
133
  readonly getActiveColumnsForState: (state: PageState) => ColumnLayout;
@@ -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>;
@@ -520,6 +520,14 @@ export declare class DomPainter {
520
520
  * Apply fill and stroke styles to a fallback shape container
521
521
  */
522
522
  private applyFallbackShapeStyle;
523
+ /**
524
+ * Shape stroke widths reach the painter in physical CSS pixels. Preset SVGs
525
+ * use a normalized 100 × 100 viewBox while VML custom geometry often uses a
526
+ * coordsize in the thousands. In both cases allowing the viewBox transform to
527
+ * scale the stroke changes the authored line weight, sometimes by orders of
528
+ * magnitude. Keep geometry scalable and paint the resolved width verbatim.
529
+ */
530
+ private applyPhysicalStrokeSemantics;
523
531
  private hasShapeTextContent;
524
532
  private createShapeTextElement;
525
533
  private createTextboxContentElement;
@@ -540,6 +548,7 @@ export declare class DomPainter {
540
548
  * @param _groupScaleY - Reserved parent-group scale factor
541
549
  */
542
550
  private createFallbackTextElement;
551
+ private applyShapeTextFlow;
543
552
  private tryCreatePresetSvg;
544
553
  /**
545
554
  * Creates an SVG string from custom geometry path data (a:custGeom).
@@ -566,6 +575,9 @@ export declare class DomPainter {
566
575
  */
567
576
  private createChartElement;
568
577
  private resolveTableRenderData;
578
+ private createTableCellLineRenderer;
579
+ /** Render drawing content nested in any canonical table, including a textbox-owned table. */
580
+ private renderDrawingContentForTable;
569
581
  private renderTableFragment;
570
582
  private renderLine;
571
583
  private createRunRenderContext;
@@ -600,6 +612,12 @@ export declare class DomPainter {
600
612
  * Uses resolved data for spatial properties and delegates PM attributes to the legacy path.
601
613
  */
602
614
  private isAnchoredMediaFragment;
615
+ /**
616
+ * Marks fragments whose paint coordinates are independent from body flow.
617
+ * DOM consumers such as header/footer hit-testing must not infer page margins
618
+ * from floating objects that happen to paint above the first flow block.
619
+ */
620
+ private applyFragmentFlowClass;
603
621
  private shouldRenderBehindPageContent;
604
622
  private isHeaderWordArtWatermark;
605
623
  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 {};
@@ -39,7 +39,7 @@ export type TableRenderDependencies = {
39
39
  /** Built-in SDT chrome rendering mode. */
40
40
  chrome?: 'default' | 'none';
41
41
  /** Function to render a line of paragraph content */
42
- renderLine: (block: ParagraphBlock, line: Line, context: FragmentRenderContext, lineIndex: number, isLastLine: boolean) => HTMLElement;
42
+ renderLine: (block: ParagraphBlock, line: Line, context: FragmentRenderContext, lineIndex: number, isLastLine: boolean, resolvedListTextStartPx?: number) => HTMLElement;
43
43
  /** Optional callback invoked after a table line's final styles/markers are applied. */
44
44
  captureLineSnapshot?: (lineEl: HTMLElement, context: FragmentRenderContext, options?: {
45
45
  inTableParagraph?: boolean;
@@ -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