@stll/folio-core 0.46.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 (366) hide show
  1. package/dist/ai-edits/apply.js +26 -24
  2. package/dist/ai-edits/headless.js +1 -1
  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/content-alignment.js +108 -12
  10. package/dist/compare/content-types.d.ts +8 -2
  11. package/dist/compare/content.js +2 -11
  12. package/dist/compare/plan.js +7 -4
  13. package/dist/compare/section-boundary-properties.js +1 -2
  14. package/dist/content-controls/checkboxDisplay.d.ts +8 -2
  15. package/dist/content-controls/checkboxDisplay.js +11 -5
  16. package/dist/content-controls/mutateContentControls.js +41 -42
  17. package/dist/controller/layoutPipeline.js +8 -3
  18. package/dist/display-list/build/buildDisplayList.js +7 -7
  19. package/dist/display-list/build/imagePrimitives.d.ts +4 -4
  20. package/dist/display-list/build/imagePrimitives.js +38 -20
  21. package/dist/display-list/build/pageBorderPrimitives.js +2 -1
  22. package/dist/display-list/build/paragraphPrimitives.js +93 -13
  23. package/dist/display-list/build/previewPrimitives.d.ts +10 -0
  24. package/dist/display-list/build/previewPrimitives.js +89 -0
  25. package/dist/display-list/build/strokes.d.ts +177 -8
  26. package/dist/display-list/build/strokes.js +167 -47
  27. package/dist/display-list/build/tablePrimitives.js +4 -2
  28. package/dist/display-list/build/textBoxPrimitives.js +6 -4
  29. package/dist/display-list/build/textDecorations.d.ts +15 -1
  30. package/dist/display-list/build/textDecorations.js +15 -1
  31. package/dist/display-list/dom/renderDisplayListToDom.js +1 -19
  32. package/dist/display-list/primitives.d.ts +13 -2
  33. package/dist/display-list/primitives.js +36 -1
  34. package/dist/document-operations.js +2 -1
  35. package/dist/docx/attributeRemainder.d.ts +34 -1
  36. package/dist/docx/attributeRemainder.js +49 -3
  37. package/dist/docx/blockContentParser.d.ts +2 -0
  38. package/dist/docx/blockContentParser.js +39 -67
  39. package/dist/docx/blockPlainText.js +3 -1
  40. package/dist/docx/borderParser.js +26 -11
  41. package/dist/docx/builtInStyles.d.ts +8 -16
  42. package/dist/docx/builtInStyles.js +54 -17
  43. package/dist/docx/commentAnchorIndex.js +1 -1
  44. package/dist/docx/commentParser.js +3 -3
  45. package/dist/docx/commentRangeIntegrity.js +1 -1
  46. package/dist/docx/commentRangeJoin.js +1 -1
  47. package/dist/docx/commentReferenceNormalization.js +3 -2
  48. package/dist/docx/commentReplyMarkers.js +1 -1
  49. package/dist/docx/compatibility.js +56 -42
  50. package/dist/docx/containerChildren.d.ts +110 -13
  51. package/dist/docx/containerChildren.gen.d.ts +16 -1
  52. package/dist/docx/containerChildren.gen.js +18 -1
  53. package/dist/docx/containerChildren.js +63 -13
  54. package/dist/docx/diagramPreview.d.ts +14 -2
  55. package/dist/docx/diagramPreview.js +81 -169
  56. package/dist/docx/documentParser.js +4 -1
  57. package/dist/docx/drawingAnchor.d.ts +87 -0
  58. package/dist/docx/drawingAnchor.js +201 -0
  59. package/dist/docx/drawingUtils.d.ts +43 -38
  60. package/dist/docx/drawingUtils.js +205 -118
  61. package/dist/docx/fontTableParser.js +102 -41
  62. package/dist/docx/footnoteParser.js +10 -6
  63. package/dist/docx/groupDrawingParser.js +4 -3
  64. package/dist/docx/headerFooterReferenceNormalization.js +1 -1
  65. package/dist/docx/hyperlinkParser.d.ts +45 -7
  66. package/dist/docx/hyperlinkParser.js +126 -57
  67. package/dist/docx/imageParser.js +127 -107
  68. package/dist/docx/index.d.ts +2 -1
  69. package/dist/docx/index.js +2 -1
  70. package/dist/docx/inlineContentRemovals.d.ts +28 -0
  71. package/dist/docx/inlineContentRemovals.js +46 -0
  72. package/dist/docx/inlineWrapperContent.d.ts +84 -3
  73. package/dist/docx/inlineWrapperContent.js +85 -4
  74. package/dist/docx/inlineWrapperParser.d.ts +11 -0
  75. package/dist/docx/inlineWrapperParser.js +60 -0
  76. package/dist/docx/nonVisualDrawingProps.d.ts +5 -13
  77. package/dist/docx/normalizeBaseDirection.js +4 -2
  78. package/dist/docx/numberingParser.d.ts +25 -2
  79. package/dist/docx/numberingParser.js +264 -361
  80. package/dist/docx/numberingReference.d.ts +9 -16
  81. package/dist/docx/numberingReference.js +17 -16
  82. package/dist/docx/numberingReferenceNormalization.js +7 -7
  83. package/dist/docx/ooxmlCounterFormatter.d.ts +1 -1
  84. package/dist/docx/ooxmlCounterFormatter.js +4 -1
  85. package/dist/docx/paraIdAttribute.d.ts +91 -1
  86. package/dist/docx/paraIdAttribute.js +79 -1
  87. package/dist/docx/paragraphParser.d.ts +9 -24
  88. package/dist/docx/paragraphParser.js +212 -396
  89. package/dist/docx/paragraphProperties.d.ts +23 -0
  90. package/dist/docx/paragraphProperties.js +279 -0
  91. package/dist/docx/paragraphPropertySource.js +2 -0
  92. package/dist/docx/paragraphTextBoxEnrichment.d.ts +2 -1
  93. package/dist/docx/paragraphTextBoxEnrichment.js +14 -7
  94. package/dist/docx/paragraphTraversal.d.ts +14 -10
  95. package/dist/docx/paragraphTraversal.js +47 -49
  96. package/dist/docx/parseWarningMessage.js +3 -0
  97. package/dist/docx/parserEnums.d.ts +6 -8
  98. package/dist/docx/parserEnums.js +4 -6
  99. package/dist/docx/preservedRunContent.js +16 -6
  100. package/dist/docx/previewBudget.d.ts +44 -23
  101. package/dist/docx/previewBudget.js +61 -30
  102. package/dist/docx/propertyElementAttributes.d.ts +178 -0
  103. package/dist/docx/propertyElementAttributes.js +114 -0
  104. package/dist/docx/renderedPageBreakNormalization.js +2 -2
  105. package/dist/docx/rezip.d.ts +28 -2
  106. package/dist/docx/rezip.js +78 -9
  107. package/dist/docx/runConsolidator.d.ts +42 -2
  108. package/dist/docx/runConsolidator.js +60 -6
  109. package/dist/docx/runParser.d.ts +54 -18
  110. package/dist/docx/runParser.js +379 -295
  111. package/dist/docx/runPayload.d.ts +5 -0
  112. package/dist/docx/runPayload.js +4 -0
  113. package/dist/docx/sdtProperties.d.ts +39 -5
  114. package/dist/docx/sdtProperties.js +205 -84
  115. package/dist/docx/sdtPropertiesPatch.d.ts +5 -9
  116. package/dist/docx/sdtPropertiesPatch.js +68 -112
  117. package/dist/docx/sectionParser.d.ts +1 -2
  118. package/dist/docx/sectionParser.js +236 -240
  119. package/dist/docx/selectiveSave.js +3 -2
  120. package/dist/docx/selectiveXmlPatch.d.ts +21 -2
  121. package/dist/docx/selectiveXmlPatch.js +195 -99
  122. package/dist/docx/serializer/blockSdtSerializer.js +2 -96
  123. package/dist/docx/serializer/borderSerializer.d.ts +5 -5
  124. package/dist/docx/serializer/borderSerializer.js +10 -8
  125. package/dist/docx/serializer/documentSerializer.js +3 -0
  126. package/dist/docx/serializer/fontTableSerializer.js +31 -3
  127. package/dist/docx/serializer/headerFooterSerializer.js +3 -0
  128. package/dist/docx/serializer/markupRangeAttributes.d.ts +9 -1
  129. package/dist/docx/serializer/markupRangeAttributes.js +9 -1
  130. package/dist/docx/serializer/noteSerializer.js +3 -0
  131. package/dist/docx/serializer/numberingSerializer.d.ts +1 -6
  132. package/dist/docx/serializer/numberingSerializer.js +81 -79
  133. package/dist/docx/serializer/paragraphSerializer.d.ts +1 -9
  134. package/dist/docx/serializer/paragraphSerializer.js +88 -188
  135. package/dist/docx/serializer/runSerializer.d.ts +1 -5
  136. package/dist/docx/serializer/runSerializer.js +109 -59
  137. package/dist/docx/serializer/sdtPropertiesSerializer.d.ts +26 -0
  138. package/dist/docx/serializer/sdtPropertiesSerializer.js +111 -0
  139. package/dist/docx/serializer/sectionPropertiesSerializer.js +34 -45
  140. package/dist/docx/serializer/settingsSerializer.js +6 -4
  141. package/dist/docx/serializer/stylesSerializer.js +8 -11
  142. package/dist/docx/serializer/tableSerializer.js +268 -100
  143. package/dist/docx/serializer/textFormattingSerializer.d.ts +28 -4
  144. package/dist/docx/serializer/textFormattingSerializer.js +111 -101
  145. package/dist/docx/serializer/xmlUtils.d.ts +1 -1
  146. package/dist/docx/serializer/xmlUtils.js +1 -1
  147. package/dist/docx/server/createBilingualDocument.js +18 -16
  148. package/dist/docx/server/migrateYjsAttrSchema.js +3 -3
  149. package/dist/docx/settingsParser.js +7 -4
  150. package/dist/docx/shadingParser.d.ts +2 -1
  151. package/dist/docx/shadingParser.js +43 -7
  152. package/dist/docx/shapeParser.js +8 -3
  153. package/dist/docx/strictNames.d.ts +11 -0
  154. package/dist/docx/strictNames.gen.d.ts +45 -0
  155. package/dist/docx/strictNames.gen.js +50 -0
  156. package/dist/docx/strictNames.js +43 -0
  157. package/dist/docx/strictValueEncodings.gen.js +133 -131
  158. package/dist/docx/styleParser.js +17 -349
  159. package/dist/docx/tableParser.d.ts +10 -1
  160. package/dist/docx/tableParser.js +505 -181
  161. package/dist/docx/textBoxParser.d.ts +3 -1
  162. package/dist/docx/textBoxParser.js +18 -8
  163. package/dist/docx/themeColorAttribute.d.ts +13 -0
  164. package/dist/docx/themeColorAttribute.js +24 -0
  165. package/dist/docx/trackedMoveRangeNormalization.js +2 -1
  166. package/dist/docx/vmlImageParser.d.ts +13 -4
  167. package/dist/docx/vmlImageParser.js +74 -31
  168. package/dist/docx/vmlPreview.js +2 -2
  169. package/dist/docx/wrapPolygon.d.ts +30 -0
  170. package/dist/docx/wrapPolygon.js +70 -0
  171. package/dist/docx/xmlParser.d.ts +14 -1
  172. package/dist/docx/xmlParser.js +18 -2
  173. package/dist/fonts/embeddedFonts.js +3 -3
  174. package/dist/headless-layout.js +2 -0
  175. package/dist/i18n/messages/catalogs.gen.d.ts +68 -0
  176. package/dist/i18n/messages/catalogs.gen.js +102 -34
  177. package/dist/i18n/messages/messages.gen.d.ts +4 -0
  178. package/dist/internal/headlessRevisionResolution.js +9 -0
  179. package/dist/internal/pageBreakRunSourceDescendantIndex.js +3 -1
  180. package/dist/internal/paragraphFormattingSerialization.d.ts +20 -9
  181. package/dist/internal/paragraphFormattingSerialization.js +118 -83
  182. package/dist/layout-bridge/convert/footnoteLayout.d.ts +1 -0
  183. package/dist/layout-bridge/convert/footnoteLayout.js +1 -0
  184. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -0
  185. package/dist/layout-bridge/convert/headerFooterLayout.js +2 -0
  186. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +17 -12
  187. package/dist/layout-bridge/convert/toFlowBlocks.js +177 -101
  188. package/dist/layout-engine/index.d.ts +2 -2
  189. package/dist/layout-engine/index.js +53 -17
  190. package/dist/layout-engine/measure/measureBlocks.d.ts +3 -0
  191. package/dist/layout-engine/measure/measureBlocks.js +6 -10
  192. package/dist/layout-engine/measure/tableCellGrid.js +2 -1
  193. package/dist/layout-engine/measure/tableFragmentBorderGeometry.js +2 -1
  194. package/dist/layout-engine/measure/tableInlinePlacement.js +2 -5
  195. package/dist/layout-engine/paragraphSequence.js +3 -2
  196. package/dist/layout-engine/renderedBreakReconciliation.js +2 -1
  197. package/dist/layout-engine/section-breaks.d.ts +49 -2
  198. package/dist/layout-engine/section-breaks.js +55 -4
  199. package/dist/layout-engine/types.d.ts +47 -17
  200. package/dist/layout-engine/types.js +16 -1
  201. package/dist/layout-painter/borderStroke.d.ts +18 -4
  202. package/dist/layout-painter/renderPage.js +6 -4
  203. package/dist/layout-painter/renderParagraph.d.ts +2 -1
  204. package/dist/layout-painter/renderParagraph.js +13 -26
  205. package/dist/layout-painter/renderTable.d.ts +4 -1
  206. package/dist/layout-painter/renderTable.js +22 -22
  207. package/dist/layout-painter/renderTextBox.js +5 -3
  208. package/dist/markdown/renderBlock.js +3 -1
  209. package/dist/markdown/renderRuns.js +7 -2
  210. package/dist/markdown/renderTable.js +2 -1
  211. package/dist/model.d.ts +3 -3
  212. package/dist/model.js +2 -2
  213. package/dist/paged-layout/sectionBlockWidths.d.ts +3 -0
  214. package/dist/paged-layout/sectionBlockWidths.js +26 -4
  215. package/dist/prosemirror/attrs/index.d.ts +22 -4
  216. package/dist/prosemirror/attrs/index.js +498 -60
  217. package/dist/prosemirror/bookmarkBoundaryAttrs.d.ts +9 -1
  218. package/dist/prosemirror/bookmarkBoundaryAttrs.js +22 -3
  219. package/dist/prosemirror/commands/comments.js +68 -53
  220. package/dist/prosemirror/commands/contentControls.js +24 -19
  221. package/dist/prosemirror/commands/image.d.ts +1 -1
  222. package/dist/prosemirror/commands/image.js +4 -1
  223. package/dist/prosemirror/commands/paragraph.d.ts +2 -1
  224. package/dist/prosemirror/commands/propertyChangeScope.d.ts +12 -4
  225. package/dist/prosemirror/commands/propertyChangeScope.js +22 -4
  226. package/dist/prosemirror/commands/sectionBreak.d.ts +33 -1
  227. package/dist/prosemirror/commands/sectionBreak.js +187 -11
  228. package/dist/prosemirror/conversion/fromProseDoc.d.ts +18 -2
  229. package/dist/prosemirror/conversion/fromProseDoc.js +330 -183
  230. package/dist/prosemirror/conversion/index.d.ts +2 -2
  231. package/dist/prosemirror/conversion/preservedSinkCarriers.d.ts +39 -0
  232. package/dist/prosemirror/conversion/preservedSinkCarriers.js +19 -0
  233. package/dist/prosemirror/conversion/runShadingMark.js +14 -1
  234. package/dist/prosemirror/conversion/sdtAttrs.d.ts +10 -1
  235. package/dist/prosemirror/conversion/sdtAttrs.js +19 -5
  236. package/dist/prosemirror/conversion/toProseDoc.js +371 -141
  237. package/dist/prosemirror/emptyRangeAnchor.d.ts +53 -0
  238. package/dist/prosemirror/emptyRangeAnchor.js +158 -0
  239. package/dist/prosemirror/extensions/StarterKit.js +8 -2
  240. package/dist/prosemirror/extensions/core/DocExtension.js +1 -1
  241. package/dist/prosemirror/extensions/core/ParagraphExtension.js +19 -15
  242. package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +3 -2
  243. package/dist/prosemirror/extensions/features/ListExtension.js +43 -24
  244. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +4 -3
  245. package/dist/prosemirror/extensions/features/PasteCleanupExtension.d.ts +3 -3
  246. package/dist/prosemirror/extensions/features/PasteCleanupExtension.js +5 -5
  247. package/dist/prosemirror/extensions/features/pasteCleanup.d.ts +3 -1
  248. package/dist/prosemirror/extensions/features/pasteCleanup.js +56 -2
  249. package/dist/prosemirror/extensions/features/pastedHeadingStyles.js +5 -4
  250. package/dist/prosemirror/extensions/markRegistry.d.ts +26 -2
  251. package/dist/prosemirror/extensions/markRegistry.js +73 -10
  252. package/dist/prosemirror/extensions/marks/InlineWrapperExtension.js +17 -3
  253. package/dist/prosemirror/extensions/marks/RunIdentityExtension.d.ts +26 -0
  254. package/dist/prosemirror/extensions/marks/RunIdentityExtension.js +134 -0
  255. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +2 -1
  256. package/dist/prosemirror/extensions/marks/UnderlineExtension.js +12 -18
  257. package/dist/prosemirror/extensions/marks/markUtils.js +2 -1
  258. package/dist/prosemirror/extensions/nodes/BlockBookmarkBoundaryExtension.d.ts +29 -0
  259. package/dist/prosemirror/extensions/nodes/BlockBookmarkBoundaryExtension.js +46 -0
  260. package/dist/prosemirror/extensions/nodes/BlockSdtExtension.d.ts +4 -3
  261. package/dist/prosemirror/extensions/nodes/BlockSdtExtension.js +18 -13
  262. package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.js +28 -53
  263. package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +10 -0
  264. package/dist/prosemirror/extensions/nodes/ImageExtension.js +8 -1
  265. package/dist/prosemirror/extensions/nodes/MoveRangeBoundaryExtension.d.ts +11 -0
  266. package/dist/prosemirror/extensions/nodes/MoveRangeBoundaryExtension.js +43 -0
  267. package/dist/prosemirror/extensions/nodes/RangeAnchorExtension.d.ts +13 -0
  268. package/dist/prosemirror/extensions/nodes/RangeAnchorExtension.js +65 -0
  269. package/dist/prosemirror/extensions/nodes/SdtExtension.d.ts +3 -1
  270. package/dist/prosemirror/extensions/nodes/SdtExtension.js +22 -16
  271. package/dist/prosemirror/extensions/nodes/ShapeExtension.js +4 -0
  272. package/dist/prosemirror/extensions/nodes/TableExtension.js +141 -123
  273. package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +4 -0
  274. package/dist/prosemirror/extensions/nodes/bookmarkBoundaryDom.d.ts +23 -0
  275. package/dist/prosemirror/extensions/nodes/bookmarkBoundaryDom.js +57 -0
  276. package/dist/prosemirror/extensions/types.d.ts +12 -3
  277. package/dist/prosemirror/index.d.ts +4 -2
  278. package/dist/prosemirror/index.js +2 -1
  279. package/dist/prosemirror/inlineWrapperStack.js +20 -3
  280. package/dist/prosemirror/listMarker.d.ts +2 -2
  281. package/dist/prosemirror/listMarker.js +7 -8
  282. package/dist/prosemirror/listRenderingAttrs.js +11 -1
  283. package/dist/prosemirror/listState.d.ts +62 -0
  284. package/dist/prosemirror/listState.js +49 -0
  285. package/dist/prosemirror/moveRangeBoundaryAttrs.d.ts +13 -0
  286. package/dist/prosemirror/moveRangeBoundaryAttrs.js +114 -0
  287. package/dist/prosemirror/numberedRefFields.js +4 -4
  288. package/dist/prosemirror/numberingAttr.d.ts +55 -0
  289. package/dist/prosemirror/numberingAttr.js +74 -0
  290. package/dist/prosemirror/outlineLevelAttr.d.ts +29 -0
  291. package/dist/prosemirror/outlineLevelAttr.js +42 -0
  292. package/dist/prosemirror/paragraphFormattingProvenance.d.ts +9 -0
  293. package/dist/prosemirror/paragraphFormattingProvenance.js +4 -1
  294. package/dist/prosemirror/plugins/selectionTracker.d.ts +3 -6
  295. package/dist/prosemirror/plugins/selectionTracker.js +3 -10
  296. package/dist/prosemirror/rangeAnchorAttrs.d.ts +14 -0
  297. package/dist/prosemirror/rangeAnchorAttrs.js +101 -0
  298. package/dist/prosemirror/replacedAnnotations.d.ts +1 -1
  299. package/dist/prosemirror/replacedAnnotations.js +24 -6
  300. package/dist/prosemirror/revisionCarriers.d.ts +86 -2
  301. package/dist/prosemirror/revisionCarriers.js +86 -60
  302. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +2 -0
  303. package/dist/prosemirror/runFormattingInlineCarriers.js +2 -0
  304. package/dist/prosemirror/runIdentity.d.ts +28 -0
  305. package/dist/prosemirror/runIdentity.js +36 -0
  306. package/dist/prosemirror/runStyleFormatting.js +1 -1
  307. package/dist/prosemirror/schema/index.d.ts +2 -2
  308. package/dist/prosemirror/schema/marks.d.ts +23 -4
  309. package/dist/prosemirror/schema/nodes.d.ts +220 -24
  310. package/dist/prosemirror/sectionCarrier.d.ts +37 -0
  311. package/dist/prosemirror/sectionCarrier.js +40 -0
  312. package/dist/prosemirror/selectionState.d.ts +3 -0
  313. package/dist/prosemirror/selectionState.js +4 -1
  314. package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +5 -4
  315. package/dist/prosemirror/styles/resolvedStyleAttrs.js +15 -13
  316. package/dist/prosemirror/tableResize.js +5 -6
  317. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +2 -0
  318. package/dist/prosemirror/trackedRunInlineAtoms.js +2 -0
  319. package/dist/prosemirror/utils/extractTrackedChanges.d.ts +10 -11
  320. package/dist/prosemirror/utils/extractTrackedChanges.js +109 -92
  321. package/dist/prosemirror/validation.js +17 -6
  322. package/dist/prosemirror/yjsDocumentMetadata.d.ts +2 -2
  323. package/dist/prosemirror/yjsDocumentMetadata.js +428 -7
  324. package/dist/prosemirror/zeroWidthAnchors.js +4 -0
  325. package/dist/style-sets/extract.js +4 -4
  326. package/dist/style-sets/stellaStyle.js +36 -23
  327. package/dist/types/colors.d.ts +2 -2
  328. package/dist/types/content.d.ts +2 -2
  329. package/dist/types/documentEnumValues.d.ts +53 -26
  330. package/dist/types/documentEnumValues.js +72 -174
  331. package/dist/types/formatting.d.ts +2 -2
  332. package/dist/types/index.d.ts +9 -2
  333. package/dist/utils/borderCss.d.ts +246 -0
  334. package/dist/utils/borderCss.js +325 -0
  335. package/dist/utils/colorResolver.d.ts +4 -3
  336. package/dist/utils/colorResolver.js +45 -76
  337. package/dist/utils/createDocument.js +24 -6
  338. package/dist/utils/findReplace.js +52 -10
  339. package/dist/utils/formatToStyle.d.ts +84 -2
  340. package/dist/utils/formatToStyle.js +133 -52
  341. package/dist/utils/headingCollector.js +3 -2
  342. package/dist/utils/mergeDocumentContent.js +5 -3
  343. package/dist/utils/paragraphFormattingMerge.js +27 -6
  344. package/dist/utils/replaceText.js +1 -1
  345. package/dist/utils/tableOperations.d.ts +5 -3
  346. package/dist/utils/tableOperations.js +14 -1
  347. package/dist/utils/tablePlacement.d.ts +7 -0
  348. package/dist/utils/tablePlacement.js +14 -0
  349. package/dist/utils/textDirectionFlow.d.ts +15 -0
  350. package/dist/utils/textDirectionFlow.js +38 -0
  351. package/dist/utils/textFormattingMerge.js +16 -4
  352. package/package.json +10 -10
  353. package/dist/ai-edits/__fixtures__/paragraphs.d.ts +0 -17
  354. package/dist/ai-edits/__fixtures__/paragraphs.js +0 -33
  355. package/dist/compare/__fixtures__/body-sequence.d.ts +0 -119
  356. package/dist/compare/__fixtures__/body-sequence.js +0 -225
  357. package/dist/compare/__fixtures__/nested-table.d.ts +0 -16
  358. package/dist/compare/__fixtures__/nested-table.js +0 -50
  359. package/dist/compare/__fixtures__/numbered-list.d.ts +0 -34
  360. package/dist/compare/__fixtures__/numbered-list.js +0 -85
  361. package/dist/docx/bookmarkPlacement.d.ts +0 -9
  362. package/dist/docx/bookmarkPlacement.js +0 -52
  363. package/dist/fonts/embeddedFontTable.d.ts +0 -45
  364. package/dist/fonts/embeddedFontTable.js +0 -80
  365. package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.d.ts +0 -13
  366. package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.js +0 -39
@@ -1,17 +1,18 @@
1
1
  import { NO_MODELLED_ATTRIBUTES, attributeRemainder } from "./attributeRemainder.js";
2
2
  import { parseBookmarkEnd, parseBookmarkStart } from "./bookmarkParser.js";
3
- import { appendBookmarkMarkerToLastParagraphInBlocks, appendBookmarkMarkerToLastParagraphInCells, prependBookmarkMarkersToFirstParagraphInBlocks, prependBookmarkMarkersToFirstParagraphInCell } from "./bookmarkPlacement.js";
4
3
  import { parseBorderSpec } from "./borderParser.js";
5
- import { CAPTURE, OWNED_ELSEWHERE, dispatchChildren, withPreservedChildren } from "./containerChildren.js";
4
+ import { CAPTURE, dispatchChildren, keptUnless, ownedElsewhere, sequencePositions, withPreservedChildren } from "./containerChildren.js";
6
5
  import { parseParagraph } from "./paragraphParser.js";
7
6
  import { enrichParagraphTextBoxes } from "./paragraphTextBoxEnrichment.js";
8
- import { FloatingTableXSpecSchema, FloatingTableYSpecSchema, TableCellTextDirectionSchema, narrowEnum } from "./parserEnums.js";
7
+ import { FloatingTableXSpecSchema, FloatingTableYSpecSchema, TableAlignmentSchema, TextDirectionSchema, narrowEnum } from "./parserEnums.js";
8
+ import { captureSdtSiblingMarkers, parseSdtProperties } from "./sdtProperties.js";
9
9
  import { parseShading } from "./shadingParser.js";
10
+ import { findChildAnySpelling } from "./strictNames.js";
10
11
  import { TABLE_LOOK_FLAGS } from "./tableLook.js";
11
12
  import { parsePropertyChangeInfo, parseTrackedChangeInfo } from "./trackedChangeInfo.js";
12
13
  import { percentageSpelling, transitionalSlotEncoding } from "./transitionalSpelling.js";
13
14
  import { captureVerbatimXml } from "./verbatimCapture.js";
14
- import { cloneElement, findChild, findChildByLocalName, findChildren, getAttribute, getLocalName, mergeXmlnsDeclarations, parseBooleanElement, parseNumericAttribute, parseOnOffAttribute, parseTableMeasurementValue, selectAlternateContentBranch } from "./xmlParser.js";
15
+ import { cloneElement, findChild, findChildren, findWordprocessingChild, getAttribute, getLocalName, mergeXmlnsDeclarations, parseBooleanElement, parseNumericAttribute, parseOnOffAttribute, parseTableMeasurementValue, selectAlternateContentBranch } from "./xmlParser.js";
15
16
  //#region src/docx/tableParser.ts
16
17
  /**
17
18
  * Sanity cap on `w:gridSpan` (and the derived table column count). Word's
@@ -78,9 +79,9 @@ function parseTableBorders(bordersElement) {
78
79
  if (top) borders.top = top;
79
80
  const bottom = parseBorderSpec(findChild(bordersElement, "w", "bottom"));
80
81
  if (bottom) borders.bottom = bottom;
81
- const left = parseBorderSpec(findChild(bordersElement, "w", "left") ?? findChild(bordersElement, "w", "start"));
82
+ const left = parseBorderSpec(findChildAnySpelling(bordersElement, "CT_Border left"));
82
83
  if (left) borders.left = left;
83
- const right = parseBorderSpec(findChild(bordersElement, "w", "right") ?? findChild(bordersElement, "w", "end"));
84
+ const right = parseBorderSpec(findChildAnySpelling(bordersElement, "CT_Border right"));
84
85
  if (right) borders.right = right;
85
86
  const insideH = parseBorderSpec(findChild(bordersElement, "w", "insideH"));
86
87
  if (insideH) borders.insideH = insideH;
@@ -112,9 +113,9 @@ function parseCellMargins(marginsElement) {
112
113
  if (top) margins.top = top;
113
114
  const bottom = parseWidth(findChild(marginsElement, "w", "bottom"));
114
115
  if (bottom) margins.bottom = bottom;
115
- const left = parseWidth(findChild(marginsElement, "w", "left") ?? findChild(marginsElement, "w", "start"));
116
+ const left = parseWidth(findChildAnySpelling(marginsElement, "CT_TblWidth left"));
116
117
  if (left) margins.left = left;
117
- const right = parseWidth(findChild(marginsElement, "w", "right") ?? findChild(marginsElement, "w", "end"));
118
+ const right = parseWidth(findChildAnySpelling(marginsElement, "CT_TblWidth right"));
118
119
  if (right) margins.right = right;
119
120
  if (Object.keys(margins).length === 0) return;
120
121
  return margins;
@@ -189,6 +190,7 @@ function parseFloatingTableProperties(tblpPrElement) {
189
190
  */
190
191
  const REVISION_PROPERTY_CHILDREN = /* @__PURE__ */ new Set([
191
192
  "tblPrChange",
193
+ "tblPrExChange",
192
194
  "trPrChange",
193
195
  "tcPrChange",
194
196
  "ins",
@@ -206,50 +208,223 @@ const withSourceXml = (formatting, element) => ({
206
208
  ...formatting,
207
209
  sourceXml: captureVerbatimXml(cloneElement(element, { elements: (element.elements ?? []).filter((child) => !REVISION_PROPERTY_CHILDREN.has(getLocalName(child.name))) }))
208
210
  });
211
+ /**
212
+ * The nine children `w:tblPr` and `w:tblPrEx` both declare, read once.
213
+ *
214
+ * `CT_TblPrEx` is the middle of `CT_TblPrBase`: the same elements, declared in
215
+ * the same order, without the ones that describe the table as a whole. Two
216
+ * handler maps over the same names would be two answers to the same question,
217
+ * and the one folio would notice is the day they stop agreeing.
218
+ */
219
+ const sharedTablePropertyHandlers = (formatting) => ({
220
+ tblW: (child) => {
221
+ const width = parseWidth(child);
222
+ if (width) formatting.width = width;
223
+ return keptUnless(width !== void 0);
224
+ },
225
+ jc: (child) => {
226
+ const justification = narrowEnum(getAttribute(child, "w", "val"), TableAlignmentSchema);
227
+ if (justification !== void 0) formatting.justification = justification;
228
+ return keptUnless(justification !== void 0);
229
+ },
230
+ tblCellSpacing: (child) => {
231
+ const cellSpacing = parseWidth(child);
232
+ if (cellSpacing) formatting.cellSpacing = cellSpacing;
233
+ return keptUnless(cellSpacing !== void 0);
234
+ },
235
+ tblInd: (child) => {
236
+ const indent = parseWidth(child);
237
+ if (indent) formatting.indent = indent;
238
+ return keptUnless(indent !== void 0);
239
+ },
240
+ tblBorders: (child) => {
241
+ const borders = parseTableBorders(child);
242
+ if (borders) formatting.borders = borders;
243
+ return keptUnless(borders !== void 0);
244
+ },
245
+ shd: (child) => {
246
+ const shading = parseShading(child);
247
+ if (shading) formatting.shading = shading;
248
+ return keptUnless(shading !== void 0);
249
+ },
250
+ tblLayout: (child) => {
251
+ const layout = getAttribute(child, "w", "type");
252
+ if (layout === "fixed" || layout === "autofit") {
253
+ formatting.layout = layout;
254
+ return;
255
+ }
256
+ return CAPTURE;
257
+ },
258
+ tblCellMar: (child) => {
259
+ const cellMargins = parseCellMargins(child);
260
+ if (cellMargins) formatting.cellMargins = cellMargins;
261
+ return keptUnless(cellMargins !== void 0);
262
+ },
263
+ tblLook: (child) => {
264
+ const look = parseTableLook(child);
265
+ if (look) formatting.look = look;
266
+ return keptUnless(look !== void 0);
267
+ }
268
+ });
269
+ /**
270
+ * The children the table walks skip, and the reader that takes each instead.
271
+ *
272
+ * Every one of them is read off its container element before the child walk
273
+ * runs, so capturing it here as well would write it twice. The claims are at
274
+ * module scope, not inside the parsers, so they are registered when the module
275
+ * loads rather than the first time a table is parsed; `ownedElsewhere` is the
276
+ * only way to make one, which is what keeps the set complete.
277
+ */
278
+ const TABLE_PROPERTY_CHANGE_OWNER = ownedElsewhere({
279
+ container: "table-properties",
280
+ child: "tblPrChange",
281
+ reader: "tableParser#parseTable"
282
+ });
283
+ const TABLE_PROPERTY_EXCEPTION_CHANGE_OWNER = ownedElsewhere({
284
+ container: "table-property-exceptions",
285
+ child: "tblPrExChange",
286
+ reader: "tableParser#parseTableRow"
287
+ });
288
+ const CELL_PROPERTIES_OWNER = ownedElsewhere({
289
+ container: "block-content",
290
+ child: "tcPr",
291
+ reader: "tableParser#parseTableCell"
292
+ });
293
+ /**
294
+ * The revisions a row's and a cell's property set carry.
295
+ *
296
+ * Each is read off the property element before its child walk runs, into
297
+ * `TableRow.structuralChange` / `propertyChanges` and the cell's equivalents,
298
+ * and written back from there. Capturing one here as well would write it twice,
299
+ * and worse: a capture replays a resolved revision into the document after a
300
+ * reviewer accepted it.
301
+ */
302
+ const ROW_INSERTION_OWNER = ownedElsewhere({
303
+ container: "row-properties",
304
+ child: "ins",
305
+ reader: "tableParser#parseTableRow"
306
+ });
307
+ const ROW_DELETION_OWNER = ownedElsewhere({
308
+ container: "row-properties",
309
+ child: "del",
310
+ reader: "tableParser#parseTableRow"
311
+ });
312
+ const ROW_PROPERTY_CHANGE_OWNER = ownedElsewhere({
313
+ container: "row-properties",
314
+ child: "trPrChange",
315
+ reader: "tableParser#parseTableRow"
316
+ });
317
+ const CELL_INSERTION_OWNER = ownedElsewhere({
318
+ container: "cell-properties",
319
+ child: "cellIns",
320
+ reader: "tableParser#parseTableCell"
321
+ });
322
+ const CELL_DELETION_OWNER = ownedElsewhere({
323
+ container: "cell-properties",
324
+ child: "cellDel",
325
+ reader: "tableParser#parseTableCell"
326
+ });
327
+ const CELL_MERGE_OWNER = ownedElsewhere({
328
+ container: "cell-properties",
329
+ child: "cellMerge",
330
+ reader: "tableParser#parseTableCell"
331
+ });
332
+ const CELL_PROPERTY_CHANGE_OWNER = ownedElsewhere({
333
+ container: "cell-properties",
334
+ child: "tcPrChange",
335
+ reader: "tableParser#parseTableCell"
336
+ });
337
+ const ROW_CHILD_OWNERS = {
338
+ trPr: ownedElsewhere({
339
+ container: "row-content",
340
+ child: "trPr",
341
+ reader: "tableParser#parseTableRowProperties"
342
+ }),
343
+ tblPrEx: ownedElsewhere({
344
+ container: "row-content",
345
+ child: "tblPrEx",
346
+ reader: "tableParser#parseTablePropertyExceptions"
347
+ })
348
+ };
349
+ const TABLE_CHILD_OWNERS = {
350
+ tblPr: ownedElsewhere({
351
+ container: "table-content",
352
+ child: "tblPr",
353
+ reader: "tableParser#parseTableProperties"
354
+ }),
355
+ tblGrid: ownedElsewhere({
356
+ container: "table-content",
357
+ child: "tblGrid",
358
+ reader: "tableParser#parseTableGrid"
359
+ })
360
+ };
209
361
  function parseTableProperties(tblPrElement) {
210
362
  if (!tblPrElement) return;
211
363
  const formatting = {};
212
- const width = parseWidth(findChild(tblPrElement, "w", "tblW"));
213
- if (width) formatting.width = width;
214
- const jcElement = findChild(tblPrElement, "w", "jc");
215
- if (jcElement) {
216
- const jcVal = getAttribute(jcElement, "w", "val");
217
- if (jcVal === "left" || jcVal === "center" || jcVal === "right" || jcVal === "start") formatting.justification = jcVal === "start" ? "left" : jcVal;
218
- }
219
- const cellSpacing = parseWidth(findChild(tblPrElement, "w", "tblCellSpacing"));
220
- if (cellSpacing) formatting.cellSpacing = cellSpacing;
221
- const indent = parseWidth(findChild(tblPrElement, "w", "tblInd"));
222
- if (indent) formatting.indent = indent;
223
- const borders = parseTableBorders(findChild(tblPrElement, "w", "tblBorders"));
224
- if (borders) formatting.borders = borders;
225
- const cellMargins = parseCellMargins(findChild(tblPrElement, "w", "tblCellMar"));
226
- if (cellMargins) formatting.cellMargins = cellMargins;
227
- const layoutElement = findChild(tblPrElement, "w", "tblLayout");
228
- if (layoutElement) {
229
- const layoutVal = getAttribute(layoutElement, "w", "type");
230
- if (layoutVal === "fixed" || layoutVal === "autofit") formatting.layout = layoutVal;
231
- }
232
- const styleElement = findChild(tblPrElement, "w", "tblStyle");
233
- if (styleElement) {
234
- const styleId = getAttribute(styleElement, "w", "val");
235
- if (styleId) formatting.styleId = styleId;
236
- }
237
- const look = parseTableLook(findChild(tblPrElement, "w", "tblLook"));
238
- if (look) formatting.look = look;
239
- const shading = parseShading(findChild(tblPrElement, "w", "shd"));
240
- if (shading) formatting.shading = shading;
241
- const overlapElement = findChild(tblPrElement, "w", "tblOverlap");
242
- if (overlapElement) {
243
- const overlapVal = getAttribute(overlapElement, "w", "val");
244
- if (overlapVal === "never" || overlapVal === "overlap") formatting.overlap = overlapVal;
245
- }
246
- const floating = parseFloatingTableProperties(findChild(tblPrElement, "w", "tblpPr"));
247
- if (floating) formatting.floating = floating;
248
- const bidiVisual = findChild(tblPrElement, "w", "bidiVisual");
249
- if (bidiVisual) formatting.bidi = parseBooleanElement(bidiVisual);
364
+ const preserved = dispatchChildren({
365
+ element: tblPrElement,
366
+ container: "table-properties",
367
+ handlers: {
368
+ ...sharedTablePropertyHandlers(formatting),
369
+ tblStyle: (child) => {
370
+ const styleId = getAttribute(child, "w", "val");
371
+ if (styleId) formatting.styleId = styleId;
372
+ return keptUnless(Boolean(styleId));
373
+ },
374
+ tblpPr: (child) => {
375
+ const floating = parseFloatingTableProperties(child);
376
+ if (floating) formatting.floating = floating;
377
+ return keptUnless(floating !== void 0);
378
+ },
379
+ tblOverlap: (child) => {
380
+ const overlap = getAttribute(child, "w", "val");
381
+ if (overlap === "never" || overlap === "overlap") {
382
+ formatting.overlap = overlap;
383
+ return;
384
+ }
385
+ return CAPTURE;
386
+ },
387
+ bidiVisual: (child) => {
388
+ formatting.bidi = parseBooleanElement(child);
389
+ },
390
+ tblStyleRowBandSize: (child) => {
391
+ const size = parseNumericAttribute(child, "w", "val");
392
+ if (size !== void 0) formatting.rowBandSize = size;
393
+ return keptUnless(size !== void 0);
394
+ },
395
+ tblStyleColBandSize: (child) => {
396
+ const size = parseNumericAttribute(child, "w", "val");
397
+ if (size !== void 0) formatting.columnBandSize = size;
398
+ return keptUnless(size !== void 0);
399
+ },
400
+ tblCaption: (child) => {
401
+ const caption = getAttribute(child, "w", "val");
402
+ if (caption !== null) formatting.caption = caption;
403
+ return keptUnless(caption !== null);
404
+ },
405
+ tblDescription: (child) => {
406
+ const description = getAttribute(child, "w", "val");
407
+ if (description !== null) formatting.description = description;
408
+ return keptUnless(description !== null);
409
+ },
410
+ tblPrChange: TABLE_PROPERTY_CHANGE_OWNER
411
+ },
412
+ capturePosition: sequencePositions("table-properties", tblPrElement)
413
+ });
414
+ if (preserved) formatting.preserved = preserved;
250
415
  if (Object.keys(formatting).length === 0) return;
251
416
  return withSourceXml(formatting, tblPrElement);
252
417
  }
418
+ /**
419
+ * A revision is the author, the date and the id; the snapshot may be empty.
420
+ *
421
+ * `<w:tblPrChange …><w:tblPr/></w:tblPrChange>` on a table that states no
422
+ * properties of its own records that a reviewer changed the table's
423
+ * properties from nothing to nothing — an accepted style change, most often.
424
+ * Dropping it because neither snapshot carried a typed value threw the
425
+ * revision away, and with it the reviewer's ability to accept or reject.
426
+ * `w:pPrChange` and `w:rPrChange` never did this.
427
+ */
253
428
  function parseTablePropertyChanges(tblPrElement, currentFormatting) {
254
429
  if (!tblPrElement) return;
255
430
  const changes = findChildren(tblPrElement, "w", "tblPrChange").map((changeElement) => {
@@ -262,7 +437,45 @@ function parseTablePropertyChanges(tblPrElement, currentFormatting) {
262
437
  if (prev !== void 0) change.previousFormatting = prev;
263
438
  if (currentFormatting !== void 0) change.currentFormatting = currentFormatting;
264
439
  return change;
265
- }).filter((change) => change.previousFormatting || change.currentFormatting);
440
+ });
441
+ return changes.length > 0 ? changes : void 0;
442
+ }
443
+ /**
444
+ * Parse a row's table property exceptions (`w:tblPrEx`).
445
+ *
446
+ * The nine children are the table's own, read by the same handlers, so an
447
+ * exception and the property it overrides can never be read into two different
448
+ * shapes. `w:tblPrExChange` is a revision rather than a property and is read by
449
+ * {@link parseTablePropertyExceptionChanges}.
450
+ */
451
+ function parseTablePropertyExceptions(tblPrExElement) {
452
+ if (!tblPrExElement) return;
453
+ const formatting = {};
454
+ const preserved = dispatchChildren({
455
+ element: tblPrExElement,
456
+ container: "table-property-exceptions",
457
+ handlers: {
458
+ ...sharedTablePropertyHandlers(formatting),
459
+ tblPrExChange: TABLE_PROPERTY_EXCEPTION_CHANGE_OWNER
460
+ },
461
+ capturePosition: sequencePositions("table-property-exceptions", tblPrExElement)
462
+ });
463
+ if (preserved) formatting.preserved = preserved;
464
+ return withSourceXml(formatting, tblPrExElement);
465
+ }
466
+ /** `w:tblPrExChange`, read the way `w:tblPrChange` is. */
467
+ function parseTablePropertyExceptionChanges(tblPrExElement, currentFormatting) {
468
+ if (!tblPrExElement) return;
469
+ const changes = findChildren(tblPrExElement, "w", "tblPrExChange").map((changeElement) => {
470
+ const change = {
471
+ type: "tablePropertyExceptionChange",
472
+ info: parsePropertyChangeInfo(changeElement)
473
+ };
474
+ const prev = parseTablePropertyExceptions(findChild(changeElement, "w", "tblPrEx"));
475
+ if (prev !== void 0) change.previousFormatting = prev;
476
+ if (currentFormatting !== void 0) change.currentFormatting = currentFormatting;
477
+ return change;
478
+ });
266
479
  return changes.length > 0 ? changes : void 0;
267
480
  }
268
481
  function parseTableRowPropertyChanges(trPrElement, currentFormatting) {
@@ -277,7 +490,7 @@ function parseTableRowPropertyChanges(trPrElement, currentFormatting) {
277
490
  if (prev !== void 0) change.previousFormatting = prev;
278
491
  if (currentFormatting !== void 0) change.currentFormatting = currentFormatting;
279
492
  return change;
280
- }).filter((change) => change.previousFormatting || change.currentFormatting);
493
+ });
281
494
  return changes.length > 0 ? changes : void 0;
282
495
  }
283
496
  function parseTableCellPropertyChanges(tcPrElement, currentFormatting) {
@@ -290,9 +503,11 @@ function parseTableCellPropertyChanges(tcPrElement, currentFormatting) {
290
503
  };
291
504
  const prev = parseTableCellProperties(previousTcPr);
292
505
  if (prev !== void 0) change.previousFormatting = prev;
506
+ const previousStructuralChange = parseTableCellStructuralChange(previousTcPr);
507
+ if (previousStructuralChange !== void 0) change.previousStructuralChange = previousStructuralChange;
293
508
  if (currentFormatting !== void 0) change.currentFormatting = currentFormatting;
294
509
  return change;
295
- }).filter((change) => change.previousFormatting || change.currentFormatting);
510
+ });
296
511
  return changes.length > 0 ? changes : void 0;
297
512
  }
298
513
  function parseTableRowStructuralChange(trPrElement) {
@@ -345,37 +560,68 @@ function parseTableCellVerticalMergeRevisionValue(value) {
345
560
  function parseTableRowProperties(trPrElement) {
346
561
  if (!trPrElement) return;
347
562
  const formatting = {};
348
- const gridBefore = parseNumericAttribute(findChild(trPrElement, "w", "gridBefore"), "w", "val");
349
- if (gridBefore !== void 0 && gridBefore > 0) formatting.gridBefore = gridBefore;
350
- const widthBefore = parseTableMeasurement(findChild(trPrElement, "w", "wBefore"));
351
- if (widthBefore) formatting.widthBefore = widthBefore;
352
- const gridAfter = parseNumericAttribute(findChild(trPrElement, "w", "gridAfter"), "w", "val");
353
- if (gridAfter !== void 0 && gridAfter > 0) formatting.gridAfter = gridAfter;
354
- const widthAfter = parseTableMeasurement(findChild(trPrElement, "w", "wAfter"));
355
- if (widthAfter) formatting.widthAfter = widthAfter;
356
- const heightElement = findChild(trPrElement, "w", "trHeight");
357
- if (heightElement) {
358
- const heightVal = parseNumericAttribute(heightElement, "w", "val");
359
- if (heightVal !== void 0 && heightVal > 0) {
360
- formatting.height = {
361
- value: heightVal,
362
- type: "dxa"
363
- };
364
- const hRule = getAttribute(heightElement, "w", "hRule");
365
- if (hRule === "auto" || hRule === "atLeast" || hRule === "exact") formatting.heightRule = hRule;
366
- }
367
- }
368
- if (parseBooleanElement(findChild(trPrElement, "w", "tblHeader"))) formatting.header = true;
369
- if (parseBooleanElement(findChild(trPrElement, "w", "cantSplit"))) formatting.cantSplit = true;
370
- const jcElement = findChild(trPrElement, "w", "jc");
371
- if (jcElement) {
372
- const jcVal = getAttribute(jcElement, "w", "val");
373
- if (jcVal === "left" || jcVal === "center" || jcVal === "right") formatting.justification = jcVal;
374
- }
375
- if (parseBooleanElement(findChild(trPrElement, "w", "hidden"))) formatting.hidden = true;
376
- const conditionalFormat = parseConditionalFormatStyle(findChild(trPrElement, "w", "cnfStyle"));
377
- if (conditionalFormat) formatting.conditionalFormat = conditionalFormat;
378
- if (Object.keys(formatting).length === 0) return;
563
+ const preserved = dispatchChildren({
564
+ element: trPrElement,
565
+ container: "row-properties",
566
+ handlers: {
567
+ cnfStyle: (child) => {
568
+ const conditionalFormat = parseConditionalFormatStyle(child);
569
+ if (conditionalFormat) formatting.conditionalFormat = conditionalFormat;
570
+ return keptUnless(conditionalFormat !== void 0);
571
+ },
572
+ divId: CAPTURE,
573
+ gridBefore: (child) => {
574
+ const gridBefore = parseNumericAttribute(child, "w", "val");
575
+ if (gridBefore !== void 0 && gridBefore > 0) formatting.gridBefore = gridBefore;
576
+ return keptUnless(gridBefore !== void 0 && gridBefore > 0);
577
+ },
578
+ gridAfter: (child) => {
579
+ const gridAfter = parseNumericAttribute(child, "w", "val");
580
+ if (gridAfter !== void 0 && gridAfter > 0) formatting.gridAfter = gridAfter;
581
+ return keptUnless(gridAfter !== void 0 && gridAfter > 0);
582
+ },
583
+ wBefore: (child) => {
584
+ const widthBefore = parseTableMeasurement(child);
585
+ if (widthBefore) formatting.widthBefore = widthBefore;
586
+ return keptUnless(widthBefore !== void 0);
587
+ },
588
+ wAfter: (child) => {
589
+ const widthAfter = parseTableMeasurement(child);
590
+ if (widthAfter) formatting.widthAfter = widthAfter;
591
+ return keptUnless(widthAfter !== void 0);
592
+ },
593
+ cantSplit: (child) => {
594
+ formatting.cantSplit = parseBooleanElement(child);
595
+ },
596
+ trHeight: (child) => {
597
+ const heightVal = parseNumericAttribute(child, "w", "val");
598
+ if (heightVal === void 0 || heightVal <= 0) return CAPTURE;
599
+ formatting.height = {
600
+ value: heightVal,
601
+ type: "dxa"
602
+ };
603
+ const hRule = getAttribute(child, "w", "hRule");
604
+ if (hRule === "auto" || hRule === "atLeast" || hRule === "exact") formatting.heightRule = hRule;
605
+ },
606
+ tblHeader: (child) => {
607
+ formatting.header = parseBooleanElement(child);
608
+ },
609
+ tblCellSpacing: CAPTURE,
610
+ jc: (child) => {
611
+ const justification = narrowEnum(getAttribute(child, "w", "val"), TableAlignmentSchema);
612
+ if (justification !== void 0) formatting.justification = justification;
613
+ return keptUnless(justification !== void 0);
614
+ },
615
+ hidden: (child) => {
616
+ formatting.hidden = parseBooleanElement(child);
617
+ },
618
+ ins: ROW_INSERTION_OWNER,
619
+ del: ROW_DELETION_OWNER,
620
+ trPrChange: ROW_PROPERTY_CHANGE_OWNER
621
+ },
622
+ capturePosition: sequencePositions("row-properties", trPrElement)
623
+ });
624
+ if (preserved) formatting.preserved = preserved;
379
625
  return withSourceXml(formatting, trPrElement);
380
626
  }
381
627
  /**
@@ -426,41 +672,88 @@ function parseConditionalFormatStyle(cnfElement) {
426
672
  function parseTableCellProperties(tcPrElement) {
427
673
  if (!tcPrElement) return;
428
674
  const formatting = {};
429
- const width = parseWidth(findChild(tcPrElement, "w", "tcW"));
430
- if (width) formatting.width = width;
431
- const borders = parseTableCellBorders(findChild(tcPrElement, "w", "tcBorders"));
432
- if (borders) formatting.borders = borders;
433
- const margins = parseCellMargins(findChild(tcPrElement, "w", "tcMar"));
434
- if (margins) formatting.margins = margins;
435
- const shading = parseShading(findChild(tcPrElement, "w", "shd"));
436
- if (shading) formatting.shading = shading;
437
- const vAlignElement = findChild(tcPrElement, "w", "vAlign");
438
- if (vAlignElement) {
439
- const vAlign = getAttribute(vAlignElement, "w", "val");
440
- if (vAlign === "top" || vAlign === "center" || vAlign === "bottom") formatting.verticalAlign = vAlign;
441
- }
442
- const textDirElement = findChild(tcPrElement, "w", "textDirection");
443
- if (textDirElement) {
444
- const textDir = narrowEnum(getAttribute(textDirElement, "w", "val"), TableCellTextDirectionSchema);
445
- if (textDir) formatting.textDirection = textDir;
446
- }
447
- const gridSpanElement = findChild(tcPrElement, "w", "gridSpan");
448
- if (gridSpanElement) {
449
- const gridSpan = parseNumericAttribute(gridSpanElement, "w", "val");
450
- if (gridSpan !== void 0 && gridSpan > 1) formatting.gridSpan = Math.min(gridSpan, 63);
451
- }
452
- const vMergeElement = findChild(tcPrElement, "w", "vMerge");
453
- if (vMergeElement) if (getAttribute(vMergeElement, "w", "val") === "restart") formatting.vMerge = "restart";
454
- else formatting.vMerge = "continue";
455
- if (parseBooleanElement(findChild(tcPrElement, "w", "tcFitText"))) formatting.fitText = true;
456
- if (parseBooleanElement(findChild(tcPrElement, "w", "noWrap"))) formatting.noWrap = true;
457
- const hideMarkElement = findChild(tcPrElement, "w", "hideMark");
458
- if (hideMarkElement) formatting.hideMark = parseBooleanElement(hideMarkElement);
459
- const conditionalFormat = parseConditionalFormatStyle(findChild(tcPrElement, "w", "cnfStyle"));
460
- if (conditionalFormat) formatting.conditionalFormat = conditionalFormat;
461
- if (Object.keys(formatting).length === 0) return;
675
+ const preserved = dispatchChildren({
676
+ element: tcPrElement,
677
+ container: "cell-properties",
678
+ handlers: {
679
+ cnfStyle: (child) => {
680
+ const conditionalFormat = parseConditionalFormatStyle(child);
681
+ if (conditionalFormat) formatting.conditionalFormat = conditionalFormat;
682
+ return keptUnless(conditionalFormat !== void 0);
683
+ },
684
+ tcW: (child) => {
685
+ const width = parseWidth(child);
686
+ if (width) formatting.width = width;
687
+ return keptUnless(width !== void 0);
688
+ },
689
+ gridSpan: (child) => {
690
+ const gridSpan = parseNumericAttribute(child, "w", "val");
691
+ if (gridSpan !== void 0 && gridSpan > 1) {
692
+ formatting.gridSpan = Math.min(gridSpan, 63);
693
+ return;
694
+ }
695
+ return CAPTURE;
696
+ },
697
+ hMerge: CAPTURE,
698
+ vMerge: (child) => {
699
+ formatting.vMerge = getAttribute(child, "w", "val") === "restart" ? "restart" : "continue";
700
+ },
701
+ tcBorders: (child) => {
702
+ const borders = parseTableCellBorders(child);
703
+ if (borders) formatting.borders = borders;
704
+ return keptUnless(borders !== void 0);
705
+ },
706
+ shd: (child) => {
707
+ const shading = parseShading(child);
708
+ if (shading) formatting.shading = shading;
709
+ return keptUnless(shading !== void 0);
710
+ },
711
+ noWrap: (child) => {
712
+ formatting.noWrap = parseBooleanElement(child);
713
+ },
714
+ tcMar: (child) => {
715
+ const margins = parseCellMargins(child);
716
+ if (margins) formatting.margins = margins;
717
+ return keptUnless(margins !== void 0);
718
+ },
719
+ textDirection: (child) => {
720
+ const textDir = narrowEnum(getAttribute(child, "w", "val"), TextDirectionSchema);
721
+ if (textDir) formatting.textDirection = textDir;
722
+ return keptUnless(textDir !== void 0);
723
+ },
724
+ tcFitText: (child) => {
725
+ formatting.fitText = parseBooleanElement(child);
726
+ },
727
+ vAlign: (child) => {
728
+ const vAlign = getAttribute(child, "w", "val");
729
+ if (vAlign === "top" || vAlign === "center" || vAlign === "bottom") {
730
+ formatting.verticalAlign = vAlign;
731
+ return;
732
+ }
733
+ return CAPTURE;
734
+ },
735
+ hideMark: (child) => {
736
+ formatting.hideMark = parseBooleanElement(child);
737
+ },
738
+ headers: CAPTURE,
739
+ cellIns: CELL_INSERTION_OWNER,
740
+ cellDel: CELL_DELETION_OWNER,
741
+ cellMerge: CELL_MERGE_OWNER,
742
+ tcPrChange: CELL_PROPERTY_CHANGE_OWNER
743
+ },
744
+ capturePosition: sequencePositions("cell-properties", tcPrElement)
745
+ });
746
+ if (preserved) formatting.preserved = preserved;
462
747
  return withSourceXml(formatting, tcPrElement);
463
748
  }
749
+ const recordContentControl = (wrapped, carriers, sdtElement) => {
750
+ const properties = parseSdtProperties(findWordprocessingChild(sdtElement, "sdtPr"), findWordprocessingChild(sdtElement, "sdtEndPr"));
751
+ const siblings = captureSdtSiblingMarkers(sdtElement);
752
+ if (siblings.before.length > 0) properties.rawSdtChildrenBeforeContent = siblings.before;
753
+ if (siblings.after.length > 0) properties.rawSdtChildrenAfterContent = siblings.after;
754
+ for (const item of wrapped) item.contentControls = [properties, ...item.contentControls ?? []];
755
+ for (const item of carriers) item.contentControls = [properties, ...item.contentControls ?? []];
756
+ };
464
757
  /**
465
758
  * Accumulate a table container's own `xmlns:*` onto the inherited in-scope set,
466
759
  * so a `w:pict` nested inside a cell still resolves prefixes scoped on the
@@ -474,13 +767,12 @@ function withContainerXmlns(options, element) {
474
767
  }
475
768
  function parseCellContent(tcElement, styles, theme, numbering, rels, media, options) {
476
769
  const modelled = [];
477
- const pendingBookmarkMarkers = [];
478
770
  const captured = [];
479
771
  const dispatchCellChildren = (element, childOptions) => {
480
772
  const preserved = dispatchChildren({
481
773
  element,
482
774
  container: "block-content",
483
- modelledCount: () => modelled.length,
775
+ capturePosition: () => modelled.length,
484
776
  undeclared: { AlternateContent: (child) => {
485
777
  const selectedBranch = selectAlternateContentBranch(child);
486
778
  if (!selectedBranch) return;
@@ -488,29 +780,30 @@ function parseCellContent(tcElement, styles, theme, numbering, rels, media, opti
488
780
  } },
489
781
  handlers: {
490
782
  p: (child) => {
491
- const para = parseParagraph(child, styles, theme, numbering, rels, media, childOptions);
783
+ const para = parseParagraph(child, styles, theme, numbering, rels, media, {
784
+ ...childOptions,
785
+ runConsolidation: "deferred"
786
+ });
492
787
  enrichParagraphTextBoxes(para, child, styles, theme, numbering, rels, media, parseTable);
493
- prependPendingBookmarkMarkers(para, pendingBookmarkMarkers);
494
788
  modelled.push(para);
495
789
  },
496
790
  tbl: (child) => {
497
791
  const table = parseTable(child, styles, theme, numbering, rels, media, childOptions);
498
792
  if (!table) return;
499
- if (prependBookmarkMarkersToFirstParagraphInBlocks([table], pendingBookmarkMarkers)) pendingBookmarkMarkers.length = 0;
500
793
  modelled.push(table);
501
794
  },
502
795
  sdt: (child) => {
503
- const sdtContent = findChildByLocalName(child, "sdtContent");
796
+ const sdtContent = findWordprocessingChild(child, "sdtContent");
504
797
  if (!sdtContent) return;
505
798
  dispatchCellChildren(sdtContent, withContainerXmlns(withContainerXmlns(childOptions, child), sdtContent));
506
799
  },
507
800
  bookmarkStart: (child) => {
508
- collectCellBookmarkMarker(child, "bookmarkStart", modelled, pendingBookmarkMarkers);
801
+ modelled.push(parseBookmarkStart(child));
509
802
  },
510
803
  bookmarkEnd: (child) => {
511
- collectCellBookmarkMarker(child, "bookmarkEnd", modelled, pendingBookmarkMarkers);
804
+ modelled.push(parseBookmarkEnd(child));
512
805
  },
513
- tcPr: OWNED_ELSEWHERE,
806
+ tcPr: CELL_PROPERTIES_OWNER,
514
807
  sectPr: CAPTURE,
515
808
  altChunk: CAPTURE,
516
809
  commentRangeEnd: CAPTURE,
@@ -540,20 +833,15 @@ function parseCellContent(tcElement, styles, theme, numbering, rels, media, opti
540
833
  if (preserved?.children) captured.push(...preserved.children);
541
834
  };
542
835
  dispatchCellChildren(tcElement, options);
543
- if (modelled.length === 0) modelled.push({
836
+ if (!modelled.some((block) => block.type === "paragraph" || block.type === "table")) modelled.push({
544
837
  type: "paragraph",
545
- content: [...pendingBookmarkMarkers]
838
+ content: []
546
839
  });
547
- else if (pendingBookmarkMarkers.length > 0) appendBookmarkMarkersToLastParagraphInBlocks(modelled, pendingBookmarkMarkers);
548
840
  return withPreservedChildren(modelled, { children: captured }, (xml) => ({
549
841
  type: "preservedBlock",
550
842
  xml
551
843
  }));
552
844
  }
553
- const collectCellBookmarkMarker = (child, localName, content, pending) => {
554
- const marker = parseBookmarkMarker(child, localName);
555
- if (!appendBookmarkMarkerToLastParagraphInBlocks(content, marker)) pending.push(marker);
556
- };
557
845
  /**
558
846
  * Parse a table cell (w:tc)
559
847
  *
@@ -596,6 +884,11 @@ function parseTableRow(trElement, styles, theme, numbering, rels, media, options
596
884
  type: "tableRow",
597
885
  cells: []
598
886
  };
887
+ const tblPrExElement = findChild(trElement, "w", "tblPrEx");
888
+ const exceptions = parseTablePropertyExceptions(tblPrExElement);
889
+ if (exceptions) row.tablePropertyExceptions = exceptions;
890
+ const exceptionChanges = parseTablePropertyExceptionChanges(tblPrExElement, exceptions);
891
+ if (exceptionChanges !== void 0) row.tablePropertyExceptionChanges = exceptionChanges;
599
892
  const trPrElement = findChild(trElement, "w", "trPr");
600
893
  const formatting = parseTableRowProperties(trPrElement);
601
894
  if (formatting) row.formatting = formatting;
@@ -604,43 +897,54 @@ function parseTableRow(trElement, styles, theme, numbering, rels, media, options
604
897
  const rowStructChange = parseTableRowStructuralChange(trPrElement);
605
898
  if (rowStructChange !== void 0) row.structuralChange = rowStructChange;
606
899
  const rowOptions = withContainerXmlns(options, trElement);
607
- const pendingBookmarkMarkers = [];
900
+ const bookmarks = [];
608
901
  const preservedChildren = [];
609
902
  /**
610
- * One row's children, or a row-level content control's.
903
+ * One row's children, or a cell-level content control's.
611
904
  *
612
- * folio unwraps `w:sdt` here and splices its rows' content into the row, so
613
- * the recursion walks the control's content with the same map; the sink is
614
- * the row's either way, because the control keeps no wrapper to hold one.
905
+ * folio keeps the cells `w:sdt` holds as the row's own and records the
906
+ * control on each of them, so the recursion walks the control's content
907
+ * with the same map; the sink is the row's either way, because the control
908
+ * holds no capture of its own.
615
909
  */
616
910
  const dispatchRowChildren = (element, childOptions) => {
617
911
  const captured = dispatchChildren({
618
912
  element,
619
913
  container: "row-content",
620
- modelledCount: () => row.cells.length,
914
+ capturePosition: () => row.cells.length,
621
915
  handlers: {
622
916
  tc: (child) => {
623
- const cell = parseTableCell(child, styles, theme, numbering, rels, media, childOptions);
624
- if (pendingBookmarkMarkers.length > 0) {
625
- prependBookmarkMarkersToFirstParagraphInCell(cell, pendingBookmarkMarkers);
626
- pendingBookmarkMarkers.length = 0;
627
- }
628
- row.cells.push(cell);
917
+ row.cells.push(parseTableCell(child, styles, theme, numbering, rels, media, childOptions));
629
918
  },
630
919
  sdt: (child) => {
631
- const sdtContent = findChildByLocalName(child, "sdtContent");
632
- if (!sdtContent) return;
920
+ const sdtContent = findWordprocessingChild(child, "sdtContent");
921
+ if (!sdtContent) return CAPTURE;
922
+ const firstWrapped = row.cells.length;
923
+ const firstCaptured = preservedChildren.length;
924
+ const firstBookmark = bookmarks.length;
633
925
  const sdtOptions = withContainerXmlns(childOptions, child);
634
926
  dispatchRowChildren(sdtContent, withContainerXmlns(sdtOptions, sdtContent));
927
+ const wrapped = row.cells.slice(firstWrapped);
928
+ if (wrapped.length === 0) {
929
+ preservedChildren.splice(firstCaptured);
930
+ bookmarks.splice(firstBookmark);
931
+ return CAPTURE;
932
+ }
933
+ recordContentControl(wrapped, [...preservedChildren.slice(firstCaptured), ...bookmarks.slice(firstBookmark)], child);
635
934
  },
636
935
  bookmarkStart: (child) => {
637
- placeBookmarkMarker(parseBookmarkStart(child));
936
+ bookmarks.push({
937
+ index: row.cells.length,
938
+ marker: parseBookmarkStart(child)
939
+ });
638
940
  },
639
941
  bookmarkEnd: (child) => {
640
- placeBookmarkMarker(parseBookmarkEnd(child));
942
+ bookmarks.push({
943
+ index: row.cells.length,
944
+ marker: parseBookmarkEnd(child)
945
+ });
641
946
  },
642
- trPr: OWNED_ELSEWHERE,
643
- tblPrEx: OWNED_ELSEWHERE,
947
+ ...ROW_CHILD_OWNERS,
644
948
  commentRangeEnd: CAPTURE,
645
949
  commentRangeStart: CAPTURE,
646
950
  customXml: CAPTURE,
@@ -668,36 +972,16 @@ function parseTableRow(trElement, styles, theme, numbering, rels, media, options
668
972
  });
669
973
  if (captured?.children) preservedChildren.push(...captured.children);
670
974
  };
671
- const placeBookmarkMarker = (marker) => {
672
- if (!appendBookmarkMarkerToLastParagraphInCells(row.cells, marker)) pendingBookmarkMarkers.push(marker);
673
- };
674
975
  dispatchRowChildren(trElement, rowOptions);
675
976
  if (preservedChildren.length > 0) row.preserved = { children: preservedChildren };
977
+ if (bookmarks.length > 0) row.bookmarks = bookmarks;
676
978
  const remainingAttributes = attributeRemainder({
677
979
  element: trElement,
678
980
  modelled: NO_MODELLED_ATTRIBUTES
679
981
  });
680
982
  if (remainingAttributes) row.preservedAttributes = remainingAttributes;
681
- if (pendingBookmarkMarkers.length > 0) appendBookmarkMarkersToLastCell(row, pendingBookmarkMarkers);
682
983
  return row;
683
984
  }
684
- function parseBookmarkMarker(child, localName) {
685
- if (localName === "bookmarkStart") return parseBookmarkStart(child);
686
- return parseBookmarkEnd(child);
687
- }
688
- function prependPendingBookmarkMarkers(paragraph, pendingBookmarkMarkers) {
689
- if (pendingBookmarkMarkers.length === 0) return;
690
- paragraph.content.unshift(...pendingBookmarkMarkers);
691
- pendingBookmarkMarkers.length = 0;
692
- }
693
- function appendBookmarkMarkersToLastParagraphInBlocks(blocks, markers) {
694
- for (const marker of markers) appendBookmarkMarkerToLastParagraphInBlocks(blocks, marker);
695
- }
696
- function appendBookmarkMarkersToLastCell(row, markers) {
697
- const lastCell = row.cells.at(-1);
698
- if (!lastCell) return;
699
- for (const marker of markers) appendBookmarkMarkerToLastParagraphInBlocks(lastCell.content, marker);
700
- }
701
985
  /**
702
986
  * Parse table grid (w:tblGrid) for column widths
703
987
  *
@@ -715,6 +999,24 @@ function parseTableGrid(tblGridElement) {
715
999
  if (widths.length > 0 && widths.every((width) => width <= 0)) return;
716
1000
  return widths.length > 0 ? widths : void 0;
717
1001
  }
1002
+ /**
1003
+ * The grid a `w:tblGridChange` snapshots, from the change's own `w:tblGrid`.
1004
+ *
1005
+ * {@link parseTableGrid} reads the *live* grid, where a column with no `w:w`
1006
+ * is a column folio has no width for and a grid of nothing but those is no
1007
+ * grid at all. A snapshot is a record of what stood, so every `w:gridCol`
1008
+ * survives whether or not it stated a width, and `undefined` is what says the
1009
+ * column stated none.
1010
+ */
1011
+ function parseTableGridChange(gridElement) {
1012
+ const changeElement = findChild(gridElement, "w", "tblGridChange");
1013
+ if (!changeElement) return;
1014
+ const snapshot = findChild(changeElement, "w", "tblGrid");
1015
+ return {
1016
+ id: parseTrackedChangeInfo(changeElement).id,
1017
+ columnWidths: (snapshot === null ? [] : findChildren(snapshot, "w", "gridCol")).map((column) => parseNumericAttribute(column, "w", "w"))
1018
+ };
1019
+ }
718
1020
  function hasRowGridOffsets(rowElement) {
719
1021
  const trPrElement = findChild(rowElement, "w", "trPr");
720
1022
  if (!trPrElement) return false;
@@ -777,28 +1079,30 @@ function parseTable(tblElement, styles, theme, numbering, rels, media, options)
777
1079
  const columnWidths = parseTableGrid(gridElement);
778
1080
  if (columnWidths) table.columnWidths = columnWidths;
779
1081
  if (gridElement) {
780
- const gridChange = findChild(gridElement, "w", "tblGridChange");
1082
+ const gridChange = parseTableGridChange(gridElement);
781
1083
  table.formatting = {
782
1084
  ...table.formatting,
783
1085
  gridSourceXml: captureVerbatimXml(gridElement),
784
- ...gridChange ? { gridChangeXml: captureVerbatimXml(gridChange) } : {}
1086
+ ...gridChange === void 0 ? {} : { gridChange }
785
1087
  };
786
1088
  }
787
1089
  const tableOptions = withContainerXmlns(options, tblElement);
788
1090
  const rowsWithGridOffsets = /* @__PURE__ */ new Set();
789
1091
  const preservedChildren = [];
1092
+ const bookmarks = [];
790
1093
  /**
791
1094
  * One table's children, or a row-level content control's.
792
1095
  *
793
- * folio unwraps `w:sdt` here and splices its rows into the table, so the
794
- * recursion walks the control's content with the same map; the sink is the
795
- * table's either way, because the control keeps no wrapper to hold one.
1096
+ * folio keeps the rows `w:sdt` holds as the table's own and records the
1097
+ * control on each of them, so the recursion walks the control's content
1098
+ * with the same map; the sink is the table's either way, because the
1099
+ * control holds no capture of its own.
796
1100
  */
797
1101
  const dispatchTableChildren = (element, childOptions) => {
798
1102
  const captured = dispatchChildren({
799
1103
  element,
800
1104
  container: "table-content",
801
- modelledCount: () => table.rows.length,
1105
+ capturePosition: () => table.rows.length,
802
1106
  handlers: {
803
1107
  tr: (child) => {
804
1108
  const rowIndex = table.rows.length;
@@ -806,15 +1110,34 @@ function parseTable(tblElement, styles, theme, numbering, rels, media, options)
806
1110
  if (hasRowGridOffsets(child)) rowsWithGridOffsets.add(rowIndex);
807
1111
  },
808
1112
  sdt: (child) => {
809
- const sdtContent = findChildByLocalName(child, "sdtContent");
810
- if (!sdtContent) return;
1113
+ const sdtContent = findWordprocessingChild(child, "sdtContent");
1114
+ if (!sdtContent) return CAPTURE;
1115
+ const firstWrapped = table.rows.length;
1116
+ const firstCaptured = preservedChildren.length;
1117
+ const firstBookmark = bookmarks.length;
811
1118
  const sdtOptions = withContainerXmlns(childOptions, child);
812
1119
  dispatchTableChildren(sdtContent, withContainerXmlns(sdtOptions, sdtContent));
1120
+ const wrapped = table.rows.slice(firstWrapped);
1121
+ if (wrapped.length === 0) {
1122
+ preservedChildren.splice(firstCaptured);
1123
+ bookmarks.splice(firstBookmark);
1124
+ return CAPTURE;
1125
+ }
1126
+ recordContentControl(wrapped, [...preservedChildren.slice(firstCaptured), ...bookmarks.slice(firstBookmark)], child);
1127
+ },
1128
+ ...TABLE_CHILD_OWNERS,
1129
+ bookmarkStart: (child) => {
1130
+ bookmarks.push({
1131
+ index: table.rows.length,
1132
+ marker: parseBookmarkStart(child)
1133
+ });
1134
+ },
1135
+ bookmarkEnd: (child) => {
1136
+ bookmarks.push({
1137
+ index: table.rows.length,
1138
+ marker: parseBookmarkEnd(child)
1139
+ });
813
1140
  },
814
- tblPr: OWNED_ELSEWHERE,
815
- tblGrid: OWNED_ELSEWHERE,
816
- bookmarkEnd: CAPTURE,
817
- bookmarkStart: CAPTURE,
818
1141
  commentRangeEnd: CAPTURE,
819
1142
  commentRangeStart: CAPTURE,
820
1143
  customXml: CAPTURE,
@@ -845,6 +1168,7 @@ function parseTable(tblElement, styles, theme, numbering, rels, media, options)
845
1168
  dispatchTableChildren(tblElement, tableOptions);
846
1169
  if (table.rows.length === 0) return;
847
1170
  if (preservedChildren.length > 0) table.preserved = { children: preservedChildren };
1171
+ if (bookmarks.length > 0) table.bookmarks = bookmarks;
848
1172
  inferImplicitSingleCellRowSpans(table, rowsWithGridOffsets);
849
1173
  return table;
850
1174
  }
@@ -953,4 +1277,4 @@ function isFloatingTable(table) {
953
1277
  return table.formatting?.floating !== void 0;
954
1278
  }
955
1279
  //#endregion
956
- export { MAX_TABLE_COLUMNS, getHeaderRows, getTableColumnCount, getTableRowCount, getTableText, hasHeaderRow, isCellHorizontallyMerged, isCellMergeContinuation, isCellMergeStart, isFloatingTable, parseCellMargins, parseConditionalFormatStyle, parseFloatingTableProperties, parseTable, parseTableBorders, parseTableCell, parseTableCellProperties, parseTableGrid, parseTableLook, parseTableMeasurement, parseTableProperties, parseTableRow, parseTableRowProperties };
1280
+ export { MAX_TABLE_COLUMNS, getHeaderRows, getTableColumnCount, getTableRowCount, getTableText, hasHeaderRow, isCellHorizontallyMerged, isCellMergeContinuation, isCellMergeStart, isFloatingTable, parseCellMargins, parseConditionalFormatStyle, parseFloatingTableProperties, parseTable, parseTableBorders, parseTableCell, parseTableCellProperties, parseTableGrid, parseTableLook, parseTableMeasurement, parseTableProperties, parseTablePropertyExceptions, parseTableRow, parseTableRowProperties };