@stll/folio-core 0.45.0 → 0.47.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 (451) hide show
  1. package/dist/ai-edits/apply.js +85 -43
  2. package/dist/ai-edits/headless.js +2 -2
  3. package/dist/ai-edits/read.d.ts +1 -0
  4. package/dist/ai-edits/read.js +1 -0
  5. package/dist/ai-edits/snapshot.js +32 -27
  6. package/dist/ai-edits/table-cell-mutations.js +15 -7
  7. package/dist/ai-edits/table-geometry.js +21 -18
  8. package/dist/ai-edits/table-template.js +2 -2
  9. package/dist/compare/compare.js +2 -5
  10. package/dist/compare/content-alignment.js +108 -12
  11. package/dist/compare/content-types.d.ts +8 -2
  12. package/dist/compare/content.js +2 -11
  13. package/dist/compare/plan.js +7 -4
  14. package/dist/compare/scenario.js +2 -5
  15. package/dist/compare/section-boundary-properties.js +1 -2
  16. package/dist/compare/types.d.ts +9 -1
  17. package/dist/compare/types.js +12 -1
  18. package/dist/compat/eigenpal.d.ts +2 -1
  19. package/dist/compat/eigenpal.js +2 -1
  20. package/dist/content-controls/checkboxDisplay.d.ts +17 -0
  21. package/dist/content-controls/checkboxDisplay.js +46 -0
  22. package/dist/content-controls/findContentControls.js +3 -1
  23. package/dist/content-controls/mutateContentControls.js +57 -43
  24. package/dist/controller/contentControlWidgetController.d.ts +1 -0
  25. package/dist/controller/contentControlWidgetController.js +3 -0
  26. package/dist/controller/hiddenEditorApi.js +3 -1
  27. package/dist/controller/hiddenEditorManager.d.ts +1 -1
  28. package/dist/controller/hiddenEditorManager.js +6 -3
  29. package/dist/controller/layoutPipeline.js +8 -3
  30. package/dist/display-list/build/buildDisplayList.js +20 -1
  31. package/dist/display-list/build/imagePrimitives.d.ts +4 -4
  32. package/dist/display-list/build/imagePrimitives.js +38 -18
  33. package/dist/display-list/build/pageBorderPrimitives.js +2 -1
  34. package/dist/display-list/build/paragraphPrimitives.js +113 -14
  35. package/dist/display-list/build/previewPrimitives.d.ts +10 -0
  36. package/dist/display-list/build/previewPrimitives.js +89 -0
  37. package/dist/display-list/build/strokes.d.ts +177 -8
  38. package/dist/display-list/build/strokes.js +167 -47
  39. package/dist/display-list/build/tablePrimitives.js +4 -2
  40. package/dist/display-list/build/textBoxPrimitives.js +6 -4
  41. package/dist/display-list/build/textDecorations.d.ts +15 -1
  42. package/dist/display-list/build/textDecorations.js +15 -1
  43. package/dist/display-list/dom/renderDisplayListToDom.js +11 -21
  44. package/dist/display-list/primitives.d.ts +13 -2
  45. package/dist/display-list/primitives.js +36 -1
  46. package/dist/display-list/types.d.ts +17 -0
  47. package/dist/document-operations.js +2 -1
  48. package/dist/docx/attributeRemainder.d.ts +76 -0
  49. package/dist/docx/attributeRemainder.js +111 -0
  50. package/dist/docx/blockContentParser.d.ts +3 -1
  51. package/dist/docx/blockContentParser.js +102 -106
  52. package/dist/docx/blockPlainText.d.ts +3 -4
  53. package/dist/docx/blockPlainText.js +3 -0
  54. package/dist/docx/borderParser.js +26 -11
  55. package/dist/docx/builtInStyles.d.ts +8 -16
  56. package/dist/docx/builtInStyles.js +54 -17
  57. package/dist/docx/commentAnchorIndex.d.ts +30 -0
  58. package/dist/docx/commentAnchorIndex.js +50 -0
  59. package/dist/docx/commentParser.d.ts +1 -1
  60. package/dist/docx/commentParser.js +56 -39
  61. package/dist/docx/commentRangeIntegrity.d.ts +16 -1
  62. package/dist/docx/commentRangeIntegrity.js +42 -1
  63. package/dist/docx/commentRangeJoin.d.ts +9 -0
  64. package/dist/docx/commentRangeJoin.js +33 -0
  65. package/dist/docx/commentReferenceCompletion.d.ts +9 -0
  66. package/dist/docx/commentReferenceCompletion.js +47 -0
  67. package/dist/docx/commentReferenceNormalization.js +3 -1
  68. package/dist/docx/commentReplyMarkers.js +11 -19
  69. package/dist/docx/compatibility.js +56 -41
  70. package/dist/docx/containerChildren.d.ts +208 -0
  71. package/dist/docx/containerChildren.gen.d.ts +43 -0
  72. package/dist/docx/containerChildren.gen.js +263 -0
  73. package/dist/docx/containerChildren.js +153 -0
  74. package/dist/docx/diagramPreview.d.ts +14 -2
  75. package/dist/docx/diagramPreview.js +81 -169
  76. package/dist/docx/documentParser.d.ts +1 -1
  77. package/dist/docx/documentParser.js +7 -4
  78. package/dist/docx/drawingAnchor.d.ts +87 -0
  79. package/dist/docx/drawingAnchor.js +201 -0
  80. package/dist/docx/drawingUtils.d.ts +43 -38
  81. package/dist/docx/drawingUtils.js +205 -118
  82. package/dist/docx/ensureParaIds.js +17 -7
  83. package/dist/docx/fieldParser.d.ts +1 -1
  84. package/dist/docx/fieldParser.js +4 -4
  85. package/dist/docx/fieldState.d.ts +26 -0
  86. package/dist/docx/fieldState.js +53 -0
  87. package/dist/docx/fontTableParser.js +102 -41
  88. package/dist/docx/footnoteParser.d.ts +1 -1
  89. package/dist/docx/footnoteParser.js +10 -6
  90. package/dist/docx/graphicFrameLocks.d.ts +16 -4
  91. package/dist/docx/graphicFrameLocks.js +19 -6
  92. package/dist/docx/groupDrawingParser.js +4 -3
  93. package/dist/docx/headerFooterParser.js +1 -1
  94. package/dist/docx/headerFooterReferenceNormalization.js +1 -0
  95. package/dist/docx/hyperlinkParser.d.ts +66 -9
  96. package/dist/docx/hyperlinkParser.js +153 -26
  97. package/dist/docx/imageParser.js +160 -115
  98. package/dist/docx/index.d.ts +2 -1
  99. package/dist/docx/index.js +2 -1
  100. package/dist/docx/inlineContentRemovals.d.ts +28 -0
  101. package/dist/docx/inlineContentRemovals.js +46 -0
  102. package/dist/docx/inlineWrapperContent.d.ts +166 -0
  103. package/dist/docx/inlineWrapperContent.js +165 -0
  104. package/dist/docx/inlineWrapperParser.d.ts +11 -0
  105. package/dist/docx/inlineWrapperParser.js +60 -0
  106. package/dist/docx/nonVisualDrawingProps.d.ts +5 -13
  107. package/dist/docx/normalizeBaseDirection.js +12 -1
  108. package/dist/docx/numberingParser.d.ts +25 -2
  109. package/dist/docx/numberingParser.js +264 -361
  110. package/dist/docx/numberingReference.d.ts +9 -16
  111. package/dist/docx/numberingReference.js +17 -16
  112. package/dist/docx/numberingReferenceNormalization.js +7 -7
  113. package/dist/docx/ooxmlCounterFormatter.d.ts +1 -1
  114. package/dist/docx/ooxmlCounterFormatter.js +4 -1
  115. package/dist/docx/paraIdAttribute.d.ts +111 -0
  116. package/dist/docx/paraIdAttribute.js +142 -0
  117. package/dist/docx/paragraphParser.d.ts +10 -25
  118. package/dist/docx/paragraphParser.js +421 -496
  119. package/dist/docx/paragraphProperties.d.ts +23 -0
  120. package/dist/docx/paragraphProperties.js +279 -0
  121. package/dist/docx/paragraphPropertySource.js +7 -1
  122. package/dist/docx/paragraphTextBoxEnrichment.d.ts +3 -2
  123. package/dist/docx/paragraphTextBoxEnrichment.js +20 -59
  124. package/dist/docx/paragraphTraversal.d.ts +14 -10
  125. package/dist/docx/paragraphTraversal.js +53 -52
  126. package/dist/docx/parseWarningMessage.js +5 -1
  127. package/dist/docx/parserEnums.d.ts +6 -8
  128. package/dist/docx/parserEnums.js +4 -6
  129. package/dist/docx/preservedRunContent.d.ts +32 -0
  130. package/dist/docx/preservedRunContent.js +96 -0
  131. package/dist/docx/previewBudget.d.ts +44 -23
  132. package/dist/docx/previewBudget.js +61 -30
  133. package/dist/docx/propertyElementAttributes.d.ts +178 -0
  134. package/dist/docx/propertyElementAttributes.js +114 -0
  135. package/dist/docx/renderedPageBreakNormalization.js +4 -6
  136. package/dist/docx/rezip.d.ts +28 -2
  137. package/dist/docx/rezip.js +152 -27
  138. package/dist/docx/runConsolidator.d.ts +42 -2
  139. package/dist/docx/runConsolidator.js +60 -6
  140. package/dist/docx/runParser.d.ts +55 -19
  141. package/dist/docx/runParser.js +394 -306
  142. package/dist/docx/runPayload.d.ts +5 -0
  143. package/dist/docx/runPayload.js +4 -0
  144. package/dist/docx/sdtProperties.d.ts +39 -5
  145. package/dist/docx/sdtProperties.js +205 -84
  146. package/dist/docx/sdtPropertiesPatch.d.ts +5 -9
  147. package/dist/docx/sdtPropertiesPatch.js +68 -112
  148. package/dist/docx/sectionParser.d.ts +1 -2
  149. package/dist/docx/sectionParser.js +241 -238
  150. package/dist/docx/selectiveSave.js +3 -2
  151. package/dist/docx/selectiveXmlPatch.d.ts +66 -3
  152. package/dist/docx/selectiveXmlPatch.js +276 -133
  153. package/dist/docx/serializer/blockSdtSerializer.js +2 -96
  154. package/dist/docx/serializer/borderSerializer.d.ts +5 -5
  155. package/dist/docx/serializer/borderSerializer.js +12 -10
  156. package/dist/docx/serializer/commentSerializer.js +5 -7
  157. package/dist/docx/serializer/documentSerializer.js +11 -11
  158. package/dist/docx/serializer/fontTableSerializer.js +31 -3
  159. package/dist/docx/serializer/headerFooterSerializer.js +10 -9
  160. package/dist/docx/serializer/markupRangeAttributes.d.ts +9 -1
  161. package/dist/docx/serializer/markupRangeAttributes.js +9 -1
  162. package/dist/docx/serializer/noteSerializer.js +11 -8
  163. package/dist/docx/serializer/numberingSerializer.d.ts +1 -6
  164. package/dist/docx/serializer/numberingSerializer.js +81 -79
  165. package/dist/docx/serializer/paragraphSerializer.d.ts +1 -9
  166. package/dist/docx/serializer/paragraphSerializer.js +156 -236
  167. package/dist/docx/serializer/runSerializer.d.ts +1 -5
  168. package/dist/docx/serializer/runSerializer.js +134 -75
  169. package/dist/docx/serializer/sdtPropertiesSerializer.d.ts +26 -0
  170. package/dist/docx/serializer/sdtPropertiesSerializer.js +111 -0
  171. package/dist/docx/serializer/sectionPropertiesSerializer.js +42 -49
  172. package/dist/docx/serializer/settingsSerializer.js +6 -4
  173. package/dist/docx/serializer/stylesSerializer.js +8 -11
  174. package/dist/docx/serializer/tableSerializer.js +283 -105
  175. package/dist/docx/serializer/textFormattingSerializer.d.ts +28 -4
  176. package/dist/docx/serializer/textFormattingSerializer.js +111 -101
  177. package/dist/docx/serializer/xmlUtils.d.ts +1 -1
  178. package/dist/docx/serializer/xmlUtils.js +1 -1
  179. package/dist/docx/server/createBilingualDocument.js +20 -16
  180. package/dist/docx/server/materializeYjsDocx.d.ts +1 -1
  181. package/dist/docx/server/materializeYjsDocx.js +9 -1
  182. package/dist/docx/server/migrateYjsAttrSchema.d.ts +55 -0
  183. package/dist/docx/server/migrateYjsAttrSchema.js +95 -0
  184. package/dist/docx/settingsParser.js +7 -4
  185. package/dist/docx/shadingParser.d.ts +2 -1
  186. package/dist/docx/shadingParser.js +43 -7
  187. package/dist/docx/shapeParser.js +13 -8
  188. package/dist/docx/strictNames.d.ts +11 -0
  189. package/dist/docx/strictNames.gen.d.ts +45 -0
  190. package/dist/docx/strictNames.gen.js +50 -0
  191. package/dist/docx/strictNames.js +43 -0
  192. package/dist/docx/strictValueEncodings.gen.js +133 -131
  193. package/dist/docx/styleParser.js +17 -349
  194. package/dist/docx/tableParser.d.ts +11 -2
  195. package/dist/docx/tableParser.js +665 -220
  196. package/dist/docx/textBoxParser.d.ts +28 -3
  197. package/dist/docx/textBoxParser.js +69 -9
  198. package/dist/docx/themeColorAttribute.d.ts +13 -0
  199. package/dist/docx/themeColorAttribute.js +24 -0
  200. package/dist/docx/trackedMoveRangeNormalization.js +2 -1
  201. package/dist/docx/unzip.js +5 -4
  202. package/dist/docx/vmlImageParser.d.ts +30 -5
  203. package/dist/docx/vmlImageParser.js +91 -32
  204. package/dist/docx/vmlPreview.js +2 -2
  205. package/dist/docx/wrapPolygon.d.ts +30 -0
  206. package/dist/docx/wrapPolygon.js +70 -0
  207. package/dist/docx/xmlEncoding.d.ts +5 -0
  208. package/dist/docx/xmlEncoding.js +12 -0
  209. package/dist/docx/xmlParser.d.ts +23 -1
  210. package/dist/docx/xmlParser.js +31 -2
  211. package/dist/fonts/embeddedFonts.js +3 -3
  212. package/dist/headless-layout.js +12 -1
  213. package/dist/i18n/messages/catalogs.gen.d.ts +68 -0
  214. package/dist/i18n/messages/catalogs.gen.js +102 -34
  215. package/dist/i18n/messages/messages.gen.d.ts +4 -0
  216. package/dist/index.d.ts +2 -1
  217. package/dist/index.js +2 -1
  218. package/dist/internal/headlessRevisionResolution.js +9 -0
  219. package/dist/internal/pageBreakRunSourceDescendantIndex.js +7 -2
  220. package/dist/internal/paragraphFormattingSerialization.d.ts +20 -9
  221. package/dist/internal/paragraphFormattingSerialization.js +118 -83
  222. package/dist/layout-bridge/convert/footnoteLayout.d.ts +1 -0
  223. package/dist/layout-bridge/convert/footnoteLayout.js +1 -0
  224. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -0
  225. package/dist/layout-bridge/convert/headerFooterLayout.js +2 -0
  226. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +17 -12
  227. package/dist/layout-bridge/convert/toFlowBlocks.js +267 -101
  228. package/dist/layout-engine/index.d.ts +2 -2
  229. package/dist/layout-engine/index.js +53 -17
  230. package/dist/layout-engine/measure/measureBlocks.d.ts +3 -0
  231. package/dist/layout-engine/measure/measureBlocks.js +6 -10
  232. package/dist/layout-engine/measure/tableCellFloating.d.ts +2 -0
  233. package/dist/layout-engine/measure/tableCellFloating.js +2 -0
  234. package/dist/layout-engine/measure/tableCellGrid.js +2 -1
  235. package/dist/layout-engine/measure/tableFragmentBorderGeometry.js +2 -1
  236. package/dist/layout-engine/measure/tableInlinePlacement.js +2 -5
  237. package/dist/layout-engine/paragraphSequence.js +3 -2
  238. package/dist/layout-engine/renderedBreakReconciliation.js +2 -1
  239. package/dist/layout-engine/section-breaks.d.ts +49 -2
  240. package/dist/layout-engine/section-breaks.js +55 -4
  241. package/dist/layout-engine/types.d.ts +69 -17
  242. package/dist/layout-engine/types.js +16 -1
  243. package/dist/layout-painter/borderStroke.d.ts +18 -4
  244. package/dist/layout-painter/renderImage.d.ts +5 -1
  245. package/dist/layout-painter/renderImage.js +10 -3
  246. package/dist/layout-painter/renderPage.d.ts +2 -0
  247. package/dist/layout-painter/renderPage.js +10 -4
  248. package/dist/layout-painter/renderParagraph.d.ts +14 -1
  249. package/dist/layout-painter/renderParagraph.js +34 -28
  250. package/dist/layout-painter/renderTable.d.ts +4 -1
  251. package/dist/layout-painter/renderTable.js +22 -22
  252. package/dist/layout-painter/renderTextBox.js +5 -3
  253. package/dist/managers/autoSaveCodec.d.ts +9 -1
  254. package/dist/managers/autoSaveCodec.js +12 -4
  255. package/dist/markdown/renderBlock.js +3 -0
  256. package/dist/markdown/renderRuns.d.ts +1 -1
  257. package/dist/markdown/renderRuns.js +34 -6
  258. package/dist/markdown/renderTable.js +24 -6
  259. package/dist/markdown/trailers.js +4 -1
  260. package/dist/model.d.ts +3 -3
  261. package/dist/model.js +2 -2
  262. package/dist/paged-layout/sectionBlockWidths.d.ts +3 -0
  263. package/dist/paged-layout/sectionBlockWidths.js +26 -4
  264. package/dist/pdf/images.js +142 -6
  265. package/dist/prosemirror/attrs/index.d.ts +34 -5
  266. package/dist/prosemirror/attrs/index.js +639 -48
  267. package/dist/prosemirror/authoredTransformAttrs.d.ts +28 -0
  268. package/dist/prosemirror/authoredTransformAttrs.js +64 -0
  269. package/dist/prosemirror/bookmarkBoundaryAttrs.d.ts +9 -1
  270. package/dist/prosemirror/bookmarkBoundaryAttrs.js +22 -3
  271. package/dist/prosemirror/commands/comments.js +68 -53
  272. package/dist/prosemirror/commands/contentControls.js +33 -20
  273. package/dist/prosemirror/commands/image.d.ts +10 -3
  274. package/dist/prosemirror/commands/image.js +46 -29
  275. package/dist/prosemirror/commands/pageBreak.js +1 -1
  276. package/dist/prosemirror/commands/paragraph.d.ts +2 -1
  277. package/dist/prosemirror/commands/propertyChangeScope.d.ts +12 -4
  278. package/dist/prosemirror/commands/propertyChangeScope.js +22 -4
  279. package/dist/prosemirror/commands/sectionBreak.d.ts +33 -1
  280. package/dist/prosemirror/commands/sectionBreak.js +187 -11
  281. package/dist/prosemirror/commentReferenceAttrs.d.ts +8 -0
  282. package/dist/prosemirror/commentReferenceAttrs.js +33 -0
  283. package/dist/prosemirror/commentReferenceIntegrity.d.ts +47 -0
  284. package/dist/prosemirror/commentReferenceIntegrity.js +43 -0
  285. package/dist/prosemirror/conversion/fromProseDoc.d.ts +17 -12
  286. package/dist/prosemirror/conversion/fromProseDoc.js +553 -207
  287. package/dist/prosemirror/conversion/index.d.ts +2 -2
  288. package/dist/prosemirror/conversion/preservedSinkCarriers.d.ts +39 -0
  289. package/dist/prosemirror/conversion/preservedSinkCarriers.js +19 -0
  290. package/dist/prosemirror/conversion/runShadingMark.js +14 -1
  291. package/dist/prosemirror/conversion/sdtAttrs.d.ts +10 -1
  292. package/dist/prosemirror/conversion/sdtAttrs.js +19 -5
  293. package/dist/prosemirror/conversion/toProseDoc.d.ts +7 -9
  294. package/dist/prosemirror/conversion/toProseDoc.js +801 -411
  295. package/dist/prosemirror/emptyRangeAnchor.d.ts +53 -0
  296. package/dist/prosemirror/emptyRangeAnchor.js +158 -0
  297. package/dist/prosemirror/extensions/StarterKit.js +14 -58
  298. package/dist/prosemirror/extensions/core/DocExtension.js +1 -1
  299. package/dist/prosemirror/extensions/core/ParagraphExtension.js +21 -16
  300. package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +48 -29
  301. package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.js +3 -1
  302. package/dist/prosemirror/extensions/features/ImagePasteExtension.js +5 -3
  303. package/dist/prosemirror/extensions/features/ListExtension.js +43 -24
  304. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +1 -0
  305. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +4 -3
  306. package/dist/prosemirror/extensions/features/PasteCleanupExtension.d.ts +3 -3
  307. package/dist/prosemirror/extensions/features/PasteCleanupExtension.js +5 -5
  308. package/dist/prosemirror/extensions/features/pasteCleanup.d.ts +3 -1
  309. package/dist/prosemirror/extensions/features/pasteCleanup.js +56 -2
  310. package/dist/prosemirror/extensions/features/pastedHeadingStyles.js +5 -4
  311. package/dist/prosemirror/extensions/markRegistry.d.ts +65 -0
  312. package/dist/prosemirror/extensions/markRegistry.js +138 -0
  313. package/dist/prosemirror/extensions/marks/InlineWrapperExtension.d.ts +18 -0
  314. package/dist/prosemirror/extensions/marks/InlineWrapperExtension.js +77 -0
  315. package/dist/prosemirror/extensions/marks/RunIdentityExtension.d.ts +26 -0
  316. package/dist/prosemirror/extensions/marks/RunIdentityExtension.js +134 -0
  317. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +2 -1
  318. package/dist/prosemirror/extensions/marks/UnderlineExtension.js +12 -18
  319. package/dist/prosemirror/extensions/marks/markUtils.d.ts +2 -1
  320. package/dist/prosemirror/extensions/marks/markUtils.js +49 -5
  321. package/dist/prosemirror/extensions/nodes/BlockBookmarkBoundaryExtension.d.ts +29 -0
  322. package/dist/prosemirror/extensions/nodes/BlockBookmarkBoundaryExtension.js +46 -0
  323. package/dist/prosemirror/extensions/nodes/BlockSdtExtension.d.ts +4 -3
  324. package/dist/prosemirror/extensions/nodes/BlockSdtExtension.js +18 -13
  325. package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.js +28 -53
  326. package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.d.ts +11 -0
  327. package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +97 -0
  328. package/dist/prosemirror/extensions/nodes/FieldExtension.js +9 -7
  329. package/dist/prosemirror/extensions/nodes/ImageExtension.js +24 -1
  330. package/dist/prosemirror/extensions/nodes/MoveRangeBoundaryExtension.d.ts +11 -0
  331. package/dist/prosemirror/extensions/nodes/MoveRangeBoundaryExtension.js +43 -0
  332. package/dist/prosemirror/extensions/nodes/PreservedBlockExtension.d.ts +32 -0
  333. package/dist/prosemirror/extensions/nodes/PreservedBlockExtension.js +67 -0
  334. package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.d.ts +16 -0
  335. package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.js +60 -0
  336. package/dist/prosemirror/extensions/nodes/RangeAnchorExtension.d.ts +13 -0
  337. package/dist/prosemirror/extensions/nodes/RangeAnchorExtension.js +65 -0
  338. package/dist/prosemirror/extensions/nodes/SdtExtension.d.ts +3 -1
  339. package/dist/prosemirror/extensions/nodes/SdtExtension.js +22 -16
  340. package/dist/prosemirror/extensions/nodes/ShapeExtension.js +7 -0
  341. package/dist/prosemirror/extensions/nodes/TableExtension.js +142 -123
  342. package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +9 -1
  343. package/dist/prosemirror/extensions/nodes/bookmarkBoundaryDom.d.ts +23 -0
  344. package/dist/prosemirror/extensions/nodes/bookmarkBoundaryDom.js +57 -0
  345. package/dist/prosemirror/extensions/types.d.ts +12 -3
  346. package/dist/prosemirror/index.d.ts +4 -2
  347. package/dist/prosemirror/index.js +2 -1
  348. package/dist/prosemirror/inlineWrapperStack.d.ts +39 -0
  349. package/dist/prosemirror/inlineWrapperStack.js +92 -0
  350. package/dist/prosemirror/listMarker.d.ts +2 -2
  351. package/dist/prosemirror/listMarker.js +7 -8
  352. package/dist/prosemirror/listRenderingAttrs.js +11 -1
  353. package/dist/prosemirror/listState.d.ts +62 -0
  354. package/dist/prosemirror/listState.js +49 -0
  355. package/dist/prosemirror/moveRangeBoundaryAttrs.d.ts +13 -0
  356. package/dist/prosemirror/moveRangeBoundaryAttrs.js +114 -0
  357. package/dist/prosemirror/numberedRefFields.js +4 -4
  358. package/dist/prosemirror/numberingAttr.d.ts +55 -0
  359. package/dist/prosemirror/numberingAttr.js +74 -0
  360. package/dist/prosemirror/outlineLevelAttr.d.ts +29 -0
  361. package/dist/prosemirror/outlineLevelAttr.js +42 -0
  362. package/dist/prosemirror/pageBreakRunProjection.d.ts +17 -7
  363. package/dist/prosemirror/pageBreakRunProjection.js +19 -9
  364. package/dist/prosemirror/paragraphFormattingProvenance.d.ts +9 -0
  365. package/dist/prosemirror/paragraphFormattingProvenance.js +4 -1
  366. package/dist/prosemirror/plugins/selectionTracker.d.ts +3 -6
  367. package/dist/prosemirror/plugins/selectionTracker.js +3 -10
  368. package/dist/prosemirror/rangeAnchorAttrs.d.ts +14 -0
  369. package/dist/prosemirror/rangeAnchorAttrs.js +101 -0
  370. package/dist/prosemirror/replacedAnnotations.d.ts +59 -0
  371. package/dist/prosemirror/replacedAnnotations.js +183 -0
  372. package/dist/prosemirror/revisionCarriers.d.ts +86 -2
  373. package/dist/prosemirror/revisionCarriers.js +86 -60
  374. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +5 -1
  375. package/dist/prosemirror/runFormattingInlineCarriers.js +7 -1
  376. package/dist/prosemirror/runIdentity.d.ts +28 -0
  377. package/dist/prosemirror/runIdentity.js +36 -0
  378. package/dist/prosemirror/runStyleFormatting.js +1 -1
  379. package/dist/prosemirror/schema/index.d.ts +3 -3
  380. package/dist/prosemirror/schema/marks.d.ts +47 -4
  381. package/dist/prosemirror/schema/nodes.d.ts +309 -26
  382. package/dist/prosemirror/schema/nodes.js +16 -1
  383. package/dist/prosemirror/sectionCarrier.d.ts +37 -0
  384. package/dist/prosemirror/sectionCarrier.js +40 -0
  385. package/dist/prosemirror/selectionState.d.ts +3 -0
  386. package/dist/prosemirror/selectionState.js +4 -1
  387. package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +5 -4
  388. package/dist/prosemirror/styles/resolvedStyleAttrs.js +15 -13
  389. package/dist/prosemirror/tableResize.js +5 -6
  390. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +4 -0
  391. package/dist/prosemirror/trackedRunInlineAtoms.js +4 -0
  392. package/dist/prosemirror/utils/extractTrackedChanges.d.ts +10 -11
  393. package/dist/prosemirror/utils/extractTrackedChanges.js +109 -92
  394. package/dist/prosemirror/validation.js +31 -6
  395. package/dist/prosemirror/yjsDocumentMetadata.d.ts +73 -0
  396. package/dist/prosemirror/yjsDocumentMetadata.js +592 -0
  397. package/dist/prosemirror/zeroWidthAnchors.js +6 -0
  398. package/dist/render-dom/commentAnchorAttributes.d.ts +37 -0
  399. package/dist/render-dom/commentAnchorAttributes.js +54 -0
  400. package/dist/server.d.ts +3 -1
  401. package/dist/server.js +3 -1
  402. package/dist/style-sets/extract.js +4 -4
  403. package/dist/style-sets/stellaStyle.js +36 -23
  404. package/dist/types/colors.d.ts +2 -2
  405. package/dist/types/content.d.ts +2 -2
  406. package/dist/types/documentEnumValues.d.ts +53 -26
  407. package/dist/types/documentEnumValues.js +72 -174
  408. package/dist/types/formatting.d.ts +2 -2
  409. package/dist/types/index.d.ts +9 -2
  410. package/dist/utils/borderCss.d.ts +246 -0
  411. package/dist/utils/borderCss.js +325 -0
  412. package/dist/utils/clipboard.d.ts +9 -1
  413. package/dist/utils/clipboard.js +27 -1
  414. package/dist/utils/colorResolver.d.ts +4 -3
  415. package/dist/utils/colorResolver.js +45 -76
  416. package/dist/utils/createDocument.js +24 -6
  417. package/dist/utils/findReplace.js +52 -10
  418. package/dist/utils/formatToStyle.d.ts +84 -2
  419. package/dist/utils/formatToStyle.js +133 -52
  420. package/dist/utils/headingCollector.js +3 -2
  421. package/dist/utils/imageLuminance.d.ts +15 -0
  422. package/dist/utils/imageLuminance.js +32 -0
  423. package/dist/utils/mergeDocumentContent.js +12 -20
  424. package/dist/utils/paragraphFormattingMerge.js +27 -6
  425. package/dist/utils/replaceText.js +1 -0
  426. package/dist/utils/tableOperations.d.ts +5 -3
  427. package/dist/utils/tableOperations.js +14 -1
  428. package/dist/utils/tablePlacement.d.ts +7 -0
  429. package/dist/utils/tablePlacement.js +14 -0
  430. package/dist/utils/textDirectionFlow.d.ts +15 -0
  431. package/dist/utils/textDirectionFlow.js +38 -0
  432. package/dist/utils/textFormattingMerge.js +16 -4
  433. package/package.json +10 -10
  434. package/dist/ai-edits/__fixtures__/paragraphs.d.ts +0 -17
  435. package/dist/ai-edits/__fixtures__/paragraphs.js +0 -33
  436. package/dist/compare/__fixtures__/body-sequence.d.ts +0 -119
  437. package/dist/compare/__fixtures__/body-sequence.js +0 -225
  438. package/dist/compare/__fixtures__/nested-table.d.ts +0 -16
  439. package/dist/compare/__fixtures__/nested-table.js +0 -50
  440. package/dist/compare/__fixtures__/numbered-list.d.ts +0 -34
  441. package/dist/compare/__fixtures__/numbered-list.js +0 -85
  442. package/dist/docx/blockRangeMarkers.d.ts +0 -36
  443. package/dist/docx/blockRangeMarkers.js +0 -59
  444. package/dist/docx/bookmarkPlacement.d.ts +0 -9
  445. package/dist/docx/bookmarkPlacement.js +0 -50
  446. package/dist/fonts/embeddedFontTable.d.ts +0 -45
  447. package/dist/fonts/embeddedFontTable.js +0 -80
  448. package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.d.ts +0 -13
  449. package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.js +0 -39
  450. package/dist/prosemirror/yjsParagraphSourceContract.d.ts +0 -9
  451. package/dist/prosemirror/yjsParagraphSourceContract.js +0 -26
@@ -12,9 +12,10 @@ import { assertValidFolioDocumentModel } from "./modelValidation.js";
12
12
  import { isNewDataUrlDrawing } from "./newImage.js";
13
13
  import { missingNoteReferenceStyles, noteReferenceNeeds } from "./noteReferenceStyles.js";
14
14
  import { parseNumbering } from "./numberingParser.js";
15
- import { isNumberingReference } from "./numberingReference.js";
15
+ import { paragraphNumberingReferenceId as paragraphNumberingReferenceId$1 } from "./numberingReference.js";
16
16
  import { isUnsafePackagePath, reconcilePackageReferences, removeUnsafeEntries } from "./packageParts.js";
17
17
  import { normalizeParaIdRangeInXmlParts } from "./paraIdRangeNormalization.js";
18
+ import { BLOCK_TREE_DESCENT, visitBlockTreeRecords } from "./paragraphTraversal.js";
18
19
  import { RELATIONSHIP_TYPES, parseRelationships, resolveRelativePath } from "./relsParser.js";
19
20
  import { removeResolvedHeaderFooterParts } from "./removeHeaderFooterParts.js";
20
21
  import { normalizeRevisionIdsInXmlParts } from "./revisionIdNormalization.js";
@@ -29,10 +30,11 @@ import { readRootNamespaceBindings } from "./serializer/partNamespaces.js";
29
30
  import { serializeSettingsXml } from "./serializer/settingsSerializer.js";
30
31
  import { serializeStyle, serializeStylesXml } from "./serializer/stylesSerializer.js";
31
32
  import { serializeThemeXml } from "./serializer/themeSerializer.js";
32
- import { OFFICE_RELATIONSHIP_NAMESPACE_URIS, WORDPROCESSINGML_NAMESPACE_URIS, findChild, getAttribute, getAttributeByNamespaceUri, getChildElements, getLocalName, getNamespaceUri, matchesName, parseXml, parseXmlDocument } from "./xmlParser.js";
33
+ import { OFFICE_RELATIONSHIP_NAMESPACE_URIS, WORDPROCESSINGML_NAMESPACE_URIS, findChild, findChildByNamespaceUri, findChildrenByNamespaceUri, getAttribute, getAttributeByNamespaceUri, getChildElements, getLocalName, getNamespaceUri, matchesName, parseXml, parseXmlDocument } from "./xmlParser.js";
33
34
  import { assertXmlResourceLimits } from "./xmlResourceLimits.js";
34
- import { panic } from "better-result";
35
+ import { TaggedError, panic } from "better-result";
35
36
  import { escapeXmlAttribute, escapeXmlText, validateDocxPackage } from "@stll/docx-core";
37
+ import { mintRelationshipId } from "@stll/docx-core/model";
36
38
  import JSZip from "jszip";
37
39
  //#region src/docx/rezip.ts
38
40
  /**
@@ -65,10 +67,34 @@ import JSZip from "jszip";
65
67
  * - word/_rels/document.xml.rels - Document relationships (preserved)
66
68
  * - docProps/* - Document properties (preserved)
67
69
  */
68
- var DocxPackageFidelityError = class extends Error {
70
+ var DocxPackageFidelityError = class extends TaggedError("DocxPackageFidelityError") {
69
71
  constructor(message) {
70
- super(message);
71
- this.name = "DocxPackageFidelityError";
72
+ super({ message });
73
+ }
74
+ };
75
+ /**
76
+ * Raised when a save would write a section the editor never authored.
77
+ *
78
+ * Two paragraphs holding the *same* `SectionProperties` object are one
79
+ * section's two halves, not two sections: ProseMirror copies a node's attrs
80
+ * when a command splits it, and the object is passed through by reference and
81
+ * never cloned, so identity is what tells a copy from a second authored break.
82
+ * The paragraph is named because the count alone does not say which of them the
83
+ * save invented.
84
+ */
85
+ var DocxDuplicateSectionCarrierError = class extends DocxPackageFidelityError {
86
+ /** The `w:paraId` of the duplicate carrier, when the package gave it one. */
87
+ paraId;
88
+ /** Its position among the paragraph-level carriers, in document order. */
89
+ carrierIndex;
90
+ /** The position of the carrier it duplicates. */
91
+ duplicatesCarrierIndex;
92
+ constructor(options) {
93
+ super(`Full DOCX repack would add a section: paragraph-level w:sectPr carrier ${options.carrierIndex}${options.paraId === null ? "" : ` (w:paraId ${options.paraId})`} holds the same section record as carrier ${options.duplicatesCarrierIndex}.`);
94
+ this.name = "DocxDuplicateSectionCarrierError";
95
+ this.paraId = options.paraId;
96
+ this.carrierIndex = options.carrierIndex;
97
+ this.duplicatesCarrierIndex = options.duplicatesCarrierIndex;
72
98
  }
73
99
  };
74
100
  /**
@@ -136,12 +162,55 @@ const consumeReferenceCount = (counts, key) => {
136
162
  counts.set(key, count - 1);
137
163
  return true;
138
164
  };
165
+ /** Every paragraph the model says a section ends at, in document order. */
166
+ const sectionCarrierParagraphs = (doc) => {
167
+ const carriers = [];
168
+ visitBlockTreeRecords(doc.package.document.content, (record) => {
169
+ if (record.type === "paragraph" && record.sectionProperties !== void 0) carriers.push(record);
170
+ return BLOCK_TREE_DESCENT.descend;
171
+ });
172
+ return carriers;
173
+ };
174
+ /**
175
+ * Every serialized section has exactly one model record, and vice versa.
176
+ *
177
+ * A split paragraph's duplicated `w:sectPr` is a section nobody added,
178
+ * repeating the real one's `w:rsidSect` and claiming its revision history too.
179
+ * Two carriers over one record are therefore invalid regardless of whether a
180
+ * separate deletion makes the total section count rise, fall, or stay equal.
181
+ *
182
+ * The count is a separate invariant: `serializeSectionProperties` fails closed
183
+ * to `""` for a record holding settings it cannot write, so carrier uniqueness
184
+ * alone does not prove the package states the sections the model holds.
185
+ */
186
+ const assertSectionCarriersMatchModel = ({ doc, serializedSectionCount }) => {
187
+ const carriers = sectionCarrierParagraphs(doc);
188
+ const firstHolder = /* @__PURE__ */ new Map();
189
+ for (const [index, paragraph] of carriers.entries()) {
190
+ const record = paragraph.sectionProperties;
191
+ const duplicates = firstHolder.get(record);
192
+ if (duplicates !== void 0) throw new DocxDuplicateSectionCarrierError({
193
+ paraId: paragraph.paraId ?? null,
194
+ carrierIndex: index,
195
+ duplicatesCarrierIndex: duplicates
196
+ });
197
+ firstHolder.set(record, index);
198
+ }
199
+ const finalSectionProperties = doc.package.document.finalSectionProperties;
200
+ if (finalSectionProperties !== void 0 && firstHolder.has(finalSectionProperties)) throw new DocxPackageFidelityError("Full DOCX repack would write the final section record from a paragraph carrier twice.");
201
+ const modelSectionCount = carriers.length + (finalSectionProperties === void 0 ? 0 : 1);
202
+ if (serializedSectionCount !== modelSectionCount) throw new DocxPackageFidelityError(`Full DOCX repack would write ${serializedSectionCount} sections where the editor holds ${modelSectionCount}.`);
203
+ };
139
204
  function assertDocumentPackageFidelity({ originalDocumentXml, serializedDocumentXml, doc, sectionEndpointRemoval, sectionReferenceRemovals = [] }) {
140
205
  const originalSectionCount = countDocumentSections(originalDocumentXml);
141
206
  const serializedSectionCount = countDocumentSections(serializedDocumentXml);
142
207
  const trackedRemovedSectionCount = sectionEndpointRemoval ? sectionEndpointRemoval.sourceParagraphEndpointCount - sectionEndpointRemoval.expectedParagraphEndpointCount : 0;
143
208
  const exactTrackedSectionRemoval = trackedRemovedSectionCount > 0 && originalSectionCount - trackedRemovedSectionCount === serializedSectionCount && serializedSectionCount < originalSectionCount;
144
209
  if (serializedSectionCount < originalSectionCount && !exactTrackedSectionRemoval) throw new DocxPackageFidelityError("Full DOCX repack would drop section properties. Use selective patching instead.");
210
+ assertSectionCarriersMatchModel({
211
+ doc,
212
+ serializedSectionCount
213
+ });
145
214
  const serializedReferenceCounts = /* @__PURE__ */ new Map();
146
215
  for (const reference of extractHeaderFooterReferences(serializedDocumentXml)) incrementReferenceCount(serializedReferenceCounts, headerFooterReferenceKey(reference));
147
216
  const removedReferenceCounts = /* @__PURE__ */ new Map();
@@ -390,7 +459,7 @@ async function processNewImages(parts, zip, compressionLevel) {
390
459
  maxImageNum++;
391
460
  maxId++;
392
461
  const mediaPath = `word/media/${`image${maxImageNum}.${extension}`}`;
393
- const newRId = `rId${maxId}`;
462
+ const newRId = mintRelationshipId(maxId);
394
463
  zip.file(mediaPath, data, {
395
464
  compression: "DEFLATE",
396
465
  compressionOptions: { level: compressionLevel }
@@ -443,6 +512,7 @@ function collectHyperlinksWithoutRId(blocks) {
443
512
  break;
444
513
  case "simpleField":
445
514
  case "inlineSdt":
515
+ case "inlineWrapper":
446
516
  case "insertion":
447
517
  case "deletion":
448
518
  case "moveFrom":
@@ -454,7 +524,7 @@ function collectHyperlinksWithoutRId(blocks) {
454
524
  };
455
525
  for (const block of blocks) if (block.type === "paragraph") collectInlineHyperlinks(block.content);
456
526
  else if (block.type === "table") for (const row of block.rows) for (const cell of row.cells) hyperlinks.push(...collectHyperlinksWithoutRId(cell.content));
457
- else hyperlinks.push(...collectHyperlinksWithoutRId(block.content));
527
+ else if (block.type === "blockSdt") hyperlinks.push(...collectHyperlinksWithoutRId(block.content));
458
528
  return hyperlinks;
459
529
  }
460
530
  /** The selective save boundary must use the same resource census as full repack. */
@@ -1425,7 +1495,26 @@ const seedStylesXmlWith = (missing) => {
1425
1495
  const rootClose = SEED_STYLES_XML.lastIndexOf(STYLES_CLOSE_ROOT);
1426
1496
  return SEED_STYLES_XML.slice(0, rootClose) + missing.map(serializeStyle).join("") + SEED_STYLES_XML.slice(rootClose);
1427
1497
  };
1428
- const STYLE_ID_PATTERN = /<w:style\b[^>]*?\bw:styleId="(?<id>[^"]+)"/gu;
1498
+ /**
1499
+ * The style ids `word/styles.xml` already defines.
1500
+ *
1501
+ * Read by parsing the part, because the model holds the *decoded* id and the
1502
+ * part holds its XML spelling: `w:styleId='Body A'` is single-quoted,
1503
+ * `w:styleId="Header &amp; Footer"` is escaped, and either may sit behind an
1504
+ * attribute value containing `>`. A reader that misses one of those reports a
1505
+ * style the part already defines as missing, and
1506
+ * {@link serializeAddedStylesIntoZip} appends it — on every save, for ever.
1507
+ */
1508
+ const definedStyleIds = (stylesXml) => {
1509
+ const root = parseXml(stylesXml);
1510
+ const styles = findChildByNamespaceUri(root, WORDPROCESSINGML_NAMESPACE_URIS, "styles") ?? root;
1511
+ const ids = /* @__PURE__ */ new Set();
1512
+ for (const style of findChildrenByNamespaceUri(styles, WORDPROCESSINGML_NAMESPACE_URIS, "style")) {
1513
+ const id = getAttributeByNamespaceUri(style, WORDPROCESSINGML_NAMESPACE_URIS, "styleId") ?? style.attributes?.["w:styleId"];
1514
+ if (id !== void 0 && id !== null && id !== "") ids.add(String(id));
1515
+ }
1516
+ return ids;
1517
+ };
1429
1518
  /**
1430
1519
  * Append styles the model defines but the original `word/styles.xml` lacks.
1431
1520
  * Existing styles stay byte-exact (edits to them are not written here, the
@@ -1471,9 +1560,13 @@ async function serializeAddedStylesIntoZip(doc, originalZip, newZip, compression
1471
1560
  });
1472
1561
  return;
1473
1562
  }
1474
- const existing = /* @__PURE__ */ new Set();
1475
- for (const match of originalXml.matchAll(STYLE_ID_PATTERN)) existing.add(match.groups["id"]);
1476
- const added = styles.styles.filter((style) => !existing.has(style.styleId));
1563
+ const existing = new Set(definedStyleIds(originalXml));
1564
+ const added = [];
1565
+ for (const style of styles.styles) {
1566
+ if (existing.has(style.styleId)) continue;
1567
+ existing.add(style.styleId);
1568
+ added.push(style);
1569
+ }
1477
1570
  if (added.length === 0) return;
1478
1571
  const patched = originalXml.slice(0, rootClose) + added.map(serializeStyle).join("") + originalXml.slice(rootClose);
1479
1572
  newZip.file(file.name, patched, {
@@ -1481,28 +1574,60 @@ async function serializeAddedStylesIntoZip(doc, originalZip, newZip, compression
1481
1574
  compressionOptions: { level: compressionLevel }
1482
1575
  });
1483
1576
  }
1577
+ /**
1578
+ * The XML to write for a patched note part, or null to keep the original.
1579
+ *
1580
+ * A refusal over comment-range balance is not a failure to serialize: the
1581
+ * splice was too narrow to keep a comment's range whole, so the part is
1582
+ * written from the model, which is balanced with itself and with the
1583
+ * `document.xml` this repack rewrites beside it. Word's required separator
1584
+ * notes come back synthesized rather than byte-exact, the price of keeping the
1585
+ * comment anchored to the text it was written about. Any other refusal means a
1586
+ * changed paragraph could not be located in the part at all, which no wider
1587
+ * rewrite fixes.
1588
+ */
1589
+ const notePartXmlFor = ({ patch, originalXml, replacementXml, hasDirtyParagraph, elementName, partName }) => {
1590
+ const keepOriginal = () => {
1591
+ if (hasDirtyParagraph) throw new DocxPackageFidelityError(`Cannot serialize changed ${elementName} paragraphs into ${partName}`);
1592
+ return null;
1593
+ };
1594
+ switch (patch.type) {
1595
+ case "patched": return patch.xml === originalXml ? keepOriginal() : patch.xml;
1596
+ case "refused": switch (patch.reason) {
1597
+ case "comment-range-balance": return replacementXml;
1598
+ case "unroutable-paragraph": return keepOriginal();
1599
+ default: {
1600
+ const unreachable = patch.reason;
1601
+ return panic("Unhandled note-part patch refusal", { reason: unreachable });
1602
+ }
1603
+ }
1604
+ default: return panic("Unhandled note-part patch", { patch });
1605
+ }
1606
+ };
1484
1607
  async function patchNotePartIntoZip({ conventionalLowerPath, currentXml, replacementXml, baselineFrom, elementName, changedNoteParaIds, originalZip, newZip, compressionLevel }) {
1485
1608
  const file = findNotePartEntry(originalZip, conventionalLowerPath);
1486
1609
  if (!file) return;
1487
1610
  const originalXml = await file.async("text");
1488
1611
  const baselineXml = baselineFrom(originalXml);
1489
1612
  const effectiveChangedNoteParaIds = changedNoteParaIds ?? collectChangedNoteParaIds(baselineXml, currentXml);
1490
- const patched = buildPatchedNotePartXml({
1613
+ const currentParaIds = collectParaIds(currentXml);
1614
+ const patchedXml = notePartXmlFor({
1615
+ patch: buildPatchedNotePartXml({
1616
+ originalXml,
1617
+ baselineXml,
1618
+ serializedXml: currentXml,
1619
+ replacementXml,
1620
+ elementName,
1621
+ changedParaIds: effectiveChangedNoteParaIds
1622
+ }),
1491
1623
  originalXml,
1492
- baselineXml,
1493
- serializedXml: currentXml,
1494
1624
  replacementXml,
1625
+ hasDirtyParagraph: [...effectiveChangedNoteParaIds].some((paraId) => currentParaIds.has(paraId)),
1495
1626
  elementName,
1496
- changedParaIds: effectiveChangedNoteParaIds
1627
+ partName: file.name
1497
1628
  });
1498
- const currentParaIds = collectParaIds(currentXml);
1499
- const hasDirtyParagraph = [...effectiveChangedNoteParaIds].some((paraId) => currentParaIds.has(paraId));
1500
- if (patched === null || hasDirtyParagraph && patched === originalXml) {
1501
- if (hasDirtyParagraph) throw new DocxPackageFidelityError(`Cannot serialize changed ${elementName} paragraphs into ${file.name}`);
1502
- return;
1503
- }
1504
- if (patched === originalXml) return;
1505
- newZip.file(file.name, patched, {
1629
+ if (patchedXml === null || patchedXml === originalXml) return;
1630
+ newZip.file(file.name, patchedXml, {
1506
1631
  compression: "DEFLATE",
1507
1632
  compressionOptions: { level: compressionLevel }
1508
1633
  });
@@ -1741,8 +1866,8 @@ const overrideXml = (partName, contentType) => `<Override PartName="${partName}"
1741
1866
  const assertStyleNumberingReferences = (doc) => {
1742
1867
  const referenced = /* @__PURE__ */ new Set();
1743
1868
  for (const style of doc.package.styles?.styles ?? []) {
1744
- const numId = style.pPr?.numPr?.numId;
1745
- if (isNumberingReference(numId)) referenced.add(numId);
1869
+ const numId = paragraphNumberingReferenceId$1(style.pPr?.numPr);
1870
+ if (numId !== void 0) referenced.add(numId);
1746
1871
  }
1747
1872
  if (referenced.size === 0) return;
1748
1873
  const available = new Map(doc.package.numbering?.nums.map((numbering) => [numbering.numId, numbering]) ?? []);
@@ -1754,4 +1879,4 @@ const assertStyleNumberingReferences = (doc) => {
1754
1879
  }
1755
1880
  };
1756
1881
  //#endregion
1757
- export { COMMENTS_CONTENT_TYPE, COMMENTS_EXTENDED_CONTENT_TYPE, COMMENTS_EXTENDED_PART, COMMENTS_EXTENDED_PART_LOWER, DocxPackageFidelityError, addCommentsExtendedOverride, addCommentsExtendedRelationship, addMedia, addRelationship, applyUpdatesToZip, collectHeaderFooterUpdates, collectHyperlinksWithoutRId, createDocx, createEmptyDocx, findMaxRId, hasModelDrivenPictureWatermark, hasUnmaterializedHeaderFooter, hasUnmaterializedInlineResources, isDocxBuffer, notePartRelsPath, removeCommentsExtendedOverride, removeCommentsExtendedRelationship, repackDocx, repackDocxFromRaw, updateCoreProperties, updateDocumentXml, updateMultipleFiles, updateXmlFile, validateDocx, withoutAttachedTemplate };
1882
+ export { COMMENTS_CONTENT_TYPE, COMMENTS_EXTENDED_CONTENT_TYPE, COMMENTS_EXTENDED_PART, COMMENTS_EXTENDED_PART_LOWER, DocxDuplicateSectionCarrierError, DocxPackageFidelityError, addCommentsExtendedOverride, addCommentsExtendedRelationship, addMedia, addRelationship, applyUpdatesToZip, collectHeaderFooterUpdates, collectHyperlinksWithoutRId, createDocx, createEmptyDocx, findMaxRId, hasModelDrivenPictureWatermark, hasUnmaterializedHeaderFooter, hasUnmaterializedInlineResources, isDocxBuffer, notePartRelsPath, removeCommentsExtendedOverride, removeCommentsExtendedRelationship, repackDocx, repackDocxFromRaw, updateCoreProperties, updateDocumentXml, updateMultipleFiles, updateXmlFile, validateDocx, withoutAttachedTemplate };
@@ -1,12 +1,21 @@
1
1
  import { document_d_exports } from "../types/document.js";
2
2
  //#region src/docx/runConsolidator.d.ts
3
+ /**
4
+ * Every `TextFormatting` field, named so the comparison below is total.
5
+ *
6
+ * A field this comparison forgets is a field one of two merged runs loses,
7
+ * silently and at parse time. Naming them turns a field added to the model
8
+ * without a comparison into a compile error rather than a fidelity defect.
9
+ */
10
+ type ComparedTextFormattingField = "bold" | "boldCs" | "italic" | "italicCs" | "underline" | "strike" | "doubleStrike" | "vertAlign" | "smallCaps" | "allCaps" | "hidden" | "noProof" | "color" | "highlight" | "shading" | "fontSize" | "fontSizeCs" | "fontFamily" | "language" | "spacing" | "position" | "scale" | "kerning" | "effect" | "emphasisMark" | "emboss" | "imprint" | "outline" | "shadow" | "rtl" | "cs" | "styleId" | "preserved";
11
+ type ComparedTextFormatting = document_d_exports.ExhaustiveFields<document_d_exports.TextFormatting, ComparedTextFormattingField>;
3
12
  /**
4
13
  * Check if two TextFormatting objects are equivalent
5
14
  *
6
15
  * Uses deep comparison of all properties to determine if runs
7
16
  * can be merged without losing formatting information.
8
17
  */
9
- declare function formattingEquals(a: document_d_exports.TextFormatting | undefined, b: document_d_exports.TextFormatting | undefined): boolean;
18
+ declare function formattingEquals(a: ComparedTextFormatting | undefined, b: ComparedTextFormatting | undefined): boolean;
10
19
  /**
11
20
  * Check if a run contains only text content
12
21
  * (runs with special content like images, fields, etc. should not be merged)
@@ -17,6 +26,37 @@ declare function isTextOnlyRun(run: document_d_exports.Run): boolean;
17
26
  * Runs with breaks, tabs, images, fields, etc. act as merge boundaries
18
27
  */
19
28
  declare function canMergeRun(run: document_d_exports.Run): boolean;
29
+ /**
30
+ * Every `Run` field, named by what a merge does with it.
31
+ *
32
+ * The merged run is the survivor spread whole, so a field added to the model
33
+ * is carried over from one side by default. Naming each one here forces the
34
+ * next field to state whether that default is right before it can compile.
35
+ */
36
+ type MergeDecidedRunField =
37
+ /** Identical for every run. */
38
+ "type" |
39
+ /** Concatenated; see {@link mergeRunContent}. */
40
+ "content" |
41
+ /** Must be equal, and the survivor keeps it. */
42
+ "formatting" |
43
+ /** Must be equal, and the survivor keeps it. */
44
+ "preservedAttributes" |
45
+ /** Refuses the merge outright; see {@link canMergeRun}. */
46
+ "propertyChanges";
47
+ type MergeDecidedRun = document_d_exports.ExhaustiveFields<document_d_exports.Run, MergeDecidedRunField>;
48
+ /**
49
+ * May two adjacent runs become one?
50
+ *
51
+ * Every consolidation site asks this one question, because a merge that any
52
+ * one site decides differently is a merge the next parse undoes. A run holds
53
+ * three records a merged run can hold only one of: its typed formatting, the
54
+ * attributes `w:r` carried that the model has no field for, and the `w:rPr`
55
+ * children no reader took a value from. Merging two runs that disagree on any
56
+ * of them discards the loser's copy, which is how both runs' `w:rsid*` used to
57
+ * vanish at parse time — before the editor, before any gate could see it.
58
+ */
59
+ declare function runsMergeable(a: MergeDecidedRun, b: MergeDecidedRun): boolean;
20
60
  /**
21
61
  * Consolidate an array of runs by merging consecutive runs with identical formatting
22
62
  *
@@ -53,4 +93,4 @@ declare function getConsolidationStats(originalParagraphs: document_d_exports.Pa
53
93
  reductionPercentage: number;
54
94
  };
55
95
  //#endregion
56
- export { canMergeRun, consolidateParagraph, consolidateParagraphContent, consolidateRuns, countRuns, formattingEquals, getConsolidationStats, isTextOnlyRun };
96
+ export { canMergeRun, consolidateParagraph, consolidateParagraphContent, consolidateRuns, countRuns, formattingEquals, getConsolidationStats, isTextOnlyRun, runsMergeable };
@@ -1,4 +1,5 @@
1
1
  import { cloneParagraphWithPropertySource } from "./paragraphPropertySource.js";
2
+ import { runHoldsPayload } from "./runPayload.js";
2
3
  //#region src/docx/runConsolidator.ts
3
4
  /**
4
5
  * Check if two TextFormatting objects are equivalent
@@ -18,6 +19,7 @@ function formattingEquals(a, b) {
18
19
  if (a.smallCaps !== b.smallCaps) return false;
19
20
  if (a.allCaps !== b.allCaps) return false;
20
21
  if (a.hidden !== b.hidden) return false;
22
+ if (a.noProof !== b.noProof) return false;
21
23
  if (a.emboss !== b.emboss) return false;
22
24
  if (a.imprint !== b.imprint) return false;
23
25
  if (a.outline !== b.outline) return false;
@@ -40,8 +42,46 @@ function formattingEquals(a, b) {
40
42
  if (!shadingEquals(a.shading, b.shading)) return false;
41
43
  if (!fontFamilyEquals(a.fontFamily, b.fontFamily)) return false;
42
44
  if (!languageEquals(a.language, b.language)) return false;
45
+ if (!preservedMarkupEquals(a.preserved, b.preserved)) return false;
43
46
  return true;
44
47
  }
48
+ /**
49
+ * Compare two verbatim sinks position by position.
50
+ *
51
+ * The sink is ordered — by `index`, then by source order within an index — and
52
+ * the order is what puts the markup back between the same modelled siblings,
53
+ * so equality is by sequence, not by set.
54
+ */
55
+ function preservedMarkupEquals(a, b) {
56
+ const left = a?.children ?? [];
57
+ const right = b?.children ?? [];
58
+ if (left.length !== right.length) return false;
59
+ return left.every(({ index, xml }, position) => {
60
+ const other = right[position];
61
+ return other !== void 0 && other.index === index && other.xml === xml;
62
+ });
63
+ }
64
+ /**
65
+ * Compare two attribute remainders as sets.
66
+ *
67
+ * An element cannot carry one expanded name twice, so (namespace, name) orders
68
+ * a remainder totally and the sorted keys compare exactly. Order is a set
69
+ * comparison rather than a sequence one because attribute order in XML says
70
+ * nothing: two runs that spelled the same attributes in a different order
71
+ * carry the same remainder and may still become one run.
72
+ */
73
+ function preservedAttributesEqual(a, b) {
74
+ const left = canonicalRemainderKeys(a);
75
+ const right = canonicalRemainderKeys(b);
76
+ return left.length === right.length && left.every((key, index) => key === right[index]);
77
+ }
78
+ /** `\u0000` cannot appear in an XML name, namespace URI or attribute value. */
79
+ const REMAINDER_KEY_SEPARATOR = "\0";
80
+ const canonicalRemainderKeys = (attributes) => (attributes ?? []).map(({ namespace, name, value }) => [
81
+ namespace ?? "",
82
+ name,
83
+ value
84
+ ].join(REMAINDER_KEY_SEPARATOR)).sort();
45
85
  function languageEquals(a, b) {
46
86
  return a?.val === b?.val && a?.eastAsia === b?.eastAsia && a?.bidi === b?.bidi;
47
87
  }
@@ -100,10 +140,24 @@ function isMergeableContent(content) {
100
140
  */
101
141
  function canMergeRun(run) {
102
142
  if (run.propertyChanges && run.propertyChanges.length > 0) return false;
103
- if (run.content.length === 0) return true;
143
+ if (!runHoldsPayload(run)) return false;
104
144
  return run.content.every(isMergeableContent);
105
145
  }
106
146
  /**
147
+ * May two adjacent runs become one?
148
+ *
149
+ * Every consolidation site asks this one question, because a merge that any
150
+ * one site decides differently is a merge the next parse undoes. A run holds
151
+ * three records a merged run can hold only one of: its typed formatting, the
152
+ * attributes `w:r` carried that the model has no field for, and the `w:rPr`
153
+ * children no reader took a value from. Merging two runs that disagree on any
154
+ * of them discards the loser's copy, which is how both runs' `w:rsid*` used to
155
+ * vanish at parse time — before the editor, before any gate could see it.
156
+ */
157
+ function runsMergeable(a, b) {
158
+ return canMergeRun(a) && canMergeRun(b) && formattingEquals(a.formatting, b.formatting) && preservedAttributesEqual(a.preservedAttributes, b.preservedAttributes);
159
+ }
160
+ /**
107
161
  * Merge the content of two runs into a single content array
108
162
  */
109
163
  function mergeRunContent(content1, content2) {
@@ -131,11 +185,12 @@ function consolidateRuns(runs) {
131
185
  const result = [];
132
186
  let current = null;
133
187
  for (const run of runs) {
134
- if (run.content.length === 0) {
188
+ if (!runHoldsPayload(run)) {
135
189
  if (current !== null) {
136
190
  result.push(current);
137
191
  current = null;
138
192
  }
193
+ result.push(run);
139
194
  continue;
140
195
  }
141
196
  if (current === null) {
@@ -145,9 +200,8 @@ function consolidateRuns(runs) {
145
200
  };
146
201
  continue;
147
202
  }
148
- if (canMergeRun(current) && canMergeRun(run) && formattingEquals(current.formatting, run.formatting)) current = {
149
- type: "run",
150
- ...current.formatting !== void 0 ? { formatting: current.formatting } : {},
203
+ if (runsMergeable(current, run)) current = {
204
+ ...current,
151
205
  content: mergeRunContent(current.content, run.content)
152
206
  };
153
207
  else {
@@ -222,4 +276,4 @@ function getConsolidationStats(originalParagraphs, consolidatedParagraphs) {
222
276
  };
223
277
  }
224
278
  //#endregion
225
- export { canMergeRun, consolidateParagraph, consolidateParagraphContent, consolidateRuns, countRuns, formattingEquals, getConsolidationStats, isTextOnlyRun };
279
+ export { canMergeRun, consolidateParagraph, consolidateParagraphContent, consolidateRuns, countRuns, formattingEquals, getConsolidationStats, isTextOnlyRun, runsMergeable };
@@ -1,7 +1,33 @@
1
1
  import { document_d_exports } from "../types/document.js";
2
- import { StyleMap } from "./styleParser.js";
3
2
  import { XmlElement } from "./xmlParser.js";
3
+ import { StyleMap } from "./styleParser.js";
4
4
  //#region src/docx/runParser.d.ts
5
+ /**
6
+ * Which record beside this `w:rPr` reads children out of it.
7
+ *
8
+ * The four owners of a run property set share one handler map, because they
9
+ * share one content model: `CT_RPr` is `EG_RPrBase` plus `w:rPrChange`, and
10
+ * `CT_ParaRPr` opens that with `EG_ParaRPrTrackChanges`. They differ only in
11
+ * which children a *sibling* record has already claimed, and a child claimed
12
+ * twice is written twice. Naming the owner states that once, at the call site
13
+ * that knows it, instead of leaving it to whichever reader ran first.
14
+ */
15
+ declare const RUN_PROPERTY_OWNERS: {
16
+ /** A `w:r`'s own properties: `Run.propertyChanges` reads the `w:rPrChange`. */
17
+ readonly run: "run";
18
+ /**
19
+ * `w:pPr/w:rPr`. The paragraph's record reads the mark's revision
20
+ * (`ParagraphMarkChange`) and its `w:specVanish`
21
+ * (`ParagraphFormatting.runInWithNext`).
22
+ */
23
+ readonly paragraphMark: "paragraphMark";
24
+ /**
25
+ * A style, a numbering level, a comment's reference mark, the snapshot
26
+ * inside a `w:rPrChange`: nothing beside it reads any of its children.
27
+ */
28
+ readonly standalone: "standalone";
29
+ };
30
+ type RunPropertyOwner = (typeof RUN_PROPERTY_OWNERS)[keyof typeof RUN_PROPERTY_OWNERS];
5
31
  /**
6
32
  * `w:vertAlign` `baseline` is the reserved value that means "no vertical
7
33
  * offset", not a third offset beside `superscript` and `subscript`. It is
@@ -10,34 +36,44 @@ import { XmlElement } from "./xmlParser.js";
10
36
  */
11
37
  declare const isBaselineVertAlign: (vertAlign: document_d_exports.TextFormatting["vertAlign"]) => boolean;
12
38
  /**
13
- * Parse run formatting properties (w:rPr)
39
+ * The one reader of a run property set (`w:rPr`).
40
+ *
41
+ * Every owner reads through here — a run, the paragraph mark, a style, a
42
+ * numbering level, a comment's reference mark and the snapshot inside either
43
+ * kind of `w:rPrChange` — so none of them can grow its own idea of which
44
+ * children exist, which values it admits, or which of two statements of one
45
+ * property wins. The style parser used to keep a copy of this function, and
46
+ * the copies had drifted on all three.
47
+ *
48
+ * Every child the content model declares carries a decision: a handler that
49
+ * reads it into {@link TextFormatting}, `ownedElsewhere` when the owner's
50
+ * sibling record reads it, or `CAPTURE` for markup folio models nothing for.
51
+ * A handler that looked and took nothing answers `CAPTURE` as well — `<w:sz/>`
52
+ * states no size and `<w:highlight w:val="chartreuse"/>` states a value the
53
+ * reader's enumeration does not admit, and neither can be decided by the
54
+ * child's name. What no reader took goes to `TextFormatting.preserved` at its
55
+ * schema ordinal, so a rebuild puts it back between the same two siblings.
56
+ *
57
+ * A property stated twice resolves to the last statement; see
58
+ * {@link readLastOccurrenceOnly} for the evidence and for why the statements
59
+ * it beat are not kept.
14
60
  *
15
- * Handles ALL rPr properties:
16
- * - w:b (bold), w:i (italic), w:u (underline with style)
17
- * - w:strike (strikethrough), w:dstrike (double strike)
18
- * - w:vertAlign (superscript/subscript)
19
- * - w:smallCaps, w:caps (capitalization)
20
- * - w:highlight (text highlight color)
21
- * - w:shd (character shading)
22
- * - w:color (text color with theme resolution)
23
- * - w:sz (font size in half-points)
24
- * - w:rFonts (font family with theme resolution)
25
- * - w:spacing (character spacing)
26
- * - w:effect (text effects)
27
- * - And more...
61
+ * An element that states nothing at all still yields a record: `undefined` here
62
+ * means the owner carried no `w:rPr`, never that the one it carried was empty.
28
63
  */
29
- declare function parseRunProperties(rPr: XmlElement | null, theme: document_d_exports.Theme | null, _styles?: StyleMap): document_d_exports.TextFormatting | undefined;
64
+ declare function parseRunProperties(rPr: XmlElement | null, theme: document_d_exports.Theme | null, owner: RunPropertyOwner): document_d_exports.TextFormatting | undefined;
30
65
  /**
31
66
  * Parse a run element (w:r)
32
67
  *
33
68
  * @param node - The w:r XML element
34
- * @param styles - Style map for resolving style references
69
+ * @param _styles - Unread: a run's properties are parsed as the source wrote
70
+ * them, and style resolution happens above this parser
35
71
  * @param theme - Theme for resolving theme colors/fonts
36
72
  * @param rels - Relationship map for resolving image references
37
73
  * @param media - Media files map for image data
38
74
  * @returns Parsed Run object
39
75
  */
40
- declare function parseRun(node: XmlElement, styles: StyleMap | null, theme: document_d_exports.Theme | null, rels?: document_d_exports.RelationshipMap | null, media?: Map<string, document_d_exports.MediaFile> | null, rootXmlns?: Record<string, string>): document_d_exports.Run;
76
+ declare function parseRun(node: XmlElement, _styles: StyleMap | null, theme: document_d_exports.Theme | null, rels?: document_d_exports.RelationshipMap | null, media?: Map<string, document_d_exports.MediaFile> | null, rootXmlns?: Record<string, string>): document_d_exports.Run;
41
77
  /**
42
78
  * Get plain text from a run
43
79
  *
@@ -81,4 +117,4 @@ declare function hasFieldChar(run: document_d_exports.Run): boolean;
81
117
  */
82
118
  declare function getFieldCharType(run: document_d_exports.Run): "begin" | "separate" | "end" | null;
83
119
  //#endregion
84
- export { getFieldCharType, getImages, getRunText, hasContent, hasFieldChar, hasImage, isBaselineVertAlign, parseRun, parseRunProperties };
120
+ export { RUN_PROPERTY_OWNERS, RunPropertyOwner, getFieldCharType, getImages, getRunText, hasContent, hasFieldChar, hasImage, isBaselineVertAlign, parseRun, parseRunProperties };