@stll/folio-core 0.35.1 → 0.37.0

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 (236) hide show
  1. package/README.md +59 -1
  2. package/dist/ai-edits/apply.js +878 -377
  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 +141 -73
  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 +105 -20
  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 +62 -61
  20. package/dist/ai-edits/word-diff.d.ts +18 -3
  21. package/dist/ai-edits/word-diff.js +556 -67
  22. package/dist/ai-suggestions/conflict.js +1 -4
  23. package/dist/ai-suggestions/text-positions.d.ts +8 -0
  24. package/dist/ai-suggestions/text-positions.js +27 -5
  25. package/dist/compare/__fixtures__/body-sequence.js +3 -4
  26. package/dist/compare/column-alignment.d.ts +13 -13
  27. package/dist/compare/column-alignment.js +78 -39
  28. package/dist/compare/compare.d.ts +4 -3
  29. package/dist/compare/compare.js +48 -21
  30. package/dist/compare/content-alignment.d.ts +95 -0
  31. package/dist/compare/content-alignment.js +1450 -0
  32. package/dist/compare/content-types.d.ts +100 -0
  33. package/dist/compare/content-types.js +0 -0
  34. package/dist/compare/content.d.ts +209 -0
  35. package/dist/compare/content.js +885 -0
  36. package/dist/compare/formatting.d.ts +5 -5
  37. package/dist/compare/formatting.js +6 -4
  38. package/dist/compare/plan.d.ts +6 -1
  39. package/dist/compare/plan.js +171 -566
  40. package/dist/compare/scenario.d.ts +2 -2
  41. package/dist/compare/types.d.ts +3 -3
  42. package/dist/compare/verification.d.ts +8 -9
  43. package/dist/compare/verification.js +72 -50
  44. package/dist/compat/eigenpal.d.ts +5 -3
  45. package/dist/compat/eigenpal.js +3 -2
  46. package/dist/controller/headerFooterEditorManager.js +18 -10
  47. package/dist/controller/hiddenEditorApi.js +1 -1
  48. package/dist/controller/hiddenEditorManager.d.ts +7 -2
  49. package/dist/controller/hiddenEditorManager.js +15 -6
  50. package/dist/controller/layoutPipeline.js +5 -3
  51. package/dist/controller/noteEditorManager.js +12 -7
  52. package/dist/display-list/build/headerFooterPrimitives.js +1 -0
  53. package/dist/display-list/build/storyPrimitives.d.ts +5 -2
  54. package/dist/display-list/build/storyPrimitives.js +60 -3
  55. package/dist/display-list/build/tablePrimitives.js +30 -0
  56. package/dist/display-list/primitives.d.ts +1 -1
  57. package/dist/document-operations.d.ts +8 -4
  58. package/dist/document-operations.js +104 -12
  59. package/dist/docx/blockContentParser.js +6 -27
  60. package/dist/docx/commentParser.js +2 -4
  61. package/dist/docx/commentRangeIntegrity.js +2 -4
  62. package/dist/docx/documentClone.d.ts +2 -0
  63. package/dist/docx/documentClone.js +2 -0
  64. package/dist/docx/ensureParaIds.js +9 -4
  65. package/dist/docx/headerFooterParser.js +2 -4
  66. package/dist/docx/normalizeBaseDirection.js +5 -7
  67. package/dist/docx/numberingParser.d.ts +3 -1
  68. package/dist/docx/numberingParser.js +4 -1
  69. package/dist/docx/paragraphParser.js +34 -35
  70. package/dist/docx/paragraphPropertySource.d.ts +49 -0
  71. package/dist/docx/paragraphPropertySource.js +113 -0
  72. package/dist/docx/paragraphTraversal.js +30 -34
  73. package/dist/docx/rezip.d.ts +0 -8
  74. package/dist/docx/rezip.js +41 -16
  75. package/dist/docx/runConsolidator.js +2 -4
  76. package/dist/docx/runParser.js +6 -17
  77. package/dist/docx/sectionParser.js +1 -15
  78. package/dist/docx/serializer/paragraphSerializer.js +289 -30
  79. package/dist/docx/serializer/runSerializer.js +6 -12
  80. package/dist/docx/serializer/sectionPropertiesSerializer.js +2 -10
  81. package/dist/docx/serializer/tableSerializer.js +4 -23
  82. package/dist/docx/serializer/trackedChangeAttributes.d.ts +11 -0
  83. package/dist/docx/serializer/trackedChangeAttributes.js +31 -0
  84. package/dist/docx/server/build.d.ts +1 -1
  85. package/dist/docx/server/createBilingualDocument.js +8 -10
  86. package/dist/docx/server/evaluateDocxXmlPatchProposal.js +22 -13
  87. package/dist/docx/server/validateDocxConformance.js +17 -13
  88. package/dist/docx/tableParser.js +1 -37
  89. package/dist/docx/trackedChangeInfo.d.ts +11 -0
  90. package/dist/docx/trackedChangeInfo.js +38 -0
  91. package/dist/docx/verbatimCapture.d.ts +20 -9
  92. package/dist/docx/verbatimCapture.js +208 -8
  93. package/dist/docx/xmlParser.d.ts +3 -1
  94. package/dist/docx/xmlParser.js +6 -1
  95. package/dist/docx/xmlSafety.d.ts +1 -1
  96. package/dist/docx/xmlSafety.js +157 -0
  97. package/dist/headless-layout.js +5 -4
  98. package/dist/index.d.ts +5 -3
  99. package/dist/index.js +3 -2
  100. package/dist/internal/headlessRevisionResolution.d.ts +23 -0
  101. package/dist/internal/headlessRevisionResolution.js +155 -0
  102. package/dist/internal/headlessRevisionResolutionGuard.d.ts +12 -0
  103. package/dist/internal/headlessRevisionResolutionGuard.js +28 -0
  104. package/dist/internal/pageBreakRunDescendantIndex.d.ts +9 -0
  105. package/dist/internal/pageBreakRunDescendantIndex.js +27 -0
  106. package/dist/internal/pageBreakRunPartition.d.ts +26 -0
  107. package/dist/internal/pageBreakRunPartition.js +35 -0
  108. package/dist/internal/pageBreakRunSourceDescendantIndex.d.ts +15 -0
  109. package/dist/internal/pageBreakRunSourceDescendantIndex.js +126 -0
  110. package/dist/internal/sectionEndpointResolution.d.ts +32 -0
  111. package/dist/internal/sectionEndpointResolution.js +38 -0
  112. package/dist/layout-bridge/convert/footnoteLayout.js +1 -0
  113. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +16 -4
  114. package/dist/layout-bridge/convert/headerFooterLayout.js +52 -9
  115. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +4 -0
  116. package/dist/layout-bridge/convert/toFlowBlocks.js +391 -82
  117. package/dist/layout-bridge/dom/clickToPositionDom.d.ts +8 -1
  118. package/dist/layout-bridge/dom/clickToPositionDom.js +114 -40
  119. package/dist/layout-bridge/dom/textStreamDom.d.ts +24 -0
  120. package/dist/layout-bridge/dom/textStreamDom.js +75 -0
  121. package/dist/layout-bridge/headerFooterLayout.js +16 -30
  122. package/dist/layout-engine/index.js +12 -3
  123. package/dist/layout-engine/measure/tableFragmentBorderGeometry.d.ts +17 -0
  124. package/dist/layout-engine/measure/tableFragmentBorderGeometry.js +24 -0
  125. package/dist/layout-engine/renderedBreakReconciliation.js +1 -1
  126. package/dist/layout-engine/types.d.ts +7 -0
  127. package/dist/layout-painter/imageLayout.d.ts +1 -1
  128. package/dist/layout-painter/renderTable.js +20 -0
  129. package/dist/markdown/renderBlock.js +7 -10
  130. package/dist/model.d.ts +1 -1
  131. package/dist/paged-layout/rangeProjection.js +6 -9
  132. package/dist/paged-layout/transactionDirtyRange.d.ts +3 -1
  133. package/dist/paged-layout/transactionDirtyRange.js +23 -1
  134. package/dist/prosemirror/attrs/index.d.ts +7 -3
  135. package/dist/prosemirror/attrs/index.js +128 -7
  136. package/dist/prosemirror/bookmarkBoundaryIntegrity.d.ts +9 -0
  137. package/dist/prosemirror/bookmarkBoundaryIntegrity.js +22 -0
  138. package/dist/prosemirror/commands/comments.d.ts +10 -1
  139. package/dist/prosemirror/commands/comments.js +551 -87
  140. package/dist/prosemirror/commands/formatPainter.d.ts +45 -10
  141. package/dist/prosemirror/commands/formatPainter.js +319 -63
  142. package/dist/prosemirror/commands/index.d.ts +2 -2
  143. package/dist/prosemirror/commands/pageBreak.d.ts +5 -2
  144. package/dist/prosemirror/commands/pageBreak.js +18 -36
  145. package/dist/prosemirror/commands/propertyChangeScope.d.ts +27 -3
  146. package/dist/prosemirror/commands/propertyChangeScope.js +85 -14
  147. package/dist/prosemirror/conversion/fromProseDoc.d.ts +8 -5
  148. package/dist/prosemirror/conversion/fromProseDoc.js +935 -223
  149. package/dist/prosemirror/conversion/runShadingMark.js +2 -2
  150. package/dist/prosemirror/conversion/toProseDoc.d.ts +26 -1
  151. package/dist/prosemirror/conversion/toProseDoc.js +439 -291
  152. package/dist/prosemirror/extensions/StarterKit.js +4 -0
  153. package/dist/prosemirror/extensions/core/ParagraphExtension.js +54 -6
  154. package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +7 -1
  155. package/dist/prosemirror/extensions/features/ListExtension.js +95 -123
  156. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +19 -6
  157. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +27 -1
  158. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +134 -30
  159. package/dist/prosemirror/extensions/features/pasteCleanup.js +9 -15
  160. package/dist/prosemirror/extensions/marks/BoldExtension.js +4 -3
  161. package/dist/prosemirror/extensions/marks/CharacterStyleExtension.d.ts +4 -7
  162. package/dist/prosemirror/extensions/marks/CharacterStyleExtension.js +5 -11
  163. package/dist/prosemirror/extensions/marks/FontSizeExtension.js +3 -3
  164. package/dist/prosemirror/extensions/marks/ItalicExtension.js +4 -3
  165. package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.d.ts +13 -0
  166. package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.js +39 -0
  167. package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.d.ts +7 -1
  168. package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.js +67 -21
  169. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +2 -0
  170. package/dist/prosemirror/extensions/marks/markUtils.d.ts +8 -1
  171. package/dist/prosemirror/extensions/marks/markUtils.js +88 -2
  172. package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.js +44 -3
  173. package/dist/prosemirror/extensions/nodes/FieldExtension.js +1 -1
  174. package/dist/prosemirror/extensions/nodes/HardBreakExtension.js +15 -4
  175. package/dist/prosemirror/extensions/nodes/PageBreakExtension.d.ts +6 -0
  176. package/dist/prosemirror/extensions/nodes/PageBreakExtension.js +6 -0
  177. package/dist/prosemirror/extensions/nodes/PageBreakRunExtension.d.ts +6 -0
  178. package/dist/prosemirror/extensions/nodes/PageBreakRunExtension.js +36 -0
  179. package/dist/prosemirror/findReplaceSelection.js +8 -3
  180. package/dist/prosemirror/index.d.ts +3 -3
  181. package/dist/prosemirror/listMarker.d.ts +26 -1
  182. package/dist/prosemirror/listMarker.js +108 -14
  183. package/dist/prosemirror/pageBreakRunProjection.d.ts +28 -0
  184. package/dist/prosemirror/pageBreakRunProjection.js +47 -0
  185. package/dist/prosemirror/paraText.js +6 -0
  186. package/dist/prosemirror/paragraphAlignment.d.ts +12 -0
  187. package/dist/prosemirror/paragraphAlignment.js +13 -0
  188. package/dist/prosemirror/paragraphSpacing.d.ts +29 -0
  189. package/dist/prosemirror/paragraphSpacing.js +125 -0
  190. package/dist/prosemirror/plugins/documentNumbering.d.ts +8 -0
  191. package/dist/prosemirror/plugins/documentNumbering.js +18 -0
  192. package/dist/prosemirror/plugins/pmTextScan.d.ts +3 -2
  193. package/dist/prosemirror/plugins/pmTextScan.js +14 -4
  194. package/dist/prosemirror/plugins/suggestionMode.js +9 -11
  195. package/dist/prosemirror/rebaseParagraphRunFormatting.d.ts +16 -0
  196. package/dist/prosemirror/rebaseParagraphRunFormatting.js +61 -0
  197. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +64 -0
  198. package/dist/prosemirror/runFormattingInlineCarriers.js +121 -0
  199. package/dist/prosemirror/runFormattingProvenance.d.ts +12 -0
  200. package/dist/prosemirror/runFormattingProvenance.js +48 -0
  201. package/dist/prosemirror/runFormattingReconciliation.d.ts +25 -0
  202. package/dist/prosemirror/runFormattingReconciliation.js +54 -0
  203. package/dist/prosemirror/runPropertyChangeResolution.d.ts +18 -0
  204. package/dist/prosemirror/runPropertyChangeResolution.js +18 -0
  205. package/dist/prosemirror/runStyleFormatting.d.ts +50 -0
  206. package/dist/prosemirror/runStyleFormatting.js +105 -0
  207. package/dist/prosemirror/schema/index.d.ts +3 -3
  208. package/dist/prosemirror/schema/marks.d.ts +84 -9
  209. package/dist/prosemirror/schema/marks.js +73 -1
  210. package/dist/prosemirror/schema/nodes.d.ts +30 -6
  211. package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +14 -2
  212. package/dist/prosemirror/styles/resolvedStyleAttrs.js +45 -23
  213. package/dist/prosemirror/styles/styleResolver.d.ts +10 -13
  214. package/dist/prosemirror/styles/styleResolver.js +3 -3
  215. package/dist/prosemirror/styles/styleToggleCascade.d.ts +8 -1
  216. package/dist/prosemirror/styles/styleToggleCascade.js +24 -1
  217. package/dist/prosemirror/tableGridMutation.d.ts +20 -0
  218. package/dist/prosemirror/tableGridMutation.js +30 -0
  219. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +31 -0
  220. package/dist/prosemirror/trackedRunInlineAtoms.js +39 -0
  221. package/dist/prosemirror/utils/visualLineNavigation.js +27 -31
  222. package/dist/prosemirror/validation.js +23 -4
  223. package/dist/redline.js +4 -1
  224. package/dist/render-dom/HeaderFooterSelectionOverlay.js +20 -20
  225. package/dist/render-dom/RenderedDomContext.js +17 -34
  226. package/dist/server.d.ts +4 -4
  227. package/dist/server.js +2 -2
  228. package/dist/style-engine/styleEngine.d.ts +1 -1
  229. package/dist/utils/clipboard.js +1 -1
  230. package/dist/utils/findReplace.js +38 -21
  231. package/dist/utils/mergeDocumentContent.js +3 -3
  232. package/dist/utils/replaceText.js +2 -1
  233. package/dist/version-comparison.d.ts +38 -44
  234. package/dist/version-comparison.js +270 -399
  235. package/dist/watermark/index.js +2 -4
  236. package/package.json +8 -2
@@ -0,0 +1,126 @@
1
+ import { panic } from "better-result";
2
+ //#region src/internal/pageBreakRunSourceDescendantIndex.ts
3
+ const SOURCE_FLAGS = {
4
+ containsPageBreak: 1,
5
+ paragraphPageBreak: 2,
6
+ paragraphTextBoxShape: 4,
7
+ pageBreakSharesTextBoxShape: 8
8
+ };
9
+ const hasFlag = (flags, flag) => (flags & flag) !== 0;
10
+ /** Index authored page-break descendants once for one source conversion. */
11
+ const buildPageBreakRunSourceDescendantIndex = (rootContent) => {
12
+ const flagsByObject = /* @__PURE__ */ new WeakMap();
13
+ const inspectObject = (node, inspectChildren) => {
14
+ const cached = flagsByObject.get(node);
15
+ if (cached !== void 0) return cached;
16
+ flagsByObject.set(node, 0);
17
+ const flags = inspectChildren();
18
+ flagsByObject.set(node, flags);
19
+ return flags;
20
+ };
21
+ const inspectMany = (items, inspect) => {
22
+ let flags = 0;
23
+ for (const item of items) flags |= inspect(item);
24
+ return flags;
25
+ };
26
+ const inspectRunContent = (content) => inspectObject(content, () => {
27
+ switch (content.type) {
28
+ case "break": return content.breakType === "page" ? SOURCE_FLAGS.containsPageBreak | SOURCE_FLAGS.paragraphPageBreak : 0;
29
+ case "shape": {
30
+ const { textBody } = content.shape;
31
+ if (!textBody) return 0;
32
+ return inspectBlocks(textBody.content) & SOURCE_FLAGS.containsPageBreak | SOURCE_FLAGS.paragraphTextBoxShape;
33
+ }
34
+ case "drawing":
35
+ case "endnoteRef":
36
+ case "fieldChar":
37
+ case "footnoteRef":
38
+ case "instrText":
39
+ case "noBreakHyphen":
40
+ case "renderedPageBreak":
41
+ case "softHyphen":
42
+ case "symbol":
43
+ case "tab":
44
+ case "text": return 0;
45
+ default: return content;
46
+ }
47
+ });
48
+ const inspectRun = (run) => inspectObject(run, () => {
49
+ const flags = inspectMany(run.content, inspectRunContent);
50
+ if (hasFlag(flags, SOURCE_FLAGS.paragraphPageBreak) && hasFlag(flags, SOURCE_FLAGS.paragraphTextBoxShape)) return flags | SOURCE_FLAGS.pageBreakSharesTextBoxShape;
51
+ return flags;
52
+ });
53
+ const inspectParagraphContent = (content) => {
54
+ if (content.type === "run") return inspectRun(content);
55
+ return inspectObject(content, () => {
56
+ switch (content.type) {
57
+ case "hyperlink": return inspectMany(content.children, inspectParagraphContent);
58
+ case "insertion":
59
+ case "deletion":
60
+ case "moveFrom":
61
+ case "moveTo":
62
+ case "inlineSdt": return inspectMany(content.content, inspectParagraphContent);
63
+ case "simpleField": {
64
+ const fieldResultFlags = inspectMany(content.content, inspectParagraphContent);
65
+ if (hasFlag(fieldResultFlags, SOURCE_FLAGS.paragraphPageBreak) && hasFlag(fieldResultFlags, SOURCE_FLAGS.paragraphTextBoxShape)) return fieldResultFlags | SOURCE_FLAGS.pageBreakSharesTextBoxShape;
66
+ return fieldResultFlags;
67
+ }
68
+ case "complexField": {
69
+ const fieldCodeFlags = inspectMany(content.fieldCode, inspectRun);
70
+ const fieldResultFlags = inspectMany(content.fieldResult, inspectRun);
71
+ const fieldFlags = fieldCodeFlags | fieldResultFlags;
72
+ if (hasFlag(fieldResultFlags, SOURCE_FLAGS.paragraphPageBreak) && hasFlag(fieldResultFlags, SOURCE_FLAGS.paragraphTextBoxShape)) return fieldFlags | SOURCE_FLAGS.pageBreakSharesTextBoxShape;
73
+ return fieldFlags;
74
+ }
75
+ case "bookmarkStart":
76
+ case "bookmarkEnd":
77
+ case "commentRangeStart":
78
+ case "commentRangeEnd":
79
+ case "commentReference":
80
+ case "moveFromRangeStart":
81
+ case "moveFromRangeEnd":
82
+ case "moveToRangeStart":
83
+ case "moveToRangeEnd":
84
+ case "mathEquation": return 0;
85
+ default: return content;
86
+ }
87
+ });
88
+ };
89
+ const inspectTableCell = (cell) => inspectObject(cell, () => inspectBlocks(cell.content));
90
+ const inspectTableRow = (row) => inspectObject(row, () => inspectMany(row.cells, inspectTableCell));
91
+ const inspectBlock = (block) => inspectObject(block, () => {
92
+ switch (block.type) {
93
+ case "paragraph": return inspectMany(block.content, inspectParagraphContent);
94
+ case "table": return inspectMany(block.rows, inspectTableRow);
95
+ case "blockSdt": return inspectBlocks(block.content);
96
+ default: return block;
97
+ }
98
+ });
99
+ function inspectBlocks(content) {
100
+ const cached = flagsByObject.get(content);
101
+ if (cached !== void 0) return cached;
102
+ flagsByObject.set(content, 0);
103
+ const flags = inspectMany(content, inspectBlock);
104
+ flagsByObject.set(content, flags);
105
+ return flags;
106
+ }
107
+ inspectBlocks(rootContent);
108
+ return {
109
+ containsPageBreakRun: (content) => {
110
+ const flags = flagsByObject.get(content);
111
+ if (flags === void 0) panic("Page-break source ownership was queried outside its conversion index");
112
+ return hasFlag(flags, SOURCE_FLAGS.containsPageBreak);
113
+ },
114
+ paragraphFeatures: (paragraph) => {
115
+ const flags = flagsByObject.get(paragraph);
116
+ if (flags === void 0) panic("Page-break paragraph ownership was queried outside its conversion index");
117
+ return {
118
+ hasPageBreakRun: hasFlag(flags, SOURCE_FLAGS.paragraphPageBreak),
119
+ hasTextBoxShape: hasFlag(flags, SOURCE_FLAGS.paragraphTextBoxShape),
120
+ pageBreakSharesTextBoxShape: hasFlag(flags, SOURCE_FLAGS.pageBreakSharesTextBoxShape)
121
+ };
122
+ }
123
+ };
124
+ };
125
+ //#endregion
126
+ export { buildPageBreakRunSourceDescendantIndex };
@@ -0,0 +1,32 @@
1
+ import { document_d_exports } from "../types/document.js";
2
+ //#region src/internal/sectionEndpointResolution.d.ts
3
+ type RemovedSectionReference = {
4
+ part: "header" | "footer";
5
+ type: document_d_exports.HeaderFooterType;
6
+ relationshipId: string;
7
+ };
8
+ /**
9
+ * Exact resolution evidence produced when tracked-change resolution removes
10
+ * section endpoints. The tracker binds this count transition to exact endpoint
11
+ * fingerprints; removed references bind the only relationship losses that the
12
+ * same resolution may legitimately cause during package serialization.
13
+ */
14
+ type TrackedSectionEndpointRemoval = {
15
+ type: "tracked-section-endpoint-removal";
16
+ sourceParagraphEndpointCount: number;
17
+ expectedParagraphEndpointCount: number;
18
+ sourceEndpointFingerprint: string;
19
+ expectedEndpointFingerprint: string;
20
+ removedReferences: readonly RemovedSectionReference[];
21
+ };
22
+ type WithTrackedSectionEndpointRemovalOptions<T> = {
23
+ document: document_d_exports.Document;
24
+ resolution: TrackedSectionEndpointRemoval;
25
+ repack: () => Promise<T>;
26
+ };
27
+ /** Run one repack with an exact authorization that no public save API accepts. */
28
+ declare const withTrackedSectionEndpointRemoval: <T>({ document, resolution, repack }: WithTrackedSectionEndpointRemovalOptions<T>) => Promise<T>;
29
+ /** @internal Consume the active authorization once for the exact document object. */
30
+ declare const consumeTrackedSectionEndpointRemoval: (document: document_d_exports.Document) => TrackedSectionEndpointRemoval | null;
31
+ //#endregion
32
+ export { RemovedSectionReference, TrackedSectionEndpointRemoval, consumeTrackedSectionEndpointRemoval, withTrackedSectionEndpointRemoval };
@@ -0,0 +1,38 @@
1
+ import { panic } from "better-result";
2
+ //#region src/internal/sectionEndpointResolution.ts
3
+ const activeSectionEndpointRepacks = /* @__PURE__ */ new WeakMap();
4
+ const snapshotAuthorization = (authorization) => {
5
+ const removedReferences = Object.freeze(authorization.removedReferences.map((reference) => Object.freeze({ ...reference })));
6
+ return Object.freeze({
7
+ ...authorization,
8
+ removedReferences
9
+ });
10
+ };
11
+ /** Run one repack with an exact authorization that no public save API accepts. */
12
+ const withTrackedSectionEndpointRemoval = async ({ document, resolution, repack }) => {
13
+ if (activeSectionEndpointRepacks.has(document)) panic("A tracked section-endpoint repack is already active for this document");
14
+ const snapshot = snapshotAuthorization(resolution);
15
+ activeSectionEndpointRepacks.set(document, {
16
+ status: "available",
17
+ authorization: snapshot
18
+ });
19
+ try {
20
+ const result = await repack();
21
+ if (activeSectionEndpointRepacks.get(document)?.status !== "consumed") panic("Tracked section-endpoint repack did not consume its authorization");
22
+ return result;
23
+ } finally {
24
+ activeSectionEndpointRepacks.delete(document);
25
+ }
26
+ };
27
+ /** @internal Consume the active authorization once for the exact document object. */
28
+ const consumeTrackedSectionEndpointRemoval = (document) => {
29
+ const active = activeSectionEndpointRepacks.get(document);
30
+ if (!active || active.status === "consumed") return null;
31
+ activeSectionEndpointRepacks.set(document, {
32
+ status: "consumed",
33
+ authorization: active.authorization
34
+ });
35
+ return active.authorization;
36
+ };
37
+ //#endregion
38
+ export { consumeTrackedSectionEndpointRemoval, withTrackedSectionEndpointRemoval };
@@ -197,6 +197,7 @@ function convertFootnoteToContent(footnote, displayNumber, contentWidth, options
197
197
  if (options.theme !== void 0) proseOptions.theme = options.theme;
198
198
  const pmDoc = footnoteToProseDoc(footnote.content, proseOptions);
199
199
  const flowOptions = {};
200
+ if (options.styles) flowOptions.styles = options.styles;
200
201
  if (options.theme !== void 0) flowOptions.theme = options.theme;
201
202
  if (options.fontAlternates !== void 0) flowOptions.fontAlternates = options.fontAlternates;
202
203
  if (options.defaultTabStopTwips !== void 0) flowOptions.defaultTabStopTwips = options.defaultTabStopTwips;
@@ -79,9 +79,21 @@ declare function convertHeaderFooterToContent(headerFooter: document_d_exports.H
79
79
  *
80
80
  * The pmDoc is expected to be a body-shaped PM doc (the result of
81
81
  * `headerFooterToProseDoc` at mount, plus any user edits applied since).
82
- * Theme + styles do NOT need to be threaded again they only matter for the
83
- * initial parse path; subsequent transformations are PM-internal.
82
+ * Theme and styles are threaded again because effective character-style
83
+ * toggles cannot all be represented by the flattened ProseMirror marks.
84
84
  */
85
- declare function convertHeaderFooterPmDocToContent(pmDoc: Node | null | undefined, contentWidth: number, metrics: HeaderFooterMetrics, options: Omit<ConvertHeaderFooterOptions, "styles">): HeaderFooterContent | undefined;
85
+ declare function convertHeaderFooterPmDocToContent(pmDoc: Node | null | undefined, contentWidth: number, metrics: HeaderFooterMetrics, options: ConvertHeaderFooterOptions): HeaderFooterContent | undefined;
86
+ /**
87
+ * A paragraph-relative wrapping image that spans the whole story width leaves
88
+ * no side on which following content can flow. Retain the host paragraph's
89
+ * line box and reserve the complete anchored extent after it.
90
+ */
91
+ type ReserveHeaderFooterFullWidthWrapBandsOptions = {
92
+ blocks: FlowBlock[];
93
+ measures: Measure[];
94
+ contentWidth: number;
95
+ metrics: HeaderFooterMetrics;
96
+ };
97
+ declare function reserveHeaderFooterFullWidthWrapBands({ blocks, measures, contentWidth, metrics }: ReserveHeaderFooterFullWidthWrapBandsOptions): Measure[];
86
98
  //#endregion
87
- export { ConvertHeaderFooterOptions, HeaderFooterMetrics, calculateHeaderFooterBodyTopClearance, calculateHeaderFooterMarginPushBounds, calculateHeaderFooterVisualBounds, convertHeaderFooterPmDocToContent, convertHeaderFooterToContent, normalizeHeaderFooterMeasureBlocks, resolveHeaderFooterPositionedVisualTop, resolveHeaderFooterVisualTop };
99
+ export { ConvertHeaderFooterOptions, HeaderFooterMetrics, calculateHeaderFooterBodyTopClearance, calculateHeaderFooterMarginPushBounds, calculateHeaderFooterVisualBounds, convertHeaderFooterPmDocToContent, convertHeaderFooterToContent, normalizeHeaderFooterMeasureBlocks, reserveHeaderFooterFullWidthWrapBands, resolveHeaderFooterPositionedVisualTop, resolveHeaderFooterVisualTop };
@@ -1,4 +1,5 @@
1
- import { isFloatingImageRun, isFloatingTextBoxBlock } from "../../layout-engine/types.js";
1
+ import { cloneParagraphWithPropertySource } from "../../docx/paragraphPropertySource.js";
2
+ import { isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun } from "../../layout-engine/types.js";
2
3
  import { headerFooterToProseDoc } from "../../prosemirror/conversion/toProseDoc.js";
3
4
  import { emuToPixels } from "../../utils/units.js";
4
5
  import { toFlowBlocks } from "./toFlowBlocks.js";
@@ -7,10 +8,9 @@ const DETACHED_WATERMARK_HOST = Symbol.for("stll.detachedWatermarkHost");
7
8
  const headerFooterToProseDocWithDetachedWatermarkHost = (headerFooter, options) => {
8
9
  return headerFooterToProseDoc(headerFooter.content.map((block, blockIndex) => {
9
10
  if (blockIndex !== headerFooter.watermarkBlockIndex || block.type !== "paragraph") return block;
10
- return {
11
- ...block,
12
- [DETACHED_WATERMARK_HOST]: true
13
- };
11
+ const marked = cloneParagraphWithPropertySource(block, {});
12
+ Reflect.set(marked, DETACHED_WATERMARK_HOST, true);
13
+ return marked;
14
14
  }), options);
15
15
  };
16
16
  function isAnchoredImageRun(run) {
@@ -342,6 +342,7 @@ function convertHeaderFooterToContent(headerFooter, contentWidth, metrics, optio
342
342
  if (options.theme !== void 0) proseDocOptions.theme = options.theme;
343
343
  const pmDoc = headerFooter.watermarkBlockIndex === void 0 ? headerFooterToProseDoc(headerFooter.content, proseDocOptions) : headerFooterToProseDocWithDetachedWatermarkHost(headerFooter, proseDocOptions);
344
344
  const flowOptions = {};
345
+ if (options.styles) flowOptions.styles = options.styles;
345
346
  if (options.theme !== void 0) flowOptions.theme = options.theme;
346
347
  if (options.fontAlternates !== void 0) flowOptions.fontAlternates = options.fontAlternates;
347
348
  if (options.defaultTabStopTwips !== void 0) flowOptions.defaultTabStopTwips = options.defaultTabStopTwips;
@@ -359,12 +360,13 @@ function convertHeaderFooterToContent(headerFooter, contentWidth, metrics, optio
359
360
  *
360
361
  * The pmDoc is expected to be a body-shaped PM doc (the result of
361
362
  * `headerFooterToProseDoc` at mount, plus any user edits applied since).
362
- * Theme + styles do NOT need to be threaded again they only matter for the
363
- * initial parse path; subsequent transformations are PM-internal.
363
+ * Theme and styles are threaded again because effective character-style
364
+ * toggles cannot all be represented by the flattened ProseMirror marks.
364
365
  */
365
366
  function convertHeaderFooterPmDocToContent(pmDoc, contentWidth, metrics, options) {
366
367
  if (!pmDoc || pmDoc.content.size === 0) return;
367
368
  const flowOptions = {};
369
+ if (options.styles) flowOptions.styles = options.styles;
368
370
  if (options.theme !== void 0) flowOptions.theme = options.theme;
369
371
  if (options.fontAlternates !== void 0) flowOptions.fontAlternates = options.fontAlternates;
370
372
  if (options.defaultTabStopTwips !== void 0) flowOptions.defaultTabStopTwips = options.defaultTabStopTwips;
@@ -374,10 +376,51 @@ function convertHeaderFooterPmDocToContent(pmDoc, contentWidth, metrics, options
374
376
  if (options.automaticHyphenation) flowOptions.automaticHyphenation = options.automaticHyphenation;
375
377
  return finalizeHeaderFooterContent(toFlowBlocks(pmDoc, flowOptions), contentWidth, metrics, options);
376
378
  }
379
+ function horizontalImageLeft({ run, contentWidth, metrics }) {
380
+ const horizontal = run.position?.horizontal;
381
+ if (horizontal?.posOffset !== void 0) return (horizontal.relativeTo === "page" ? -metrics.margins.left : 0) + emuToPixels(horizontal.posOffset);
382
+ const alignment = getPositionAlignment(horizontal);
383
+ const frameWidth = horizontal?.relativeTo === "page" ? metrics.pageSize.w : contentWidth;
384
+ const frameLeft = horizontal?.relativeTo === "page" ? -metrics.margins.left : 0;
385
+ if (alignment === "center") return frameLeft + (frameWidth - run.width) / 2;
386
+ if (alignment === "right" || alignment === "outside") return frameLeft + frameWidth - run.width;
387
+ return frameLeft;
388
+ }
389
+ function reserveHeaderFooterFullWidthWrapBands({ blocks, measures, contentWidth, metrics }) {
390
+ return measures.map((measure, index) => {
391
+ const block = blocks[index];
392
+ if (block?.kind !== "paragraph" || measure.kind !== "paragraph") return measure;
393
+ let reservedHeight = 0;
394
+ for (const run of block.runs) {
395
+ if (run.kind !== "image" || !isTextWrappingFloatingImageRun(run)) continue;
396
+ const relativeTo = run.position?.vertical?.relativeTo;
397
+ if (relativeTo !== void 0 && relativeTo !== "paragraph" && relativeTo !== "line") continue;
398
+ const distLeft = run.distLeft ?? 0;
399
+ const left = horizontalImageLeft({
400
+ run,
401
+ contentWidth,
402
+ metrics
403
+ }) - distLeft;
404
+ const right = left + run.width + distLeft + (run.distRight ?? 0);
405
+ if (left > 0 || right < contentWidth) continue;
406
+ const offset = emuToPixels(run.position?.vertical?.posOffset ?? 0);
407
+ reservedHeight = Math.max(reservedHeight, Math.max(0, offset) + run.height + (run.distBottom ?? 0));
408
+ }
409
+ return reservedHeight > 0 ? {
410
+ ...measure,
411
+ totalHeight: measure.totalHeight + reservedHeight
412
+ } : measure;
413
+ });
414
+ }
377
415
  function finalizeHeaderFooterContent(blocks, contentWidth, metrics, options) {
378
416
  if (blocks.length === 0) return;
379
417
  const blocksForMeasure = normalizeHeaderFooterMeasureBlocks(blocks, metrics.section);
380
- const measures = options.measureBlocks(blocksForMeasure, contentWidth);
418
+ const measures = reserveHeaderFooterFullWidthWrapBands({
419
+ blocks,
420
+ measures: options.measureBlocks(blocksForMeasure, contentWidth),
421
+ contentWidth,
422
+ metrics
423
+ });
381
424
  let flowHeight = 0;
382
425
  for (let i = 0; i < measures.length; i++) {
383
426
  const m = measures[i];
@@ -532,4 +575,4 @@ function serializeRunFmt(run) {
532
575
  return JSON.stringify(out);
533
576
  }
534
577
  //#endregion
535
- export { calculateHeaderFooterBodyTopClearance, calculateHeaderFooterMarginPushBounds, calculateHeaderFooterVisualBounds, convertHeaderFooterPmDocToContent, convertHeaderFooterToContent, normalizeHeaderFooterMeasureBlocks, resolveHeaderFooterPositionedVisualTop, resolveHeaderFooterVisualTop };
578
+ export { calculateHeaderFooterBodyTopClearance, calculateHeaderFooterMarginPushBounds, calculateHeaderFooterVisualBounds, convertHeaderFooterPmDocToContent, convertHeaderFooterToContent, normalizeHeaderFooterMeasureBlocks, reserveHeaderFooterFullWidthWrapBands, resolveHeaderFooterPositionedVisualTop, resolveHeaderFooterVisualTop };
@@ -14,10 +14,14 @@ type ToFlowBlocksOptions = {
14
14
  defaultSize?: number;
15
15
  /** Theme for resolving theme colors. */
16
16
  theme?: document_d_exports.Theme | null;
17
+ /** Document styles used to resolve character-style toggles without per-run copies. */
18
+ styles?: document_d_exports.StyleDefinitions;
17
19
  /** Document-scoped OOXML primary-font to `w:altName` lookup. */
18
20
  fontAlternates?: FontAlternates;
19
21
  /** Page content height in pixels (pageHeight - marginTop - marginBottom). Images taller than this are scaled down to fit. */
20
22
  pageContentHeight?: number;
23
+ /** Whether a trailing page break moves its paragraph mark to the next page. */
24
+ splitPageBreakAndParagraphMark?: boolean;
21
25
  /** Shared list counters for nested containers. */
22
26
  listCounters?: Map<number, number[]>;
23
27
  /** Latest concrete counters by abstract numbering definition. */