@stll/folio-core 0.45.0 → 0.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (451) hide show
  1. package/dist/ai-edits/apply.js +85 -43
  2. package/dist/ai-edits/headless.js +2 -2
  3. package/dist/ai-edits/read.d.ts +1 -0
  4. package/dist/ai-edits/read.js +1 -0
  5. package/dist/ai-edits/snapshot.js +32 -27
  6. package/dist/ai-edits/table-cell-mutations.js +15 -7
  7. package/dist/ai-edits/table-geometry.js +21 -18
  8. package/dist/ai-edits/table-template.js +2 -2
  9. package/dist/compare/compare.js +2 -5
  10. package/dist/compare/content-alignment.js +108 -12
  11. package/dist/compare/content-types.d.ts +8 -2
  12. package/dist/compare/content.js +2 -11
  13. package/dist/compare/plan.js +7 -4
  14. package/dist/compare/scenario.js +2 -5
  15. package/dist/compare/section-boundary-properties.js +1 -2
  16. package/dist/compare/types.d.ts +9 -1
  17. package/dist/compare/types.js +12 -1
  18. package/dist/compat/eigenpal.d.ts +2 -1
  19. package/dist/compat/eigenpal.js +2 -1
  20. package/dist/content-controls/checkboxDisplay.d.ts +17 -0
  21. package/dist/content-controls/checkboxDisplay.js +46 -0
  22. package/dist/content-controls/findContentControls.js +3 -1
  23. package/dist/content-controls/mutateContentControls.js +57 -43
  24. package/dist/controller/contentControlWidgetController.d.ts +1 -0
  25. package/dist/controller/contentControlWidgetController.js +3 -0
  26. package/dist/controller/hiddenEditorApi.js +3 -1
  27. package/dist/controller/hiddenEditorManager.d.ts +1 -1
  28. package/dist/controller/hiddenEditorManager.js +6 -3
  29. package/dist/controller/layoutPipeline.js +8 -3
  30. package/dist/display-list/build/buildDisplayList.js +20 -1
  31. package/dist/display-list/build/imagePrimitives.d.ts +4 -4
  32. package/dist/display-list/build/imagePrimitives.js +38 -18
  33. package/dist/display-list/build/pageBorderPrimitives.js +2 -1
  34. package/dist/display-list/build/paragraphPrimitives.js +113 -14
  35. package/dist/display-list/build/previewPrimitives.d.ts +10 -0
  36. package/dist/display-list/build/previewPrimitives.js +89 -0
  37. package/dist/display-list/build/strokes.d.ts +177 -8
  38. package/dist/display-list/build/strokes.js +167 -47
  39. package/dist/display-list/build/tablePrimitives.js +4 -2
  40. package/dist/display-list/build/textBoxPrimitives.js +6 -4
  41. package/dist/display-list/build/textDecorations.d.ts +15 -1
  42. package/dist/display-list/build/textDecorations.js +15 -1
  43. package/dist/display-list/dom/renderDisplayListToDom.js +11 -21
  44. package/dist/display-list/primitives.d.ts +13 -2
  45. package/dist/display-list/primitives.js +36 -1
  46. package/dist/display-list/types.d.ts +17 -0
  47. package/dist/document-operations.js +2 -1
  48. package/dist/docx/attributeRemainder.d.ts +76 -0
  49. package/dist/docx/attributeRemainder.js +111 -0
  50. package/dist/docx/blockContentParser.d.ts +3 -1
  51. package/dist/docx/blockContentParser.js +102 -106
  52. package/dist/docx/blockPlainText.d.ts +3 -4
  53. package/dist/docx/blockPlainText.js +3 -0
  54. package/dist/docx/borderParser.js +26 -11
  55. package/dist/docx/builtInStyles.d.ts +8 -16
  56. package/dist/docx/builtInStyles.js +54 -17
  57. package/dist/docx/commentAnchorIndex.d.ts +30 -0
  58. package/dist/docx/commentAnchorIndex.js +50 -0
  59. package/dist/docx/commentParser.d.ts +1 -1
  60. package/dist/docx/commentParser.js +56 -39
  61. package/dist/docx/commentRangeIntegrity.d.ts +16 -1
  62. package/dist/docx/commentRangeIntegrity.js +42 -1
  63. package/dist/docx/commentRangeJoin.d.ts +9 -0
  64. package/dist/docx/commentRangeJoin.js +33 -0
  65. package/dist/docx/commentReferenceCompletion.d.ts +9 -0
  66. package/dist/docx/commentReferenceCompletion.js +47 -0
  67. package/dist/docx/commentReferenceNormalization.js +3 -1
  68. package/dist/docx/commentReplyMarkers.js +11 -19
  69. package/dist/docx/compatibility.js +56 -41
  70. package/dist/docx/containerChildren.d.ts +208 -0
  71. package/dist/docx/containerChildren.gen.d.ts +43 -0
  72. package/dist/docx/containerChildren.gen.js +263 -0
  73. package/dist/docx/containerChildren.js +153 -0
  74. package/dist/docx/diagramPreview.d.ts +14 -2
  75. package/dist/docx/diagramPreview.js +81 -169
  76. package/dist/docx/documentParser.d.ts +1 -1
  77. package/dist/docx/documentParser.js +7 -4
  78. package/dist/docx/drawingAnchor.d.ts +87 -0
  79. package/dist/docx/drawingAnchor.js +201 -0
  80. package/dist/docx/drawingUtils.d.ts +43 -38
  81. package/dist/docx/drawingUtils.js +205 -118
  82. package/dist/docx/ensureParaIds.js +17 -7
  83. package/dist/docx/fieldParser.d.ts +1 -1
  84. package/dist/docx/fieldParser.js +4 -4
  85. package/dist/docx/fieldState.d.ts +26 -0
  86. package/dist/docx/fieldState.js +53 -0
  87. package/dist/docx/fontTableParser.js +102 -41
  88. package/dist/docx/footnoteParser.d.ts +1 -1
  89. package/dist/docx/footnoteParser.js +10 -6
  90. package/dist/docx/graphicFrameLocks.d.ts +16 -4
  91. package/dist/docx/graphicFrameLocks.js +19 -6
  92. package/dist/docx/groupDrawingParser.js +4 -3
  93. package/dist/docx/headerFooterParser.js +1 -1
  94. package/dist/docx/headerFooterReferenceNormalization.js +1 -0
  95. package/dist/docx/hyperlinkParser.d.ts +66 -9
  96. package/dist/docx/hyperlinkParser.js +153 -26
  97. package/dist/docx/imageParser.js +160 -115
  98. package/dist/docx/index.d.ts +2 -1
  99. package/dist/docx/index.js +2 -1
  100. package/dist/docx/inlineContentRemovals.d.ts +28 -0
  101. package/dist/docx/inlineContentRemovals.js +46 -0
  102. package/dist/docx/inlineWrapperContent.d.ts +166 -0
  103. package/dist/docx/inlineWrapperContent.js +165 -0
  104. package/dist/docx/inlineWrapperParser.d.ts +11 -0
  105. package/dist/docx/inlineWrapperParser.js +60 -0
  106. package/dist/docx/nonVisualDrawingProps.d.ts +5 -13
  107. package/dist/docx/normalizeBaseDirection.js +12 -1
  108. package/dist/docx/numberingParser.d.ts +25 -2
  109. package/dist/docx/numberingParser.js +264 -361
  110. package/dist/docx/numberingReference.d.ts +9 -16
  111. package/dist/docx/numberingReference.js +17 -16
  112. package/dist/docx/numberingReferenceNormalization.js +7 -7
  113. package/dist/docx/ooxmlCounterFormatter.d.ts +1 -1
  114. package/dist/docx/ooxmlCounterFormatter.js +4 -1
  115. package/dist/docx/paraIdAttribute.d.ts +111 -0
  116. package/dist/docx/paraIdAttribute.js +142 -0
  117. package/dist/docx/paragraphParser.d.ts +10 -25
  118. package/dist/docx/paragraphParser.js +421 -496
  119. package/dist/docx/paragraphProperties.d.ts +23 -0
  120. package/dist/docx/paragraphProperties.js +279 -0
  121. package/dist/docx/paragraphPropertySource.js +7 -1
  122. package/dist/docx/paragraphTextBoxEnrichment.d.ts +3 -2
  123. package/dist/docx/paragraphTextBoxEnrichment.js +20 -59
  124. package/dist/docx/paragraphTraversal.d.ts +14 -10
  125. package/dist/docx/paragraphTraversal.js +53 -52
  126. package/dist/docx/parseWarningMessage.js +5 -1
  127. package/dist/docx/parserEnums.d.ts +6 -8
  128. package/dist/docx/parserEnums.js +4 -6
  129. package/dist/docx/preservedRunContent.d.ts +32 -0
  130. package/dist/docx/preservedRunContent.js +96 -0
  131. package/dist/docx/previewBudget.d.ts +44 -23
  132. package/dist/docx/previewBudget.js +61 -30
  133. package/dist/docx/propertyElementAttributes.d.ts +178 -0
  134. package/dist/docx/propertyElementAttributes.js +114 -0
  135. package/dist/docx/renderedPageBreakNormalization.js +4 -6
  136. package/dist/docx/rezip.d.ts +28 -2
  137. package/dist/docx/rezip.js +152 -27
  138. package/dist/docx/runConsolidator.d.ts +42 -2
  139. package/dist/docx/runConsolidator.js +60 -6
  140. package/dist/docx/runParser.d.ts +55 -19
  141. package/dist/docx/runParser.js +394 -306
  142. package/dist/docx/runPayload.d.ts +5 -0
  143. package/dist/docx/runPayload.js +4 -0
  144. package/dist/docx/sdtProperties.d.ts +39 -5
  145. package/dist/docx/sdtProperties.js +205 -84
  146. package/dist/docx/sdtPropertiesPatch.d.ts +5 -9
  147. package/dist/docx/sdtPropertiesPatch.js +68 -112
  148. package/dist/docx/sectionParser.d.ts +1 -2
  149. package/dist/docx/sectionParser.js +241 -238
  150. package/dist/docx/selectiveSave.js +3 -2
  151. package/dist/docx/selectiveXmlPatch.d.ts +66 -3
  152. package/dist/docx/selectiveXmlPatch.js +276 -133
  153. package/dist/docx/serializer/blockSdtSerializer.js +2 -96
  154. package/dist/docx/serializer/borderSerializer.d.ts +5 -5
  155. package/dist/docx/serializer/borderSerializer.js +12 -10
  156. package/dist/docx/serializer/commentSerializer.js +5 -7
  157. package/dist/docx/serializer/documentSerializer.js +11 -11
  158. package/dist/docx/serializer/fontTableSerializer.js +31 -3
  159. package/dist/docx/serializer/headerFooterSerializer.js +10 -9
  160. package/dist/docx/serializer/markupRangeAttributes.d.ts +9 -1
  161. package/dist/docx/serializer/markupRangeAttributes.js +9 -1
  162. package/dist/docx/serializer/noteSerializer.js +11 -8
  163. package/dist/docx/serializer/numberingSerializer.d.ts +1 -6
  164. package/dist/docx/serializer/numberingSerializer.js +81 -79
  165. package/dist/docx/serializer/paragraphSerializer.d.ts +1 -9
  166. package/dist/docx/serializer/paragraphSerializer.js +156 -236
  167. package/dist/docx/serializer/runSerializer.d.ts +1 -5
  168. package/dist/docx/serializer/runSerializer.js +134 -75
  169. package/dist/docx/serializer/sdtPropertiesSerializer.d.ts +26 -0
  170. package/dist/docx/serializer/sdtPropertiesSerializer.js +111 -0
  171. package/dist/docx/serializer/sectionPropertiesSerializer.js +42 -49
  172. package/dist/docx/serializer/settingsSerializer.js +6 -4
  173. package/dist/docx/serializer/stylesSerializer.js +8 -11
  174. package/dist/docx/serializer/tableSerializer.js +283 -105
  175. package/dist/docx/serializer/textFormattingSerializer.d.ts +28 -4
  176. package/dist/docx/serializer/textFormattingSerializer.js +111 -101
  177. package/dist/docx/serializer/xmlUtils.d.ts +1 -1
  178. package/dist/docx/serializer/xmlUtils.js +1 -1
  179. package/dist/docx/server/createBilingualDocument.js +20 -16
  180. package/dist/docx/server/materializeYjsDocx.d.ts +1 -1
  181. package/dist/docx/server/materializeYjsDocx.js +9 -1
  182. package/dist/docx/server/migrateYjsAttrSchema.d.ts +55 -0
  183. package/dist/docx/server/migrateYjsAttrSchema.js +95 -0
  184. package/dist/docx/settingsParser.js +7 -4
  185. package/dist/docx/shadingParser.d.ts +2 -1
  186. package/dist/docx/shadingParser.js +43 -7
  187. package/dist/docx/shapeParser.js +13 -8
  188. package/dist/docx/strictNames.d.ts +11 -0
  189. package/dist/docx/strictNames.gen.d.ts +45 -0
  190. package/dist/docx/strictNames.gen.js +50 -0
  191. package/dist/docx/strictNames.js +43 -0
  192. package/dist/docx/strictValueEncodings.gen.js +133 -131
  193. package/dist/docx/styleParser.js +17 -349
  194. package/dist/docx/tableParser.d.ts +11 -2
  195. package/dist/docx/tableParser.js +665 -220
  196. package/dist/docx/textBoxParser.d.ts +28 -3
  197. package/dist/docx/textBoxParser.js +69 -9
  198. package/dist/docx/themeColorAttribute.d.ts +13 -0
  199. package/dist/docx/themeColorAttribute.js +24 -0
  200. package/dist/docx/trackedMoveRangeNormalization.js +2 -1
  201. package/dist/docx/unzip.js +5 -4
  202. package/dist/docx/vmlImageParser.d.ts +30 -5
  203. package/dist/docx/vmlImageParser.js +91 -32
  204. package/dist/docx/vmlPreview.js +2 -2
  205. package/dist/docx/wrapPolygon.d.ts +30 -0
  206. package/dist/docx/wrapPolygon.js +70 -0
  207. package/dist/docx/xmlEncoding.d.ts +5 -0
  208. package/dist/docx/xmlEncoding.js +12 -0
  209. package/dist/docx/xmlParser.d.ts +23 -1
  210. package/dist/docx/xmlParser.js +31 -2
  211. package/dist/fonts/embeddedFonts.js +3 -3
  212. package/dist/headless-layout.js +12 -1
  213. package/dist/i18n/messages/catalogs.gen.d.ts +68 -0
  214. package/dist/i18n/messages/catalogs.gen.js +102 -34
  215. package/dist/i18n/messages/messages.gen.d.ts +4 -0
  216. package/dist/index.d.ts +2 -1
  217. package/dist/index.js +2 -1
  218. package/dist/internal/headlessRevisionResolution.js +9 -0
  219. package/dist/internal/pageBreakRunSourceDescendantIndex.js +7 -2
  220. package/dist/internal/paragraphFormattingSerialization.d.ts +20 -9
  221. package/dist/internal/paragraphFormattingSerialization.js +118 -83
  222. package/dist/layout-bridge/convert/footnoteLayout.d.ts +1 -0
  223. package/dist/layout-bridge/convert/footnoteLayout.js +1 -0
  224. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -0
  225. package/dist/layout-bridge/convert/headerFooterLayout.js +2 -0
  226. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +17 -12
  227. package/dist/layout-bridge/convert/toFlowBlocks.js +267 -101
  228. package/dist/layout-engine/index.d.ts +2 -2
  229. package/dist/layout-engine/index.js +53 -17
  230. package/dist/layout-engine/measure/measureBlocks.d.ts +3 -0
  231. package/dist/layout-engine/measure/measureBlocks.js +6 -10
  232. package/dist/layout-engine/measure/tableCellFloating.d.ts +2 -0
  233. package/dist/layout-engine/measure/tableCellFloating.js +2 -0
  234. package/dist/layout-engine/measure/tableCellGrid.js +2 -1
  235. package/dist/layout-engine/measure/tableFragmentBorderGeometry.js +2 -1
  236. package/dist/layout-engine/measure/tableInlinePlacement.js +2 -5
  237. package/dist/layout-engine/paragraphSequence.js +3 -2
  238. package/dist/layout-engine/renderedBreakReconciliation.js +2 -1
  239. package/dist/layout-engine/section-breaks.d.ts +49 -2
  240. package/dist/layout-engine/section-breaks.js +55 -4
  241. package/dist/layout-engine/types.d.ts +69 -17
  242. package/dist/layout-engine/types.js +16 -1
  243. package/dist/layout-painter/borderStroke.d.ts +18 -4
  244. package/dist/layout-painter/renderImage.d.ts +5 -1
  245. package/dist/layout-painter/renderImage.js +10 -3
  246. package/dist/layout-painter/renderPage.d.ts +2 -0
  247. package/dist/layout-painter/renderPage.js +10 -4
  248. package/dist/layout-painter/renderParagraph.d.ts +14 -1
  249. package/dist/layout-painter/renderParagraph.js +34 -28
  250. package/dist/layout-painter/renderTable.d.ts +4 -1
  251. package/dist/layout-painter/renderTable.js +22 -22
  252. package/dist/layout-painter/renderTextBox.js +5 -3
  253. package/dist/managers/autoSaveCodec.d.ts +9 -1
  254. package/dist/managers/autoSaveCodec.js +12 -4
  255. package/dist/markdown/renderBlock.js +3 -0
  256. package/dist/markdown/renderRuns.d.ts +1 -1
  257. package/dist/markdown/renderRuns.js +34 -6
  258. package/dist/markdown/renderTable.js +24 -6
  259. package/dist/markdown/trailers.js +4 -1
  260. package/dist/model.d.ts +3 -3
  261. package/dist/model.js +2 -2
  262. package/dist/paged-layout/sectionBlockWidths.d.ts +3 -0
  263. package/dist/paged-layout/sectionBlockWidths.js +26 -4
  264. package/dist/pdf/images.js +142 -6
  265. package/dist/prosemirror/attrs/index.d.ts +34 -5
  266. package/dist/prosemirror/attrs/index.js +639 -48
  267. package/dist/prosemirror/authoredTransformAttrs.d.ts +28 -0
  268. package/dist/prosemirror/authoredTransformAttrs.js +64 -0
  269. package/dist/prosemirror/bookmarkBoundaryAttrs.d.ts +9 -1
  270. package/dist/prosemirror/bookmarkBoundaryAttrs.js +22 -3
  271. package/dist/prosemirror/commands/comments.js +68 -53
  272. package/dist/prosemirror/commands/contentControls.js +33 -20
  273. package/dist/prosemirror/commands/image.d.ts +10 -3
  274. package/dist/prosemirror/commands/image.js +46 -29
  275. package/dist/prosemirror/commands/pageBreak.js +1 -1
  276. package/dist/prosemirror/commands/paragraph.d.ts +2 -1
  277. package/dist/prosemirror/commands/propertyChangeScope.d.ts +12 -4
  278. package/dist/prosemirror/commands/propertyChangeScope.js +22 -4
  279. package/dist/prosemirror/commands/sectionBreak.d.ts +33 -1
  280. package/dist/prosemirror/commands/sectionBreak.js +187 -11
  281. package/dist/prosemirror/commentReferenceAttrs.d.ts +8 -0
  282. package/dist/prosemirror/commentReferenceAttrs.js +33 -0
  283. package/dist/prosemirror/commentReferenceIntegrity.d.ts +47 -0
  284. package/dist/prosemirror/commentReferenceIntegrity.js +43 -0
  285. package/dist/prosemirror/conversion/fromProseDoc.d.ts +17 -12
  286. package/dist/prosemirror/conversion/fromProseDoc.js +553 -207
  287. package/dist/prosemirror/conversion/index.d.ts +2 -2
  288. package/dist/prosemirror/conversion/preservedSinkCarriers.d.ts +39 -0
  289. package/dist/prosemirror/conversion/preservedSinkCarriers.js +19 -0
  290. package/dist/prosemirror/conversion/runShadingMark.js +14 -1
  291. package/dist/prosemirror/conversion/sdtAttrs.d.ts +10 -1
  292. package/dist/prosemirror/conversion/sdtAttrs.js +19 -5
  293. package/dist/prosemirror/conversion/toProseDoc.d.ts +7 -9
  294. package/dist/prosemirror/conversion/toProseDoc.js +801 -411
  295. package/dist/prosemirror/emptyRangeAnchor.d.ts +53 -0
  296. package/dist/prosemirror/emptyRangeAnchor.js +158 -0
  297. package/dist/prosemirror/extensions/StarterKit.js +14 -58
  298. package/dist/prosemirror/extensions/core/DocExtension.js +1 -1
  299. package/dist/prosemirror/extensions/core/ParagraphExtension.js +21 -16
  300. package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +48 -29
  301. package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.js +3 -1
  302. package/dist/prosemirror/extensions/features/ImagePasteExtension.js +5 -3
  303. package/dist/prosemirror/extensions/features/ListExtension.js +43 -24
  304. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +1 -0
  305. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +4 -3
  306. package/dist/prosemirror/extensions/features/PasteCleanupExtension.d.ts +3 -3
  307. package/dist/prosemirror/extensions/features/PasteCleanupExtension.js +5 -5
  308. package/dist/prosemirror/extensions/features/pasteCleanup.d.ts +3 -1
  309. package/dist/prosemirror/extensions/features/pasteCleanup.js +56 -2
  310. package/dist/prosemirror/extensions/features/pastedHeadingStyles.js +5 -4
  311. package/dist/prosemirror/extensions/markRegistry.d.ts +65 -0
  312. package/dist/prosemirror/extensions/markRegistry.js +138 -0
  313. package/dist/prosemirror/extensions/marks/InlineWrapperExtension.d.ts +18 -0
  314. package/dist/prosemirror/extensions/marks/InlineWrapperExtension.js +77 -0
  315. package/dist/prosemirror/extensions/marks/RunIdentityExtension.d.ts +26 -0
  316. package/dist/prosemirror/extensions/marks/RunIdentityExtension.js +134 -0
  317. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +2 -1
  318. package/dist/prosemirror/extensions/marks/UnderlineExtension.js +12 -18
  319. package/dist/prosemirror/extensions/marks/markUtils.d.ts +2 -1
  320. package/dist/prosemirror/extensions/marks/markUtils.js +49 -5
  321. package/dist/prosemirror/extensions/nodes/BlockBookmarkBoundaryExtension.d.ts +29 -0
  322. package/dist/prosemirror/extensions/nodes/BlockBookmarkBoundaryExtension.js +46 -0
  323. package/dist/prosemirror/extensions/nodes/BlockSdtExtension.d.ts +4 -3
  324. package/dist/prosemirror/extensions/nodes/BlockSdtExtension.js +18 -13
  325. package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.js +28 -53
  326. package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.d.ts +11 -0
  327. package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +97 -0
  328. package/dist/prosemirror/extensions/nodes/FieldExtension.js +9 -7
  329. package/dist/prosemirror/extensions/nodes/ImageExtension.js +24 -1
  330. package/dist/prosemirror/extensions/nodes/MoveRangeBoundaryExtension.d.ts +11 -0
  331. package/dist/prosemirror/extensions/nodes/MoveRangeBoundaryExtension.js +43 -0
  332. package/dist/prosemirror/extensions/nodes/PreservedBlockExtension.d.ts +32 -0
  333. package/dist/prosemirror/extensions/nodes/PreservedBlockExtension.js +67 -0
  334. package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.d.ts +16 -0
  335. package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.js +60 -0
  336. package/dist/prosemirror/extensions/nodes/RangeAnchorExtension.d.ts +13 -0
  337. package/dist/prosemirror/extensions/nodes/RangeAnchorExtension.js +65 -0
  338. package/dist/prosemirror/extensions/nodes/SdtExtension.d.ts +3 -1
  339. package/dist/prosemirror/extensions/nodes/SdtExtension.js +22 -16
  340. package/dist/prosemirror/extensions/nodes/ShapeExtension.js +7 -0
  341. package/dist/prosemirror/extensions/nodes/TableExtension.js +142 -123
  342. package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +9 -1
  343. package/dist/prosemirror/extensions/nodes/bookmarkBoundaryDom.d.ts +23 -0
  344. package/dist/prosemirror/extensions/nodes/bookmarkBoundaryDom.js +57 -0
  345. package/dist/prosemirror/extensions/types.d.ts +12 -3
  346. package/dist/prosemirror/index.d.ts +4 -2
  347. package/dist/prosemirror/index.js +2 -1
  348. package/dist/prosemirror/inlineWrapperStack.d.ts +39 -0
  349. package/dist/prosemirror/inlineWrapperStack.js +92 -0
  350. package/dist/prosemirror/listMarker.d.ts +2 -2
  351. package/dist/prosemirror/listMarker.js +7 -8
  352. package/dist/prosemirror/listRenderingAttrs.js +11 -1
  353. package/dist/prosemirror/listState.d.ts +62 -0
  354. package/dist/prosemirror/listState.js +49 -0
  355. package/dist/prosemirror/moveRangeBoundaryAttrs.d.ts +13 -0
  356. package/dist/prosemirror/moveRangeBoundaryAttrs.js +114 -0
  357. package/dist/prosemirror/numberedRefFields.js +4 -4
  358. package/dist/prosemirror/numberingAttr.d.ts +55 -0
  359. package/dist/prosemirror/numberingAttr.js +74 -0
  360. package/dist/prosemirror/outlineLevelAttr.d.ts +29 -0
  361. package/dist/prosemirror/outlineLevelAttr.js +42 -0
  362. package/dist/prosemirror/pageBreakRunProjection.d.ts +17 -7
  363. package/dist/prosemirror/pageBreakRunProjection.js +19 -9
  364. package/dist/prosemirror/paragraphFormattingProvenance.d.ts +9 -0
  365. package/dist/prosemirror/paragraphFormattingProvenance.js +4 -1
  366. package/dist/prosemirror/plugins/selectionTracker.d.ts +3 -6
  367. package/dist/prosemirror/plugins/selectionTracker.js +3 -10
  368. package/dist/prosemirror/rangeAnchorAttrs.d.ts +14 -0
  369. package/dist/prosemirror/rangeAnchorAttrs.js +101 -0
  370. package/dist/prosemirror/replacedAnnotations.d.ts +59 -0
  371. package/dist/prosemirror/replacedAnnotations.js +183 -0
  372. package/dist/prosemirror/revisionCarriers.d.ts +86 -2
  373. package/dist/prosemirror/revisionCarriers.js +86 -60
  374. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +5 -1
  375. package/dist/prosemirror/runFormattingInlineCarriers.js +7 -1
  376. package/dist/prosemirror/runIdentity.d.ts +28 -0
  377. package/dist/prosemirror/runIdentity.js +36 -0
  378. package/dist/prosemirror/runStyleFormatting.js +1 -1
  379. package/dist/prosemirror/schema/index.d.ts +3 -3
  380. package/dist/prosemirror/schema/marks.d.ts +47 -4
  381. package/dist/prosemirror/schema/nodes.d.ts +309 -26
  382. package/dist/prosemirror/schema/nodes.js +16 -1
  383. package/dist/prosemirror/sectionCarrier.d.ts +37 -0
  384. package/dist/prosemirror/sectionCarrier.js +40 -0
  385. package/dist/prosemirror/selectionState.d.ts +3 -0
  386. package/dist/prosemirror/selectionState.js +4 -1
  387. package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +5 -4
  388. package/dist/prosemirror/styles/resolvedStyleAttrs.js +15 -13
  389. package/dist/prosemirror/tableResize.js +5 -6
  390. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +4 -0
  391. package/dist/prosemirror/trackedRunInlineAtoms.js +4 -0
  392. package/dist/prosemirror/utils/extractTrackedChanges.d.ts +10 -11
  393. package/dist/prosemirror/utils/extractTrackedChanges.js +109 -92
  394. package/dist/prosemirror/validation.js +31 -6
  395. package/dist/prosemirror/yjsDocumentMetadata.d.ts +73 -0
  396. package/dist/prosemirror/yjsDocumentMetadata.js +592 -0
  397. package/dist/prosemirror/zeroWidthAnchors.js +6 -0
  398. package/dist/render-dom/commentAnchorAttributes.d.ts +37 -0
  399. package/dist/render-dom/commentAnchorAttributes.js +54 -0
  400. package/dist/server.d.ts +3 -1
  401. package/dist/server.js +3 -1
  402. package/dist/style-sets/extract.js +4 -4
  403. package/dist/style-sets/stellaStyle.js +36 -23
  404. package/dist/types/colors.d.ts +2 -2
  405. package/dist/types/content.d.ts +2 -2
  406. package/dist/types/documentEnumValues.d.ts +53 -26
  407. package/dist/types/documentEnumValues.js +72 -174
  408. package/dist/types/formatting.d.ts +2 -2
  409. package/dist/types/index.d.ts +9 -2
  410. package/dist/utils/borderCss.d.ts +246 -0
  411. package/dist/utils/borderCss.js +325 -0
  412. package/dist/utils/clipboard.d.ts +9 -1
  413. package/dist/utils/clipboard.js +27 -1
  414. package/dist/utils/colorResolver.d.ts +4 -3
  415. package/dist/utils/colorResolver.js +45 -76
  416. package/dist/utils/createDocument.js +24 -6
  417. package/dist/utils/findReplace.js +52 -10
  418. package/dist/utils/formatToStyle.d.ts +84 -2
  419. package/dist/utils/formatToStyle.js +133 -52
  420. package/dist/utils/headingCollector.js +3 -2
  421. package/dist/utils/imageLuminance.d.ts +15 -0
  422. package/dist/utils/imageLuminance.js +32 -0
  423. package/dist/utils/mergeDocumentContent.js +12 -20
  424. package/dist/utils/paragraphFormattingMerge.js +27 -6
  425. package/dist/utils/replaceText.js +1 -0
  426. package/dist/utils/tableOperations.d.ts +5 -3
  427. package/dist/utils/tableOperations.js +14 -1
  428. package/dist/utils/tablePlacement.d.ts +7 -0
  429. package/dist/utils/tablePlacement.js +14 -0
  430. package/dist/utils/textDirectionFlow.d.ts +15 -0
  431. package/dist/utils/textDirectionFlow.js +38 -0
  432. package/dist/utils/textFormattingMerge.js +16 -4
  433. package/package.json +10 -10
  434. package/dist/ai-edits/__fixtures__/paragraphs.d.ts +0 -17
  435. package/dist/ai-edits/__fixtures__/paragraphs.js +0 -33
  436. package/dist/compare/__fixtures__/body-sequence.d.ts +0 -119
  437. package/dist/compare/__fixtures__/body-sequence.js +0 -225
  438. package/dist/compare/__fixtures__/nested-table.d.ts +0 -16
  439. package/dist/compare/__fixtures__/nested-table.js +0 -50
  440. package/dist/compare/__fixtures__/numbered-list.d.ts +0 -34
  441. package/dist/compare/__fixtures__/numbered-list.js +0 -85
  442. package/dist/docx/blockRangeMarkers.d.ts +0 -36
  443. package/dist/docx/blockRangeMarkers.js +0 -59
  444. package/dist/docx/bookmarkPlacement.d.ts +0 -9
  445. package/dist/docx/bookmarkPlacement.js +0 -50
  446. package/dist/fonts/embeddedFontTable.d.ts +0 -45
  447. package/dist/fonts/embeddedFontTable.js +0 -80
  448. package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.d.ts +0 -13
  449. package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.js +0 -39
  450. package/dist/prosemirror/yjsParagraphSourceContract.d.ts +0 -9
  451. package/dist/prosemirror/yjsParagraphSourceContract.js +0 -26
@@ -1,16 +1,18 @@
1
- import { attachPendingRangeMarkers, attachTrailingRangeMarkers, isBlockRangeMarker } from "./blockRangeMarkers.js";
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";
4
+ import { CAPTURE, dispatchChildren, keptUnless, ownedElsewhere, sequencePositions, withPreservedChildren } from "./containerChildren.js";
5
5
  import { parseParagraph } from "./paragraphParser.js";
6
6
  import { enrichParagraphTextBoxes } from "./paragraphTextBoxEnrichment.js";
7
- 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";
8
9
  import { parseShading } from "./shadingParser.js";
10
+ import { findChildAnySpelling } from "./strictNames.js";
9
11
  import { TABLE_LOOK_FLAGS } from "./tableLook.js";
10
12
  import { parsePropertyChangeInfo, parseTrackedChangeInfo } from "./trackedChangeInfo.js";
11
13
  import { percentageSpelling, transitionalSlotEncoding } from "./transitionalSpelling.js";
12
14
  import { captureVerbatimXml } from "./verbatimCapture.js";
13
- import { cloneElement, findChild, findChildByLocalName, findChildren, getAttribute, getChildElements, 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";
14
16
  //#region src/docx/tableParser.ts
15
17
  /**
16
18
  * Sanity cap on `w:gridSpan` (and the derived table column count). Word's
@@ -77,9 +79,9 @@ function parseTableBorders(bordersElement) {
77
79
  if (top) borders.top = top;
78
80
  const bottom = parseBorderSpec(findChild(bordersElement, "w", "bottom"));
79
81
  if (bottom) borders.bottom = bottom;
80
- const left = parseBorderSpec(findChild(bordersElement, "w", "left") ?? findChild(bordersElement, "w", "start"));
82
+ const left = parseBorderSpec(findChildAnySpelling(bordersElement, "CT_Border left"));
81
83
  if (left) borders.left = left;
82
- const right = parseBorderSpec(findChild(bordersElement, "w", "right") ?? findChild(bordersElement, "w", "end"));
84
+ const right = parseBorderSpec(findChildAnySpelling(bordersElement, "CT_Border right"));
83
85
  if (right) borders.right = right;
84
86
  const insideH = parseBorderSpec(findChild(bordersElement, "w", "insideH"));
85
87
  if (insideH) borders.insideH = insideH;
@@ -111,9 +113,9 @@ function parseCellMargins(marginsElement) {
111
113
  if (top) margins.top = top;
112
114
  const bottom = parseWidth(findChild(marginsElement, "w", "bottom"));
113
115
  if (bottom) margins.bottom = bottom;
114
- const left = parseWidth(findChild(marginsElement, "w", "left") ?? findChild(marginsElement, "w", "start"));
116
+ const left = parseWidth(findChildAnySpelling(marginsElement, "CT_TblWidth left"));
115
117
  if (left) margins.left = left;
116
- const right = parseWidth(findChild(marginsElement, "w", "right") ?? findChild(marginsElement, "w", "end"));
118
+ const right = parseWidth(findChildAnySpelling(marginsElement, "CT_TblWidth right"));
117
119
  if (right) margins.right = right;
118
120
  if (Object.keys(margins).length === 0) return;
119
121
  return margins;
@@ -188,6 +190,7 @@ function parseFloatingTableProperties(tblpPrElement) {
188
190
  */
189
191
  const REVISION_PROPERTY_CHILDREN = /* @__PURE__ */ new Set([
190
192
  "tblPrChange",
193
+ "tblPrExChange",
191
194
  "trPrChange",
192
195
  "tcPrChange",
193
196
  "ins",
@@ -205,50 +208,223 @@ const withSourceXml = (formatting, element) => ({
205
208
  ...formatting,
206
209
  sourceXml: captureVerbatimXml(cloneElement(element, { elements: (element.elements ?? []).filter((child) => !REVISION_PROPERTY_CHILDREN.has(getLocalName(child.name))) }))
207
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
+ };
208
361
  function parseTableProperties(tblPrElement) {
209
362
  if (!tblPrElement) return;
210
363
  const formatting = {};
211
- const width = parseWidth(findChild(tblPrElement, "w", "tblW"));
212
- if (width) formatting.width = width;
213
- const jcElement = findChild(tblPrElement, "w", "jc");
214
- if (jcElement) {
215
- const jcVal = getAttribute(jcElement, "w", "val");
216
- if (jcVal === "left" || jcVal === "center" || jcVal === "right" || jcVal === "start") formatting.justification = jcVal === "start" ? "left" : jcVal;
217
- }
218
- const cellSpacing = parseWidth(findChild(tblPrElement, "w", "tblCellSpacing"));
219
- if (cellSpacing) formatting.cellSpacing = cellSpacing;
220
- const indent = parseWidth(findChild(tblPrElement, "w", "tblInd"));
221
- if (indent) formatting.indent = indent;
222
- const borders = parseTableBorders(findChild(tblPrElement, "w", "tblBorders"));
223
- if (borders) formatting.borders = borders;
224
- const cellMargins = parseCellMargins(findChild(tblPrElement, "w", "tblCellMar"));
225
- if (cellMargins) formatting.cellMargins = cellMargins;
226
- const layoutElement = findChild(tblPrElement, "w", "tblLayout");
227
- if (layoutElement) {
228
- const layoutVal = getAttribute(layoutElement, "w", "type");
229
- if (layoutVal === "fixed" || layoutVal === "autofit") formatting.layout = layoutVal;
230
- }
231
- const styleElement = findChild(tblPrElement, "w", "tblStyle");
232
- if (styleElement) {
233
- const styleId = getAttribute(styleElement, "w", "val");
234
- if (styleId) formatting.styleId = styleId;
235
- }
236
- const look = parseTableLook(findChild(tblPrElement, "w", "tblLook"));
237
- if (look) formatting.look = look;
238
- const shading = parseShading(findChild(tblPrElement, "w", "shd"));
239
- if (shading) formatting.shading = shading;
240
- const overlapElement = findChild(tblPrElement, "w", "tblOverlap");
241
- if (overlapElement) {
242
- const overlapVal = getAttribute(overlapElement, "w", "val");
243
- if (overlapVal === "never" || overlapVal === "overlap") formatting.overlap = overlapVal;
244
- }
245
- const floating = parseFloatingTableProperties(findChild(tblPrElement, "w", "tblpPr"));
246
- if (floating) formatting.floating = floating;
247
- const bidiVisual = findChild(tblPrElement, "w", "bidiVisual");
248
- 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;
249
415
  if (Object.keys(formatting).length === 0) return;
250
416
  return withSourceXml(formatting, tblPrElement);
251
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
+ */
252
428
  function parseTablePropertyChanges(tblPrElement, currentFormatting) {
253
429
  if (!tblPrElement) return;
254
430
  const changes = findChildren(tblPrElement, "w", "tblPrChange").map((changeElement) => {
@@ -261,7 +437,45 @@ function parseTablePropertyChanges(tblPrElement, currentFormatting) {
261
437
  if (prev !== void 0) change.previousFormatting = prev;
262
438
  if (currentFormatting !== void 0) change.currentFormatting = currentFormatting;
263
439
  return change;
264
- }).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
+ });
265
479
  return changes.length > 0 ? changes : void 0;
266
480
  }
267
481
  function parseTableRowPropertyChanges(trPrElement, currentFormatting) {
@@ -276,7 +490,7 @@ function parseTableRowPropertyChanges(trPrElement, currentFormatting) {
276
490
  if (prev !== void 0) change.previousFormatting = prev;
277
491
  if (currentFormatting !== void 0) change.currentFormatting = currentFormatting;
278
492
  return change;
279
- }).filter((change) => change.previousFormatting || change.currentFormatting);
493
+ });
280
494
  return changes.length > 0 ? changes : void 0;
281
495
  }
282
496
  function parseTableCellPropertyChanges(tcPrElement, currentFormatting) {
@@ -289,9 +503,11 @@ function parseTableCellPropertyChanges(tcPrElement, currentFormatting) {
289
503
  };
290
504
  const prev = parseTableCellProperties(previousTcPr);
291
505
  if (prev !== void 0) change.previousFormatting = prev;
506
+ const previousStructuralChange = parseTableCellStructuralChange(previousTcPr);
507
+ if (previousStructuralChange !== void 0) change.previousStructuralChange = previousStructuralChange;
292
508
  if (currentFormatting !== void 0) change.currentFormatting = currentFormatting;
293
509
  return change;
294
- }).filter((change) => change.previousFormatting || change.currentFormatting);
510
+ });
295
511
  return changes.length > 0 ? changes : void 0;
296
512
  }
297
513
  function parseTableRowStructuralChange(trPrElement) {
@@ -344,37 +560,68 @@ function parseTableCellVerticalMergeRevisionValue(value) {
344
560
  function parseTableRowProperties(trPrElement) {
345
561
  if (!trPrElement) return;
346
562
  const formatting = {};
347
- const gridBefore = parseNumericAttribute(findChild(trPrElement, "w", "gridBefore"), "w", "val");
348
- if (gridBefore !== void 0 && gridBefore > 0) formatting.gridBefore = gridBefore;
349
- const widthBefore = parseTableMeasurement(findChild(trPrElement, "w", "wBefore"));
350
- if (widthBefore) formatting.widthBefore = widthBefore;
351
- const gridAfter = parseNumericAttribute(findChild(trPrElement, "w", "gridAfter"), "w", "val");
352
- if (gridAfter !== void 0 && gridAfter > 0) formatting.gridAfter = gridAfter;
353
- const widthAfter = parseTableMeasurement(findChild(trPrElement, "w", "wAfter"));
354
- if (widthAfter) formatting.widthAfter = widthAfter;
355
- const heightElement = findChild(trPrElement, "w", "trHeight");
356
- if (heightElement) {
357
- const heightVal = parseNumericAttribute(heightElement, "w", "val");
358
- if (heightVal !== void 0 && heightVal > 0) {
359
- formatting.height = {
360
- value: heightVal,
361
- type: "dxa"
362
- };
363
- const hRule = getAttribute(heightElement, "w", "hRule");
364
- if (hRule === "auto" || hRule === "atLeast" || hRule === "exact") formatting.heightRule = hRule;
365
- }
366
- }
367
- if (parseBooleanElement(findChild(trPrElement, "w", "tblHeader"))) formatting.header = true;
368
- if (parseBooleanElement(findChild(trPrElement, "w", "cantSplit"))) formatting.cantSplit = true;
369
- const jcElement = findChild(trPrElement, "w", "jc");
370
- if (jcElement) {
371
- const jcVal = getAttribute(jcElement, "w", "val");
372
- if (jcVal === "left" || jcVal === "center" || jcVal === "right") formatting.justification = jcVal;
373
- }
374
- if (parseBooleanElement(findChild(trPrElement, "w", "hidden"))) formatting.hidden = true;
375
- const conditionalFormat = parseConditionalFormatStyle(findChild(trPrElement, "w", "cnfStyle"));
376
- if (conditionalFormat) formatting.conditionalFormat = conditionalFormat;
377
- 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;
378
625
  return withSourceXml(formatting, trPrElement);
379
626
  }
380
627
  /**
@@ -425,41 +672,88 @@ function parseConditionalFormatStyle(cnfElement) {
425
672
  function parseTableCellProperties(tcPrElement) {
426
673
  if (!tcPrElement) return;
427
674
  const formatting = {};
428
- const width = parseWidth(findChild(tcPrElement, "w", "tcW"));
429
- if (width) formatting.width = width;
430
- const borders = parseTableCellBorders(findChild(tcPrElement, "w", "tcBorders"));
431
- if (borders) formatting.borders = borders;
432
- const margins = parseCellMargins(findChild(tcPrElement, "w", "tcMar"));
433
- if (margins) formatting.margins = margins;
434
- const shading = parseShading(findChild(tcPrElement, "w", "shd"));
435
- if (shading) formatting.shading = shading;
436
- const vAlignElement = findChild(tcPrElement, "w", "vAlign");
437
- if (vAlignElement) {
438
- const vAlign = getAttribute(vAlignElement, "w", "val");
439
- if (vAlign === "top" || vAlign === "center" || vAlign === "bottom") formatting.verticalAlign = vAlign;
440
- }
441
- const textDirElement = findChild(tcPrElement, "w", "textDirection");
442
- if (textDirElement) {
443
- const textDir = narrowEnum(getAttribute(textDirElement, "w", "val"), TableCellTextDirectionSchema);
444
- if (textDir) formatting.textDirection = textDir;
445
- }
446
- const gridSpanElement = findChild(tcPrElement, "w", "gridSpan");
447
- if (gridSpanElement) {
448
- const gridSpan = parseNumericAttribute(gridSpanElement, "w", "val");
449
- if (gridSpan !== void 0 && gridSpan > 1) formatting.gridSpan = Math.min(gridSpan, 63);
450
- }
451
- const vMergeElement = findChild(tcPrElement, "w", "vMerge");
452
- if (vMergeElement) if (getAttribute(vMergeElement, "w", "val") === "restart") formatting.vMerge = "restart";
453
- else formatting.vMerge = "continue";
454
- if (parseBooleanElement(findChild(tcPrElement, "w", "tcFitText"))) formatting.fitText = true;
455
- if (parseBooleanElement(findChild(tcPrElement, "w", "noWrap"))) formatting.noWrap = true;
456
- const hideMarkElement = findChild(tcPrElement, "w", "hideMark");
457
- if (hideMarkElement) formatting.hideMark = parseBooleanElement(hideMarkElement);
458
- const conditionalFormat = parseConditionalFormatStyle(findChild(tcPrElement, "w", "cnfStyle"));
459
- if (conditionalFormat) formatting.conditionalFormat = conditionalFormat;
460
- 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;
461
747
  return withSourceXml(formatting, tcPrElement);
462
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
+ };
463
757
  /**
464
758
  * Accumulate a table container's own `xmlns:*` onto the inherited in-scope set,
465
759
  * so a `w:pict` nested inside a cell still resolves prefixes scoped on the
@@ -472,58 +766,81 @@ function withContainerXmlns(options, element) {
472
766
  };
473
767
  }
474
768
  function parseCellContent(tcElement, styles, theme, numbering, rels, media, options) {
475
- const content = [];
476
- const pendingBookmarkMarkers = [];
477
- const pendingRangeMarkers = [];
478
- const elements = getChildElements(tcElement);
479
- const parseCellChild = (child, childOptions = options) => {
480
- if (!child.name) return;
481
- const localName = getLocalName(child.name);
482
- if (localName === "p") {
483
- const para = parseParagraph(child, styles, theme, numbering, rels, media, childOptions);
484
- enrichParagraphTextBoxes(para, child, styles, theme, numbering, rels, media, parseTable);
485
- prependPendingBookmarkMarkers(para, pendingBookmarkMarkers);
486
- attachPendingRangeMarkers(para, pendingRangeMarkers);
487
- content.push(para);
488
- return;
489
- }
490
- if (localName === "tbl") {
491
- const table = parseTable(child, styles, theme, numbering, rels, media, childOptions);
492
- if (!table) return;
493
- if (prependBookmarkMarkersToFirstParagraphInBlocks([table], pendingBookmarkMarkers)) pendingBookmarkMarkers.length = 0;
494
- attachPendingRangeMarkers(table, pendingRangeMarkers);
495
- content.push(table);
496
- return;
497
- }
498
- if (localName === "AlternateContent") {
499
- const selectedBranch = selectAlternateContentBranch(child);
500
- if (!selectedBranch) return;
501
- const branchOptions = withContainerXmlns(withContainerXmlns(childOptions, child), selectedBranch);
502
- for (const selectedChild of getChildElements(selectedBranch)) parseCellChild(selectedChild, branchOptions);
503
- return;
504
- }
505
- if (localName === "sdt") {
506
- const sdtContent = findChildByLocalName(child, "sdtContent");
507
- if (!sdtContent) return;
508
- const sdtContentOptions = withContainerXmlns(withContainerXmlns(childOptions, child), sdtContent);
509
- for (const sdtChild of getChildElements(sdtContent)) parseCellChild(sdtChild, sdtContentOptions);
510
- return;
511
- }
512
- if (localName === "bookmarkStart" || localName === "bookmarkEnd") {
513
- const marker = parseBookmarkMarker(child, localName);
514
- if (!appendBookmarkMarkerToLastParagraphInBlocks(content, marker)) pendingBookmarkMarkers.push(marker);
515
- return;
516
- }
517
- if (isBlockRangeMarker(localName)) pendingRangeMarkers.push(captureVerbatimXml(child));
769
+ const modelled = [];
770
+ const captured = [];
771
+ const dispatchCellChildren = (element, childOptions) => {
772
+ const preserved = dispatchChildren({
773
+ element,
774
+ container: "block-content",
775
+ capturePosition: () => modelled.length,
776
+ undeclared: { AlternateContent: (child) => {
777
+ const selectedBranch = selectAlternateContentBranch(child);
778
+ if (!selectedBranch) return;
779
+ dispatchCellChildren(selectedBranch, withContainerXmlns(withContainerXmlns(childOptions, child), selectedBranch));
780
+ } },
781
+ handlers: {
782
+ p: (child) => {
783
+ const para = parseParagraph(child, styles, theme, numbering, rels, media, {
784
+ ...childOptions,
785
+ runConsolidation: "deferred"
786
+ });
787
+ enrichParagraphTextBoxes(para, child, styles, theme, numbering, rels, media, parseTable);
788
+ modelled.push(para);
789
+ },
790
+ tbl: (child) => {
791
+ const table = parseTable(child, styles, theme, numbering, rels, media, childOptions);
792
+ if (!table) return;
793
+ modelled.push(table);
794
+ },
795
+ sdt: (child) => {
796
+ const sdtContent = findWordprocessingChild(child, "sdtContent");
797
+ if (!sdtContent) return;
798
+ dispatchCellChildren(sdtContent, withContainerXmlns(withContainerXmlns(childOptions, child), sdtContent));
799
+ },
800
+ bookmarkStart: (child) => {
801
+ modelled.push(parseBookmarkStart(child));
802
+ },
803
+ bookmarkEnd: (child) => {
804
+ modelled.push(parseBookmarkEnd(child));
805
+ },
806
+ tcPr: CELL_PROPERTIES_OWNER,
807
+ sectPr: CAPTURE,
808
+ altChunk: CAPTURE,
809
+ commentRangeEnd: CAPTURE,
810
+ commentRangeStart: CAPTURE,
811
+ customXml: CAPTURE,
812
+ customXmlDelRangeEnd: CAPTURE,
813
+ customXmlDelRangeStart: CAPTURE,
814
+ customXmlInsRangeEnd: CAPTURE,
815
+ customXmlInsRangeStart: CAPTURE,
816
+ customXmlMoveFromRangeEnd: CAPTURE,
817
+ customXmlMoveFromRangeStart: CAPTURE,
818
+ customXmlMoveToRangeEnd: CAPTURE,
819
+ customXmlMoveToRangeStart: CAPTURE,
820
+ del: CAPTURE,
821
+ ins: CAPTURE,
822
+ moveFrom: CAPTURE,
823
+ moveFromRangeEnd: CAPTURE,
824
+ moveFromRangeStart: CAPTURE,
825
+ moveTo: CAPTURE,
826
+ moveToRangeEnd: CAPTURE,
827
+ moveToRangeStart: CAPTURE,
828
+ permEnd: CAPTURE,
829
+ permStart: CAPTURE,
830
+ proofErr: CAPTURE
831
+ }
832
+ });
833
+ if (preserved?.children) captured.push(...preserved.children);
518
834
  };
519
- for (const child of elements) parseCellChild(child);
520
- if (content.length === 0) content.push({
835
+ dispatchCellChildren(tcElement, options);
836
+ if (!modelled.some((block) => block.type === "paragraph" || block.type === "table")) modelled.push({
521
837
  type: "paragraph",
522
- content: [...pendingBookmarkMarkers]
838
+ content: []
523
839
  });
524
- else if (pendingBookmarkMarkers.length > 0) appendBookmarkMarkersToLastParagraphInBlocks(content, pendingBookmarkMarkers);
525
- attachTrailingRangeMarkers(content, pendingRangeMarkers);
526
- return content;
840
+ return withPreservedChildren(modelled, { children: captured }, (xml) => ({
841
+ type: "preservedBlock",
842
+ xml
843
+ }));
527
844
  }
528
845
  /**
529
846
  * Parse a table cell (w:tc)
@@ -567,6 +884,11 @@ function parseTableRow(trElement, styles, theme, numbering, rels, media, options
567
884
  type: "tableRow",
568
885
  cells: []
569
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;
570
892
  const trPrElement = findChild(trElement, "w", "trPr");
571
893
  const formatting = parseTableRowProperties(trPrElement);
572
894
  if (formatting) row.formatting = formatting;
@@ -575,50 +897,91 @@ function parseTableRow(trElement, styles, theme, numbering, rels, media, options
575
897
  const rowStructChange = parseTableRowStructuralChange(trPrElement);
576
898
  if (rowStructChange !== void 0) row.structuralChange = rowStructChange;
577
899
  const rowOptions = withContainerXmlns(options, trElement);
578
- const pendingBookmarkMarkers = [];
579
- const parseRowChild = (child, childOptions = rowOptions) => {
580
- const localName = getLocalName(child.name);
581
- if (localName === "tc") {
582
- const cell = parseTableCell(child, styles, theme, numbering, rels, media, childOptions);
583
- if (pendingBookmarkMarkers.length > 0) {
584
- prependBookmarkMarkersToFirstParagraphInCell(cell, pendingBookmarkMarkers);
585
- pendingBookmarkMarkers.length = 0;
900
+ const bookmarks = [];
901
+ const preservedChildren = [];
902
+ /**
903
+ * One row's children, or a cell-level content control's.
904
+ *
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.
909
+ */
910
+ const dispatchRowChildren = (element, childOptions) => {
911
+ const captured = dispatchChildren({
912
+ element,
913
+ container: "row-content",
914
+ capturePosition: () => row.cells.length,
915
+ handlers: {
916
+ tc: (child) => {
917
+ row.cells.push(parseTableCell(child, styles, theme, numbering, rels, media, childOptions));
918
+ },
919
+ sdt: (child) => {
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;
925
+ const sdtOptions = withContainerXmlns(childOptions, child);
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);
934
+ },
935
+ bookmarkStart: (child) => {
936
+ bookmarks.push({
937
+ index: row.cells.length,
938
+ marker: parseBookmarkStart(child)
939
+ });
940
+ },
941
+ bookmarkEnd: (child) => {
942
+ bookmarks.push({
943
+ index: row.cells.length,
944
+ marker: parseBookmarkEnd(child)
945
+ });
946
+ },
947
+ ...ROW_CHILD_OWNERS,
948
+ commentRangeEnd: CAPTURE,
949
+ commentRangeStart: CAPTURE,
950
+ customXml: CAPTURE,
951
+ customXmlDelRangeEnd: CAPTURE,
952
+ customXmlDelRangeStart: CAPTURE,
953
+ customXmlInsRangeEnd: CAPTURE,
954
+ customXmlInsRangeStart: CAPTURE,
955
+ customXmlMoveFromRangeEnd: CAPTURE,
956
+ customXmlMoveFromRangeStart: CAPTURE,
957
+ customXmlMoveToRangeEnd: CAPTURE,
958
+ customXmlMoveToRangeStart: CAPTURE,
959
+ del: CAPTURE,
960
+ ins: CAPTURE,
961
+ moveFrom: CAPTURE,
962
+ moveFromRangeEnd: CAPTURE,
963
+ moveFromRangeStart: CAPTURE,
964
+ moveTo: CAPTURE,
965
+ moveToRangeEnd: CAPTURE,
966
+ moveToRangeStart: CAPTURE,
967
+ permEnd: CAPTURE,
968
+ permStart: CAPTURE,
969
+ proofErr: CAPTURE,
970
+ tr: CAPTURE
586
971
  }
587
- row.cells.push(cell);
588
- return;
589
- }
590
- if (localName === "sdt") {
591
- const sdtContent = findChildByLocalName(child, "sdtContent");
592
- if (!sdtContent) return;
593
- const sdtContentOptions = withContainerXmlns(withContainerXmlns(childOptions, child), sdtContent);
594
- for (const sdtChild of getChildElements(sdtContent)) parseRowChild(sdtChild, sdtContentOptions);
595
- return;
596
- }
597
- if (localName !== "bookmarkStart" && localName !== "bookmarkEnd") return;
598
- const marker = parseBookmarkMarker(child, localName);
599
- if (!appendBookmarkMarkerToLastParagraphInCells(row.cells, marker)) pendingBookmarkMarkers.push(marker);
972
+ });
973
+ if (captured?.children) preservedChildren.push(...captured.children);
600
974
  };
601
- for (const child of getChildElements(trElement)) parseRowChild(child);
602
- if (pendingBookmarkMarkers.length > 0) appendBookmarkMarkersToLastCell(row, pendingBookmarkMarkers);
975
+ dispatchRowChildren(trElement, rowOptions);
976
+ if (preservedChildren.length > 0) row.preserved = { children: preservedChildren };
977
+ if (bookmarks.length > 0) row.bookmarks = bookmarks;
978
+ const remainingAttributes = attributeRemainder({
979
+ element: trElement,
980
+ modelled: NO_MODELLED_ATTRIBUTES
981
+ });
982
+ if (remainingAttributes) row.preservedAttributes = remainingAttributes;
603
983
  return row;
604
984
  }
605
- function parseBookmarkMarker(child, localName) {
606
- if (localName === "bookmarkStart") return parseBookmarkStart(child);
607
- return parseBookmarkEnd(child);
608
- }
609
- function prependPendingBookmarkMarkers(paragraph, pendingBookmarkMarkers) {
610
- if (pendingBookmarkMarkers.length === 0) return;
611
- paragraph.content.unshift(...pendingBookmarkMarkers);
612
- pendingBookmarkMarkers.length = 0;
613
- }
614
- function appendBookmarkMarkersToLastParagraphInBlocks(blocks, markers) {
615
- for (const marker of markers) appendBookmarkMarkerToLastParagraphInBlocks(blocks, marker);
616
- }
617
- function appendBookmarkMarkersToLastCell(row, markers) {
618
- const lastCell = row.cells.at(-1);
619
- if (!lastCell) return;
620
- for (const marker of markers) appendBookmarkMarkerToLastParagraphInBlocks(lastCell.content, marker);
621
- }
622
985
  /**
623
986
  * Parse table grid (w:tblGrid) for column widths
624
987
  *
@@ -636,6 +999,24 @@ function parseTableGrid(tblGridElement) {
636
999
  if (widths.length > 0 && widths.every((width) => width <= 0)) return;
637
1000
  return widths.length > 0 ? widths : void 0;
638
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
+ }
639
1020
  function hasRowGridOffsets(rowElement) {
640
1021
  const trPrElement = findChild(rowElement, "w", "trPr");
641
1022
  if (!trPrElement) return false;
@@ -698,32 +1079,96 @@ function parseTable(tblElement, styles, theme, numbering, rels, media, options)
698
1079
  const columnWidths = parseTableGrid(gridElement);
699
1080
  if (columnWidths) table.columnWidths = columnWidths;
700
1081
  if (gridElement) {
701
- const gridChange = findChild(gridElement, "w", "tblGridChange");
1082
+ const gridChange = parseTableGridChange(gridElement);
702
1083
  table.formatting = {
703
1084
  ...table.formatting,
704
1085
  gridSourceXml: captureVerbatimXml(gridElement),
705
- ...gridChange ? { gridChangeXml: captureVerbatimXml(gridChange) } : {}
1086
+ ...gridChange === void 0 ? {} : { gridChange }
706
1087
  };
707
1088
  }
708
1089
  const tableOptions = withContainerXmlns(options, tblElement);
709
1090
  const rowsWithGridOffsets = /* @__PURE__ */ new Set();
710
- const parseTableChild = (child, childOptions = tableOptions) => {
711
- const localName = getLocalName(child.name);
712
- if (localName === "tr") {
713
- const rowIndex = table.rows.length;
714
- const row = parseTableRow(child, styles, theme, numbering, rels, media, childOptions);
715
- table.rows.push(row);
716
- if (hasRowGridOffsets(child)) rowsWithGridOffsets.add(rowIndex);
717
- return;
718
- }
719
- if (localName !== "sdt") return;
720
- const sdtContent = findChildByLocalName(child, "sdtContent");
721
- if (!sdtContent) return;
722
- const sdtContentOptions = withContainerXmlns(withContainerXmlns(childOptions, child), sdtContent);
723
- for (const sdtChild of getChildElements(sdtContent)) parseTableChild(sdtChild, sdtContentOptions);
1091
+ const preservedChildren = [];
1092
+ const bookmarks = [];
1093
+ /**
1094
+ * One table's children, or a row-level content control's.
1095
+ *
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.
1100
+ */
1101
+ const dispatchTableChildren = (element, childOptions) => {
1102
+ const captured = dispatchChildren({
1103
+ element,
1104
+ container: "table-content",
1105
+ capturePosition: () => table.rows.length,
1106
+ handlers: {
1107
+ tr: (child) => {
1108
+ const rowIndex = table.rows.length;
1109
+ table.rows.push(parseTableRow(child, styles, theme, numbering, rels, media, childOptions));
1110
+ if (hasRowGridOffsets(child)) rowsWithGridOffsets.add(rowIndex);
1111
+ },
1112
+ sdt: (child) => {
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;
1118
+ const sdtOptions = withContainerXmlns(childOptions, child);
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
+ });
1140
+ },
1141
+ commentRangeEnd: CAPTURE,
1142
+ commentRangeStart: CAPTURE,
1143
+ customXml: CAPTURE,
1144
+ customXmlPr: CAPTURE,
1145
+ customXmlDelRangeEnd: CAPTURE,
1146
+ customXmlDelRangeStart: CAPTURE,
1147
+ customXmlInsRangeEnd: CAPTURE,
1148
+ customXmlInsRangeStart: CAPTURE,
1149
+ customXmlMoveFromRangeEnd: CAPTURE,
1150
+ customXmlMoveFromRangeStart: CAPTURE,
1151
+ customXmlMoveToRangeEnd: CAPTURE,
1152
+ customXmlMoveToRangeStart: CAPTURE,
1153
+ del: CAPTURE,
1154
+ ins: CAPTURE,
1155
+ moveFrom: CAPTURE,
1156
+ moveFromRangeEnd: CAPTURE,
1157
+ moveFromRangeStart: CAPTURE,
1158
+ moveTo: CAPTURE,
1159
+ moveToRangeEnd: CAPTURE,
1160
+ moveToRangeStart: CAPTURE,
1161
+ permEnd: CAPTURE,
1162
+ permStart: CAPTURE,
1163
+ proofErr: CAPTURE
1164
+ }
1165
+ });
1166
+ if (captured?.children) preservedChildren.push(...captured.children);
724
1167
  };
725
- for (const child of getChildElements(tblElement)) parseTableChild(child);
1168
+ dispatchTableChildren(tblElement, tableOptions);
726
1169
  if (table.rows.length === 0) return;
1170
+ if (preservedChildren.length > 0) table.preserved = { children: preservedChildren };
1171
+ if (bookmarks.length > 0) table.bookmarks = bookmarks;
727
1172
  inferImplicitSingleCellRowSpans(table, rowsWithGridOffsets);
728
1173
  return table;
729
1174
  }
@@ -832,4 +1277,4 @@ function isFloatingTable(table) {
832
1277
  return table.formatting?.floating !== void 0;
833
1278
  }
834
1279
  //#endregion
835
- 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 };