@stll/folio-core 0.46.0 → 0.47.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (370) hide show
  1. package/dist/ai-edits/apply.d.ts +17 -1
  2. package/dist/ai-edits/apply.js +31 -27
  3. package/dist/ai-edits/headless.d.ts +9 -2
  4. package/dist/ai-edits/headless.js +5 -3
  5. package/dist/ai-edits/read.d.ts +1 -0
  6. package/dist/ai-edits/read.js +1 -0
  7. package/dist/ai-edits/snapshot.js +32 -27
  8. package/dist/ai-edits/table-cell-mutations.js +15 -7
  9. package/dist/ai-edits/table-geometry.js +21 -18
  10. package/dist/ai-edits/table-template.js +2 -2
  11. package/dist/compare/compare.js +2 -1
  12. package/dist/compare/content-alignment.js +192 -46
  13. package/dist/compare/content-types.d.ts +8 -2
  14. package/dist/compare/content.js +2 -11
  15. package/dist/compare/plan.js +7 -4
  16. package/dist/compare/section-boundary-properties.js +1 -2
  17. package/dist/content-controls/checkboxDisplay.d.ts +8 -2
  18. package/dist/content-controls/checkboxDisplay.js +11 -5
  19. package/dist/content-controls/mutateContentControls.js +41 -42
  20. package/dist/controller/layoutPipeline.js +8 -3
  21. package/dist/display-list/build/buildDisplayList.js +7 -7
  22. package/dist/display-list/build/imagePrimitives.d.ts +4 -4
  23. package/dist/display-list/build/imagePrimitives.js +38 -20
  24. package/dist/display-list/build/pageBorderPrimitives.js +2 -1
  25. package/dist/display-list/build/paragraphPrimitives.js +93 -13
  26. package/dist/display-list/build/previewPrimitives.d.ts +10 -0
  27. package/dist/display-list/build/previewPrimitives.js +89 -0
  28. package/dist/display-list/build/strokes.d.ts +177 -8
  29. package/dist/display-list/build/strokes.js +167 -47
  30. package/dist/display-list/build/tablePrimitives.js +4 -2
  31. package/dist/display-list/build/textBoxPrimitives.js +6 -4
  32. package/dist/display-list/build/textDecorations.d.ts +15 -1
  33. package/dist/display-list/build/textDecorations.js +15 -1
  34. package/dist/display-list/dom/renderDisplayListToDom.js +1 -19
  35. package/dist/display-list/primitives.d.ts +13 -2
  36. package/dist/display-list/primitives.js +36 -1
  37. package/dist/document-operations.d.ts +9 -2
  38. package/dist/document-operations.js +5 -3
  39. package/dist/docx/attributeRemainder.d.ts +34 -1
  40. package/dist/docx/attributeRemainder.js +49 -3
  41. package/dist/docx/blockContentParser.d.ts +2 -0
  42. package/dist/docx/blockContentParser.js +39 -67
  43. package/dist/docx/blockPlainText.js +3 -1
  44. package/dist/docx/borderParser.js +26 -11
  45. package/dist/docx/builtInStyles.d.ts +8 -16
  46. package/dist/docx/builtInStyles.js +54 -17
  47. package/dist/docx/commentAnchorIndex.js +1 -1
  48. package/dist/docx/commentParser.js +3 -3
  49. package/dist/docx/commentRangeIntegrity.js +1 -1
  50. package/dist/docx/commentRangeJoin.js +1 -1
  51. package/dist/docx/commentReferenceNormalization.js +3 -2
  52. package/dist/docx/commentReplyMarkers.js +1 -1
  53. package/dist/docx/compatibility.js +56 -42
  54. package/dist/docx/containerChildren.d.ts +110 -13
  55. package/dist/docx/containerChildren.gen.d.ts +16 -1
  56. package/dist/docx/containerChildren.gen.js +18 -1
  57. package/dist/docx/containerChildren.js +63 -13
  58. package/dist/docx/diagramPreview.d.ts +14 -2
  59. package/dist/docx/diagramPreview.js +81 -169
  60. package/dist/docx/documentParser.js +4 -1
  61. package/dist/docx/drawingAnchor.d.ts +87 -0
  62. package/dist/docx/drawingAnchor.js +201 -0
  63. package/dist/docx/drawingUtils.d.ts +43 -38
  64. package/dist/docx/drawingUtils.js +205 -118
  65. package/dist/docx/fontTableParser.js +102 -41
  66. package/dist/docx/footnoteParser.js +10 -6
  67. package/dist/docx/groupDrawingParser.js +4 -3
  68. package/dist/docx/headerFooterReferenceNormalization.js +1 -1
  69. package/dist/docx/hyperlinkParser.d.ts +45 -7
  70. package/dist/docx/hyperlinkParser.js +126 -57
  71. package/dist/docx/imageParser.js +127 -107
  72. package/dist/docx/index.d.ts +2 -1
  73. package/dist/docx/index.js +2 -1
  74. package/dist/docx/inlineContentRemovals.d.ts +28 -0
  75. package/dist/docx/inlineContentRemovals.js +46 -0
  76. package/dist/docx/inlineWrapperContent.d.ts +84 -3
  77. package/dist/docx/inlineWrapperContent.js +85 -4
  78. package/dist/docx/inlineWrapperParser.d.ts +11 -0
  79. package/dist/docx/inlineWrapperParser.js +60 -0
  80. package/dist/docx/nonVisualDrawingProps.d.ts +5 -13
  81. package/dist/docx/normalizeBaseDirection.js +4 -2
  82. package/dist/docx/numberingParser.d.ts +25 -2
  83. package/dist/docx/numberingParser.js +264 -361
  84. package/dist/docx/numberingReference.d.ts +9 -16
  85. package/dist/docx/numberingReference.js +17 -16
  86. package/dist/docx/numberingReferenceNormalization.js +7 -7
  87. package/dist/docx/ooxmlCounterFormatter.d.ts +1 -1
  88. package/dist/docx/ooxmlCounterFormatter.js +4 -1
  89. package/dist/docx/paraIdAttribute.d.ts +91 -1
  90. package/dist/docx/paraIdAttribute.js +79 -1
  91. package/dist/docx/paragraphParser.d.ts +9 -24
  92. package/dist/docx/paragraphParser.js +212 -396
  93. package/dist/docx/paragraphProperties.d.ts +23 -0
  94. package/dist/docx/paragraphProperties.js +279 -0
  95. package/dist/docx/paragraphPropertySource.js +2 -0
  96. package/dist/docx/paragraphTextBoxEnrichment.d.ts +2 -1
  97. package/dist/docx/paragraphTextBoxEnrichment.js +14 -7
  98. package/dist/docx/paragraphTraversal.d.ts +14 -10
  99. package/dist/docx/paragraphTraversal.js +47 -49
  100. package/dist/docx/parseWarningMessage.js +3 -0
  101. package/dist/docx/parserEnums.d.ts +6 -8
  102. package/dist/docx/parserEnums.js +4 -6
  103. package/dist/docx/preservedRunContent.js +16 -6
  104. package/dist/docx/previewBudget.d.ts +44 -23
  105. package/dist/docx/previewBudget.js +61 -30
  106. package/dist/docx/propertyElementAttributes.d.ts +178 -0
  107. package/dist/docx/propertyElementAttributes.js +114 -0
  108. package/dist/docx/renderedPageBreakNormalization.js +2 -2
  109. package/dist/docx/rezip.d.ts +28 -2
  110. package/dist/docx/rezip.js +78 -9
  111. package/dist/docx/runConsolidator.d.ts +42 -2
  112. package/dist/docx/runConsolidator.js +60 -6
  113. package/dist/docx/runParser.d.ts +54 -18
  114. package/dist/docx/runParser.js +379 -295
  115. package/dist/docx/runPayload.d.ts +5 -0
  116. package/dist/docx/runPayload.js +4 -0
  117. package/dist/docx/sdtProperties.d.ts +39 -5
  118. package/dist/docx/sdtProperties.js +205 -84
  119. package/dist/docx/sdtPropertiesPatch.d.ts +5 -9
  120. package/dist/docx/sdtPropertiesPatch.js +68 -112
  121. package/dist/docx/sectionParser.d.ts +1 -2
  122. package/dist/docx/sectionParser.js +236 -240
  123. package/dist/docx/selectiveSave.js +3 -2
  124. package/dist/docx/selectiveXmlPatch.d.ts +21 -2
  125. package/dist/docx/selectiveXmlPatch.js +195 -99
  126. package/dist/docx/serializer/blockSdtSerializer.js +2 -96
  127. package/dist/docx/serializer/borderSerializer.d.ts +5 -5
  128. package/dist/docx/serializer/borderSerializer.js +10 -8
  129. package/dist/docx/serializer/documentSerializer.js +3 -0
  130. package/dist/docx/serializer/fontTableSerializer.js +31 -3
  131. package/dist/docx/serializer/headerFooterSerializer.js +3 -0
  132. package/dist/docx/serializer/markupRangeAttributes.d.ts +9 -1
  133. package/dist/docx/serializer/markupRangeAttributes.js +9 -1
  134. package/dist/docx/serializer/noteSerializer.js +3 -0
  135. package/dist/docx/serializer/numberingSerializer.d.ts +1 -6
  136. package/dist/docx/serializer/numberingSerializer.js +81 -79
  137. package/dist/docx/serializer/paragraphSerializer.d.ts +1 -9
  138. package/dist/docx/serializer/paragraphSerializer.js +88 -188
  139. package/dist/docx/serializer/runSerializer.d.ts +1 -5
  140. package/dist/docx/serializer/runSerializer.js +109 -59
  141. package/dist/docx/serializer/sdtPropertiesSerializer.d.ts +26 -0
  142. package/dist/docx/serializer/sdtPropertiesSerializer.js +111 -0
  143. package/dist/docx/serializer/sectionPropertiesSerializer.js +34 -45
  144. package/dist/docx/serializer/settingsSerializer.js +6 -4
  145. package/dist/docx/serializer/stylesSerializer.js +8 -11
  146. package/dist/docx/serializer/tableSerializer.js +268 -100
  147. package/dist/docx/serializer/textFormattingSerializer.d.ts +28 -4
  148. package/dist/docx/serializer/textFormattingSerializer.js +111 -101
  149. package/dist/docx/serializer/xmlUtils.d.ts +1 -1
  150. package/dist/docx/serializer/xmlUtils.js +1 -1
  151. package/dist/docx/server/createBilingualDocument.js +18 -16
  152. package/dist/docx/server/migrateYjsAttrSchema.js +3 -3
  153. package/dist/docx/settingsParser.js +7 -4
  154. package/dist/docx/shadingParser.d.ts +2 -1
  155. package/dist/docx/shadingParser.js +43 -7
  156. package/dist/docx/shapeParser.js +8 -3
  157. package/dist/docx/strictNames.d.ts +11 -0
  158. package/dist/docx/strictNames.gen.d.ts +45 -0
  159. package/dist/docx/strictNames.gen.js +50 -0
  160. package/dist/docx/strictNames.js +43 -0
  161. package/dist/docx/strictValueEncodings.gen.js +133 -131
  162. package/dist/docx/styleParser.js +17 -349
  163. package/dist/docx/tableParser.d.ts +10 -1
  164. package/dist/docx/tableParser.js +505 -181
  165. package/dist/docx/textBoxParser.d.ts +3 -1
  166. package/dist/docx/textBoxParser.js +18 -8
  167. package/dist/docx/themeColorAttribute.d.ts +13 -0
  168. package/dist/docx/themeColorAttribute.js +24 -0
  169. package/dist/docx/trackedMoveRangeNormalization.js +2 -1
  170. package/dist/docx/vmlImageParser.d.ts +13 -4
  171. package/dist/docx/vmlImageParser.js +74 -31
  172. package/dist/docx/vmlPreview.js +2 -2
  173. package/dist/docx/wrapPolygon.d.ts +30 -0
  174. package/dist/docx/wrapPolygon.js +70 -0
  175. package/dist/docx/xmlParser.d.ts +14 -1
  176. package/dist/docx/xmlParser.js +18 -2
  177. package/dist/fonts/embeddedFonts.js +3 -3
  178. package/dist/headless-layout.js +2 -0
  179. package/dist/i18n/messages/catalogs.gen.d.ts +68 -0
  180. package/dist/i18n/messages/catalogs.gen.js +102 -34
  181. package/dist/i18n/messages/messages.gen.d.ts +4 -0
  182. package/dist/internal/headlessRevisionResolution.js +9 -0
  183. package/dist/internal/pageBreakRunSourceDescendantIndex.js +3 -1
  184. package/dist/internal/paragraphFormattingSerialization.d.ts +20 -9
  185. package/dist/internal/paragraphFormattingSerialization.js +118 -83
  186. package/dist/layout-bridge/convert/footnoteLayout.d.ts +1 -0
  187. package/dist/layout-bridge/convert/footnoteLayout.js +1 -0
  188. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -0
  189. package/dist/layout-bridge/convert/headerFooterLayout.js +2 -0
  190. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +17 -12
  191. package/dist/layout-bridge/convert/toFlowBlocks.js +177 -101
  192. package/dist/layout-engine/index.d.ts +2 -2
  193. package/dist/layout-engine/index.js +53 -17
  194. package/dist/layout-engine/measure/measureBlocks.d.ts +3 -0
  195. package/dist/layout-engine/measure/measureBlocks.js +6 -10
  196. package/dist/layout-engine/measure/tableCellGrid.js +2 -1
  197. package/dist/layout-engine/measure/tableFragmentBorderGeometry.js +2 -1
  198. package/dist/layout-engine/measure/tableInlinePlacement.js +2 -5
  199. package/dist/layout-engine/paragraphSequence.js +3 -2
  200. package/dist/layout-engine/renderedBreakReconciliation.js +2 -1
  201. package/dist/layout-engine/section-breaks.d.ts +49 -2
  202. package/dist/layout-engine/section-breaks.js +55 -4
  203. package/dist/layout-engine/types.d.ts +47 -17
  204. package/dist/layout-engine/types.js +16 -1
  205. package/dist/layout-painter/borderStroke.d.ts +18 -4
  206. package/dist/layout-painter/renderPage.js +6 -4
  207. package/dist/layout-painter/renderParagraph.d.ts +2 -1
  208. package/dist/layout-painter/renderParagraph.js +13 -26
  209. package/dist/layout-painter/renderTable.d.ts +4 -1
  210. package/dist/layout-painter/renderTable.js +22 -22
  211. package/dist/layout-painter/renderTextBox.js +5 -3
  212. package/dist/markdown/renderBlock.js +3 -1
  213. package/dist/markdown/renderRuns.js +7 -2
  214. package/dist/markdown/renderTable.js +2 -1
  215. package/dist/model.d.ts +3 -3
  216. package/dist/model.js +2 -2
  217. package/dist/paged-layout/sectionBlockWidths.d.ts +3 -0
  218. package/dist/paged-layout/sectionBlockWidths.js +26 -4
  219. package/dist/prosemirror/attrs/index.d.ts +22 -4
  220. package/dist/prosemirror/attrs/index.js +498 -60
  221. package/dist/prosemirror/bookmarkBoundaryAttrs.d.ts +9 -1
  222. package/dist/prosemirror/bookmarkBoundaryAttrs.js +22 -3
  223. package/dist/prosemirror/commands/comments.js +68 -53
  224. package/dist/prosemirror/commands/contentControls.js +24 -19
  225. package/dist/prosemirror/commands/image.d.ts +1 -1
  226. package/dist/prosemirror/commands/image.js +4 -1
  227. package/dist/prosemirror/commands/paragraph.d.ts +2 -1
  228. package/dist/prosemirror/commands/propertyChangeScope.d.ts +12 -4
  229. package/dist/prosemirror/commands/propertyChangeScope.js +22 -4
  230. package/dist/prosemirror/commands/sectionBreak.d.ts +33 -1
  231. package/dist/prosemirror/commands/sectionBreak.js +187 -11
  232. package/dist/prosemirror/conversion/fromProseDoc.d.ts +18 -2
  233. package/dist/prosemirror/conversion/fromProseDoc.js +330 -183
  234. package/dist/prosemirror/conversion/index.d.ts +2 -2
  235. package/dist/prosemirror/conversion/preservedSinkCarriers.d.ts +39 -0
  236. package/dist/prosemirror/conversion/preservedSinkCarriers.js +19 -0
  237. package/dist/prosemirror/conversion/runShadingMark.js +14 -1
  238. package/dist/prosemirror/conversion/sdtAttrs.d.ts +10 -1
  239. package/dist/prosemirror/conversion/sdtAttrs.js +19 -5
  240. package/dist/prosemirror/conversion/toProseDoc.js +371 -141
  241. package/dist/prosemirror/emptyRangeAnchor.d.ts +53 -0
  242. package/dist/prosemirror/emptyRangeAnchor.js +158 -0
  243. package/dist/prosemirror/extensions/StarterKit.js +8 -2
  244. package/dist/prosemirror/extensions/core/DocExtension.js +1 -1
  245. package/dist/prosemirror/extensions/core/ParagraphExtension.js +19 -15
  246. package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +3 -2
  247. package/dist/prosemirror/extensions/features/ListExtension.js +43 -24
  248. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +4 -3
  249. package/dist/prosemirror/extensions/features/PasteCleanupExtension.d.ts +3 -3
  250. package/dist/prosemirror/extensions/features/PasteCleanupExtension.js +5 -5
  251. package/dist/prosemirror/extensions/features/pasteCleanup.d.ts +3 -1
  252. package/dist/prosemirror/extensions/features/pasteCleanup.js +56 -2
  253. package/dist/prosemirror/extensions/features/pastedHeadingStyles.js +5 -4
  254. package/dist/prosemirror/extensions/markRegistry.d.ts +26 -2
  255. package/dist/prosemirror/extensions/markRegistry.js +73 -10
  256. package/dist/prosemirror/extensions/marks/InlineWrapperExtension.js +17 -3
  257. package/dist/prosemirror/extensions/marks/RunIdentityExtension.d.ts +26 -0
  258. package/dist/prosemirror/extensions/marks/RunIdentityExtension.js +134 -0
  259. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +2 -1
  260. package/dist/prosemirror/extensions/marks/UnderlineExtension.js +12 -18
  261. package/dist/prosemirror/extensions/marks/markUtils.js +2 -1
  262. package/dist/prosemirror/extensions/nodes/BlockBookmarkBoundaryExtension.d.ts +29 -0
  263. package/dist/prosemirror/extensions/nodes/BlockBookmarkBoundaryExtension.js +46 -0
  264. package/dist/prosemirror/extensions/nodes/BlockSdtExtension.d.ts +4 -3
  265. package/dist/prosemirror/extensions/nodes/BlockSdtExtension.js +18 -13
  266. package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.js +28 -53
  267. package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +10 -0
  268. package/dist/prosemirror/extensions/nodes/ImageExtension.js +8 -1
  269. package/dist/prosemirror/extensions/nodes/MoveRangeBoundaryExtension.d.ts +11 -0
  270. package/dist/prosemirror/extensions/nodes/MoveRangeBoundaryExtension.js +43 -0
  271. package/dist/prosemirror/extensions/nodes/RangeAnchorExtension.d.ts +13 -0
  272. package/dist/prosemirror/extensions/nodes/RangeAnchorExtension.js +65 -0
  273. package/dist/prosemirror/extensions/nodes/SdtExtension.d.ts +3 -1
  274. package/dist/prosemirror/extensions/nodes/SdtExtension.js +22 -16
  275. package/dist/prosemirror/extensions/nodes/ShapeExtension.js +4 -0
  276. package/dist/prosemirror/extensions/nodes/TableExtension.js +141 -123
  277. package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +4 -0
  278. package/dist/prosemirror/extensions/nodes/bookmarkBoundaryDom.d.ts +23 -0
  279. package/dist/prosemirror/extensions/nodes/bookmarkBoundaryDom.js +57 -0
  280. package/dist/prosemirror/extensions/types.d.ts +12 -3
  281. package/dist/prosemirror/index.d.ts +4 -2
  282. package/dist/prosemirror/index.js +2 -1
  283. package/dist/prosemirror/inlineWrapperStack.js +20 -3
  284. package/dist/prosemirror/listMarker.d.ts +2 -2
  285. package/dist/prosemirror/listMarker.js +7 -8
  286. package/dist/prosemirror/listRenderingAttrs.js +11 -1
  287. package/dist/prosemirror/listState.d.ts +62 -0
  288. package/dist/prosemirror/listState.js +49 -0
  289. package/dist/prosemirror/moveRangeBoundaryAttrs.d.ts +13 -0
  290. package/dist/prosemirror/moveRangeBoundaryAttrs.js +114 -0
  291. package/dist/prosemirror/numberedRefFields.js +4 -4
  292. package/dist/prosemirror/numberingAttr.d.ts +55 -0
  293. package/dist/prosemirror/numberingAttr.js +74 -0
  294. package/dist/prosemirror/outlineLevelAttr.d.ts +29 -0
  295. package/dist/prosemirror/outlineLevelAttr.js +42 -0
  296. package/dist/prosemirror/paragraphFormattingProvenance.d.ts +9 -0
  297. package/dist/prosemirror/paragraphFormattingProvenance.js +4 -1
  298. package/dist/prosemirror/plugins/selectionTracker.d.ts +3 -6
  299. package/dist/prosemirror/plugins/selectionTracker.js +3 -10
  300. package/dist/prosemirror/rangeAnchorAttrs.d.ts +14 -0
  301. package/dist/prosemirror/rangeAnchorAttrs.js +101 -0
  302. package/dist/prosemirror/replacedAnnotations.d.ts +1 -1
  303. package/dist/prosemirror/replacedAnnotations.js +24 -6
  304. package/dist/prosemirror/revisionCarriers.d.ts +86 -2
  305. package/dist/prosemirror/revisionCarriers.js +86 -60
  306. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +2 -0
  307. package/dist/prosemirror/runFormattingInlineCarriers.js +2 -0
  308. package/dist/prosemirror/runIdentity.d.ts +28 -0
  309. package/dist/prosemirror/runIdentity.js +36 -0
  310. package/dist/prosemirror/runStyleFormatting.js +1 -1
  311. package/dist/prosemirror/schema/index.d.ts +2 -2
  312. package/dist/prosemirror/schema/marks.d.ts +23 -4
  313. package/dist/prosemirror/schema/nodes.d.ts +220 -24
  314. package/dist/prosemirror/sectionCarrier.d.ts +37 -0
  315. package/dist/prosemirror/sectionCarrier.js +40 -0
  316. package/dist/prosemirror/selectionState.d.ts +3 -0
  317. package/dist/prosemirror/selectionState.js +4 -1
  318. package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +5 -4
  319. package/dist/prosemirror/styles/resolvedStyleAttrs.js +15 -13
  320. package/dist/prosemirror/tableResize.js +5 -6
  321. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +2 -0
  322. package/dist/prosemirror/trackedRunInlineAtoms.js +2 -0
  323. package/dist/prosemirror/utils/extractTrackedChanges.d.ts +10 -11
  324. package/dist/prosemirror/utils/extractTrackedChanges.js +109 -92
  325. package/dist/prosemirror/validation.js +17 -6
  326. package/dist/prosemirror/yjsDocumentMetadata.d.ts +2 -2
  327. package/dist/prosemirror/yjsDocumentMetadata.js +428 -7
  328. package/dist/prosemirror/zeroWidthAnchors.js +4 -0
  329. package/dist/style-sets/extract.js +4 -4
  330. package/dist/style-sets/stellaStyle.js +36 -23
  331. package/dist/types/colors.d.ts +2 -2
  332. package/dist/types/content.d.ts +2 -2
  333. package/dist/types/documentEnumValues.d.ts +53 -26
  334. package/dist/types/documentEnumValues.js +72 -174
  335. package/dist/types/formatting.d.ts +2 -2
  336. package/dist/types/index.d.ts +9 -2
  337. package/dist/utils/borderCss.d.ts +246 -0
  338. package/dist/utils/borderCss.js +325 -0
  339. package/dist/utils/colorResolver.d.ts +4 -3
  340. package/dist/utils/colorResolver.js +45 -76
  341. package/dist/utils/createDocument.js +24 -6
  342. package/dist/utils/findReplace.js +52 -10
  343. package/dist/utils/formatToStyle.d.ts +84 -2
  344. package/dist/utils/formatToStyle.js +133 -52
  345. package/dist/utils/headingCollector.js +3 -2
  346. package/dist/utils/mergeDocumentContent.js +5 -3
  347. package/dist/utils/paragraphFormattingMerge.js +27 -6
  348. package/dist/utils/replaceText.js +1 -1
  349. package/dist/utils/tableOperations.d.ts +5 -3
  350. package/dist/utils/tableOperations.js +14 -1
  351. package/dist/utils/tablePlacement.d.ts +7 -0
  352. package/dist/utils/tablePlacement.js +14 -0
  353. package/dist/utils/textDirectionFlow.d.ts +15 -0
  354. package/dist/utils/textDirectionFlow.js +38 -0
  355. package/dist/utils/textFormattingMerge.js +16 -4
  356. package/package.json +10 -10
  357. package/dist/ai-edits/__fixtures__/paragraphs.d.ts +0 -17
  358. package/dist/ai-edits/__fixtures__/paragraphs.js +0 -33
  359. package/dist/compare/__fixtures__/body-sequence.d.ts +0 -119
  360. package/dist/compare/__fixtures__/body-sequence.js +0 -225
  361. package/dist/compare/__fixtures__/nested-table.d.ts +0 -16
  362. package/dist/compare/__fixtures__/nested-table.js +0 -50
  363. package/dist/compare/__fixtures__/numbered-list.d.ts +0 -34
  364. package/dist/compare/__fixtures__/numbered-list.js +0 -85
  365. package/dist/docx/bookmarkPlacement.d.ts +0 -9
  366. package/dist/docx/bookmarkPlacement.js +0 -52
  367. package/dist/fonts/embeddedFontTable.d.ts +0 -45
  368. package/dist/fonts/embeddedFontTable.js +0 -80
  369. package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.d.ts +0 -13
  370. package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.js +0 -39
@@ -1,13 +1,16 @@
1
1
  import { rangedCommentIds } from "../../docx/commentAnchorIndex.js";
2
2
  import { resolveColorValueToHex } from "../../docx/drawingUtils.js";
3
3
  import { isInlineSdtContent, isTrackedChangeWrapperChild } from "../../docx/inlineWrapperContent.js";
4
- import { isNumberingReference } from "../../docx/numberingReference.js";
4
+ import { mergeParagraphNumbering as mergeParagraphNumbering$1, paragraphNumberingReferenceId as paragraphNumberingReferenceId$1 } from "../../docx/numberingReference.js";
5
5
  import { PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, createProseParagraphWithPropertySource, getDocumentParagraphPropertySourceContract, recreateProseNodeWithParagraphPropertySource, transportTableCellsWithParagraphPropertySources } from "../../docx/paragraphPropertySource.js";
6
6
  import { isBaselineVertAlign } from "../../docx/runParser.js";
7
7
  import { resolveTableLook } from "../../docx/tableLook.js";
8
8
  import { isCellMergeContinuation } from "../../docx/tableParser.js";
9
+ import { copiedWrapPolygon } from "../../docx/wrapPolygon.js";
9
10
  import { buildPageBreakRunSourceDescendantIndex } from "../../internal/pageBreakRunSourceDescendantIndex.js";
10
11
  import { createStyleEngine } from "../../style-engine/styleEngine.js";
12
+ import { outlineAttrForDash } from "../../types/documentEnumValues.js";
13
+ import { cssBorderStyleForDash } from "../../utils/borderCss.js";
11
14
  import { normalizeHorizontalScalePercent } from "../../utils/horizontalScale.js";
12
15
  import { mergeParagraphFormatting, mergeParagraphTabStops } from "../../utils/paragraphFormattingMerge.js";
13
16
  import { tableOfContentsStyleLevel } from "../../utils/tableOfContentsStyle.js";
@@ -16,14 +19,21 @@ import { emuToPixels, emuToStrokePixels } from "../../utils/units.js";
16
19
  import { expectInlineWrapperMarkAttrs } from "../attrs/index.js";
17
20
  import { authoredTransformAttrs } from "../authoredTransformAttrs.js";
18
21
  import { setAutospacingBaseValue } from "../autospacingBase.js";
22
+ import { planEmptyRanges } from "../emptyRangeAnchor.js";
23
+ import { INLINE_WRAPPER_MARK_NAME } from "../extensions/marks/InlineWrapperExtension.js";
19
24
  import { textFormattingToMarks } from "../extensions/marks/markUtils.js";
25
+ import { MOVE_RANGE_BOUNDARY_NODE_NAME } from "../extensions/nodes/MoveRangeBoundaryExtension.js";
26
+ import { RANGE_ANCHOR_NODE_NAME } from "../extensions/nodes/RangeAnchorExtension.js";
27
+ import "../extensions/nodes/SdtExtension.js";
20
28
  import { inlineWrapperLayer } from "../inlineWrapperStack.js";
21
29
  import { listRenderingAttrPatch } from "../listRenderingAttrs.js";
22
30
  import { stampNumberedRefFieldBaselines } from "../numberedRefFields.js";
31
+ import { paragraphNumberingAttr } from "../numberingAttr.js";
23
32
  import { pageBreakRunParagraphProjectionDispositionForFeatures } from "../pageBreakRunProjection.js";
24
33
  import { directionFromBidi } from "../paragraphDirection.js";
25
34
  import { styleResolvedParagraphFormatting } from "../paragraphFormattingProvenance.js";
26
35
  import { lineSpacingProvenanceFromSpacing } from "../paragraphSpacing.js";
36
+ import { RUN_IDENTITY_MARK_NAME, hasRunIdentityPayload, runIdentityAttrs } from "../runIdentity.js";
27
37
  import { getParagraphMarkSuppressionOverrides, hasDirectRunFormatting, resolveParagraphBodyRunFormatting, stripParagraphMarkFormattingForBodyRuns, stripParagraphMarkOnlyFormatting, suppressParagraphMarkFormatting } from "../runStyleFormatting.js";
28
38
  import { schema } from "../schema/index.js";
29
39
  import { PRESERVED_XML_LEVELS } from "../schema/nodes.js";
@@ -31,6 +41,7 @@ import { cascadeStyleTextFormatting } from "../styles/styleToggleCascade.js";
31
41
  import { canCarryTrackedRunMark, trackedRunInlineAtomDisposition } from "../trackedRunInlineAtoms.js";
32
42
  import { assertValidProseMirrorDocument } from "../validation.js";
33
43
  import { resolveEffectiveTableCellFormatting } from "./effectiveTableCellFormatting.js";
44
+ import { hasSinkChildren } from "./preservedSinkCarriers.js";
34
45
  import { sdtAttrsFromProperties } from "./sdtAttrs.js";
35
46
  import { panic } from "better-result";
36
47
  import { DRAWING_RAW_XML_MODES, PARSE_WARNING_CODES } from "@stll/docx-core/model";
@@ -58,6 +69,26 @@ const createTextBoxGroupIdFactory = () => {
58
69
  let index = 0;
59
70
  return () => `${salt}:${index++}`;
60
71
  };
72
+ /**
73
+ * The identity mark for one authored `w:r`, or `null` when it carries nothing
74
+ * worth a mark.
75
+ *
76
+ * The only place the mark is minted. Both run-converting paths call it — the
77
+ * paragraph's and the hyperlink's — so the next payload field is added once
78
+ * rather than to whichever site the author happened to open.
79
+ *
80
+ * Minted when the run holds a page break (the leaves it is cut into have to be
81
+ * rejoined into one `w:r` on save), an attribute remainder, or a `w:rPr` sink.
82
+ * 57.5% of corpus files hold none of the three and mint nothing.
83
+ */
84
+ const runIdentityMark = (run, nextRunIdentityId) => {
85
+ const payload = {
86
+ preservedAttributes: run.preservedAttributes,
87
+ preserved: run.formatting?.preserved
88
+ };
89
+ if (!runHasPageBreakContent(run) && !hasRunIdentityPayload(payload)) return null;
90
+ return schema.mark(RUN_IDENTITY_MARK_NAME, runIdentityAttrs(nextRunIdentityId(), payload));
91
+ };
61
92
  /** Keep imported hyperlink identity unique across every nested conversion scope. */
62
93
  const createHyperlinkInstanceIndexAllocator = () => {
63
94
  let index = 0;
@@ -101,6 +132,9 @@ const collectPairedBookmarkIds = (blocks) => {
101
132
  visitRun(child);
102
133
  break;
103
134
  case "preservedInline": break;
135
+ case "inlineWrapper":
136
+ for (const wrapped of child.content) visitParagraphContent(wrapped);
137
+ break;
104
138
  default: panic(`Unsupported hyperlink child: ${JSON.stringify(child)}`);
105
139
  }
106
140
  };
@@ -119,8 +153,7 @@ const collectPairedBookmarkIds = (blocks) => {
119
153
  visitHyperlink(content);
120
154
  return;
121
155
  case "simpleField":
122
- for (const child of content.content) if (child.type === "hyperlink") visitHyperlink(child);
123
- else if (child.type === "run") visitRun(child);
156
+ for (const child of content.content) visitParagraphContent(child);
124
157
  return;
125
158
  case "complexField":
126
159
  for (const run of [...content.fieldCode ?? [], ...content.fieldResult]) visitRun(run);
@@ -151,12 +184,22 @@ const collectPairedBookmarkIds = (blocks) => {
151
184
  for (const content of block.content) visitParagraphContent(content);
152
185
  break;
153
186
  case "table":
154
- for (const row of block.rows) for (const cell of row.cells) visitBlocks(cell.content);
187
+ for (const { marker } of block.bookmarks ?? []) countBoundary(marker.id, marker.type === "bookmarkStart" ? "start" : "end");
188
+ for (const row of block.rows) {
189
+ for (const { marker } of row.bookmarks ?? []) countBoundary(marker.id, marker.type === "bookmarkStart" ? "start" : "end");
190
+ for (const cell of row.cells) visitBlocks(cell.content);
191
+ }
155
192
  break;
156
193
  case "blockSdt":
157
194
  visitBlocks(block.content);
158
195
  break;
159
196
  case "preservedBlock": break;
197
+ case "bookmarkStart":
198
+ countBoundary(block.id, "start");
199
+ break;
200
+ case "bookmarkEnd":
201
+ countBoundary(block.id, "end");
202
+ break;
160
203
  default: panic(`Unsupported block content: ${JSON.stringify(block)}`);
161
204
  }
162
205
  };
@@ -203,6 +246,10 @@ function toProseDoc(document, options) {
203
246
  case "preservedBlock":
204
247
  out.push(convertPreservedBlock(block));
205
248
  break;
249
+ case "bookmarkStart":
250
+ case "bookmarkEnd":
251
+ out.push(convertBlockBookmarkBoundary(block));
252
+ break;
206
253
  default: panic(`Unsupported block content: ${JSON.stringify(block)}`);
207
254
  }
208
255
  return out;
@@ -229,6 +276,29 @@ function convertPreservedBlock(block) {
229
276
  return schema.node("preservedBlock", { xml: block.xml });
230
277
  }
231
278
  /**
279
+ * Carry a bookmark marker that stands between two blocks into the editor.
280
+ *
281
+ * Unconditional, unlike the inline atom: an unpaired inline boundary falls
282
+ * back to the paragraph's `bookmarks` attribute, and a marker between blocks
283
+ * has no paragraph to fall back to. Dropping it is the loss this node exists
284
+ * to prevent, and the integrity pass removes a boundary whose partner really
285
+ * has gone.
286
+ */
287
+ function convertBlockBookmarkBoundary(block) {
288
+ return schema.node("blockBookmarkBoundary", block.type === "bookmarkStart" ? {
289
+ type: "start",
290
+ id: block.id,
291
+ name: block.name,
292
+ colFirst: block.colFirst,
293
+ colLast: block.colLast,
294
+ displacedByCustomXml: block.displacedByCustomXml
295
+ } : {
296
+ type: "end",
297
+ id: block.id,
298
+ displacedByCustomXml: block.displacedByCustomXml
299
+ });
300
+ }
301
+ /**
232
302
  * Carry an inline child folio does not model into the editor as an opaque atom.
233
303
  *
234
304
  * The same atom the run level uses, tagged with the level it came from: the
@@ -246,8 +316,8 @@ function preservedInlineNode(content) {
246
316
  /**
247
317
  * Convert a `BlockSdt` model node into a `blockSdt` PM node, recursively
248
318
  * converting its children with the caller-supplied block converter. Pass
249
- * `rawPropertiesXml` / `rawEndPropertiesXml` through as attrs so the
250
- * serializer can replay them verbatim after a save.
319
+ * the preserved `w:sdtPr` children and the verbatim `<w:sdtEndPr>` through
320
+ * as attrs so the serializer can put them back after a save.
251
321
  */
252
322
  function convertBlockSdt(blockSdt, convertBlocks) {
253
323
  const props = blockSdt.properties;
@@ -258,15 +328,16 @@ function convertBlockSdt(blockSdt, convertBlocks) {
258
328
  id: props.id ?? null,
259
329
  lock: props.lock ?? null,
260
330
  placeholder: props.placeholder ?? null,
261
- showingPlaceholder: props.showingPlaceholder ?? false,
331
+ showingPlaceholder: props.showingPlaceholder ?? null,
262
332
  dateFormat: props.dateFormat ?? null,
263
333
  dateValueISO: props.dateValueISO ?? null,
264
334
  listItems: props.listItems ? JSON.stringify(props.listItems) : null,
265
335
  dropdownLastValue: props.dropdownLastValue ?? null,
266
336
  checked: props.checked ?? null,
267
337
  _originallyEmpty: blockSdt.content.length === 0,
268
- rawPropertiesXml: props.rawPropertiesXml ?? null,
338
+ _preserved: props.preserved ?? null,
269
339
  rawEndPropertiesXml: props.rawEndPropertiesXml ?? null,
340
+ endProperties: props.endProperties ?? null,
270
341
  rawSdtChildrenBeforeContent: props.rawSdtChildrenBeforeContent ?? null,
271
342
  rawSdtChildrenAfterContent: props.rawSdtChildrenAfterContent ?? null
272
343
  };
@@ -282,8 +353,8 @@ function convertBlockSdt(blockSdt, convertBlocks) {
282
353
  */
283
354
  function convertParagraph(paragraph, styleResolver, context, extraRunFormatting, tableParagraphOverlay, textBoxAnchors) {
284
355
  const { nextHyperlinkInstanceIndex, pairedBookmarkIds, pageBreakRunSourceDescendants, storyRangedCommentIds, openCommentIds } = context;
285
- let pageBreakRunOwnerId = 0;
286
- const nextPageBreakRunOwnerId = () => pageBreakRunOwnerId++;
356
+ let runIdentityId = 0;
357
+ const nextRunIdentityId = () => runIdentityId++;
287
358
  const { attrs, effectiveFrame } = paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOverlay);
288
359
  reportParagraphPageBreakProjection({
289
360
  paragraph,
@@ -365,11 +436,33 @@ function convertParagraph(paragraph, styleResolver, context, extraRunFormatting,
365
436
  toggleCascade: inheritedToggleCascade
366
437
  };
367
438
  };
439
+ const getHistoricalRunFormatting = (formatting) => {
440
+ const hasCharacterStyle = formatting?.styleId !== void 0;
441
+ const inheritedBaseFormatting = hasCharacterStyle ? baseRunFormatting : ordinaryBaseWithDefaultCharacter;
442
+ const inheritedToggleCascade = hasCharacterStyle ? orderedToggleFormatting : defaultCharacterStyleCascade;
443
+ return {
444
+ formatting: inheritedBaseFormatting,
445
+ ...!hasCharacterStyle ? { implicitCharacterStyleApplied: true } : {},
446
+ toggleCascade: inheritedToggleCascade
447
+ };
448
+ };
449
+ const trackedRunFormattingResolvers = {
450
+ current: getInheritedRunFormatting,
451
+ historical: getHistoricalRunFormatting
452
+ };
368
453
  const emitTrackedChange = (change, markType, moveKind) => {
369
- emitInlineNodes(convertTrackedChange(change, markType, nextHyperlinkInstanceIndex, nextPageBreakRunOwnerId, getInheritedRunFormatting, styleResolver, moveKind, textBoxAnchors, wrapperStack));
454
+ emitInlineNodes(convertTrackedChange(change, markType, nextHyperlinkInstanceIndex, nextRunIdentityId, trackedRunFormattingResolvers, styleResolver, moveKind, textBoxAnchors, wrapperStack));
370
455
  };
371
- for (const { content, stack } of withInlineWrapperStacks(paragraph.content)) {
456
+ const stacked = withInlineWrapperStacks(paragraph.content);
457
+ const emptyRanges = planEmptyRanges(stacked.map((item) => item.content));
458
+ for (const [index, { content, stack }] of stacked.entries()) {
372
459
  wrapperStack = stack;
460
+ const anchored = emptyRanges.anchorAt.get(index);
461
+ if (anchored) {
462
+ emitInlineNode(schema.node(RANGE_ANCHOR_NODE_NAME, anchored));
463
+ continue;
464
+ }
465
+ if (emptyRanges.closedAt.has(index)) continue;
373
466
  switch (content.type) {
374
467
  case "commentRangeStart":
375
468
  openCommentIds.add(content.id);
@@ -382,7 +475,7 @@ function convertParagraph(paragraph, styleResolver, context, extraRunFormatting,
382
475
  emitInlineNode(schema.node("commentReference", { commentId: content.id }));
383
476
  break;
384
477
  case "run":
385
- emitInlineNodes(convertRun(content, getInheritedRunFormatting(content.formatting), nextPageBreakRunOwnerId, styleResolver, textBoxAnchors));
478
+ emitInlineNodes(convertRun(content, getInheritedRunFormatting(content.formatting), nextRunIdentityId, styleResolver, textBoxAnchors));
386
479
  break;
387
480
  case "hyperlink": {
388
481
  const linkNodes = convertHyperlink(content, {
@@ -390,7 +483,7 @@ function convertParagraph(paragraph, styleResolver, context, extraRunFormatting,
390
483
  styleResolver,
391
484
  hyperlinkIndex: nextHyperlinkInstanceIndex(),
392
485
  textBoxAnchors,
393
- nextPageBreakRunOwnerId
486
+ nextRunIdentityId
394
487
  });
395
488
  if (linkNodes.length === 0) {
396
489
  emptyHyperlinks ??= [];
@@ -412,12 +505,12 @@ function convertParagraph(paragraph, styleResolver, context, extraRunFormatting,
412
505
  getInheritedRunFormatting,
413
506
  styleResolver,
414
507
  nextHyperlinkInstanceIndex,
415
- nextPageBreakRunOwnerId,
508
+ nextRunIdentityId,
416
509
  textBoxAnchors
417
510
  }));
418
511
  break;
419
512
  case "inlineSdt":
420
- emitInlineNode(convertInlineSdt(content, nextHyperlinkInstanceIndex, nextPageBreakRunOwnerId, getInheritedRunFormatting, styleResolver, textBoxAnchors, stack));
513
+ emitInlineNode(convertInlineSdt(content, nextHyperlinkInstanceIndex, nextRunIdentityId, getInheritedRunFormatting, trackedRunFormattingResolvers, styleResolver, textBoxAnchors, stack));
421
514
  break;
422
515
  case "insertion":
423
516
  case "moveTo":
@@ -458,7 +551,9 @@ function convertParagraph(paragraph, styleResolver, context, extraRunFormatting,
458
551
  case "moveFromRangeStart":
459
552
  case "moveFromRangeEnd":
460
553
  case "moveToRangeStart":
461
- case "moveToRangeEnd": break;
554
+ case "moveToRangeEnd":
555
+ emitInlineNode(schema.node(MOVE_RANGE_BOUNDARY_NODE_NAME, { marker: content }));
556
+ break;
462
557
  case "preservedInline":
463
558
  emitInlineNode(preservedInlineNode(content));
464
559
  break;
@@ -498,30 +593,51 @@ function anchorPointComment(nodes, commentId) {
498
593
  }
499
594
  }
500
595
  /**
596
+ * One node of a revision's content with the revision recorded on it.
597
+ *
598
+ * An inline content control is an `inline*` node rather than an atom, so it is
599
+ * not a run carrier: the revision goes on the leaves it holds. That is what
600
+ * makes `w:ins > w:sdt` and `w:sdt > w:ins` the same marks on the same leaves,
601
+ * and it is what lets the save leg hoist a revision covering all of them back
602
+ * around the control instead of losing it.
603
+ */
604
+ const withTrackedRunMark = (node, mark) => {
605
+ if (node.marks.some(({ type }) => type.name === "insertion" || type.name === "deletion")) return node;
606
+ if (node.type.name === "sdt") {
607
+ const marked = [];
608
+ for (let index = 0; index < node.childCount; index += 1) marked.push(withTrackedRunMark(node.child(index), mark));
609
+ return recreateProseNodeWithParagraphPropertySource(node, { content: marked });
610
+ }
611
+ if (trackedRunInlineAtomDisposition(node) === "outside-wrapper") panic(`Inline atom ${JSON.stringify(node.type.name)} cannot occur in a tracked-run wrapper`);
612
+ if (canCarryTrackedRunMark(node)) return node.mark(mark.addToSet(node.marks));
613
+ return node;
614
+ };
615
+ /**
501
616
  * Convert tracked change (insertion or deletion) content to PM nodes with
502
617
  * an insertion/deletion mark applied.
503
618
  */
504
- function convertTrackedChange(change, markType, nextHyperlinkInstanceIndex, nextPageBreakRunOwnerId, getInheritedRunFormatting, styleResolver, moveKind = null, textBoxAnchors, wrappedBy = []) {
619
+ function convertTrackedChange(change, markType, nextHyperlinkInstanceIndex, nextRunIdentityId, runFormattingResolvers, styleResolver, moveKind = null, textBoxAnchors, wrappedBy = []) {
505
620
  const nodes = [];
621
+ const getTrackedRunFormatting = markType === "deletion" ? runFormattingResolvers.historical : runFormattingResolvers.current;
506
622
  for (const { content: item, stack } of withInlineWrapperStacks(change.content)) {
507
623
  if (!isTrackedChangeWrapperChild(item)) continue;
508
624
  const itemNodes = [];
509
- if (item.type === "run") itemNodes.push(...convertRun(item, getInheritedRunFormatting(item.formatting), nextPageBreakRunOwnerId, styleResolver, textBoxAnchors));
625
+ if (item.type === "run") itemNodes.push(...convertRun(item, getTrackedRunFormatting(item.formatting), nextRunIdentityId, styleResolver, textBoxAnchors));
510
626
  else if (item.type === "hyperlink") {
511
627
  const currentHyperlinkIndex = nextHyperlinkInstanceIndex();
512
628
  itemNodes.push(...convertHyperlink(item, {
513
- getInheritedRunFormatting,
629
+ getInheritedRunFormatting: getTrackedRunFormatting,
514
630
  styleResolver,
515
631
  hyperlinkIndex: currentHyperlinkIndex,
516
632
  textBoxAnchors,
517
- nextPageBreakRunOwnerId
633
+ nextRunIdentityId
518
634
  }));
519
635
  } else if (item.type === "simpleField" || item.type === "complexField") {
520
636
  const fieldNode = convertField(item, {
521
- getInheritedRunFormatting,
637
+ getInheritedRunFormatting: getTrackedRunFormatting,
522
638
  styleResolver,
523
639
  nextHyperlinkInstanceIndex,
524
- nextPageBreakRunOwnerId,
640
+ nextRunIdentityId,
525
641
  textBoxAnchors
526
642
  });
527
643
  if (fieldNode) itemNodes.push(fieldNode);
@@ -531,9 +647,9 @@ function convertTrackedChange(change, markType, nextHyperlinkInstanceIndex, next
531
647
  } else if (item.type === "insertion" || item.type === "deletion" || item.type === "moveFrom" || item.type === "moveTo") {
532
648
  const nestedMarkType = item.type === "insertion" || item.type === "moveTo" ? "insertion" : "deletion";
533
649
  const nestedMoveKind = item.type === "moveFrom" || item.type === "moveTo" ? item.type : null;
534
- itemNodes.push(...convertTrackedChange(item, nestedMarkType, nextHyperlinkInstanceIndex, nextPageBreakRunOwnerId, getInheritedRunFormatting, styleResolver, nestedMoveKind, textBoxAnchors));
650
+ itemNodes.push(...convertTrackedChange(item, nestedMarkType, nextHyperlinkInstanceIndex, nextRunIdentityId, runFormattingResolvers, styleResolver, nestedMoveKind, textBoxAnchors));
535
651
  } else if (item.type === "inlineSdt") {
536
- const sdtNode = convertInlineSdt(item, nextHyperlinkInstanceIndex, nextPageBreakRunOwnerId, getInheritedRunFormatting, styleResolver, textBoxAnchors, [...wrappedBy, ...stack]);
652
+ const sdtNode = convertInlineSdt(item, nextHyperlinkInstanceIndex, nextRunIdentityId, getTrackedRunFormatting, runFormattingResolvers, styleResolver, textBoxAnchors, [...wrappedBy, ...stack]);
537
653
  if (sdtNode) itemNodes.push(sdtNode);
538
654
  } else if (item.type === "bookmarkStart") itemNodes.push(schema.node("bookmarkBoundary", {
539
655
  type: "start",
@@ -558,14 +674,10 @@ function convertTrackedChange(change, markType, nextHyperlinkInstanceIndex, next
558
674
  date: change.info.date ?? null,
559
675
  utcDate: change.info.utcDate?.value ?? null,
560
676
  initials: change.info.initials ?? null,
561
- moveKind
562
- });
563
- return nodes.map((node) => {
564
- if (node.marks.some(({ type }) => type.name === "insertion" || type.name === "deletion")) return node;
565
- if (trackedRunInlineAtomDisposition(node) === "outside-wrapper") panic(`Inline atom ${JSON.stringify(node.type.name)} cannot occur in a tracked-run wrapper`);
566
- if (canCarryTrackedRunMark(node)) return node.mark(mark.addToSet(node.marks));
567
- return node;
677
+ moveKind,
678
+ ...markType === "deletion" ? { _historicalFormatting: true } : {}
568
679
  });
680
+ return nodes.map((node) => withTrackedRunMark(node, mark));
569
681
  }
570
682
  function paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOverlay) {
571
683
  const formatting = paragraph.formatting;
@@ -581,11 +693,21 @@ function paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOver
581
693
  if (paragraph.reviewCarrier) attrs.reviewCarrier = paragraph.reviewCarrier;
582
694
  if (styleId) attrs.styleId = styleId;
583
695
  if (tableOfContentsLevel !== void 0) attrs._tableOfContentsLevel = tableOfContentsLevel;
584
- if (formatting?.numPr) attrs.numPr = formatting.numPr;
585
- if (formatting?.numPrFromStyle) attrs.numPrFromStyle = formatting.numPrFromStyle;
696
+ if (formatting?.numPr) attrs.numPr = paragraphNumberingAttr(formatting.numPr);
697
+ if (formatting?.numPrFromStyle) attrs.numPrFromStyle = paragraphNumberingAttr(formatting.numPrFromStyle);
586
698
  if (paragraph.listRendering) Object.assign(attrs, listRenderingAttrPatch(paragraph.listRendering));
587
699
  if (formatting) attrs._originalFormatting = formatting;
588
- if (paragraph.propertyChanges && paragraph.propertyChanges.length > 0) attrs._propertyChanges = [...paragraph.propertyChanges];
700
+ if (paragraph.propertyChanges && paragraph.propertyChanges.length > 0) attrs._propertyChanges = paragraph.propertyChanges.map(({ previousFormatting, ...change }) => {
701
+ if (previousFormatting === void 0) return change;
702
+ const { numPr, ...rest } = previousFormatting;
703
+ return {
704
+ ...change,
705
+ previousFormatting: numPr === void 0 ? rest : {
706
+ ...rest,
707
+ numPr: paragraphNumberingAttr(numPr)
708
+ }
709
+ };
710
+ });
589
711
  if (paragraph.preservedAttributes && paragraph.preservedAttributes.length > 0) attrs._preservedAttributes = paragraph.preservedAttributes;
590
712
  if (paragraph.pPrMark) attrs.pPrMark = paragraph.pPrMark;
591
713
  const set = (key, val) => {
@@ -615,7 +737,7 @@ function paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOver
615
737
  if (formatting?.spaceBefore === void 0 && tableParagraphOverlay?.spaceBefore === void 0 && paragraphStyle?.pPr?.spaceBefore === void 0 && docDefaultSpacing?.spaceBefore !== void 0) spacingFromDocDefaults.before = true;
616
738
  if (formatting?.spaceAfter === void 0 && tableParagraphOverlay?.spaceAfter === void 0 && paragraphStyle?.pPr?.spaceAfter === void 0 && docDefaultSpacing?.spaceAfter !== void 0) spacingFromDocDefaults.after = true;
617
739
  if (spacingFromDocDefaults.before || spacingFromDocDefaults.after) attrs.spacingFromDocDefaults = spacingFromDocDefaults;
618
- const effectiveIndent = mergeParagraphFormatting(formatting?.numPr?.numId === 0 && isNumberingReference(stylePpr?.numPr?.numId) ? void 0 : stylePpr, formatting);
740
+ const effectiveIndent = mergeParagraphFormatting(formatting?.numPr?.kind === "none" && paragraphNumberingReferenceId$1(stylePpr?.numPr) !== void 0 ? void 0 : stylePpr, formatting);
619
741
  set("indentLeft", effectiveIndent?.indentLeft);
620
742
  set("indentRight", formatting?.indentRight ?? stylePpr?.indentRight);
621
743
  set("indentFirstLine", effectiveIndent?.indentFirstLine);
@@ -635,12 +757,11 @@ function paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOver
635
757
  set("outlineLevel", formatting?.outlineLevel ?? stylePpr?.outlineLevel);
636
758
  set("direction", directionFromBidi(formatting?.bidi ?? stylePpr?.bidi));
637
759
  set("defaultTextFormatting", resolveParagraphDefaultTextFormatting(styleId, formatting, styleResolver, { includeParagraphMarkRunProperties: tableOfContentsLevel === void 0 && (styleId === void 0 || paragraph.content.length === 0) }));
638
- if (stylePpr?.numPr && formatting?.numPr?.numId === void 0 && isNumberingReference(stylePpr.numPr.numId)) {
639
- attrs.numPr = {
640
- ...stylePpr.numPr,
641
- ...formatting?.numPr
642
- };
643
- attrs.numPrFromStyle = stylePpr.numPr;
760
+ const styleNumbering = stylePpr?.numPr;
761
+ if (styleNumbering?.kind === "reference" && (formatting?.numPr === void 0 || formatting.numPr.kind === "levelOnly")) {
762
+ const merged = mergeParagraphNumbering$1(styleNumbering, formatting?.numPr);
763
+ if (merged !== void 0) attrs.numPr = paragraphNumberingAttr(merged);
764
+ attrs.numPrFromStyle = paragraphNumberingAttr(styleNumbering);
644
765
  }
645
766
  } else {
646
767
  set("alignment", formatting?.alignment);
@@ -670,11 +791,7 @@ function paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOver
670
791
  set("direction", directionFromBidi(formatting?.bidi));
671
792
  set("defaultTextFormatting", stripParagraphMarkOnlyFormatting(resolveTextFormatting(formatting?.runProperties, styleResolver) ?? {}));
672
793
  }
673
- if (paragraph.sectionProperties) {
674
- attrs._sectionProperties = paragraph.sectionProperties;
675
- const st = paragraph.sectionProperties.sectionStart;
676
- if (st === "nextPage" || st === "continuous" || st === "oddPage" || st === "evenPage") attrs.sectionBreakType = st;
677
- }
794
+ if (paragraph.sectionProperties) attrs._sectionProperties = paragraph.sectionProperties;
678
795
  if (paragraph.renderedPageBreakBefore) attrs.renderedPageBreakBefore = true;
679
796
  const beforeAutospacing = formatting?.beforeAutospacing ?? stylePpr?.beforeAutospacing;
680
797
  const afterAutospacing = formatting?.afterAutospacing ?? stylePpr?.afterAutospacing;
@@ -913,6 +1030,7 @@ function tableCellHasMeaningfulContent(cell) {
913
1030
  }
914
1031
  function blockHasMeaningfulContent(block) {
915
1032
  if (block.type === "preservedBlock") return true;
1033
+ if (block.type === "bookmarkStart" || block.type === "bookmarkEnd") return true;
916
1034
  if (block.type === "table") return block.rows.some((row) => row.cells.some((cell) => tableCellHasMeaningfulContent(cell)));
917
1035
  return block.content.some(paragraphContentHasMeaningfulContent);
918
1036
  }
@@ -972,6 +1090,8 @@ function convertTable(table, styleResolver, context) {
972
1090
  if (resolvedTableBidi !== void 0) attrs._resolvedBidi = resolvedTableBidi;
973
1091
  attrs._originalFormatting = table.formatting ?? {};
974
1092
  if (table.propertyChanges && table.propertyChanges.length > 0) attrs.tblPrChange = [...table.propertyChanges];
1093
+ if (table.bookmarks && table.bookmarks.length > 0) attrs._bookmarks = table.bookmarks;
1094
+ if (hasSinkChildren(table.preserved)) attrs._preserved = table.preserved;
975
1095
  const conditionalStyles = {};
976
1096
  const setCS = (key, type) => {
977
1097
  const val = resolveTableStyleConditional(styleResolver, conditionalTableStyleId, type);
@@ -1023,6 +1143,19 @@ function countTableColumns(rows) {
1023
1143
  }
1024
1144
  return maxColumns;
1025
1145
  }
1146
+ function createOmittedGridSlotCell({ colspan, slot, columnWidths, totalWidth, startColumn }) {
1147
+ const attrs = {
1148
+ colspan,
1149
+ rowspan: 1,
1150
+ _omittedGridSlot: slot
1151
+ };
1152
+ if (columnWidths && totalWidth && totalWidth > 0) {
1153
+ const slotWidth = columnWidths.slice(startColumn, startColumn + colspan).reduce((sum, width) => sum + width, 0);
1154
+ attrs.width = Math.round(slotWidth / totalWidth * 100);
1155
+ attrs.widthType = "pct";
1156
+ }
1157
+ return schema.node("tableCell", attrs, [schema.node("paragraph")]);
1158
+ }
1026
1159
  /**
1027
1160
  * Convert a TableRow to a ProseMirror table row node
1028
1161
  */
@@ -1030,11 +1163,16 @@ function convertTableRow(row, styleResolver, context, isHeaderRow, columnWidths,
1030
1163
  const attrsWithoutStructuralChange = { isHeader: !!row.formatting?.header };
1031
1164
  if (row.formatting?.height?.value !== void 0) attrsWithoutStructuralChange.height = row.formatting.height.value;
1032
1165
  if (row.formatting?.heightRule) attrsWithoutStructuralChange.heightRule = row.formatting.heightRule;
1033
- if (row.formatting?.hidden) attrsWithoutStructuralChange.hidden = true;
1166
+ if (row.formatting?.hidden !== void 0) attrsWithoutStructuralChange.hidden = row.formatting.hidden;
1034
1167
  if (resolvedJustification) attrsWithoutStructuralChange._resolvedJustification = resolvedJustification;
1035
1168
  if (row.formatting) attrsWithoutStructuralChange._originalFormatting = row.formatting;
1169
+ if (row.tablePropertyExceptions) attrsWithoutStructuralChange._tablePropertyExceptions = row.tablePropertyExceptions;
1170
+ if (row.tablePropertyExceptionChanges && row.tablePropertyExceptionChanges.length > 0) attrsWithoutStructuralChange.tblPrExChange = [...row.tablePropertyExceptionChanges];
1036
1171
  if (row.propertyChanges && row.propertyChanges.length > 0) attrsWithoutStructuralChange.trPrChange = [...row.propertyChanges];
1037
1172
  if (row.preservedAttributes && row.preservedAttributes.length > 0) attrsWithoutStructuralChange._preservedAttributes = row.preservedAttributes;
1173
+ if (row.bookmarks && row.bookmarks.length > 0) attrsWithoutStructuralChange._bookmarks = row.bookmarks;
1174
+ if (row.contentControls && row.contentControls.length > 0) attrsWithoutStructuralChange.contentControls = row.contentControls;
1175
+ if (hasSinkChildren(row.preserved)) attrsWithoutStructuralChange._preserved = row.preserved;
1038
1176
  let attrs = attrsWithoutStructuralChange;
1039
1177
  const rowStructuralChange = row.structuralChange;
1040
1178
  if (rowStructuralChange) {
@@ -1065,6 +1203,8 @@ function convertTableRow(row, styleResolver, context, isHeaderRow, columnWidths,
1065
1203
  }
1066
1204
  }
1067
1205
  const numCells = row.cells.length;
1206
+ const gridBefore = row.formatting?.gridBefore ?? 0;
1207
+ const gridAfter = row.formatting?.gridAfter ?? 0;
1068
1208
  const isFirstRow = rowIndex === 0;
1069
1209
  const isLastRow = rowIndex === (totalRows ?? 1) - 1;
1070
1210
  const rowCnf = row.formatting?.conditionalFormat;
@@ -1072,16 +1212,24 @@ function convertTableRow(row, styleResolver, context, isHeaderRow, columnWidths,
1072
1212
  const rowIsLastRow = rowCnf?.lastRow ?? isLastRow;
1073
1213
  const totalCols = totalColumns != null && totalColumns > 0 ? totalColumns : Math.max(numCells, 1);
1074
1214
  let effectiveCells = row.cells;
1075
- if (effectiveCells.length === 0) {
1215
+ const uncoveredColumns = Math.max(0, totalCols - gridBefore - gridAfter);
1216
+ if (effectiveCells.length === 0 && uncoveredColumns > 0) {
1076
1217
  const fallback = {
1077
1218
  type: "tableCell",
1078
1219
  content: []
1079
1220
  };
1080
- if (totalCols > 1) fallback.formatting = { gridSpan: totalCols };
1221
+ if (uncoveredColumns > 1) fallback.formatting = { gridSpan: uncoveredColumns };
1081
1222
  effectiveCells = [fallback];
1082
1223
  }
1083
- let colIndex = row.formatting?.gridBefore ?? 0;
1224
+ let colIndex = gridBefore;
1084
1225
  const cells = [];
1226
+ if (gridBefore > 0) cells.push(createOmittedGridSlotCell({
1227
+ colspan: gridBefore,
1228
+ slot: "before",
1229
+ columnWidths,
1230
+ totalWidth,
1231
+ startColumn: 0
1232
+ }));
1085
1233
  for (const cellIndex_item of effectiveCells) {
1086
1234
  const cell = cellIndex_item;
1087
1235
  const colspan = cell.formatting?.gridSpan ?? 1;
@@ -1149,6 +1297,13 @@ function convertTableRow(row, styleResolver, context, isHeaderRow, columnWidths,
1149
1297
  defaultCellMargins
1150
1298
  }));
1151
1299
  }
1300
+ if (gridAfter > 0) cells.push(createOmittedGridSlotCell({
1301
+ colspan: gridAfter,
1302
+ slot: "after",
1303
+ columnWidths,
1304
+ totalWidth,
1305
+ startColumn: colIndex
1306
+ }));
1152
1307
  return schema.node("tableRow", attrs, cells);
1153
1308
  }
1154
1309
  /**
@@ -1173,6 +1328,10 @@ function convertTableCell({ cell, styleResolver, context, isHeader, gridWidthPer
1173
1328
  if (effectiveFormatting.width.type === "value") {
1174
1329
  attrs.width = effectiveFormatting.width.value;
1175
1330
  if (effectiveFormatting.width.widthType) attrs.widthType = effectiveFormatting.width.widthType;
1331
+ if (effectiveFormatting.width.source === "direct") attrs._authoredWidth = {
1332
+ value: effectiveFormatting.width.value,
1333
+ type: effectiveFormatting.width.widthType
1334
+ };
1176
1335
  }
1177
1336
  if (formatting?.verticalAlign) attrs.verticalAlign = formatting.verticalAlign;
1178
1337
  if (effectiveFormatting.background.type === "color") {
@@ -1193,6 +1352,7 @@ function convertTableCell({ cell, styleResolver, context, isHeader, gridWidthPer
1193
1352
  }
1194
1353
  if (formatting) attrs._originalFormatting = formatting;
1195
1354
  if (cell.propertyChanges && cell.propertyChanges.length > 0) attrs.tcPrChange = [...cell.propertyChanges];
1355
+ if (cell.contentControls && cell.contentControls.length > 0) attrs.contentControls = cell.contentControls;
1196
1356
  const cellStructuralChange = cell.structuralChange;
1197
1357
  if (cellStructuralChange) {
1198
1358
  const info = {
@@ -1246,6 +1406,10 @@ function convertTableCell({ cell, styleResolver, context, isHeader, gridWidthPer
1246
1406
  case "preservedBlock":
1247
1407
  contentNodes.push(convertPreservedBlock(content));
1248
1408
  break;
1409
+ case "bookmarkStart":
1410
+ case "bookmarkEnd":
1411
+ contentNodes.push(convertBlockBookmarkBoundary(content));
1412
+ break;
1249
1413
  default: panic(`Unsupported table cell content: ${JSON.stringify(content)}`);
1250
1414
  }
1251
1415
  if (contentNodes.length === 0) contentNodes.push(schema.node("paragraph", {}, []));
@@ -1281,49 +1445,55 @@ function standaloneTableCellToProseMirror(cell, nodeType) {
1281
1445
  defaultCellMargins: void 0
1282
1446
  });
1283
1447
  }
1284
- function convertField(field, { getInheritedRunFormatting, styleResolver, nextHyperlinkInstanceIndex, nextPageBreakRunOwnerId, textBoxAnchors }) {
1448
+ function convertField(field, { getInheritedRunFormatting, styleResolver, nextHyperlinkInstanceIndex, nextRunIdentityId, textBoxAnchors }) {
1285
1449
  let displayText = "";
1286
1450
  let fieldFormatting;
1287
1451
  let fieldPropertyChanges;
1288
1452
  const inlineNodes = [];
1289
- const hasStructuredSourceContent = fieldResultHasPageBreakContent(field) || field.type === "simpleField" && field.content.some((content) => content.type === "hyperlink" || content.type === "preservedInline");
1290
- const appendRun = (run) => {
1453
+ const hasStructuredSourceContent = fieldResultHasPageBreakContent(field) || field.type === "simpleField" && field.content.some((content) => content.type === "hyperlink" || content.type === "preservedInline" || content.type === "inlineWrapper");
1454
+ const appendRun = (run, into) => {
1291
1455
  for (const content of run.content) if (content.type === "text") displayText += content.text;
1292
1456
  fieldFormatting ??= run.formatting;
1293
1457
  fieldPropertyChanges ??= run.propertyChanges;
1294
1458
  if (!hasStructuredSourceContent) return;
1295
- inlineNodes.push(...convertRun(run, getInheritedRunFormatting(run.formatting, field.fieldType), nextPageBreakRunOwnerId, styleResolver, textBoxAnchors));
1459
+ into.push(...convertRun(run, getInheritedRunFormatting(run.formatting, field.fieldType), nextRunIdentityId, styleResolver, textBoxAnchors));
1296
1460
  };
1297
- if (field.type === "simpleField") for (const content of field.content) {
1298
- if (content.type === "run") {
1299
- appendRun(content);
1300
- continue;
1301
- }
1302
- if (content.type === "preservedInline") {
1303
- inlineNodes.push(preservedInlineNode(content));
1304
- continue;
1305
- }
1306
- for (const child of content.children) if (child.type === "run") {
1307
- for (const runContent of child.content) if (runContent.type === "text") displayText += runContent.text;
1308
- fieldFormatting ??= child.formatting;
1309
- fieldPropertyChanges ??= child.propertyChanges;
1461
+ if (field.type === "simpleField") for (const { content, stack } of withInlineWrapperStacks(field.content)) {
1462
+ const itemNodes = [];
1463
+ switch (content.type) {
1464
+ case "run":
1465
+ appendRun(content, itemNodes);
1466
+ break;
1467
+ case "preservedInline":
1468
+ itemNodes.push(preservedInlineNode(content));
1469
+ break;
1470
+ case "hyperlink":
1471
+ for (const { content: child } of withInlineWrapperStacks(content.children)) if (child.type === "run") {
1472
+ for (const runContent of child.content) if (runContent.type === "text") displayText += runContent.text;
1473
+ fieldFormatting ??= child.formatting;
1474
+ fieldPropertyChanges ??= child.propertyChanges;
1475
+ }
1476
+ itemNodes.push(...convertHyperlink(content, {
1477
+ getInheritedRunFormatting: (formatting) => getInheritedRunFormatting(formatting, field.fieldType),
1478
+ styleResolver,
1479
+ hyperlinkIndex: nextHyperlinkInstanceIndex(),
1480
+ textBoxAnchors,
1481
+ nextRunIdentityId
1482
+ }));
1483
+ break;
1484
+ default: break;
1310
1485
  }
1311
- inlineNodes.push(...convertHyperlink(content, {
1312
- getInheritedRunFormatting: (formatting) => getInheritedRunFormatting(formatting, field.fieldType),
1313
- styleResolver,
1314
- hyperlinkIndex: nextHyperlinkInstanceIndex(),
1315
- textBoxAnchors,
1316
- nextPageBreakRunOwnerId
1317
- }));
1486
+ inlineNodes.push(...withInlineWrapperMark(itemNodes, stack));
1318
1487
  }
1319
- else for (const run of field.fieldResult) appendRun(run);
1488
+ else for (const run of field.fieldResult) appendRun(run, inlineNodes);
1320
1489
  if (!fieldFormatting && field.type === "complexField" && field.fieldResult.length === 0) fieldFormatting = field.formatting;
1321
1490
  const inheritedFormatting = getInheritedRunFormatting(fieldFormatting, field.fieldType);
1322
1491
  const { marks } = buildRunMarks(fieldFormatting, inheritedFormatting, styleResolver);
1323
1492
  const hasConvertedHyperlinkContent = inlineNodes.some((node) => node.marks.some((mark) => mark.type.name === "hyperlink"));
1324
1493
  const hasConvertedPageBreakContent = inlineNodes.some((node) => node.type.name === "pageBreakRun");
1325
1494
  const hasConvertedPreservedContent = inlineNodes.some((node) => node.type.name === "preservedXml");
1326
- const createStructuredField = hasConvertedPageBreakContent || hasConvertedPreservedContent || hasStructuredSourceContent && hasConvertedHyperlinkContent;
1495
+ const hasConvertedWrapperContent = inlineNodes.some((node) => node.marks.some((mark) => mark.type.name === INLINE_WRAPPER_MARK_NAME));
1496
+ const createStructuredField = hasConvertedPageBreakContent || hasConvertedPreservedContent || hasStructuredSourceContent && (hasConvertedHyperlinkContent || hasConvertedWrapperContent);
1327
1497
  if (!createStructuredField && fieldPropertyChanges && fieldPropertyChanges.length > 0) marks.push(schema.mark("runPropertyChange", { changes: [...fieldPropertyChanges] }));
1328
1498
  return schema.node(createStructuredField ? "structuredField" : "field", {
1329
1499
  fieldType: field.fieldType,
@@ -1393,7 +1563,7 @@ function convertMathEquation(math) {
1393
1563
  * its own leaves, so nothing outside can mark them afterwards: the caller's
1394
1564
  * stack has to reach them here, under the wrappers written inside the control.
1395
1565
  */
1396
- function convertInlineSdt(sdt, nextHyperlinkInstanceIndex, nextPageBreakRunOwnerId, getInheritedRunFormatting, styleResolver, textBoxAnchors, wrappedBy = []) {
1566
+ function convertInlineSdt(sdt, nextHyperlinkInstanceIndex, nextRunIdentityId, getInheritedRunFormatting, trackedRunFormattingResolvers, styleResolver, textBoxAnchors, wrappedBy = []) {
1397
1567
  const props = sdt.properties;
1398
1568
  const inlineNodes = [];
1399
1569
  for (const { content, stack } of withInlineWrapperStacks(sdt.content, wrappedBy)) {
@@ -1401,7 +1571,7 @@ function convertInlineSdt(sdt, nextHyperlinkInstanceIndex, nextPageBreakRunOwner
1401
1571
  const itemNodes = [];
1402
1572
  switch (content.type) {
1403
1573
  case "run":
1404
- itemNodes.push(...convertRun(content, getInheritedRunFormatting(content.formatting), nextPageBreakRunOwnerId, styleResolver, textBoxAnchors));
1574
+ itemNodes.push(...convertRun(content, getInheritedRunFormatting(content.formatting), nextRunIdentityId, styleResolver, textBoxAnchors));
1405
1575
  break;
1406
1576
  case "hyperlink": {
1407
1577
  const currentHyperlinkIndex = nextHyperlinkInstanceIndex();
@@ -1410,7 +1580,7 @@ function convertInlineSdt(sdt, nextHyperlinkInstanceIndex, nextPageBreakRunOwner
1410
1580
  styleResolver,
1411
1581
  hyperlinkIndex: currentHyperlinkIndex,
1412
1582
  textBoxAnchors,
1413
- nextPageBreakRunOwnerId
1583
+ nextRunIdentityId
1414
1584
  }));
1415
1585
  break;
1416
1586
  }
@@ -1420,14 +1590,14 @@ function convertInlineSdt(sdt, nextHyperlinkInstanceIndex, nextPageBreakRunOwner
1420
1590
  getInheritedRunFormatting,
1421
1591
  styleResolver,
1422
1592
  nextHyperlinkInstanceIndex,
1423
- nextPageBreakRunOwnerId,
1593
+ nextRunIdentityId,
1424
1594
  textBoxAnchors
1425
1595
  });
1426
1596
  if (fieldNode) itemNodes.push(fieldNode);
1427
1597
  break;
1428
1598
  }
1429
1599
  case "inlineSdt": {
1430
- const nestedSdt = convertInlineSdt(content, nextHyperlinkInstanceIndex, nextPageBreakRunOwnerId, getInheritedRunFormatting, styleResolver, textBoxAnchors, stack);
1600
+ const nestedSdt = convertInlineSdt(content, nextHyperlinkInstanceIndex, nextRunIdentityId, getInheritedRunFormatting, trackedRunFormattingResolvers, styleResolver, textBoxAnchors, stack);
1431
1601
  if (nestedSdt) itemNodes.push(nestedSdt);
1432
1602
  break;
1433
1603
  }
@@ -1435,13 +1605,30 @@ function convertInlineSdt(sdt, nextHyperlinkInstanceIndex, nextPageBreakRunOwner
1435
1605
  case "deletion":
1436
1606
  case "moveTo":
1437
1607
  case "moveFrom":
1438
- itemNodes.push(...convertTrackedChange(content, content.type === "insertion" || content.type === "moveTo" ? "insertion" : "deletion", nextHyperlinkInstanceIndex, nextPageBreakRunOwnerId, getInheritedRunFormatting, styleResolver, content.type === "moveTo" || content.type === "moveFrom" ? content.type : null, textBoxAnchors));
1608
+ itemNodes.push(...convertTrackedChange(content, content.type === "insertion" || content.type === "moveTo" ? "insertion" : "deletion", nextHyperlinkInstanceIndex, nextRunIdentityId, trackedRunFormattingResolvers, styleResolver, content.type === "moveTo" || content.type === "moveFrom" ? content.type : null, textBoxAnchors));
1439
1609
  break;
1440
1610
  case "mathEquation": {
1441
1611
  const mathNode = convertMathEquation(content);
1442
1612
  if (mathNode) itemNodes.push(mathNode);
1443
1613
  break;
1444
1614
  }
1615
+ case "bookmarkStart":
1616
+ itemNodes.push(schema.node("bookmarkBoundary", {
1617
+ type: "start",
1618
+ id: content.id,
1619
+ name: content.name,
1620
+ colFirst: content.colFirst,
1621
+ colLast: content.colLast,
1622
+ displacedByCustomXml: content.displacedByCustomXml
1623
+ }));
1624
+ break;
1625
+ case "bookmarkEnd":
1626
+ itemNodes.push(schema.node("bookmarkBoundary", {
1627
+ type: "end",
1628
+ id: content.id,
1629
+ displacedByCustomXml: content.displacedByCustomXml
1630
+ }));
1631
+ break;
1445
1632
  case "preservedInline":
1446
1633
  itemNodes.push(preservedInlineNode(content));
1447
1634
  break;
@@ -1457,11 +1644,12 @@ function convertInlineSdt(sdt, nextHyperlinkInstanceIndex, nextPageBreakRunOwner
1457
1644
  * @param run - The run to convert
1458
1645
  * @param resolvedStyleFormatting - Paragraph formatting and its explicit style-toggle state
1459
1646
  */
1460
- function convertRun(run, resolvedStyleFormatting, nextPageBreakRunOwnerId, styleResolver, textBoxAnchors) {
1647
+ function convertRun(run, resolvedStyleFormatting, nextRunIdentityId, styleResolver, textBoxAnchors) {
1461
1648
  const nodes = [];
1462
1649
  const { marks, mergedFormatting } = buildRunMarks(run.formatting, resolvedStyleFormatting, styleResolver);
1463
1650
  if (run.propertyChanges && run.propertyChanges.length > 0) marks.push(schema.mark("runPropertyChange", { changes: [...run.propertyChanges] }));
1464
- if (run.content.some((content) => content.type === "break" && content.breakType === "page")) marks.push(schema.mark("pageBreakRunOwner", { id: nextPageBreakRunOwnerId() }));
1651
+ const identity = runIdentityMark(run, nextRunIdentityId);
1652
+ if (identity) marks.push(identity);
1465
1653
  for (const content of run.content) {
1466
1654
  const contentNodes = convertRunContent(content, marks, mergedFormatting, textBoxAnchors, run.formatting);
1467
1655
  nodes.push(...contentNodes);
@@ -1477,14 +1665,15 @@ const runHasPageBreakContent = (run) => run.content.some((content) => content.ty
1477
1665
  * predicate for the two, because a reporter that disagreed with the converter
1478
1666
  * would name a loss nobody suffered.
1479
1667
  */
1480
- const fieldResultHasPageBreakContent = (field) => field.type === "simpleField" ? field.content.some((content) => {
1668
+ const inlineHasPageBreakContent = (items) => items.some((content) => {
1481
1669
  switch (content.type) {
1482
1670
  case "run": return runHasPageBreakContent(content);
1483
- case "hyperlink": return content.children.some((child) => child.type === "run" && runHasPageBreakContent(child));
1484
- case "preservedInline": return false;
1485
- default: panic(`Unsupported simple-field content: ${JSON.stringify(content)}`);
1671
+ case "hyperlink": return inlineHasPageBreakContent(content.children);
1672
+ case "inlineWrapper": return inlineHasPageBreakContent(content.content);
1673
+ default: return false;
1486
1674
  }
1487
- }) : field.fieldResult.some(runHasPageBreakContent);
1675
+ });
1676
+ const fieldResultHasPageBreakContent = (field) => field.type === "simpleField" ? inlineHasPageBreakContent(field.content) : field.fieldResult.some(runHasPageBreakContent);
1488
1677
  function reportPageBreakSourceRunContent(run, warn) {
1489
1678
  if (!runHasPageBreakContent(run)) return;
1490
1679
  reportRunContentBesidePageBreak(run, "page-break-bearing-run", warn);
@@ -1646,7 +1835,7 @@ const PAGE_BREAK_OWNER_DESCRIPTIONS = {
1646
1835
  * Record what a page-break-bearing run loses when the editor re-cuts it.
1647
1836
  *
1648
1837
  * The run is split into one node per inline atom and rebuilt from the
1649
- * `pageBreakRunOwner` mark, and the kinds below have no node of their own:
1838
+ * `runIdentity` mark, and the kinds below have no node of their own:
1650
1839
  * a hyphen returns as its character, a field character or instruction leaves
1651
1840
  * no trace, and a text-box shape is hoisted to its own block. Every one of
1652
1841
  * those losses is what the same run suffers with no page break in it, so
@@ -1707,7 +1896,8 @@ const RUN_FORMATTING_INFERENCE = {
1707
1896
  shadow: "visible-boolean",
1708
1897
  rtl: "visible-boolean",
1709
1898
  cs: "structural",
1710
- styleId: "structural"
1899
+ styleId: "structural",
1900
+ preserved: "structural"
1711
1901
  };
1712
1902
  const sameFormattingValue = (left, right) => {
1713
1903
  if (left === right) return true;
@@ -1932,8 +2122,14 @@ function convertRunContent(content, marks, formatting, textBoxAnchors, authoredF
1932
2122
  }).mark(marks)];
1933
2123
  }
1934
2124
  }
2125
+ /**
2126
+ * The marks that name an element the atom has to stay inside: a `w:hyperlink`
2127
+ * and the authored `w:r` itself. A leaf that carries one has to hold the whole
2128
+ * mark set, because the save leg rebuilds those elements around it.
2129
+ */
2130
+ const RUN_BOUNDARY_MARK_NAMES = /* @__PURE__ */ new Set(["hyperlink", RUN_IDENTITY_MARK_NAME]);
1935
2131
  function withRunBoundaryMarks(node, marks) {
1936
- if (!marks.some(({ type }) => type.name === "hyperlink" || type.name === "pageBreakRunOwner")) return node;
2132
+ if (!marks.some(({ type }) => RUN_BOUNDARY_MARK_NAMES.has(type.name))) return node;
1937
2133
  return node.mark(marks);
1938
2134
  }
1939
2135
  /**
@@ -1941,6 +2137,28 @@ function withRunBoundaryMarks(node, marks) {
1941
2137
  * none of these values and there is accordingly nothing to carry.
1942
2138
  */
1943
2139
  const authoredEmuAttrs = (values) => Object.values(values).some((value) => value !== void 0) ? values : void 0;
2140
+ /**
2141
+ * A copy of the anchor record: ProseMirror keeps object-valued attrs by
2142
+ * reference, so sharing it with the source would let a mutation of either reach
2143
+ * the other outside a transaction.
2144
+ */
2145
+ const copiedDrawingAnchor = (anchor) => anchor === void 0 ? void 0 : {
2146
+ ...anchor,
2147
+ ...anchor.simplePosition === void 0 ? {} : { simplePosition: { ...anchor.simplePosition } }
2148
+ };
2149
+ /**
2150
+ * A copy of the inset-slot record, for the reason {@link copiedDrawingAnchor}
2151
+ * is copied: ProseMirror keeps object-valued attrs by reference.
2152
+ */
2153
+ const copiedWrapDistanceSlots = (slots) => slots === void 0 ? void 0 : {
2154
+ ...slots.drawing === void 0 ? {} : { drawing: { ...slots.drawing } },
2155
+ ...slots.wrapChild === void 0 ? {} : { wrapChild: { ...slots.wrapChild } }
2156
+ };
2157
+ /** A copy of the effect-extent slots, for {@link copiedWrapDistanceSlots}'s reason. */
2158
+ const copiedEffectExtentSlots = (slots) => slots === void 0 ? void 0 : {
2159
+ ...slots.drawing === void 0 ? {} : { drawing: { ...slots.drawing } },
2160
+ ...slots.wrapChild === void 0 ? {} : { wrapChild: { ...slots.wrapChild } }
2161
+ };
1944
2162
  /** The wrap insets of a drawing, keyed by the pixel attribute each becomes. */
1945
2163
  const wrapDistanceEmu = (wrap) => ({
1946
2164
  distTop: wrap?.distT,
@@ -1998,22 +2216,11 @@ function convertImage({ image, rawXml, rawXmlMode, rawImageFingerprint, runForma
1998
2216
  if (image.outline && image.outline.width) {
1999
2217
  borderWidth = emuToStrokePixels(image.outline.width);
2000
2218
  if (image.outline.color?.rgb) borderColor = `#${image.outline.color.rgb}`;
2001
- borderStyle = image.outline.style ? {
2002
- solid: "solid",
2003
- dot: "dotted",
2004
- dash: "dashed",
2005
- lgDash: "dashed",
2006
- dashDot: "dashed",
2007
- lgDashDot: "dashed",
2008
- lgDashDotDot: "dashed",
2009
- sysDot: "dotted",
2010
- sysDash: "dashed",
2011
- sysDashDot: "dashed",
2012
- sysDashDotDot: "dashed"
2013
- }[image.outline.style] || "solid" : "solid";
2219
+ borderStyle = cssBorderStyleForDash(image.outline.dash);
2014
2220
  }
2015
2221
  return schema.node("image", {
2016
2222
  src: image.src || "",
2223
+ preview: image.preview,
2017
2224
  docPrName: image.docPrName,
2018
2225
  alt: image.alt,
2019
2226
  title: image.title,
@@ -2040,7 +2247,10 @@ function convertImage({ image, rawXml, rawXmlMode, rawImageFingerprint, runForma
2040
2247
  paddingBottom: image.padding?.bottom,
2041
2248
  paddingLeft: image.padding?.left,
2042
2249
  position,
2043
- layoutInCell: image.layoutInCell,
2250
+ anchor: copiedDrawingAnchor(image.anchor),
2251
+ wrapDistanceSlots: copiedWrapDistanceSlots(image.wrap.distanceSlots),
2252
+ wrapEffectExtentSlots: copiedEffectExtentSlots(image.wrap.effectExtentSlots),
2253
+ wrapPolygon: copiedWrapPolygon(image.wrap.polygon),
2044
2254
  decorative: image.decorative,
2045
2255
  hidden: image.hidden,
2046
2256
  docPrExtensions: image.docPrExtensions ? [...image.docPrExtensions] : void 0,
@@ -2057,6 +2267,9 @@ function convertImage({ image, rawXml, rawXmlMode, rawImageFingerprint, runForma
2057
2267
  wrapText,
2058
2268
  hlinkHref: image.hlinkHref,
2059
2269
  hlinkRId: image.hlinkRId,
2270
+ hlinkClickSource: image.hlinkClickSource ? { ...image.hlinkClickSource } : void 0,
2271
+ hlinkHoverXml: image.hlinkHoverXml,
2272
+ docPrId: image.id,
2060
2273
  _docxRawXml: rawXml,
2061
2274
  _docxRawXmlMode: rawXmlMode,
2062
2275
  _docxRawImageFingerprint: rawImageFingerprint,
@@ -2064,7 +2277,7 @@ function convertImage({ image, rawXml, rawXmlMode, rawImageFingerprint, runForma
2064
2277
  _docxRunFormatting: runFormatting
2065
2278
  });
2066
2279
  }
2067
- function convertHyperlink(hyperlink, { getInheritedRunFormatting, styleResolver, hyperlinkIndex, textBoxAnchors, nextPageBreakRunOwnerId }) {
2280
+ function convertHyperlink(hyperlink, { getInheritedRunFormatting, styleResolver, hyperlinkIndex, textBoxAnchors, nextRunIdentityId }) {
2068
2281
  const nodes = [];
2069
2282
  const href = hyperlink.href || (hyperlink.anchor ? `#${hyperlink.anchor}` : "");
2070
2283
  const linkMark = schema.mark("hyperlink", {
@@ -2073,38 +2286,42 @@ function convertHyperlink(hyperlink, { getInheritedRunFormatting, styleResolver,
2073
2286
  rId: hyperlink.rId,
2074
2287
  _docxHyperlinkIndex: hyperlinkIndex
2075
2288
  });
2076
- for (const child of hyperlink.children) {
2077
- if (child.type === "bookmarkStart") {
2078
- nodes.push(schema.node("bookmarkBoundary", {
2079
- type: "start",
2080
- id: child.id,
2081
- name: child.name,
2082
- colFirst: child.colFirst,
2083
- colLast: child.colLast,
2084
- displacedByCustomXml: child.displacedByCustomXml
2085
- }, void 0, [linkMark]));
2086
- continue;
2087
- }
2088
- if (child.type === "bookmarkEnd") {
2089
- nodes.push(schema.node("bookmarkBoundary", {
2090
- type: "end",
2091
- id: child.id,
2092
- displacedByCustomXml: child.displacedByCustomXml
2093
- }, void 0, [linkMark]));
2094
- continue;
2095
- }
2096
- if (child.type === "preservedInline") {
2097
- nodes.push(preservedInlineNode(child).mark([linkMark]));
2098
- continue;
2099
- }
2100
- if (child.type === "run") {
2101
- const inheritedFormatting = getInheritedRunFormatting(child.formatting);
2102
- const { marks: runMarks, mergedFormatting } = buildRunMarks(child.formatting, inheritedFormatting, styleResolver);
2103
- if (child.propertyChanges && child.propertyChanges.length > 0) runMarks.push(schema.mark("runPropertyChange", { changes: [...child.propertyChanges] }));
2104
- if (child.content.some((content) => content.type === "break" && content.breakType === "page")) runMarks.push(schema.mark("pageBreakRunOwner", { id: nextPageBreakRunOwnerId() }));
2105
- const allMarks = [...runMarks, linkMark];
2106
- for (const content of child.content) nodes.push(...convertRunContent(content, allMarks, mergedFormatting, textBoxAnchors, child.formatting));
2289
+ for (const { content: child, stack } of withInlineWrapperStacks(hyperlink.children)) {
2290
+ const childNodes = [];
2291
+ switch (child.type) {
2292
+ case "bookmarkStart":
2293
+ childNodes.push(schema.node("bookmarkBoundary", {
2294
+ type: "start",
2295
+ id: child.id,
2296
+ name: child.name,
2297
+ colFirst: child.colFirst,
2298
+ colLast: child.colLast,
2299
+ displacedByCustomXml: child.displacedByCustomXml
2300
+ }, void 0, [linkMark]));
2301
+ break;
2302
+ case "bookmarkEnd":
2303
+ childNodes.push(schema.node("bookmarkBoundary", {
2304
+ type: "end",
2305
+ id: child.id,
2306
+ displacedByCustomXml: child.displacedByCustomXml
2307
+ }, void 0, [linkMark]));
2308
+ break;
2309
+ case "preservedInline":
2310
+ childNodes.push(preservedInlineNode(child).mark([linkMark]));
2311
+ break;
2312
+ case "run": {
2313
+ const inheritedFormatting = getInheritedRunFormatting(child.formatting);
2314
+ const { marks: runMarks, mergedFormatting } = buildRunMarks(child.formatting, inheritedFormatting, styleResolver);
2315
+ if (child.propertyChanges && child.propertyChanges.length > 0) runMarks.push(schema.mark("runPropertyChange", { changes: [...child.propertyChanges] }));
2316
+ const identity = runIdentityMark(child, nextRunIdentityId);
2317
+ if (identity) runMarks.push(identity);
2318
+ const allMarks = [...runMarks, linkMark];
2319
+ for (const content of child.content) childNodes.push(...convertRunContent(content, allMarks, mergedFormatting, textBoxAnchors, child.formatting));
2320
+ break;
2321
+ }
2322
+ default: break;
2107
2323
  }
2324
+ nodes.push(...withInlineWrapperMark(childNodes, stack));
2108
2325
  }
2109
2326
  return nodes;
2110
2327
  }
@@ -2152,7 +2369,7 @@ function convertShape(shape, runFormatting) {
2152
2369
  outlineColorValue = shape.outline.color;
2153
2370
  outlineColor = resolveColorValueToHex(shape.outline.color);
2154
2371
  }
2155
- outlineStyle = shape.outline.style;
2372
+ outlineStyle = outlineAttrForDash(shape.outline.dash);
2156
2373
  outlineCap = shape.outline.cap;
2157
2374
  outlineJoin = shape.outline.join;
2158
2375
  outlineHeadEnd = shape.outline.headEnd;
@@ -2183,6 +2400,10 @@ function convertShape(shape, runFormatting) {
2183
2400
  geometryAdjustments: shape.geometryAdjustments === void 0 ? void 0 : JSON.stringify(shape.geometryAdjustments),
2184
2401
  shapeId: shape.id,
2185
2402
  shapeName: shape.name,
2403
+ anchor: copiedDrawingAnchor(shape.anchor),
2404
+ wrapDistanceSlots: copiedWrapDistanceSlots(shape.wrap?.distanceSlots),
2405
+ wrapEffectExtentSlots: copiedEffectExtentSlots(shape.wrap?.effectExtentSlots),
2406
+ wrapPolygon: copiedWrapPolygon(shape.wrap?.polygon),
2186
2407
  alt: shape.alt,
2187
2408
  title: shape.title,
2188
2409
  width: widthPx,
@@ -2367,6 +2588,7 @@ function textBoxFromShape(shape, textBody) {
2367
2588
  if (shape.title !== void 0) textBox.title = shape.title;
2368
2589
  if (shape.position) textBox.position = shape.position;
2369
2590
  if (shape.wrap) textBox.wrap = shape.wrap;
2591
+ if (shape.anchor) textBox.anchor = shape.anchor;
2370
2592
  if (shape.fill) textBox.fill = shape.fill;
2371
2593
  if (shape.outline) textBox.outline = shape.outline;
2372
2594
  if (shape.transform) textBox.transform = shape.transform;
@@ -2393,7 +2615,7 @@ function convertTextBox(textBox, styleResolver, options) {
2393
2615
  if (textBox.outline && textBox.outline.width) {
2394
2616
  outlineWidth = emuToStrokePixels(textBox.outline.width);
2395
2617
  if (textBox.outline.color?.rgb) outlineColor = `#${textBox.outline.color.rgb}`;
2396
- outlineStyle = textBox.outline.style || "solid";
2618
+ outlineStyle = outlineAttrForDash(textBox.outline.dash) ?? "solid";
2397
2619
  }
2398
2620
  const transformAttrs = authoredTransformAttrs(textBox.transform);
2399
2621
  const marginTop = textBox.margins?.top !== void 0 ? emuToPixels(textBox.margins.top) : void 0;
@@ -2464,6 +2686,10 @@ function convertTextBox(textBox, styleResolver, options) {
2464
2686
  marginRight: textBox.margins?.right,
2465
2687
  ...wrapDistanceEmu(textBox.wrap)
2466
2688
  }),
2689
+ anchor: copiedDrawingAnchor(textBox.anchor),
2690
+ wrapDistanceSlots: copiedWrapDistanceSlots(textBox.wrap?.distanceSlots),
2691
+ wrapEffectExtentSlots: copiedEffectExtentSlots(textBox.wrap?.effectExtentSlots),
2692
+ wrapPolygon: copiedWrapPolygon(textBox.wrap?.polygon),
2467
2693
  autoFit: textBox.autoFit,
2468
2694
  wordArt: textBox.wordArt,
2469
2695
  textWrap: textBox.textWrap,
@@ -2552,6 +2778,10 @@ function headerFooterToProseDoc(content, options) {
2552
2778
  case "preservedBlock":
2553
2779
  out.push(convertPreservedBlock(block));
2554
2780
  break;
2781
+ case "bookmarkStart":
2782
+ case "bookmarkEnd":
2783
+ out.push(convertBlockBookmarkBoundary(block));
2784
+ break;
2555
2785
  default: panic(`Unsupported block content: ${JSON.stringify(block)}`);
2556
2786
  }
2557
2787
  return out;