@stll/folio-core 0.36.0 → 0.37.1

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 (200) hide show
  1. package/README.md +59 -1
  2. package/dist/ai-edits/apply.js +689 -367
  3. package/dist/ai-edits/block-identity.d.ts +4 -1
  4. package/dist/ai-edits/block-identity.js +4 -1
  5. package/dist/ai-edits/blockRange.js +14 -14
  6. package/dist/ai-edits/clean-text.d.ts +40 -1
  7. package/dist/ai-edits/clean-text.js +52 -2
  8. package/dist/ai-edits/headless.d.ts +3 -1
  9. package/dist/ai-edits/headless.js +133 -71
  10. package/dist/ai-edits/index.d.ts +3 -3
  11. package/dist/ai-edits/index.js +2 -2
  12. package/dist/ai-edits/read.js +38 -20
  13. package/dist/ai-edits/snapshot.d.ts +14 -6
  14. package/dist/ai-edits/snapshot.js +99 -19
  15. package/dist/ai-edits/table-cell-mutations.js +1 -1
  16. package/dist/ai-edits/table-row-column-mutations.js +7 -0
  17. package/dist/ai-edits/table-template.d.ts +11 -1
  18. package/dist/ai-edits/table-template.js +49 -17
  19. package/dist/ai-edits/types.d.ts +60 -57
  20. package/dist/ai-suggestions/conflict.js +1 -4
  21. package/dist/ai-suggestions/text-positions.d.ts +8 -0
  22. package/dist/ai-suggestions/text-positions.js +27 -5
  23. package/dist/compare/__fixtures__/body-sequence.js +3 -4
  24. package/dist/compare/column-alignment.d.ts +13 -13
  25. package/dist/compare/column-alignment.js +78 -39
  26. package/dist/compare/compare.d.ts +4 -3
  27. package/dist/compare/compare.js +41 -5
  28. package/dist/compare/content-alignment.d.ts +95 -0
  29. package/dist/compare/content-alignment.js +1450 -0
  30. package/dist/compare/content-types.d.ts +100 -0
  31. package/dist/compare/content-types.js +0 -0
  32. package/dist/compare/content.d.ts +209 -0
  33. package/dist/compare/content.js +885 -0
  34. package/dist/compare/formatting.d.ts +5 -5
  35. package/dist/compare/formatting.js +6 -4
  36. package/dist/compare/plan.d.ts +6 -1
  37. package/dist/compare/plan.js +201 -569
  38. package/dist/compare/scenario.d.ts +2 -2
  39. package/dist/compare/types.d.ts +3 -3
  40. package/dist/compare/verification.d.ts +2 -2
  41. package/dist/compare/verification.js +25 -8
  42. package/dist/compat/eigenpal.d.ts +5 -3
  43. package/dist/compat/eigenpal.js +3 -2
  44. package/dist/controller/headerFooterEditorManager.js +14 -6
  45. package/dist/controller/hiddenEditorManager.d.ts +7 -2
  46. package/dist/controller/hiddenEditorManager.js +15 -6
  47. package/dist/controller/layoutPipeline.js +5 -3
  48. package/dist/controller/noteEditorManager.js +12 -7
  49. package/dist/display-list/build/headerFooterPrimitives.js +1 -0
  50. package/dist/display-list/build/storyPrimitives.d.ts +5 -2
  51. package/dist/display-list/build/storyPrimitives.js +60 -3
  52. package/dist/display-list/build/tablePrimitives.js +30 -0
  53. package/dist/display-list/primitives.d.ts +1 -1
  54. package/dist/document-operations.d.ts +8 -6
  55. package/dist/document-operations.js +121 -26
  56. package/dist/docx/blockContentParser.js +6 -27
  57. package/dist/docx/ensureParaIds.js +9 -4
  58. package/dist/docx/numberingParser.d.ts +3 -1
  59. package/dist/docx/numberingParser.js +4 -1
  60. package/dist/docx/paragraphParser.js +7 -6
  61. package/dist/docx/paragraphTraversal.js +30 -34
  62. package/dist/docx/rezip.d.ts +0 -8
  63. package/dist/docx/rezip.js +41 -16
  64. package/dist/docx/runParser.js +4 -2
  65. package/dist/docx/serializer/paragraphSerializer.js +2 -0
  66. package/dist/docx/serializer/runSerializer.js +5 -3
  67. package/dist/docx/serializer/trackedChangeAttributes.d.ts +3 -1
  68. package/dist/docx/serializer/trackedChangeAttributes.js +11 -1
  69. package/dist/docx/server/build.d.ts +1 -1
  70. package/dist/headless-layout.js +5 -4
  71. package/dist/index.d.ts +5 -3
  72. package/dist/index.js +3 -2
  73. package/dist/internal/headlessRevisionResolution.d.ts +23 -0
  74. package/dist/internal/headlessRevisionResolution.js +176 -0
  75. package/dist/internal/headlessRevisionResolutionGuard.d.ts +12 -0
  76. package/dist/internal/headlessRevisionResolutionGuard.js +28 -0
  77. package/dist/internal/pageBreakRunDescendantIndex.d.ts +9 -0
  78. package/dist/internal/pageBreakRunDescendantIndex.js +27 -0
  79. package/dist/internal/pageBreakRunPartition.d.ts +26 -0
  80. package/dist/internal/pageBreakRunPartition.js +35 -0
  81. package/dist/internal/pageBreakRunSourceDescendantIndex.d.ts +15 -0
  82. package/dist/internal/pageBreakRunSourceDescendantIndex.js +126 -0
  83. package/dist/internal/sectionEndpointResolution.d.ts +32 -0
  84. package/dist/internal/sectionEndpointResolution.js +38 -0
  85. package/dist/layout-bridge/convert/footnoteLayout.js +1 -0
  86. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +16 -4
  87. package/dist/layout-bridge/convert/headerFooterLayout.js +48 -5
  88. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +4 -0
  89. package/dist/layout-bridge/convert/toFlowBlocks.js +379 -75
  90. package/dist/layout-bridge/dom/clickToPositionDom.d.ts +8 -1
  91. package/dist/layout-bridge/dom/clickToPositionDom.js +114 -40
  92. package/dist/layout-bridge/dom/textStreamDom.d.ts +24 -0
  93. package/dist/layout-bridge/dom/textStreamDom.js +75 -0
  94. package/dist/layout-bridge/headerFooterLayout.js +16 -30
  95. package/dist/layout-engine/index.js +12 -3
  96. package/dist/layout-engine/measure/tableFragmentBorderGeometry.d.ts +17 -0
  97. package/dist/layout-engine/measure/tableFragmentBorderGeometry.js +24 -0
  98. package/dist/layout-engine/renderedBreakReconciliation.js +1 -1
  99. package/dist/layout-engine/types.d.ts +7 -0
  100. package/dist/layout-painter/imageLayout.d.ts +1 -1
  101. package/dist/layout-painter/renderTable.js +20 -0
  102. package/dist/model.d.ts +1 -1
  103. package/dist/paged-layout/rangeProjection.js +6 -9
  104. package/dist/paged-layout/transactionDirtyRange.d.ts +3 -1
  105. package/dist/paged-layout/transactionDirtyRange.js +23 -1
  106. package/dist/prosemirror/attrs/index.d.ts +7 -3
  107. package/dist/prosemirror/attrs/index.js +113 -7
  108. package/dist/prosemirror/bookmarkBoundaryIntegrity.d.ts +9 -0
  109. package/dist/prosemirror/bookmarkBoundaryIntegrity.js +22 -0
  110. package/dist/prosemirror/commands/comments.d.ts +10 -1
  111. package/dist/prosemirror/commands/comments.js +167 -59
  112. package/dist/prosemirror/commands/formatPainter.d.ts +45 -10
  113. package/dist/prosemirror/commands/formatPainter.js +319 -63
  114. package/dist/prosemirror/commands/index.d.ts +2 -2
  115. package/dist/prosemirror/commands/pageBreak.d.ts +5 -2
  116. package/dist/prosemirror/commands/pageBreak.js +18 -36
  117. package/dist/prosemirror/commands/propertyChangeScope.d.ts +7 -5
  118. package/dist/prosemirror/commands/propertyChangeScope.js +27 -18
  119. package/dist/prosemirror/conversion/fromProseDoc.d.ts +7 -2
  120. package/dist/prosemirror/conversion/fromProseDoc.js +809 -209
  121. package/dist/prosemirror/conversion/runShadingMark.js +2 -2
  122. package/dist/prosemirror/conversion/toProseDoc.d.ts +26 -1
  123. package/dist/prosemirror/conversion/toProseDoc.js +416 -283
  124. package/dist/prosemirror/extensions/StarterKit.js +4 -0
  125. package/dist/prosemirror/extensions/core/ParagraphExtension.js +12 -8
  126. package/dist/prosemirror/extensions/features/ListExtension.js +95 -123
  127. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +1 -1
  128. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +27 -1
  129. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +134 -30
  130. package/dist/prosemirror/extensions/features/pasteCleanup.js +9 -15
  131. package/dist/prosemirror/extensions/marks/BoldExtension.js +4 -3
  132. package/dist/prosemirror/extensions/marks/CharacterStyleExtension.d.ts +4 -7
  133. package/dist/prosemirror/extensions/marks/CharacterStyleExtension.js +5 -11
  134. package/dist/prosemirror/extensions/marks/FontSizeExtension.js +3 -3
  135. package/dist/prosemirror/extensions/marks/ItalicExtension.js +4 -3
  136. package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.d.ts +13 -0
  137. package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.js +39 -0
  138. package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.d.ts +7 -1
  139. package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.js +67 -21
  140. package/dist/prosemirror/extensions/marks/markUtils.d.ts +8 -1
  141. package/dist/prosemirror/extensions/marks/markUtils.js +88 -2
  142. package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.js +44 -3
  143. package/dist/prosemirror/extensions/nodes/FieldExtension.js +1 -1
  144. package/dist/prosemirror/extensions/nodes/HardBreakExtension.js +15 -4
  145. package/dist/prosemirror/extensions/nodes/PageBreakExtension.d.ts +6 -0
  146. package/dist/prosemirror/extensions/nodes/PageBreakExtension.js +6 -0
  147. package/dist/prosemirror/extensions/nodes/PageBreakRunExtension.d.ts +6 -0
  148. package/dist/prosemirror/extensions/nodes/PageBreakRunExtension.js +36 -0
  149. package/dist/prosemirror/findReplaceSelection.js +8 -3
  150. package/dist/prosemirror/index.d.ts +3 -3
  151. package/dist/prosemirror/listMarker.d.ts +26 -1
  152. package/dist/prosemirror/listMarker.js +108 -14
  153. package/dist/prosemirror/pageBreakRunProjection.d.ts +28 -0
  154. package/dist/prosemirror/pageBreakRunProjection.js +47 -0
  155. package/dist/prosemirror/paraText.js +6 -0
  156. package/dist/prosemirror/paragraphSpacing.d.ts +29 -0
  157. package/dist/prosemirror/paragraphSpacing.js +125 -0
  158. package/dist/prosemirror/plugins/documentNumbering.d.ts +8 -0
  159. package/dist/prosemirror/plugins/documentNumbering.js +18 -0
  160. package/dist/prosemirror/plugins/pmTextScan.d.ts +3 -2
  161. package/dist/prosemirror/plugins/pmTextScan.js +14 -4
  162. package/dist/prosemirror/plugins/suggestionMode.js +8 -10
  163. package/dist/prosemirror/rebaseParagraphRunFormatting.d.ts +16 -0
  164. package/dist/prosemirror/rebaseParagraphRunFormatting.js +61 -0
  165. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +64 -0
  166. package/dist/prosemirror/runFormattingInlineCarriers.js +121 -0
  167. package/dist/prosemirror/runFormattingProvenance.d.ts +12 -0
  168. package/dist/prosemirror/runFormattingProvenance.js +48 -0
  169. package/dist/prosemirror/runFormattingReconciliation.d.ts +25 -0
  170. package/dist/prosemirror/runFormattingReconciliation.js +54 -0
  171. package/dist/prosemirror/runPropertyChangeResolution.d.ts +18 -0
  172. package/dist/prosemirror/runPropertyChangeResolution.js +18 -0
  173. package/dist/prosemirror/runStyleFormatting.d.ts +50 -0
  174. package/dist/prosemirror/runStyleFormatting.js +105 -0
  175. package/dist/prosemirror/schema/index.d.ts +3 -3
  176. package/dist/prosemirror/schema/marks.d.ts +82 -9
  177. package/dist/prosemirror/schema/marks.js +73 -1
  178. package/dist/prosemirror/schema/nodes.d.ts +18 -5
  179. package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +14 -2
  180. package/dist/prosemirror/styles/resolvedStyleAttrs.js +44 -23
  181. package/dist/prosemirror/styles/styleResolver.d.ts +10 -13
  182. package/dist/prosemirror/styles/styleResolver.js +3 -3
  183. package/dist/prosemirror/styles/styleToggleCascade.d.ts +8 -1
  184. package/dist/prosemirror/styles/styleToggleCascade.js +24 -1
  185. package/dist/prosemirror/tableGridMutation.d.ts +20 -0
  186. package/dist/prosemirror/tableGridMutation.js +30 -0
  187. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +31 -0
  188. package/dist/prosemirror/trackedRunInlineAtoms.js +39 -0
  189. package/dist/prosemirror/utils/visualLineNavigation.js +27 -31
  190. package/dist/prosemirror/validation.js +23 -4
  191. package/dist/render-dom/HeaderFooterSelectionOverlay.js +20 -20
  192. package/dist/render-dom/RenderedDomContext.js +17 -34
  193. package/dist/server.d.ts +4 -4
  194. package/dist/server.js +2 -2
  195. package/dist/style-engine/styleEngine.d.ts +1 -1
  196. package/dist/utils/clipboard.js +1 -1
  197. package/dist/utils/findReplace.js +38 -21
  198. package/dist/version-comparison.d.ts +38 -44
  199. package/dist/version-comparison.js +270 -401
  200. package/package.json +3 -2
@@ -1,4 +1,4 @@
1
- import { FolioAIInlineFormatting } from "../ai-edits/types.js";
1
+ import { FolioAIInlineFormattingPatch } from "../ai-edits/types.js";
2
2
  import { CompareDocxParseError, CompareDocxSerializeError } from "./types.js";
3
3
  import { Result } from "better-result";
4
4
  //#region src/compare/scenario.d.ts
@@ -42,7 +42,7 @@ type EditScriptStep = {
42
42
  blockIndex: number;
43
43
  startOffset: number;
44
44
  endOffset: number;
45
- formatting: FolioAIInlineFormatting;
45
+ formatting: FolioAIInlineFormattingPatch;
46
46
  } | {
47
47
  type: "insertTableRow";
48
48
  blockIndex: number;
@@ -1,4 +1,4 @@
1
- import { FolioAIBlockParagraphProperties, FolioAIBlockTableLocation, FolioAIEditSkippedOperation, FolioAIInlineFormatting } from "../ai-edits/types.js";
1
+ import { FolioAIBlockParagraphProperties, FolioAIBlockTableLocation, FolioAIEditSkippedOperation, FolioAIInlineFormattingPatch } from "../ai-edits/types.js";
2
2
  import { WordDiffGranularity } from "../ai-edits/word-diff.js";
3
3
  import { FolioDocumentStoryHandle, FolioNumberingLevel } from "../ai-edits/headless.js";
4
4
  import { CompareVerification, CompareVerificationCause, CompareVerificationFailure, CompareVerificationInvariant, FinalParagraphMarkRevision } from "./verification.js";
@@ -45,8 +45,8 @@ type CompareChangeLocation = {
45
45
  type CompareFormatRange = {
46
46
  startOffset: number;
47
47
  endOffset: number;
48
- /** Only the properties that differ, set to the target document's value. */
49
- formatting: FolioAIInlineFormatting;
48
+ /** Differing properties set to the target value; null removes a direct property. */
49
+ formatting: FolioAIInlineFormattingPatch;
50
50
  };
51
51
  /**
52
52
  * One difference between the two documents, in target-document order with
@@ -10,7 +10,7 @@ type CompareVerificationInvariant = (typeof COMPARE_VERIFICATION_INVARIANTS)[num
10
10
  * that fits is the one reported, because a block in the wrong container is a
11
11
  * different finding from a block whose words are wrong even when both are true.
12
12
  */
13
- declare const COMPARE_VERIFICATION_CAUSES: readonly ["invisible-structure", "block-count", "container", "table-geometry", "style", "list-level", "alignment", "inline-formatting", "whitespace", "text"];
13
+ declare const COMPARE_VERIFICATION_CAUSES: readonly ["invisible-structure", "block-count", "container", "inline-structure", "table-geometry", "style", "list-level", "alignment", "spacing", "inline-formatting", "whitespace", "text"];
14
14
  type CompareVerificationCause = (typeof COMPARE_VERIFICATION_CAUSES)[number];
15
15
  /** One invariant that did not hold, in one story. */
16
16
  type CompareVerificationFailure = {
@@ -35,7 +35,7 @@ type CompareVerification = {
35
35
  };
36
36
  /** Effective supported formatting with equivalent adjacent runs normalized. */
37
37
  declare const projectSupportedInlineFormatting: ({ text, previewRuns }: FolioAIBlock) => string;
38
- type ProjectedBlock = Pick<FolioAIBlock, "text" | "table" | "styleId" | "listLevel" | "directAlignment">;
38
+ type ProjectedBlock = Pick<FolioAIBlock, "text" | "table" | "styleId" | "listLevel" | "directAlignment" | "directSpacing" | "structuralBoundaries">;
39
39
  type ClassifyOptions<T> = {
40
40
  invariant: CompareVerificationInvariant;
41
41
  story: FolioDocumentStoryHandle;
@@ -1,3 +1,4 @@
1
+ import { paragraphSpacingEqual } from "../prosemirror/paragraphSpacing.js";
1
2
  import { resolveColorToHex } from "../utils/colorResolver.js";
2
3
  import { PARAGRAPH_MARK_CHANGE_KINDS } from "@stll/docx-core/model";
3
4
  //#region src/compare/verification.ts
@@ -7,9 +8,9 @@ import { PARAGRAPH_MARK_CHANGE_KINDS } from "@stll/docx-core/model";
7
8
  * The check compares two block projections: what accepting the generated
8
9
  * revisions leaves against the target, and what rejecting them leaves against
9
10
  * the base. A projection carries each block's container, style, list level,
10
- * direct alignment and text, so WHICH field diverged names which part of the
11
- * pipeline lost the difference — and that is worth reporting as a typed cause
12
- * rather than as one opaque "did not reproduce".
11
+ * direct alignment, direct spacing and text, so WHICH field diverged names
12
+ * which part of the pipeline lost the difference — and that is worth reporting
13
+ * as a typed cause rather than as one opaque "did not reproduce".
13
14
  *
14
15
  * Every `detail` string here is structural: counts, offsets, container kinds.
15
16
  * Never a phrase of either document, because a caller may log it, put it in a
@@ -27,10 +28,12 @@ const COMPARE_VERIFICATION_CAUSES = Object.freeze([
27
28
  "invisible-structure",
28
29
  "block-count",
29
30
  "container",
31
+ "inline-structure",
30
32
  "table-geometry",
31
33
  "style",
32
34
  "list-level",
33
35
  "alignment",
36
+ "spacing",
34
37
  "inline-formatting",
35
38
  "whitespace",
36
39
  "text"
@@ -43,10 +46,10 @@ const supportedInlineStyle = ({ bold, italic, underline, strike, fontFamily, fon
43
46
  fontFamily ?? null,
44
47
  fontSizePt ?? null,
45
48
  normalizeInlineFormattingColor(color) ?? null,
46
- directFormatting?.bold === true,
47
- directFormatting?.italic === true,
48
- directFormatting?.underline === true,
49
- directFormatting?.strike === true,
49
+ directFormatting?.bold ?? null,
50
+ directFormatting?.italic ?? null,
51
+ directFormatting?.underline ?? null,
52
+ directFormatting?.strike ?? null,
50
53
  directFormatting?.fontFamily ?? null,
51
54
  directFormatting?.fontSizePt ?? null,
52
55
  normalizeInlineFormattingColor(directFormatting?.color ?? void 0) ?? null
@@ -73,7 +76,19 @@ const sameContainer = (left, right) => {
73
76
  if (!left || !right) return left === right;
74
77
  return left.outerTableIndex === right.outerTableIndex && left.tableIndex === right.tableIndex && left.rowIndex === right.rowIndex && left.cellIndex === right.cellIndex && left.gridColumnIndex === right.gridColumnIndex && left.columnSpan === right.columnSpan && left.rowSpan === right.rowSpan && left.paragraphIndex === right.paragraphIndex;
75
78
  };
76
- const sameProjectedBlock = (left, right) => sameContainer(left.table, right.table) && left.styleId === right.styleId && left.listLevel === right.listLevel && left.directAlignment === right.directAlignment && left.text === right.text;
79
+ const sameStructuralBoundaries = (left, right) => {
80
+ const leftLength = left?.length ?? 0;
81
+ if (leftLength !== (right?.length ?? 0)) return false;
82
+ if (leftLength === 0) return true;
83
+ if (left === void 0 || right === void 0) return false;
84
+ for (let index = 0; index < leftLength; index++) {
85
+ const boundary = left[index];
86
+ const other = right[index];
87
+ if (boundary === void 0 || other === void 0 || boundary.type !== other.type || boundary.offset !== other.offset || boundary.clear !== other.clear) return false;
88
+ }
89
+ return true;
90
+ };
91
+ const sameProjectedBlock = (left, right) => sameContainer(left.table, right.table) && sameStructuralBoundaries(left.structuralBoundaries, right.structuralBoundaries) && left.styleId === right.styleId && left.listLevel === right.listLevel && left.directAlignment === right.directAlignment && paragraphSpacingEqual(left.directSpacing, right.directSpacing) && left.text === right.text;
77
92
  const containerKind = (container) => container ? "cell" : "body";
78
93
  const collapseWhitespace = (text) => text.replace(/\s+/gu, " ").trim();
79
94
  const sameBlockProjection = (left, right) => left.length === right.length && left.every((entry, index) => {
@@ -188,9 +203,11 @@ const classifyProjectionMismatch = ({ invariant, story, actual, expected }) => {
188
203
  if (divergence.actual === null || divergence.expected === null) return failure("block-count", `${actual.length > expected.length ? "more" : "fewer"} blocks than expected (${counts}), diverging ${at}`);
189
204
  const { actual: left, expected: right } = divergence;
190
205
  if (!sameContainer(left.table, right.table)) return failure("container", `a block sits in a ${containerKind(left.table)} where it is expected in a ${containerKind(right.table)}, ${at} (${counts})`);
206
+ if (!sameStructuralBoundaries(left.structuralBoundaries, right.structuralBoundaries)) return failure("inline-structure", `a block's zero-width inline structure does not match ${at} (${counts})`);
191
207
  if (left.text === right.text && left.styleId !== right.styleId) return failure("style", `the paragraph style did not move ${at} (${counts})`);
192
208
  if (left.text === right.text && left.listLevel !== right.listLevel) return failure("list-level", `the list level did not move ${at} (${counts})`);
193
209
  if (left.text === right.text && left.directAlignment !== right.directAlignment) return failure("alignment", `the direct paragraph alignment did not move ${at} (${counts})`);
210
+ if (left.text === right.text && !paragraphSpacingEqual(left.directSpacing, right.directSpacing)) return failure("spacing", `the direct paragraph spacing did not move ${at} (${counts})`);
194
211
  if (collapseWhitespace(left.text) === collapseWhitespace(right.text)) return failure("whitespace", `a block's text differs only in whitespace ${at} (${counts})`);
195
212
  if (actual.length !== expected.length) return failure("block-count", `${counts}, first differing ${at}`);
196
213
  return failure("text", `a ${containerKind(left.table)} block's text does not match ${at}, length ${String(left.text.length)} against ${String(right.text.length)} (${counts})`);
@@ -1,14 +1,16 @@
1
1
  import { document_d_exports } from "../types/document.js";
2
- import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIBlockTableLocation, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditNormalization, FolioAIEditNormalizationCode, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAISignatureParty } from "../ai-edits/types.js";
2
+ import { FolioContentBlock, FolioContentContainerPathEntry, FolioContentIdStability, FolioContentInlineBooleanProperty, FolioContentInlineFormatting, FolioContentInlineFormattingPatch, FolioContentLineSpacingRule, FolioContentParagraphAlignment, FolioContentParagraphSpacing, FolioContentRun, FolioContentSnapshot, FolioContentTableLocation } from "../compare/content-types.js";
3
+ import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIBlockStructuralBoundary, FolioAIBlockTableLocation, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditNormalization, FolioAIEditNormalizationCode, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAIInlineBooleanProperty, FolioAIInlineFormatting, FolioAIInlineFormattingPatch, FolioAIParagraphSpacing, FolioAISignatureParty } from "../ai-edits/types.js";
3
4
  import { WORD_DIFF_GRANULARITIES, WordDiffGranularity, WordDiffNormalization, WordDiffOptions, WordDiffSegment, diffWordSegments } from "../ai-edits/word-diff.js";
4
5
  import { FolioAIEditApplyOutcome, FolioRevisionStamp, FolioWordDiffOptions, applyFolioAIEditOperations } from "../ai-edits/apply.js";
5
- import { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationResultBase, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "../document-operations.js";
6
+ import { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationResultBase, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "../document-operations.js";
6
7
  import { createFolioAIEditSnapshot, hashFolioAIBlockText, isFolioAIContentBlock, normalizeFolioAIBlockText } from "../ai-edits/snapshot.js";
7
8
  import { DeriveBlockIdInput, FolioBlockId, currentFolioBlockId, deriveBlockId, getFolioParaIdFromBlockId, isFolioBlockId, isSequentialFolioBlockId } from "../types/block-id.js";
8
9
  import { AIBarStatus, AIChatMode, AICitation, AICitationSource, AIGenerateInput, AISuggestion, AISuggestionApplyMode, AISuggestionPreset, AISuggestionSeverity, AISuggestionStatus, DEFAULT_AI_SUGGESTION_PRESETS } from "../ai-suggestions/types.js";
9
10
  import { ApplyResult, applySuggestions } from "../ai-suggestions/apply.js";
10
11
  import { ResolvedAnchor, isSuggestionStale, resolveSuggestionAnchor } from "../ai-suggestions/conflict.js";
11
12
  import { PositionalText, buildPositionalText } from "../ai-suggestions/text-positions.js";
13
+ import { CompareContentOptions, FOLIO_CONTENT_COMPARISON_LIMITS, FolioContentBlockProperty, FolioContentComparison, FolioContentComparisonError, FolioContentComparisonEvent, FolioContentComparisonLimit, FolioContentComparisonLimitError, FolioContentFormatRange, FolioContentFormattingChange, FolioContentParagraphFormattingPatch, FolioContentStructuralChange, FolioContentTextSegment, InvalidFolioContentComparisonError, compareContent } from "../compare/content.js";
12
14
  import { COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareVerification, CompareVerificationCause, CompareVerificationFailure, CompareVerificationInvariant, FinalParagraphMarkRevision } from "../compare/verification.js";
13
15
  import { COMPARE_UNSUPPORTED_REASONS, CompareChange, CompareChangeLocation, CompareDocxApplyError, CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, CompareFormatRange, CompareResult, CompareUnsupportedPart, CompareUnsupportedReason, InvalidCompareDocxOptionsError } from "../compare/types.js";
14
16
  import { MAX_COMPARE_OPERATIONS, compareDocx } from "../compare/compare.js";
@@ -37,4 +39,4 @@ import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled
37
39
  import { DOCX_CONFORMANCE_CLASSES } from "../index.js";
38
40
  type Document = document_d_exports.Document;
39
41
  type DocxConformanceClass = document_d_exports.DocxConformanceClass;
40
- export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type BlockRect, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, type CompareChange, type CompareChangeLocation, CompareDocxApplyError, type CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, type CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, type CompareFormatRange, type CompareResult, type CompareUnsupportedPart, type CompareUnsupportedReason, type CompareVerification, type CompareVerificationCause, type CompareVerificationFailure, type CompareVerificationInvariant, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, type FinalParagraphMarkRevision, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIBlockTableLocation, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyOutcome, type FolioAIEditApplyResult, type FolioAIEditNormalization, type FolioAIEditNormalizationCode, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAISignatureParty, type FolioBlockId, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationResultBase, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type FolioRevisionStamp, type FolioWordDiffOptions, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidCompareDocxOptionsError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, type WordDiffGranularity, type WordDiffNormalization, type WordDiffOptions, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
42
+ export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type BlockRect, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, type CompareChange, type CompareChangeLocation, type CompareContentOptions, CompareDocxApplyError, type CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, type CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, type CompareFormatRange, type CompareResult, type CompareUnsupportedPart, type CompareUnsupportedReason, type CompareVerification, type CompareVerificationCause, type CompareVerificationFailure, type CompareVerificationInvariant, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_CONTENT_COMPARISON_LIMITS, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, type FinalParagraphMarkRevision, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIBlockStructuralBoundary, type FolioAIBlockTableLocation, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyOutcome, type FolioAIEditApplyResult, type FolioAIEditNormalization, type FolioAIEditNormalizationCode, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAIInlineBooleanProperty, type FolioAIInlineFormatting, type FolioAIInlineFormattingPatch, type FolioAIParagraphSpacing, type FolioAISignatureParty, type FolioBlockId, type FolioContentBlock, type FolioContentBlockProperty, type FolioContentComparison, type FolioContentComparisonError, type FolioContentComparisonEvent, type FolioContentComparisonLimit, FolioContentComparisonLimitError, type FolioContentContainerPathEntry, type FolioContentFormatRange, type FolioContentFormattingChange, type FolioContentIdStability, type FolioContentInlineBooleanProperty, type FolioContentInlineFormatting, type FolioContentInlineFormattingPatch, type FolioContentLineSpacingRule, type FolioContentParagraphAlignment, type FolioContentParagraphFormattingPatch, type FolioContentParagraphSpacing, type FolioContentRun, type FolioContentSnapshot, type FolioContentStructuralChange, type FolioContentTableLocation, type FolioContentTextSegment, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationResultBase, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type FolioRevisionStamp, type FolioWordDiffOptions, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidCompareDocxOptionsError, InvalidFolioContentComparisonError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, type WordDiffGranularity, type WordDiffNormalization, type WordDiffOptions, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareContent, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
@@ -6,9 +6,10 @@ import { isSuggestionStale, resolveSuggestionAnchor } from "../ai-suggestions/co
6
6
  import { buildPositionalText } from "../ai-suggestions/text-positions.js";
7
7
  import { DEFAULT_AI_SUGGESTION_PRESETS } from "../ai-suggestions/types.js";
8
8
  import { MAX_COMPARE_OPERATIONS, compareDocx } from "../compare/compare.js";
9
+ import { FOLIO_CONTENT_COMPARISON_LIMITS, FolioContentComparisonLimitError, InvalidFolioContentComparisonError, compareContent } from "../compare/content.js";
9
10
  import { COMPARE_UNSUPPORTED_REASONS, CompareDocxApplyError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, InvalidCompareDocxOptionsError } from "../compare/types.js";
10
11
  import { COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS } from "../compare/verification.js";
11
- import { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "../document-operations.js";
12
+ import { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "../document-operations.js";
12
13
  import { inspectDocxCompatibility } from "../docx/compatibility.js";
13
14
  import { createDocx } from "../docx/rezip.js";
14
15
  import { buildEmbeddedFontFamilyMap, extractEmbeddedFonts, getEmbeddedFontFaces, scopeEmbeddedFontFamily } from "../fonts/embeddedFonts.js";
@@ -31,4 +32,4 @@ import { currentFolioBlockId, deriveBlockId, getFolioParaIdFromBlockId, isFolioB
31
32
  import { createEmptyDocument } from "../utils/createDocument.js";
32
33
  import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled } from "../utils/fontResolver.js";
33
34
  import { mergeDocumentContent } from "../utils/mergeDocumentContent.js";
34
- export { COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareDocxApplyError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, InvalidCompareDocxOptionsError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, STELLA_STYLE_SET_NAME, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
35
+ export { COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareDocxApplyError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, FOLIO_CONTENT_COMPARISON_LIMITS, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, FolioContentComparisonLimitError, InvalidCompareDocxOptionsError, InvalidFolioContentComparisonError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, STELLA_STYLE_SET_NAME, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareContent, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
@@ -6,6 +6,7 @@ import { ExtensionManager } from "../prosemirror/extensions/ExtensionManager.js"
6
6
  import { createStarterKit } from "../prosemirror/extensions/StarterKit.js";
7
7
  import { ensureBaseDirectionInState } from "../prosemirror/extensions/features/AutoBidiDetectionExtension.js";
8
8
  import { ensureParaIdsInState } from "../prosemirror/extensions/features/ParaIdAllocatorExtension.js";
9
+ import { createDocumentNumberingPlugin } from "../prosemirror/plugins/documentNumbering.js";
9
10
  import { createDocumentStylesPlugin } from "../prosemirror/plugins/documentStyles.js";
10
11
  import { schema } from "../prosemirror/schema/index.js";
11
12
  import { EditorState } from "prosemirror-state";
@@ -20,7 +21,7 @@ const headerFooterToProseDocWithDetachedWatermarkHost = (headerFooter, options)
20
21
  return marked;
21
22
  }), options);
22
23
  };
23
- const buildInitialState = (headerFooter, styles, theme, manager) => {
24
+ const buildInitialState = (headerFooter, styles, theme, numbering, manager) => {
24
25
  const proseDocOptions = {};
25
26
  if (styles) proseDocOptions.styles = styles;
26
27
  if (theme !== void 0) proseDocOptions.theme = theme;
@@ -28,7 +29,11 @@ const buildInitialState = (headerFooter, styles, theme, manager) => {
28
29
  return ensureBaseDirectionInState(ensureParaIdsInState(EditorState.create({
29
30
  doc: document,
30
31
  schema,
31
- plugins: [...manager.getPlugins(), createDocumentStylesPlugin(styles)]
32
+ plugins: [
33
+ ...manager.getPlugins(),
34
+ createDocumentStylesPlugin(styles),
35
+ createDocumentNumberingPlugin(numbering)
36
+ ]
32
37
  })));
33
38
  };
34
39
  const enumerateHeaderFooterParts = ({ headers, footers }) => {
@@ -72,6 +77,7 @@ const createHeaderFooterEditorManager = (deps) => {
72
77
  const document = deps.getDocument();
73
78
  const styles = deps.getStyles();
74
79
  const theme = deps.getTheme();
80
+ const numbering = document?.package.numbering;
75
81
  const wanted = new Map(enumerateDocumentHeaderFooterParts(document).map((part) => [part.rId, part]));
76
82
  for (const [rId, part] of mounted) {
77
83
  if (wanted.has(rId)) continue;
@@ -85,13 +91,14 @@ const createHeaderFooterEditorManager = (deps) => {
85
91
  if (existing) {
86
92
  if (existing.mountNode.parentElement !== host) host.append(existing.mountNode);
87
93
  const contentIsCurrent = existing.appliedHeaderFooter === headerFooter && existing.appliedContent === headerFooter.content;
88
- const contextIsCurrent = existing.appliedStyles === styles && existing.appliedTheme === theme;
94
+ const contextIsCurrent = existing.appliedStyles === styles && existing.appliedTheme === theme && existing.appliedNumbering === numbering;
89
95
  if (contentIsCurrent && contextIsCurrent) continue;
90
- existing.view.updateState(buildInitialState(headerFooter, styles, theme, existing.manager));
96
+ existing.view.updateState(buildInitialState(headerFooter, styles, theme, numbering, existing.manager));
91
97
  existing.appliedHeaderFooter = headerFooter;
92
98
  existing.appliedContent = headerFooter.content;
93
99
  existing.appliedStyles = styles;
94
100
  existing.appliedTheme = theme;
101
+ existing.appliedNumbering = numbering;
95
102
  existing.dirty = false;
96
103
  continue;
97
104
  }
@@ -103,7 +110,7 @@ const createHeaderFooterEditorManager = (deps) => {
103
110
  mountNode.dataset["hfKind"] = part.kind;
104
111
  host.append(mountNode);
105
112
  const view = new EditorView(mountNode, {
106
- state: buildInitialState(headerFooter, styles, theme, manager),
113
+ state: buildInitialState(headerFooter, styles, theme, numbering, manager),
107
114
  dispatchTransaction(transaction) {
108
115
  const nextState = view.state.apply(transaction);
109
116
  view.updateState(nextState);
@@ -121,6 +128,7 @@ const createHeaderFooterEditorManager = (deps) => {
121
128
  mounted.set(part.rId, {
122
129
  appliedContent: headerFooter.content,
123
130
  appliedHeaderFooter: headerFooter,
131
+ appliedNumbering: numbering,
124
132
  appliedStyles: styles,
125
133
  appliedTheme: theme,
126
134
  dirty: false,
@@ -151,7 +159,7 @@ const createHeaderFooterEditorManager = (deps) => {
151
159
  if (!source || !existing) continue;
152
160
  const updated = {
153
161
  ...existing,
154
- content: proseDocToBlocks(view.state.doc, existing.content)
162
+ content: proseDocToBlocks(view.state.doc, existing.content, document.package.styles)
155
163
  };
156
164
  clearHeaderFooterVerbatimXml(updated);
157
165
  if (kind === "header") {
@@ -63,7 +63,7 @@ type HiddenEditorManagerDeps = {
63
63
  getDocumentIdentity: () => string;
64
64
  /** Document context for the API's `getDocument` (PM state -> Document). */
65
65
  getDocumentContext: () => document_d_exports.Document | null;
66
- onTransaction: (transaction: Transaction, newState: EditorState) => void;
66
+ onTransaction: (update: HiddenEditorTransactionUpdate) => void;
67
67
  onSelectionChange: (state: EditorState) => void;
68
68
  onKeyDown: (view: EditorView, event: KeyboardEvent) => boolean;
69
69
  onCopy?: () => void;
@@ -74,6 +74,11 @@ type HiddenEditorManagerDeps = {
74
74
  onEditorViewDestroy: () => void;
75
75
  onRemoteSelectionsChange: (selections: HiddenProseMirrorRemoteSelection[]) => void;
76
76
  };
77
+ type HiddenEditorTransactionUpdate = {
78
+ transactions: readonly Transaction[];
79
+ newState: EditorState;
80
+ docChanged: boolean;
81
+ };
77
82
  type PreventableDomEvent = {
78
83
  preventDefault: () => void;
79
84
  };
@@ -97,4 +102,4 @@ type HiddenEditorManager = {
97
102
  };
98
103
  declare const createHiddenEditorManager: (deps: HiddenEditorManagerDeps) => HiddenEditorManager;
99
104
  //#endregion
100
- export { CollaborationModules, CreateHiddenEditorStateOptions, HiddenEditorManager, HiddenEditorManagerDeps, HiddenProseMirrorCollaboration, HiddenProseMirrorRemoteSelection, collectRemoteSelections, createHiddenEditorClipboardHandlers, createHiddenEditorManager, createHiddenEditorState };
105
+ export { CollaborationModules, CreateHiddenEditorStateOptions, HiddenEditorManager, HiddenEditorManagerDeps, HiddenEditorTransactionUpdate, HiddenProseMirrorCollaboration, HiddenProseMirrorRemoteSelection, collectRemoteSelections, createHiddenEditorClipboardHandlers, createHiddenEditorManager, createHiddenEditorState };
@@ -4,6 +4,7 @@ import { isReadOnlyEditKey } from "../paged-layout/readOnlyEditAttempt.js";
4
4
  import { createEmptyDoc, toProseDoc } from "../prosemirror/conversion/toProseDoc.js";
5
5
  import { ensureBaseDirectionInState } from "../prosemirror/extensions/features/AutoBidiDetectionExtension.js";
6
6
  import { ensureParaIdsInDoc, ensureParaIdsInState } from "../prosemirror/extensions/features/ParaIdAllocatorExtension.js";
7
+ import { createDocumentNumberingPlugin } from "../prosemirror/plugins/documentNumbering.js";
7
8
  import { createDocumentStylesPlugin } from "../prosemirror/plugins/documentStyles.js";
8
9
  import { schema } from "../prosemirror/schema/index.js";
9
10
  import { createHiddenEditorApi } from "./hiddenEditorApi.js";
@@ -108,10 +109,12 @@ function createHiddenEditorState(options) {
108
109
  recordHiddenEditorPhase(reason, "to-prose-doc", performance.now() - startedAt);
109
110
  } else localDoc = ensureParaIdsInDoc(localDoc);
110
111
  const styleResolverPlugin = createDocumentStylesPlugin(styles ?? document?.package.styles);
112
+ const numberingPlugin = createDocumentNumberingPlugin(document?.package.numbering);
111
113
  const plugins = [
112
114
  ...externalPlugins,
113
115
  ...manager?.getPlugins() ?? [],
114
- styleResolverPlugin
116
+ styleResolverPlugin,
117
+ numberingPlugin
115
118
  ];
116
119
  if (collaboration) {
117
120
  if (!collaborationModules) panic("Collaboration modules must be loaded before creating collaborative editor state.");
@@ -218,13 +221,19 @@ const createHiddenEditorManager = (deps) => {
218
221
  deps.onReadOnlyEditAttempt();
219
222
  return;
220
223
  }
221
- const newState = view.state.apply(transaction);
222
- view.updateState(newState);
223
- deps.onTransaction(transaction, newState);
224
- if (transaction.selectionSet || transaction.docChanged) deps.onSelectionChange(newState);
224
+ const applied = view.state.applyTransaction(transaction);
225
+ view.updateState(applied.state);
226
+ const docChanged = applied.transactions.some((appliedTransaction) => appliedTransaction.docChanged);
227
+ const selectionChanged = applied.transactions.some((appliedTransaction) => appliedTransaction.selectionSet || appliedTransaction.docChanged);
228
+ deps.onTransaction({
229
+ transactions: applied.transactions,
230
+ newState: applied.state,
231
+ docChanged
232
+ });
233
+ if (selectionChanged) deps.onSelectionChange(applied.state);
225
234
  const currentCollaboration = deps.getCollaboration();
226
235
  const currentCollaborationModules = deps.getCollaborationModules();
227
- if (currentCollaboration?.awareness && currentCollaborationModules) deps.onRemoteSelectionsChange(collectRemoteSelections(newState, currentCollaboration.awareness, currentCollaborationModules));
236
+ if (currentCollaboration?.awareness && currentCollaborationModules) deps.onRemoteSelectionsChange(collectRemoteSelections(applied.state, currentCollaboration.awareness, currentCollaborationModules));
228
237
  },
229
238
  handleKeyDown: (pmView, event) => {
230
239
  if (deps.getReadOnly() && isReadOnlyEditKey(event)) {
@@ -117,10 +117,12 @@ function runLayoutPipeline(deps, state, options = {}) {
117
117
  const fontAlternates = buildFontAlternates(document?.package.fontTable);
118
118
  const flowOpts = {
119
119
  pageContentHeight,
120
- fontAlternates
120
+ fontAlternates,
121
+ ...styles ? { styles } : {}
121
122
  };
122
123
  if (_theme !== void 0) flowOpts.theme = _theme;
123
124
  if (defaultTabStop !== void 0) flowOpts.defaultTabStopTwips = defaultTabStop;
125
+ if (document?.package.settings?.splitPageBreakAndParagraphMark === true) flowOpts.splitPageBreakAndParagraphMark = true;
124
126
  if (document?.package.settings?.lineBreakRules) flowOpts.lineBreakRules = document.package.settings.lineBreakRules;
125
127
  const documentSettings = document?.package.settings;
126
128
  const justificationCompatibility = resolveJustificationCompatibility(documentSettings?.compatibilityMode);
@@ -181,7 +183,7 @@ function runLayoutPipeline(deps, state, options = {}) {
181
183
  const buildHfOptions = (pageCount, fieldInputs) => {
182
184
  const hfMeasureBlocks = (hfBlocks, hfWidth) => measureBlocks(hfBlocks, hfWidth, void 0, void 0, buildHeaderFooterFieldValues(hfBlocks, pageCount, hfClock, fieldInputs));
183
185
  return {
184
- ...styles ? { styles } : {},
186
+ ...flowOpts.styles ? { styles: flowOpts.styles } : {},
185
187
  ..._theme !== void 0 ? { theme: _theme } : {},
186
188
  fontAlternates,
187
189
  measureBlocks: hfMeasureBlocks,
@@ -329,7 +331,7 @@ function runLayoutPipeline(deps, state, options = {}) {
329
331
  if (hasFootnotes) {
330
332
  footnoteContentMap = buildFootnoteContentMap(documentFootnotes, footnoteRefs, contentWidth, (() => {
331
333
  const footnoteOptions = { measureBlocks };
332
- if (styles) footnoteOptions.styles = styles;
334
+ if (flowOpts.styles) footnoteOptions.styles = flowOpts.styles;
333
335
  if (_theme !== void 0) footnoteOptions.theme = _theme;
334
336
  footnoteOptions.fontAlternates = fontAlternates;
335
337
  if (defaultTabStop !== void 0) footnoteOptions.defaultTabStopTwips = defaultTabStop;
@@ -5,6 +5,7 @@ import { ExtensionManager } from "../prosemirror/extensions/ExtensionManager.js"
5
5
  import { createStarterKit } from "../prosemirror/extensions/StarterKit.js";
6
6
  import { ensureBaseDirectionInState } from "../prosemirror/extensions/features/AutoBidiDetectionExtension.js";
7
7
  import { ensureParaIdsInState } from "../prosemirror/extensions/features/ParaIdAllocatorExtension.js";
8
+ import { createDocumentNumberingPlugin } from "../prosemirror/plugins/documentNumbering.js";
8
9
  import { createDocumentStylesPlugin } from "../prosemirror/plugins/documentStyles.js";
9
10
  import { schema } from "../prosemirror/schema/index.js";
10
11
  import { EditorState } from "prosemirror-state";
@@ -31,14 +32,15 @@ const noteToProseDocument = (note, styles, theme) => {
31
32
  if (theme !== void 0) options.theme = theme;
32
33
  return footnoteToProseDoc(note.content, options);
33
34
  };
34
- const buildInitialState = (document, styles, manager, externalPlugins) => {
35
+ const buildInitialState = (document, styles, numbering, manager, externalPlugins) => {
35
36
  return ensureBaseDirectionInState(ensureParaIdsInState(EditorState.create({
36
37
  doc: document,
37
38
  schema,
38
39
  plugins: [
39
40
  ...manager.getPlugins(),
40
41
  ...externalPlugins,
41
- createDocumentStylesPlugin(styles)
42
+ createDocumentStylesPlugin(styles),
43
+ createDocumentNumberingPlugin(numbering)
42
44
  ]
43
45
  })));
44
46
  };
@@ -65,6 +67,7 @@ const createNoteEditorManager = (deps) => {
65
67
  const document = deps.getDocument();
66
68
  const styles = deps.getStyles();
67
69
  const theme = deps.getTheme();
70
+ const numbering = document?.package.numbering;
68
71
  const externalPlugins = deps.getPlugins?.() ?? EMPTY_PLUGINS;
69
72
  const wanted = new Map(enumerateDocumentNoteStories(document).map((story) => [storyMapKey(story), story]));
70
73
  const activeKey = active ? storyMapKey(active) : null;
@@ -81,18 +84,19 @@ const createNoteEditorManager = (deps) => {
81
84
  if (existing) {
82
85
  if (existing.mountNode.parentElement !== host) host.append(existing.mountNode);
83
86
  const nextProseDocument = noteToProseDocument(note, styles, theme);
84
- const contextIsCurrent = existing.appliedStyles === styles && existing.appliedTheme === theme && existing.appliedPlugins === externalPlugins;
87
+ const contextIsCurrent = existing.appliedStyles === styles && existing.appliedTheme === theme && existing.appliedNumbering === numbering && existing.appliedPlugins === externalPlugins;
85
88
  if ((existing.appliedNote === note && existing.appliedContent === note.content || existing.appliedProseDocument.eq(nextProseDocument)) && contextIsCurrent) {
86
89
  existing.appliedNote = note;
87
90
  existing.appliedContent = note.content;
88
91
  existing.appliedProseDocument = nextProseDocument;
89
92
  continue;
90
93
  }
91
- existing.view.updateState(buildInitialState(nextProseDocument, styles, existing.manager, externalPlugins));
94
+ existing.view.updateState(buildInitialState(nextProseDocument, styles, numbering, existing.manager, externalPlugins));
92
95
  existing.appliedNote = note;
93
96
  existing.appliedContent = note.content;
94
97
  existing.appliedStyles = styles;
95
98
  existing.appliedTheme = theme;
99
+ existing.appliedNumbering = numbering;
96
100
  existing.appliedPlugins = externalPlugins;
97
101
  existing.appliedProseDocument = nextProseDocument;
98
102
  existing.dirty = false;
@@ -107,7 +111,7 @@ const createNoteEditorManager = (deps) => {
107
111
  host.append(mountNode);
108
112
  const proseDocument = noteToProseDocument(note, styles, theme);
109
113
  const view = new EditorView(mountNode, {
110
- state: buildInitialState(proseDocument, styles, manager, externalPlugins),
114
+ state: buildInitialState(proseDocument, styles, numbering, manager, externalPlugins),
111
115
  dispatchTransaction(transaction) {
112
116
  view.updateState(view.state.apply(transaction));
113
117
  const mountedStory = mounted.get(key);
@@ -123,6 +127,7 @@ const createNoteEditorManager = (deps) => {
123
127
  mounted.set(key, {
124
128
  appliedContent: note.content,
125
129
  appliedNote: note,
130
+ appliedNumbering: numbering,
126
131
  appliedPlugins: externalPlugins,
127
132
  appliedProseDocument: proseDocument,
128
133
  appliedStyles: styles,
@@ -169,7 +174,7 @@ const createNoteEditorManager = (deps) => {
169
174
  }
170
175
  const updated = {
171
176
  ...current,
172
- content: proseDocToBlocks(story.view.state.doc, current.content)
177
+ content: proseDocToBlocks(story.view.state.doc, current.content, document.package.styles)
173
178
  };
174
179
  footnotes[index] = updated;
175
180
  story.appliedNote = updated;
@@ -186,7 +191,7 @@ const createNoteEditorManager = (deps) => {
186
191
  }
187
192
  const updated = {
188
193
  ...current,
189
- content: proseDocToBlocks(story.view.state.doc, current.content)
194
+ content: proseDocToBlocks(story.view.state.doc, current.content, document.package.styles)
190
195
  };
191
196
  endnotes[index] = updated;
192
197
  story.appliedNote = updated;
@@ -28,6 +28,7 @@ const paintHeaderFooter = ({ composer, page, section, content, distancePx, conte
28
28
  xPx: page.margins.left,
29
29
  yPx: originYPx,
30
30
  widthPx: page.size.w - page.margins.left - page.margins.right,
31
+ page,
31
32
  context: {
32
33
  ...context,
33
34
  story
@@ -1,4 +1,4 @@
1
- import { FlowBlock, Measure } from "../../layout-engine/types.js";
1
+ import { FlowBlock, Measure, Page } from "../../layout-engine/types.js";
2
2
  import { BuildContext } from "./buildContext.js";
3
3
  import { PageComposer } from "./regions.js";
4
4
  //#region src/display-list/build/storyPrimitives.d.ts
@@ -13,6 +13,9 @@ type PaintStoryOptions = {
13
13
  readonly context: BuildContext;
14
14
  readonly label: string;
15
15
  };
16
+ type PaintHeaderFooterStoryOptions = PaintStoryOptions & {
17
+ readonly page: Page;
18
+ };
16
19
  /**
17
20
  * A footnote body: every block stacks by its measured height, which is the
18
21
  * height the paginator reserved the band from.
@@ -24,6 +27,6 @@ declare const paintFootnoteBlocks: ({ composer, blocks, measures, xPx, yPx, widt
24
27
  * they are reported rather than painted: their position resolves against page
25
28
  * and margin anchors the display list producer does not carry.
26
29
  */
27
- declare const paintHeaderFooterBlocks: ({ composer, blocks, measures, xPx, yPx, widthPx, context, label }: PaintStoryOptions) => void;
30
+ declare const paintHeaderFooterBlocks: ({ composer, blocks, measures, xPx, yPx, widthPx, page, context, label }: PaintHeaderFooterStoryOptions) => void;
28
31
  //#endregion
29
32
  export { PaintStoryOptions, paintFootnoteBlocks, paintHeaderFooterBlocks };
@@ -1,6 +1,7 @@
1
1
  import { isFloatingImageRun, isFloatingTextBoxBlock } from "../../layout-engine/types.js";
2
+ import { resolveAnchoredImagePosition } from "../../layout-painter/anchoredImagePosition.js";
2
3
  import { HIT_REGION_KINDS } from "../primitives.js";
3
- import { paintImageFragment } from "./imagePrimitives.js";
4
+ import { paintImage, paintImageFragment } from "./imagePrimitives.js";
4
5
  import { paintParagraphFragment } from "./paragraphPrimitives.js";
5
6
  import { blockRegion } from "./regions.js";
6
7
  import { paintTableFragment } from "./tablePrimitives.js";
@@ -150,6 +151,47 @@ const measuredHeightPx = (measure) => {
150
151
  default: return 0;
151
152
  }
152
153
  };
154
+ const paintHeaderFooterFloatingImage = ({ composer, run, block, paragraphYPx, page, context, label }) => {
155
+ const contentWidth = page.size.w - page.margins.left - page.margins.right;
156
+ const geometry = {
157
+ pageWidth: page.size.w,
158
+ pageHeight: page.size.h,
159
+ marginLeft: page.margins.left,
160
+ marginTop: page.margins.top,
161
+ marginRight: page.margins.right,
162
+ marginBottom: page.margins.bottom,
163
+ ...page.authoredMargins === void 0 ? {} : { authoredMargins: page.authoredMargins },
164
+ contentWidth,
165
+ contentHeight: page.size.h - page.margins.top - page.margins.bottom
166
+ };
167
+ const position = resolveAnchoredImagePosition(run, paragraphYPx - page.margins.top, geometry);
168
+ const fragment = {
169
+ blockId: block.id,
170
+ x: page.margins.left + position.x,
171
+ y: page.margins.top + position.y,
172
+ width: run.width,
173
+ height: run.height,
174
+ ...run.pmStart === void 0 ? {} : { pmStart: run.pmStart },
175
+ ...run.pmEnd === void 0 ? {} : { pmEnd: run.pmEnd }
176
+ };
177
+ composer.region(blockRegion({
178
+ fragment,
179
+ kind: HIT_REGION_KINDS.image,
180
+ context
181
+ }), () => {
182
+ composer.push(paintImage({
183
+ source: run,
184
+ rect: {
185
+ xPx: fragment.x,
186
+ yPx: fragment.y,
187
+ widthPx: fragment.width,
188
+ heightPx: fragment.height
189
+ },
190
+ context,
191
+ label: `${label} floating image`
192
+ }));
193
+ });
194
+ };
153
195
  /**
154
196
  * A footnote body: every block stacks by its measured height, which is the
155
197
  * height the paginator reserved the band from.
@@ -182,7 +224,7 @@ const paintFootnoteBlocks = ({ composer, blocks, measures, xPx, yPx, widthPx, co
182
224
  * they are reported rather than painted: their position resolves against page
183
225
  * and margin anchors the display list producer does not carry.
184
226
  */
185
- const paintHeaderFooterBlocks = ({ composer, blocks, measures, xPx, yPx, widthPx, context, label }) => {
227
+ const paintHeaderFooterBlocks = ({ composer, blocks, measures, xPx, yPx, widthPx, page, context, label }) => {
186
228
  let cursorYPx = yPx;
187
229
  const reportOutOfFlow = (detail) => {
188
230
  context.unsupported.report(UNSUPPORTED_CONSTRUCT.headerFooterContent, context.pageIndex, `${label}: ${detail}`);
@@ -196,7 +238,6 @@ const paintHeaderFooterBlocks = ({ composer, blocks, measures, xPx, yPx, widthPx
196
238
  switch (block.kind) {
197
239
  case "paragraph":
198
240
  if (measure.kind !== "paragraph") break;
199
- if (block.runs.some((run) => run.kind === "image" && (isFloatingImageRun(run) || run.position !== void 0))) reportOutOfFlow(`paragraph ${String(block.id)} anchors a floating picture, which resolves against page and margin anchors the display list does not carry`);
200
241
  paintStoryBlock({
201
242
  composer,
202
243
  block,
@@ -208,6 +249,22 @@ const paintHeaderFooterBlocks = ({ composer, blocks, measures, xPx, yPx, widthPx
208
249
  label,
209
250
  construct: UNSUPPORTED_CONSTRUCT.headerFooterContent
210
251
  });
252
+ for (const run of block.runs) {
253
+ if (run.kind !== "image" || !isFloatingImageRun(run) && run.position === void 0) continue;
254
+ if (run.wrapType === "behind") {
255
+ reportOutOfFlow(`paragraph ${String(block.id)} anchors a behind-text picture that requires the page-underlay paint phase`);
256
+ continue;
257
+ }
258
+ paintHeaderFooterFloatingImage({
259
+ composer,
260
+ run,
261
+ block,
262
+ paragraphYPx: cursorYPx,
263
+ page,
264
+ context,
265
+ label
266
+ });
267
+ }
211
268
  cursorYPx += measure.totalHeight;
212
269
  continue;
213
270
  case "table":