docxmlater 10.0.1 → 10.0.3

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 (395) hide show
  1. package/README.md +3 -2
  2. package/dist/constants/legacyCompatFlags.d.ts.map +1 -1
  3. package/dist/constants/legacyCompatFlags.js.map +1 -1
  4. package/dist/constants/limits.d.ts +0 -27
  5. package/dist/constants/limits.d.ts.map +1 -1
  6. package/dist/constants/limits.js +13 -13
  7. package/dist/constants/limits.js.map +1 -1
  8. package/dist/core/Document.d.ts +24 -19
  9. package/dist/core/Document.d.ts.map +1 -1
  10. package/dist/core/Document.js +272 -71
  11. package/dist/core/Document.js.map +1 -1
  12. package/dist/core/DocumentContent.d.ts.map +1 -1
  13. package/dist/core/DocumentContent.js.map +1 -1
  14. package/dist/core/DocumentGenerator.d.ts.map +1 -1
  15. package/dist/core/DocumentGenerator.js +59 -24
  16. package/dist/core/DocumentGenerator.js.map +1 -1
  17. package/dist/core/DocumentIdManager.d.ts.map +1 -1
  18. package/dist/core/DocumentIdManager.js.map +1 -1
  19. package/dist/core/DocumentParser.d.ts +6 -6
  20. package/dist/core/DocumentParser.d.ts.map +1 -1
  21. package/dist/core/DocumentParser.js +60 -54
  22. package/dist/core/DocumentParser.js.map +1 -1
  23. package/dist/core/DocumentValidator.d.ts.map +1 -1
  24. package/dist/core/DocumentValidator.js.map +1 -1
  25. package/dist/core/Relationship.d.ts.map +1 -1
  26. package/dist/core/Relationship.js +1 -1
  27. package/dist/core/Relationship.js.map +1 -1
  28. package/dist/core/RelationshipManager.js +3 -3
  29. package/dist/core/RelationshipManager.js.map +1 -1
  30. package/dist/elements/AlternateContent.js.map +1 -1
  31. package/dist/elements/Bookmark.d.ts.map +1 -1
  32. package/dist/elements/Bookmark.js.map +1 -1
  33. package/dist/elements/BookmarkManager.d.ts.map +1 -1
  34. package/dist/elements/BookmarkManager.js.map +1 -1
  35. package/dist/elements/Comment.js +1 -1
  36. package/dist/elements/Comment.js.map +1 -1
  37. package/dist/elements/CommentManager.d.ts.map +1 -1
  38. package/dist/elements/CommentManager.js +8 -2
  39. package/dist/elements/CommentManager.js.map +1 -1
  40. package/dist/elements/CommonTypes.d.ts.map +1 -1
  41. package/dist/elements/CommonTypes.js +1 -2
  42. package/dist/elements/CommonTypes.js.map +1 -1
  43. package/dist/elements/CustomXml.js.map +1 -1
  44. package/dist/elements/Endnote.d.ts.map +1 -1
  45. package/dist/elements/Endnote.js.map +1 -1
  46. package/dist/elements/EndnoteManager.d.ts.map +1 -1
  47. package/dist/elements/EndnoteManager.js.map +1 -1
  48. package/dist/elements/Field.d.ts.map +1 -1
  49. package/dist/elements/Field.js +31 -28
  50. package/dist/elements/Field.js.map +1 -1
  51. package/dist/elements/FieldHelpers.d.ts.map +1 -1
  52. package/dist/elements/FieldHelpers.js +6 -6
  53. package/dist/elements/FieldHelpers.js.map +1 -1
  54. package/dist/elements/FontManager.d.ts.map +1 -1
  55. package/dist/elements/FontManager.js.map +1 -1
  56. package/dist/elements/Footer.js.map +1 -1
  57. package/dist/elements/Footnote.d.ts.map +1 -1
  58. package/dist/elements/Footnote.js.map +1 -1
  59. package/dist/elements/FootnoteManager.d.ts.map +1 -1
  60. package/dist/elements/FootnoteManager.js.map +1 -1
  61. package/dist/elements/Header.js.map +1 -1
  62. package/dist/elements/HeaderFooterManager.js.map +1 -1
  63. package/dist/elements/Hyperlink.d.ts.map +1 -1
  64. package/dist/elements/Hyperlink.js +5 -5
  65. package/dist/elements/Hyperlink.js.map +1 -1
  66. package/dist/elements/Image.d.ts +2 -2
  67. package/dist/elements/Image.d.ts.map +1 -1
  68. package/dist/elements/Image.js +21 -5
  69. package/dist/elements/Image.js.map +1 -1
  70. package/dist/elements/ImageManager.d.ts.map +1 -1
  71. package/dist/elements/ImageManager.js +2 -2
  72. package/dist/elements/ImageManager.js.map +1 -1
  73. package/dist/elements/ImageRun.js.map +1 -1
  74. package/dist/elements/MathElement.js.map +1 -1
  75. package/dist/elements/Paragraph.d.ts.map +1 -1
  76. package/dist/elements/Paragraph.js +128 -117
  77. package/dist/elements/Paragraph.js.map +1 -1
  78. package/dist/elements/PreservedElement.js.map +1 -1
  79. package/dist/elements/PropertyChangeTypes.js.map +1 -1
  80. package/dist/elements/RangeMarker.js.map +1 -1
  81. package/dist/elements/Revision.d.ts +1 -0
  82. package/dist/elements/Revision.d.ts.map +1 -1
  83. package/dist/elements/Revision.js +44 -5
  84. package/dist/elements/Revision.js.map +1 -1
  85. package/dist/elements/RevisionContent.js.map +1 -1
  86. package/dist/elements/RevisionManager.d.ts.map +1 -1
  87. package/dist/elements/RevisionManager.js.map +1 -1
  88. package/dist/elements/Run.d.ts.map +1 -1
  89. package/dist/elements/Run.js +1 -3
  90. package/dist/elements/Run.js.map +1 -1
  91. package/dist/elements/Section.d.ts.map +1 -1
  92. package/dist/elements/Section.js +127 -118
  93. package/dist/elements/Section.js.map +1 -1
  94. package/dist/elements/Shape.d.ts.map +1 -1
  95. package/dist/elements/Shape.js +21 -0
  96. package/dist/elements/Shape.js.map +1 -1
  97. package/dist/elements/StructuredDocumentTag.d.ts.map +1 -1
  98. package/dist/elements/StructuredDocumentTag.js +20 -8
  99. package/dist/elements/StructuredDocumentTag.js.map +1 -1
  100. package/dist/elements/Table.d.ts +2 -2
  101. package/dist/elements/Table.d.ts.map +1 -1
  102. package/dist/elements/Table.js +29 -35
  103. package/dist/elements/Table.js.map +1 -1
  104. package/dist/elements/TableCell.d.ts +2 -2
  105. package/dist/elements/TableCell.d.ts.map +1 -1
  106. package/dist/elements/TableCell.js +63 -67
  107. package/dist/elements/TableCell.js.map +1 -1
  108. package/dist/elements/TableGridChange.js.map +1 -1
  109. package/dist/elements/TableOfContents.d.ts +6 -6
  110. package/dist/elements/TableOfContents.d.ts.map +1 -1
  111. package/dist/elements/TableOfContents.js.map +1 -1
  112. package/dist/elements/TableOfContentsElement.js.map +1 -1
  113. package/dist/elements/TableRow.d.ts.map +1 -1
  114. package/dist/elements/TableRow.js +65 -47
  115. package/dist/elements/TableRow.js.map +1 -1
  116. package/dist/elements/TextBox.d.ts.map +1 -1
  117. package/dist/elements/TextBox.js +1 -1
  118. package/dist/elements/TextBox.js.map +1 -1
  119. package/dist/formatting/AbstractNumbering.d.ts +1 -1
  120. package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
  121. package/dist/formatting/AbstractNumbering.js +11 -11
  122. package/dist/formatting/AbstractNumbering.js.map +1 -1
  123. package/dist/formatting/NumberingInstance.d.ts.map +1 -1
  124. package/dist/formatting/NumberingInstance.js +4 -4
  125. package/dist/formatting/NumberingInstance.js.map +1 -1
  126. package/dist/formatting/NumberingLevel.d.ts.map +1 -1
  127. package/dist/formatting/NumberingLevel.js +26 -26
  128. package/dist/formatting/NumberingLevel.js.map +1 -1
  129. package/dist/formatting/NumberingManager.d.ts +1 -1
  130. package/dist/formatting/NumberingManager.d.ts.map +1 -1
  131. package/dist/formatting/NumberingManager.js.map +1 -1
  132. package/dist/formatting/Style.d.ts.map +1 -1
  133. package/dist/formatting/Style.js +87 -95
  134. package/dist/formatting/Style.js.map +1 -1
  135. package/dist/formatting/StylesManager.d.ts +3 -3
  136. package/dist/formatting/StylesManager.d.ts.map +1 -1
  137. package/dist/formatting/StylesManager.js.map +1 -1
  138. package/dist/helpers/CleanupHelper.d.ts.map +1 -1
  139. package/dist/helpers/CleanupHelper.js +1 -7
  140. package/dist/helpers/CleanupHelper.js.map +1 -1
  141. package/dist/images/ImageOptimizer.js.map +1 -1
  142. package/dist/index.js.map +1 -1
  143. package/dist/managers/DrawingManager.d.ts.map +1 -1
  144. package/dist/managers/DrawingManager.js.map +1 -1
  145. package/dist/tracking/DocumentTrackingContext.js.map +1 -1
  146. package/dist/tracking/TrackingContext.js.map +1 -1
  147. package/dist/types/compatibility-types.js.map +1 -1
  148. package/dist/types/formatting.js.map +1 -1
  149. package/dist/types/list-types.d.ts +4 -4
  150. package/dist/types/list-types.d.ts.map +1 -1
  151. package/dist/types/list-types.js.map +1 -1
  152. package/dist/types/settings-types.js.map +1 -1
  153. package/dist/types/styleConfig.js.map +1 -1
  154. package/dist/utils/ChangelogGenerator.d.ts.map +1 -1
  155. package/dist/utils/ChangelogGenerator.js.map +1 -1
  156. package/dist/utils/CompatibilityUpgrader.d.ts.map +1 -1
  157. package/dist/utils/CompatibilityUpgrader.js +7 -7
  158. package/dist/utils/CompatibilityUpgrader.js.map +1 -1
  159. package/dist/utils/InMemoryRevisionAcceptor.js +1 -1
  160. package/dist/utils/InMemoryRevisionAcceptor.js.map +1 -1
  161. package/dist/utils/MoveOperationHelper.js.map +1 -1
  162. package/dist/utils/RevisionAwareProcessor.js.map +1 -1
  163. package/dist/utils/RevisionWalker.js.map +1 -1
  164. package/dist/utils/SelectiveRevisionAcceptor.js.map +1 -1
  165. package/dist/utils/ShadingResolver.js +1 -1
  166. package/dist/utils/ShadingResolver.js.map +1 -1
  167. package/dist/utils/acceptRevisions.d.ts +0 -28
  168. package/dist/utils/acceptRevisions.d.ts.map +1 -1
  169. package/dist/utils/acceptRevisions.js +5 -7
  170. package/dist/utils/acceptRevisions.js.map +1 -1
  171. package/dist/utils/cnfStyleDecoder.js +1 -1
  172. package/dist/utils/cnfStyleDecoder.js.map +1 -1
  173. package/dist/utils/corruptionDetection.js.map +1 -1
  174. package/dist/utils/dateFormatting.js.map +1 -1
  175. package/dist/utils/deepClone.d.ts +0 -1
  176. package/dist/utils/deepClone.d.ts.map +1 -1
  177. package/dist/utils/deepClone.js +0 -7
  178. package/dist/utils/deepClone.js.map +1 -1
  179. package/dist/utils/diagnostics.d.ts +2 -2
  180. package/dist/utils/diagnostics.d.ts.map +1 -1
  181. package/dist/utils/diagnostics.js.map +1 -1
  182. package/dist/utils/errorHandling.js.map +1 -1
  183. package/dist/utils/formatting.js.map +1 -1
  184. package/dist/utils/list-detection.d.ts +2 -2
  185. package/dist/utils/list-detection.d.ts.map +1 -1
  186. package/dist/utils/list-detection.js +3 -3
  187. package/dist/utils/list-detection.js.map +1 -1
  188. package/dist/utils/logger.d.ts +2 -4
  189. package/dist/utils/logger.d.ts.map +1 -1
  190. package/dist/utils/logger.js +0 -2
  191. package/dist/utils/logger.js.map +1 -1
  192. package/dist/utils/parsingHelpers.js.map +1 -1
  193. package/dist/utils/stripTrackedChanges.d.ts +0 -19
  194. package/dist/utils/stripTrackedChanges.d.ts.map +1 -1
  195. package/dist/utils/stripTrackedChanges.js +0 -2
  196. package/dist/utils/stripTrackedChanges.js.map +1 -1
  197. package/dist/utils/textDiff.js.map +1 -1
  198. package/dist/utils/units.js.map +1 -1
  199. package/dist/utils/validation.d.ts.map +1 -1
  200. package/dist/utils/validation.js.map +1 -1
  201. package/dist/utils/xmlSanitization.js.map +1 -1
  202. package/dist/validation/RevisionAutoFixer.js.map +1 -1
  203. package/dist/validation/RevisionValidator.js.map +1 -1
  204. package/dist/validation/ValidationRules.js.map +1 -1
  205. package/dist/validation/index.js.map +1 -1
  206. package/dist/xml/XMLBuilder.d.ts.map +1 -1
  207. package/dist/xml/XMLBuilder.js +10 -0
  208. package/dist/xml/XMLBuilder.js.map +1 -1
  209. package/dist/xml/XMLParser.d.ts.map +1 -1
  210. package/dist/xml/XMLParser.js +4 -5
  211. package/dist/xml/XMLParser.js.map +1 -1
  212. package/dist/zip/ZipHandler.js.map +1 -1
  213. package/dist/zip/ZipReader.js.map +1 -1
  214. package/dist/zip/ZipWriter.js.map +1 -1
  215. package/dist/zip/errors.js.map +1 -1
  216. package/dist/zip/types.js.map +1 -1
  217. package/package.json +34 -4
  218. package/src/__tests__/helper-methods.test.ts +512 -0
  219. package/src/constants/legacyCompatFlags.ts +138 -0
  220. package/src/constants/limits.ts +50 -0
  221. package/src/core/CLAUDE.md +109 -0
  222. package/src/core/Document.ts +15569 -0
  223. package/src/core/DocumentContent.ts +467 -0
  224. package/src/core/DocumentGenerator.ts +1104 -0
  225. package/src/core/DocumentIdManager.ts +158 -0
  226. package/src/core/DocumentParser.ts +10107 -0
  227. package/src/core/DocumentValidator.ts +372 -0
  228. package/src/core/Relationship.ts +367 -0
  229. package/src/core/RelationshipManager.ts +428 -0
  230. package/src/elements/AlternateContent.ts +42 -0
  231. package/src/elements/Bookmark.ts +210 -0
  232. package/src/elements/BookmarkManager.ts +250 -0
  233. package/src/elements/CLAUDE.md +126 -0
  234. package/src/elements/Comment.ts +359 -0
  235. package/src/elements/CommentManager.ts +502 -0
  236. package/src/elements/CommonTypes.ts +549 -0
  237. package/src/elements/CustomXml.ts +36 -0
  238. package/src/elements/Endnote.ts +217 -0
  239. package/src/elements/EndnoteManager.ts +249 -0
  240. package/src/elements/Field.ts +1233 -0
  241. package/src/elements/FieldHelpers.ts +333 -0
  242. package/src/elements/FontManager.ts +339 -0
  243. package/src/elements/Footer.ts +269 -0
  244. package/src/elements/Footnote.ts +217 -0
  245. package/src/elements/FootnoteManager.ts +249 -0
  246. package/src/elements/Header.ts +269 -0
  247. package/src/elements/HeaderFooterManager.ts +219 -0
  248. package/src/elements/Hyperlink.ts +1146 -0
  249. package/src/elements/Image.ts +1756 -0
  250. package/src/elements/ImageManager.ts +432 -0
  251. package/src/elements/ImageRun.ts +59 -0
  252. package/src/elements/MathElement.ts +65 -0
  253. package/src/elements/Paragraph.ts +4227 -0
  254. package/src/elements/PreservedElement.ts +53 -0
  255. package/src/elements/PropertyChangeTypes.ts +442 -0
  256. package/src/elements/RangeMarker.ts +400 -0
  257. package/src/elements/Revision.ts +1217 -0
  258. package/src/elements/RevisionContent.ts +73 -0
  259. package/src/elements/RevisionManager.ts +1070 -0
  260. package/src/elements/Run.ts +3068 -0
  261. package/src/elements/Section.ts +1421 -0
  262. package/src/elements/Shape.ts +873 -0
  263. package/src/elements/StructuredDocumentTag.ts +978 -0
  264. package/src/elements/Table.ts +2524 -0
  265. package/src/elements/TableCell.ts +1586 -0
  266. package/src/elements/TableGridChange.ts +151 -0
  267. package/src/elements/TableOfContents.ts +691 -0
  268. package/src/elements/TableOfContentsElement.ts +89 -0
  269. package/src/elements/TableRow.ts +906 -0
  270. package/src/elements/TextBox.ts +768 -0
  271. package/src/formatting/AbstractNumbering.ts +548 -0
  272. package/src/formatting/CLAUDE.md +74 -0
  273. package/src/formatting/NumberingInstance.ts +212 -0
  274. package/src/formatting/NumberingLevel.ts +1006 -0
  275. package/src/formatting/NumberingManager.ts +827 -0
  276. package/src/formatting/Style.ts +1833 -0
  277. package/src/formatting/StylesManager.ts +1005 -0
  278. package/src/helpers/CleanupHelper.ts +524 -0
  279. package/src/images/ImageOptimizer.ts +274 -0
  280. package/src/index.ts +554 -0
  281. package/src/managers/CLAUDE.md +47 -0
  282. package/src/managers/DrawingManager.ts +319 -0
  283. package/src/tracking/DocumentTrackingContext.ts +643 -0
  284. package/src/tracking/TrackingContext.ts +173 -0
  285. package/src/types/compatibility-types.ts +49 -0
  286. package/src/types/formatting.ts +210 -0
  287. package/src/types/list-types.ts +152 -0
  288. package/src/types/settings-types.ts +59 -0
  289. package/src/types/styleConfig.ts +189 -0
  290. package/src/utils/CLAUDE.md +153 -0
  291. package/src/utils/ChangelogGenerator.ts +1581 -0
  292. package/src/utils/CompatibilityUpgrader.ts +237 -0
  293. package/src/utils/InMemoryRevisionAcceptor.ts +668 -0
  294. package/src/utils/MoveOperationHelper.ts +238 -0
  295. package/src/utils/RevisionAwareProcessor.ts +526 -0
  296. package/src/utils/RevisionWalker.ts +457 -0
  297. package/src/utils/SelectiveRevisionAcceptor.ts +613 -0
  298. package/src/utils/ShadingResolver.ts +107 -0
  299. package/src/utils/acceptRevisions.ts +714 -0
  300. package/src/utils/cnfStyleDecoder.ts +217 -0
  301. package/src/utils/corruptionDetection.ts +345 -0
  302. package/src/utils/dateFormatting.ts +20 -0
  303. package/src/utils/deepClone.ts +78 -0
  304. package/src/utils/diagnostics.ts +129 -0
  305. package/src/utils/errorHandling.ts +80 -0
  306. package/src/utils/formatting.ts +213 -0
  307. package/src/utils/list-detection.ts +274 -0
  308. package/src/utils/logger.ts +404 -0
  309. package/src/utils/parsingHelpers.ts +190 -0
  310. package/src/utils/stripTrackedChanges.ts +353 -0
  311. package/src/utils/textDiff.ts +100 -0
  312. package/src/utils/units.ts +421 -0
  313. package/src/utils/validation.ts +542 -0
  314. package/src/utils/xmlSanitization.ts +182 -0
  315. package/src/validation/RevisionAutoFixer.ts +542 -0
  316. package/src/validation/RevisionValidator.ts +460 -0
  317. package/src/validation/ValidationRules.ts +338 -0
  318. package/src/validation/index.ts +30 -0
  319. package/src/xml/CLAUDE.md +65 -0
  320. package/src/xml/XMLBuilder.ts +871 -0
  321. package/src/xml/XMLParser.ts +919 -0
  322. package/src/zip/CLAUDE.md +55 -0
  323. package/src/zip/ZipHandler.ts +637 -0
  324. package/src/zip/ZipReader.ts +299 -0
  325. package/src/zip/ZipWriter.ts +390 -0
  326. package/src/zip/errors.ts +69 -0
  327. package/src/zip/types.ts +116 -0
  328. package/dist/core/ListNormalizer.d.ts +0 -23
  329. package/dist/core/ListNormalizer.d.ts.map +0 -1
  330. package/dist/core/ListNormalizer.js +0 -624
  331. package/dist/core/ListNormalizer.js.map +0 -1
  332. package/dist/images/index.d.ts +0 -2
  333. package/dist/images/index.d.ts.map +0 -1
  334. package/dist/images/index.js +0 -8
  335. package/dist/images/index.js.map +0 -1
  336. package/dist/ms-doc/cfb/CFBReader.d.ts +0 -35
  337. package/dist/ms-doc/cfb/CFBReader.d.ts.map +0 -1
  338. package/dist/ms-doc/cfb/CFBReader.js +0 -360
  339. package/dist/ms-doc/cfb/CFBReader.js.map +0 -1
  340. package/dist/ms-doc/converter/DocToDocxConverter.d.ts +0 -55
  341. package/dist/ms-doc/converter/DocToDocxConverter.d.ts.map +0 -1
  342. package/dist/ms-doc/converter/DocToDocxConverter.js +0 -324
  343. package/dist/ms-doc/converter/DocToDocxConverter.js.map +0 -1
  344. package/dist/ms-doc/fib/FIB.d.ts +0 -18
  345. package/dist/ms-doc/fib/FIB.d.ts.map +0 -1
  346. package/dist/ms-doc/fib/FIB.js +0 -342
  347. package/dist/ms-doc/fib/FIB.js.map +0 -1
  348. package/dist/ms-doc/fields/FieldParser.d.ts +0 -31
  349. package/dist/ms-doc/fields/FieldParser.d.ts.map +0 -1
  350. package/dist/ms-doc/fields/FieldParser.js +0 -266
  351. package/dist/ms-doc/fields/FieldParser.js.map +0 -1
  352. package/dist/ms-doc/images/PictureExtractor.d.ts +0 -22
  353. package/dist/ms-doc/images/PictureExtractor.d.ts.map +0 -1
  354. package/dist/ms-doc/images/PictureExtractor.js +0 -233
  355. package/dist/ms-doc/images/PictureExtractor.js.map +0 -1
  356. package/dist/ms-doc/index.d.ts +0 -20
  357. package/dist/ms-doc/index.d.ts.map +0 -1
  358. package/dist/ms-doc/index.js +0 -59
  359. package/dist/ms-doc/index.js.map +0 -1
  360. package/dist/ms-doc/properties/SPRM.d.ts +0 -210
  361. package/dist/ms-doc/properties/SPRM.d.ts.map +0 -1
  362. package/dist/ms-doc/properties/SPRM.js +0 -633
  363. package/dist/ms-doc/properties/SPRM.js.map +0 -1
  364. package/dist/ms-doc/sections/SectionParser.d.ts +0 -25
  365. package/dist/ms-doc/sections/SectionParser.d.ts.map +0 -1
  366. package/dist/ms-doc/sections/SectionParser.js +0 -214
  367. package/dist/ms-doc/sections/SectionParser.js.map +0 -1
  368. package/dist/ms-doc/styles/StyleSheet.d.ts +0 -23
  369. package/dist/ms-doc/styles/StyleSheet.d.ts.map +0 -1
  370. package/dist/ms-doc/styles/StyleSheet.js +0 -268
  371. package/dist/ms-doc/styles/StyleSheet.js.map +0 -1
  372. package/dist/ms-doc/subdocuments/SubdocumentParser.d.ts +0 -61
  373. package/dist/ms-doc/subdocuments/SubdocumentParser.d.ts.map +0 -1
  374. package/dist/ms-doc/subdocuments/SubdocumentParser.js +0 -208
  375. package/dist/ms-doc/subdocuments/SubdocumentParser.js.map +0 -1
  376. package/dist/ms-doc/tables/TableParser.d.ts +0 -29
  377. package/dist/ms-doc/tables/TableParser.d.ts.map +0 -1
  378. package/dist/ms-doc/tables/TableParser.js +0 -176
  379. package/dist/ms-doc/tables/TableParser.js.map +0 -1
  380. package/dist/ms-doc/text/PieceTable.d.ts +0 -21
  381. package/dist/ms-doc/text/PieceTable.d.ts.map +0 -1
  382. package/dist/ms-doc/text/PieceTable.js +0 -171
  383. package/dist/ms-doc/text/PieceTable.js.map +0 -1
  384. package/dist/ms-doc/types/Constants.d.ts +0 -99
  385. package/dist/ms-doc/types/Constants.d.ts.map +0 -1
  386. package/dist/ms-doc/types/Constants.js +0 -102
  387. package/dist/ms-doc/types/Constants.js.map +0 -1
  388. package/dist/ms-doc/types/DocTypes.d.ts +0 -368
  389. package/dist/ms-doc/types/DocTypes.d.ts.map +0 -1
  390. package/dist/ms-doc/types/DocTypes.js +0 -3
  391. package/dist/ms-doc/types/DocTypes.js.map +0 -1
  392. package/dist/tracking/index.d.ts +0 -3
  393. package/dist/tracking/index.d.ts.map +0 -1
  394. package/dist/tracking/index.js +0 -6
  395. package/dist/tracking/index.js.map +0 -1
@@ -0,0 +1,1217 @@
1
+ /**
2
+ * Revision - Represents tracked changes in a Word document
3
+ *
4
+ * Track changes allow tracking of insertions, deletions, and modifications
5
+ * to document content, showing who made changes and when.
6
+ */
7
+
8
+ import { Run } from './Run';
9
+ import type { RunFormatting } from './Run';
10
+ import { XMLElement } from '../xml/XMLBuilder';
11
+ import type { RevisionLocation } from './PropertyChangeTypes';
12
+ import type { RevisionContent } from './RevisionContent';
13
+ import { isRunContent, isHyperlinkContent } from './RevisionContent';
14
+ import { formatDateForXml } from '../utils/dateFormatting';
15
+
16
+ /**
17
+ * Revision type - All OpenXML WordprocessingML revision types
18
+ */
19
+ export type RevisionType =
20
+ // Content changes
21
+ | 'insert' // w:ins - Inserted content
22
+ | 'delete' // w:del - Deleted content
23
+ // Property changes
24
+ | 'runPropertiesChange' // w:rPrChange - Run formatting change (bold, italic, font, etc.)
25
+ | 'paragraphPropertiesChange' // w:pPrChange - Paragraph formatting change
26
+ | 'tablePropertiesChange' // w:tblPrChange - Table formatting change
27
+ | 'tableExceptionPropertiesChange' // w:tblPrExChange - Table exception properties change
28
+ | 'tableRowPropertiesChange' // w:trPrChange - Table row properties change
29
+ | 'tableCellPropertiesChange' // w:tcPrChange - Table cell properties change
30
+ | 'sectionPropertiesChange' // w:sectPrChange - Section properties change
31
+ // Move operations
32
+ | 'moveFrom' // w:moveFrom - Content moved from this location
33
+ | 'moveTo' // w:moveTo - Content moved to this location
34
+ // Table operations
35
+ | 'tableCellInsert' // w:cellIns - Table cell inserted
36
+ | 'tableCellDelete' // w:cellDel - Table cell deleted
37
+ | 'tableCellMerge' // w:cellMerge - Table cells merged
38
+ // Numbering
39
+ | 'numberingChange' // w:numberingChange - List numbering changed
40
+ // Hyperlink changes
41
+ | 'hyperlinkChange' // Hyperlink URL, text, or formatting change
42
+ // Rich content changes (new tracking types)
43
+ | 'imageChange' // Image insertion, deletion, or property change
44
+ | 'fieldChange' // Field insertion, deletion, or value change
45
+ | 'commentChange' // Comment insertion, deletion, or content change
46
+ | 'bookmarkChange' // Bookmark creation, deletion, or range change
47
+ | 'contentControlChange'; // Content control insertion, deletion, or property change
48
+
49
+ /**
50
+ * Field context for revisions inside complex fields
51
+ * Provides information about the parent field when a revision appears in a field result
52
+ */
53
+ export interface FieldContext {
54
+ /** Reference to the parent ComplexField (if revision is in field result) */
55
+ field?: import('./Field').ComplexField;
56
+ /** Field instruction (e.g., "HYPERLINK", "TOC", "MERGEFIELD") */
57
+ instruction?: string;
58
+ /** Position within field: 'instruction' or 'result' */
59
+ position: 'instruction' | 'result';
60
+ }
61
+
62
+ /**
63
+ * Revision properties
64
+ */
65
+ export interface RevisionProperties {
66
+ /** Unique revision ID (assigned by RevisionManager) */
67
+ id?: number;
68
+ /** Author who made the change */
69
+ author: string;
70
+ /** Date when the change was made */
71
+ date?: Date;
72
+ /** Type of revision */
73
+ type: RevisionType;
74
+ /** Content affected by the revision (Run, Hyperlink, or arrays thereof) */
75
+ content: RevisionContent | RevisionContent[];
76
+ /** Previous properties (for property change revisions) */
77
+ previousProperties?: Record<string, any>;
78
+ /** New properties (for property change revisions) */
79
+ newProperties?: Record<string, any>;
80
+ /** Move ID (for moveFrom/moveTo operations) */
81
+ moveId?: string;
82
+ /** Destination location (for moveFrom) or source location (for moveTo) */
83
+ moveLocation?: string;
84
+ /** Location of this revision within the document structure */
85
+ location?: RevisionLocation;
86
+ /** Field context if revision is inside a complex field */
87
+ fieldContext?: FieldContext;
88
+ }
89
+
90
+ /**
91
+ * Represents a tracked change (revision) in a document
92
+ */
93
+ export class Revision {
94
+ private id: number;
95
+ private author: string;
96
+ private date: Date;
97
+ private type: RevisionType;
98
+ private content: RevisionContent[];
99
+ private previousProperties?: Record<string, any>;
100
+ private newProperties?: Record<string, any>;
101
+ private moveId?: string;
102
+ private moveLocation?: string;
103
+ private isFieldInstruction = false;
104
+ private location?: RevisionLocation;
105
+ private fieldContext?: FieldContext;
106
+
107
+ /**
108
+ * Creates a new Revision
109
+ * @param properties - Revision properties
110
+ */
111
+ constructor(properties: RevisionProperties) {
112
+ this.id = properties.id ?? 0; // Will be assigned by RevisionManager
113
+ this.author = properties.author;
114
+ this.date = properties.date || new Date();
115
+ this.type = properties.type;
116
+ this.content = Array.isArray(properties.content) ? properties.content : [properties.content];
117
+ this.previousProperties = properties.previousProperties;
118
+ this.newProperties = properties.newProperties;
119
+ this.moveId = properties.moveId;
120
+ this.moveLocation = properties.moveLocation;
121
+ this.location = properties.location;
122
+ this.fieldContext = properties.fieldContext;
123
+ }
124
+
125
+ /**
126
+ * Gets the revision ID
127
+ */
128
+ getId(): number {
129
+ return this.id;
130
+ }
131
+
132
+ /**
133
+ * Sets the revision ID (used by RevisionManager)
134
+ * @internal
135
+ */
136
+ setId(id: number): void {
137
+ this.id = id;
138
+ }
139
+
140
+ /**
141
+ * Gets the author
142
+ */
143
+ getAuthor(): string {
144
+ return this.author;
145
+ }
146
+
147
+ /**
148
+ * Sets the author
149
+ */
150
+ setAuthor(author: string): this {
151
+ this.author = author;
152
+ return this;
153
+ }
154
+
155
+ /**
156
+ * Gets the revision date
157
+ */
158
+ getDate(): Date {
159
+ return this.date;
160
+ }
161
+
162
+ /**
163
+ * Sets the revision date
164
+ */
165
+ setDate(date: Date): this {
166
+ this.date = date;
167
+ return this;
168
+ }
169
+
170
+ /**
171
+ * Gets the revision type
172
+ */
173
+ getType(): RevisionType {
174
+ return this.type;
175
+ }
176
+
177
+ /**
178
+ * Gets all content items in this revision
179
+ * @returns Array of RevisionContent (Run or Hyperlink objects)
180
+ */
181
+ getContent(): RevisionContent[] {
182
+ return [...this.content];
183
+ }
184
+
185
+ /**
186
+ * Gets only the Run objects from this revision (backward compatible)
187
+ * @returns Array of Run objects
188
+ */
189
+ getRuns(): Run[] {
190
+ return this.content.filter((item): item is Run => isRunContent(item));
191
+ }
192
+
193
+ /**
194
+ * Gets only the Hyperlink objects from this revision
195
+ * @returns Array of Hyperlink objects
196
+ */
197
+ getHyperlinks(): import('./Hyperlink').Hyperlink[] {
198
+ return this.content.filter((item): item is import('./Hyperlink').Hyperlink => isHyperlinkContent(item));
199
+ }
200
+
201
+ /**
202
+ * Adds a run to this revision
203
+ */
204
+ addRun(run: Run): this {
205
+ this.content.push(run);
206
+ return this;
207
+ }
208
+
209
+ /**
210
+ * Adds a hyperlink to this revision
211
+ */
212
+ addHyperlink(hyperlink: import('./Hyperlink').Hyperlink): this {
213
+ this.content.push(hyperlink);
214
+ return this;
215
+ }
216
+
217
+ /**
218
+ * Adds content (Run or Hyperlink) to this revision
219
+ */
220
+ addContent(item: RevisionContent): this {
221
+ this.content.push(item);
222
+ return this;
223
+ }
224
+
225
+ /**
226
+ * Gets the combined text content from all Runs and Hyperlinks in this revision.
227
+ * This is used by isParagraphBlank() to detect text inside revision elements.
228
+ * @returns Combined text string from all content items
229
+ */
230
+ getText(): string {
231
+ return this.content
232
+ .filter((item): item is Run | import('./Hyperlink').Hyperlink =>
233
+ isRunContent(item) || isHyperlinkContent(item)
234
+ )
235
+ .map((item) => item.getText())
236
+ .join('');
237
+ }
238
+
239
+ /**
240
+ * Gets the previous properties (for property change revisions)
241
+ */
242
+ getPreviousProperties(): Record<string, any> | undefined {
243
+ return this.previousProperties;
244
+ }
245
+
246
+ /**
247
+ * Gets the new properties (for property change revisions)
248
+ */
249
+ getNewProperties(): Record<string, any> | undefined {
250
+ return this.newProperties;
251
+ }
252
+
253
+ /**
254
+ * Gets the move ID (for moveFrom/moveTo operations)
255
+ */
256
+ getMoveId(): string | undefined {
257
+ return this.moveId;
258
+ }
259
+
260
+ /**
261
+ * Gets the move location
262
+ */
263
+ getMoveLocation(): string | undefined {
264
+ return this.moveLocation;
265
+ }
266
+
267
+ /**
268
+ * Gets the location of this revision within the document
269
+ * @returns Location information or undefined if not set
270
+ */
271
+ getLocation(): RevisionLocation | undefined {
272
+ return this.location;
273
+ }
274
+
275
+ /**
276
+ * Sets the location of this revision within the document
277
+ * @param location - Location information
278
+ * @returns This revision for chaining
279
+ */
280
+ setLocation(location: RevisionLocation): this {
281
+ this.location = location;
282
+ return this;
283
+ }
284
+
285
+ /**
286
+ * Gets the field context if this revision is inside a complex field
287
+ * @returns Field context information or undefined if not inside a field
288
+ */
289
+ getFieldContext(): FieldContext | undefined {
290
+ return this.fieldContext;
291
+ }
292
+
293
+ /**
294
+ * Sets the field context for this revision
295
+ * @param context - Field context information
296
+ * @returns This revision for chaining
297
+ */
298
+ setFieldContext(context: FieldContext): this {
299
+ this.fieldContext = context;
300
+ return this;
301
+ }
302
+
303
+ /**
304
+ * Checks if this revision is inside a complex field
305
+ * @returns True if the revision is inside a field result or instruction section
306
+ */
307
+ isInsideField(): boolean {
308
+ return this.fieldContext !== undefined;
309
+ }
310
+
311
+ /**
312
+ * Checks if this revision is inside a field result section
313
+ * @returns True if the revision is in the result section of a complex field
314
+ */
315
+ isInsideFieldResult(): boolean {
316
+ return this.fieldContext?.position === 'result';
317
+ }
318
+
319
+ /**
320
+ * Checks if this revision is inside a field instruction section
321
+ * @returns True if the revision is in the instruction section of a complex field
322
+ */
323
+ isInsideFieldInstruction(): boolean {
324
+ return this.fieldContext?.position === 'instruction';
325
+ }
326
+
327
+ /**
328
+ * Gets the parent field if this revision is inside a complex field
329
+ * @returns The parent ComplexField or undefined
330
+ */
331
+ getParentField(): import('./Field').ComplexField | undefined {
332
+ return this.fieldContext?.field;
333
+ }
334
+
335
+ /**
336
+ * Marks this revision as a field instruction deletion
337
+ * When true, uses w:delInstrText instead of w:delText
338
+ */
339
+ setAsFieldInstruction(): this {
340
+ this.isFieldInstruction = true;
341
+ return this;
342
+ }
343
+
344
+ /**
345
+ * Checks if this is a field instruction deletion
346
+ */
347
+ isFieldInstructionDeletion(): boolean {
348
+ return this.isFieldInstruction;
349
+ }
350
+
351
+ /**
352
+ * Formats a date to ISO 8601 format for XML
353
+ * Per ECMA-376, revision dates must be in ISO 8601 format (e.g., "2024-01-01T12:00:00Z")
354
+ * Uses formatDateForXml() to strip milliseconds which Word does not accept.
355
+ * @param date - Date to format
356
+ * @returns ISO 8601 formatted date string without milliseconds
357
+ */
358
+ private formatDate(date: Date): string {
359
+ return formatDateForXml(date);
360
+ }
361
+
362
+ /**
363
+ * Gets the XML element name for this revision type
364
+ * Maps internal revision types to OOXML WordprocessingML element names per ECMA-376
365
+ *
366
+ * Mappings:
367
+ * - insert → w:ins (inserted content)
368
+ * - delete → w:del (deleted content)
369
+ * - runPropertiesChange → w:rPrChange (run formatting change)
370
+ * - paragraphPropertiesChange → w:pPrChange (paragraph formatting change)
371
+ * - tablePropertiesChange → w:tblPrChange (table formatting change)
372
+ * - tableRowPropertiesChange → w:trPrChange (table row properties change)
373
+ * - tableCellPropertiesChange → w:tcPrChange (table cell properties change)
374
+ * - sectionPropertiesChange → w:sectPrChange (section properties change)
375
+ * - moveFrom → w:moveFrom (source location of moved content)
376
+ * - moveTo → w:moveTo (destination location of moved content)
377
+ * - tableCellInsert → w:cellIns (inserted table cell)
378
+ * - tableCellDelete → w:cellDel (deleted table cell)
379
+ * - tableCellMerge → w:cellMerge (merged table cells)
380
+ * - numberingChange → w:numberingChange (list numbering changed)
381
+ *
382
+ * @returns OOXML element name (e.g., "w:ins", "w:del")
383
+ */
384
+ private getElementName(): string {
385
+ switch (this.type) {
386
+ case 'insert':
387
+ return 'w:ins';
388
+ case 'delete':
389
+ return 'w:del';
390
+ case 'runPropertiesChange':
391
+ return 'w:rPrChange';
392
+ case 'paragraphPropertiesChange':
393
+ return 'w:pPrChange';
394
+ case 'tablePropertiesChange':
395
+ return 'w:tblPrChange';
396
+ case 'tableExceptionPropertiesChange':
397
+ return 'w:tblPrExChange';
398
+ case 'tableRowPropertiesChange':
399
+ return 'w:trPrChange';
400
+ case 'tableCellPropertiesChange':
401
+ return 'w:tcPrChange';
402
+ case 'sectionPropertiesChange':
403
+ return 'w:sectPrChange';
404
+ case 'moveFrom':
405
+ return 'w:moveFrom';
406
+ case 'moveTo':
407
+ return 'w:moveTo';
408
+ case 'tableCellInsert':
409
+ return 'w:cellIns';
410
+ case 'tableCellDelete':
411
+ return 'w:cellDel';
412
+ case 'tableCellMerge':
413
+ return 'w:cellMerge';
414
+ case 'numberingChange':
415
+ return 'w:numberingChange';
416
+ // Internal tracking types - no OOXML element equivalent
417
+ // These are used for changelog generation and internal tracking,
418
+ // not for XML serialization. OOXML tracks these as insert/delete pairs.
419
+ case 'hyperlinkChange':
420
+ case 'imageChange':
421
+ case 'fieldChange':
422
+ case 'commentChange':
423
+ case 'bookmarkChange':
424
+ case 'contentControlChange':
425
+ throw new Error(
426
+ `Revision type '${this.type}' is an internal tracking type and cannot be serialized to OOXML XML. ` +
427
+ `OOXML does not have a native element for this type. ` +
428
+ `Use insert/delete revision pairs for tracking changes to ${this.type.replace('Change', '')}s.`
429
+ );
430
+ default:
431
+ // TypeScript exhaustiveness check - this should never be reached
432
+ // if all RevisionType values are handled above
433
+ const _exhaustiveCheck: never = this.type;
434
+ throw new Error(`Unknown revision type: ${_exhaustiveCheck}`);
435
+ }
436
+ }
437
+
438
+ /**
439
+ * Generates XML for this revision per OOXML WordprocessingML specification (ECMA-376)
440
+ *
441
+ * **XML Structure:**
442
+ *
443
+ * Content revisions (w:ins, w:del, w:moveFrom, w:moveTo):
444
+ * ```xml
445
+ * <w:ins w:id="0" w:author="Author Name" w:date="2024-01-01T12:00:00Z">
446
+ * <w:r>
447
+ * <w:t>Inserted text</w:t>
448
+ * </w:r>
449
+ * </w:ins>
450
+ * ```
451
+ *
452
+ * Deletion revisions use w:delText instead of w:t:
453
+ * ```xml
454
+ * <w:del w:id="1" w:author="Author Name" w:date="2024-01-01T12:00:00Z">
455
+ * <w:r>
456
+ * <w:delText>Deleted text</w:delText>
457
+ * </w:r>
458
+ * </w:del>
459
+ * ```
460
+ *
461
+ * Property change revisions (w:rPrChange, w:pPrChange, etc.):
462
+ * ```xml
463
+ * <w:rPrChange w:id="2" w:author="Author Name" w:date="2024-01-01T12:00:00Z">
464
+ * <w:rPr>
465
+ * <w:b/> <!-- Previous bold setting -->
466
+ * <w:sz w:val="24"/> <!-- Previous font size -->
467
+ * </w:rPr>
468
+ * </w:rPrChange>
469
+ * ```
470
+ *
471
+ * **Required Attributes (per ECMA-376):**
472
+ * - w:id: Unique revision identifier (ST_DecimalNumber) - REQUIRED
473
+ * - w:author: Author who made the change (ST_String) - REQUIRED
474
+ * - w:date: When the change was made (ST_DateTime, ISO 8601) - OPTIONAL
475
+ *
476
+ * **Move Operations:**
477
+ * For moveFrom/moveTo, an additional w:moveId attribute links the source and destination:
478
+ * ```xml
479
+ * <w:moveFrom w:id="3" w:author="Author" w:date="..." w:moveId="move-1">...</w:moveFrom>
480
+ * <w:moveTo w:id="4" w:author="Author" w:date="..." w:moveId="move-1">...</w:moveTo>
481
+ * ```
482
+ *
483
+ * **Content vs Property Changes:**
484
+ * - Content revisions (insert/delete/move): Contain w:r elements with text runs
485
+ * - Property revisions (rPrChange/pPrChange): Contain previous property elements (w:rPr, w:pPr)
486
+ *
487
+ * @returns XMLElement representing the revision in OOXML format, or null for internal-only types
488
+ * @see ECMA-376 Part 1 §17.13.5 (Revision Identifiers for Paragraph Content)
489
+ * @see ECMA-376 Part 1 §17.13.5.15 (Inserted Paragraph)
490
+ * @see ECMA-376 Part 1 §17.13.5.14 (Deleted Paragraph)
491
+ */
492
+ toXML(): XMLElement | null {
493
+ // Internal tracking types have no OOXML equivalent and cannot be serialized
494
+ // They are used for changelog generation and internal tracking only
495
+ const INTERNAL_TRACKING_TYPES: RevisionType[] = [
496
+ 'hyperlinkChange',
497
+ 'imageChange',
498
+ 'fieldChange',
499
+ 'commentChange',
500
+ 'bookmarkChange',
501
+ 'contentControlChange',
502
+ ];
503
+
504
+ if (INTERNAL_TRACKING_TYPES.includes(this.type)) {
505
+ // Return null for internal types - callers should skip these
506
+ return null;
507
+ }
508
+
509
+ const attributes: Record<string, string> = {
510
+ 'w:id': this.id.toString(),
511
+ 'w:author': this.author,
512
+ 'w:date': this.formatDate(this.date),
513
+ };
514
+
515
+ // Add move-specific attributes
516
+ if ((this.type === 'moveFrom' || this.type === 'moveTo') && this.moveId) {
517
+ attributes['w:moveId'] = this.moveId;
518
+ }
519
+
520
+ const elementName = this.getElementName();
521
+ const children: XMLElement[] = [];
522
+
523
+ // Handle different revision types
524
+ if (this.isPropertyChangeType()) {
525
+ // Property change revisions contain the previous properties
526
+ if (this.previousProperties) {
527
+ children.push(this.createPropertiesElement());
528
+ }
529
+ }
530
+
531
+ // Check if content contains only a single hyperlink (needs nesting inversion per ECMA-376)
532
+ // w:hyperlink is NOT a valid child of w:ins/w:del; instead w:ins/w:del must be inside w:hyperlink
533
+ const firstItem = this.content[0];
534
+ const singleHyperlink = this.content.length === 1 && firstItem && isHyperlinkContent(firstItem)
535
+ ? firstItem : null;
536
+
537
+ if (singleHyperlink && !this.isPropertyChangeType()) {
538
+ return this.createHyperlinkWrappedRevisionXml(singleHyperlink, elementName, attributes);
539
+ }
540
+
541
+ // Add content to the revision (handles both Run and Hyperlink)
542
+ for (const item of this.content) {
543
+ if (isHyperlinkContent(item)) {
544
+ // For multiple-item revisions containing hyperlinks, extract the runs
545
+ // and add them directly (hyperlink wrapper omitted to maintain validity)
546
+ const hyperlinkXml = item.toXML();
547
+ if (hyperlinkXml.children) {
548
+ for (const child of hyperlinkXml.children) {
549
+ if (typeof child === 'object' && child.name === 'w:r') {
550
+ if (this.type === 'delete' || this.type === 'moveFrom') {
551
+ children.push(this.convertRunXmlToDeleted(child));
552
+ } else {
553
+ children.push(child);
554
+ }
555
+ }
556
+ }
557
+ }
558
+ } else if (isRunContent(item)) {
559
+ // Handle Run content (existing behavior)
560
+ if (this.type === 'delete' || this.type === 'moveFrom') {
561
+ // For deletions and moveFrom, we need to modify the run XML to use w:delText instead of w:t
562
+ const runXml = this.createDeletedRunXml(item);
563
+ children.push(runXml);
564
+ } else {
565
+ // For other types, use normal run XML
566
+ children.push(item.toXML());
567
+ }
568
+ }
569
+ }
570
+
571
+ return {
572
+ name: elementName,
573
+ attributes,
574
+ children,
575
+ };
576
+ }
577
+
578
+ /**
579
+ * Checks if this is a property change revision type
580
+ *
581
+ * Property change revisions track formatting changes, not content changes.
582
+ * They contain previous property elements (w:rPr, w:pPr, etc.) instead of text runs.
583
+ *
584
+ * **Property Change Types:**
585
+ * - runPropertiesChange: Run formatting (bold, italic, font, color, etc.)
586
+ * - paragraphPropertiesChange: Paragraph formatting (alignment, spacing, indentation, etc.)
587
+ * - tablePropertiesChange: Table formatting
588
+ * - tableRowPropertiesChange: Table row properties
589
+ * - tableCellPropertiesChange: Table cell properties
590
+ * - sectionPropertiesChange: Section properties (page size, margins, etc.)
591
+ * - numberingChange: List numbering properties
592
+ *
593
+ * **Content Change Types (NOT property changes):**
594
+ * - insert: Added text
595
+ * - delete: Removed text
596
+ * - moveFrom: Moved text source
597
+ * - moveTo: Moved text destination
598
+ * - tableCellInsert: Added table cell
599
+ * - tableCellDelete: Removed table cell
600
+ * - tableCellMerge: Merged table cells
601
+ *
602
+ * @returns true if this revision tracks a property/formatting change, false otherwise
603
+ */
604
+ private isPropertyChangeType(): boolean {
605
+ return [
606
+ 'runPropertiesChange',
607
+ 'paragraphPropertiesChange',
608
+ 'tablePropertiesChange',
609
+ 'tableExceptionPropertiesChange',
610
+ 'tableRowPropertiesChange',
611
+ 'tableCellPropertiesChange',
612
+ 'sectionPropertiesChange',
613
+ 'numberingChange',
614
+ ].includes(this.type);
615
+ }
616
+
617
+ /**
618
+ * Creates XML element for previous properties in property change revisions
619
+ *
620
+ * **Purpose:**
621
+ * Property change revisions (w:rPrChange, w:pPrChange, etc.) must contain a child element
622
+ * with the PREVIOUS state of the properties before the change. This allows Word to show
623
+ * what changed and enables accepting/rejecting the change.
624
+ *
625
+ * **Structure:**
626
+ * ```xml
627
+ * <w:rPrChange w:id="0" w:author="Author" w:date="...">
628
+ * <w:rPr>
629
+ * <!-- Previous run properties -->
630
+ * <w:b/> <!-- Was bold -->
631
+ * <w:sz w:val="24"/> <!-- Was 12pt (24 half-points) -->
632
+ * </w:rPr>
633
+ * </w:rPrChange>
634
+ * ```
635
+ *
636
+ * **Property Element Mapping:**
637
+ * - runPropertiesChange → w:rPr (run properties)
638
+ * - paragraphPropertiesChange → w:pPr (paragraph properties)
639
+ * - tablePropertiesChange → w:tblPr (table properties)
640
+ * - tableRowPropertiesChange → w:trPr (table row properties)
641
+ * - tableCellPropertiesChange → w:tcPr (table cell properties)
642
+ * - sectionPropertiesChange → w:sectPr (section properties)
643
+ * - numberingChange → w:numPr (numbering properties)
644
+ *
645
+ * **Implementation:**
646
+ * This method converts the previousProperties object into OOXML elements.
647
+ * - Boolean properties (e.g., bold) → <w:b/>
648
+ * - Value properties (e.g., font size) → <w:sz w:val="24"/>
649
+ *
650
+ * @returns XMLElement containing previous properties (w:rPr, w:pPr, etc.)
651
+ * @see ECMA-376 Part 1 §17.13.5.31 (Run Properties Change)
652
+ * @see ECMA-376 Part 1 §17.13.5.29 (Paragraph Properties Change)
653
+ */
654
+ private createPropertiesElement(): XMLElement {
655
+ // For runPropertiesChange, delegate to Run.generateRunPropertiesXML for correct
656
+ // ECMA-376 element names and ordering (e.g., bold→w:b, font→w:rFonts, size→w:sz)
657
+ if (this.type === 'runPropertiesChange' && this.previousProperties) {
658
+ const rPr = Run.generateRunPropertiesXML(this.previousProperties as RunFormatting);
659
+ return rPr || { name: 'w:rPr', attributes: {}, children: [] };
660
+ }
661
+
662
+ // The property element name depends on the revision type
663
+ let propElementName = 'w:rPr';
664
+
665
+ switch (this.type) {
666
+ case 'runPropertiesChange':
667
+ propElementName = 'w:rPr';
668
+ break;
669
+ case 'paragraphPropertiesChange':
670
+ propElementName = 'w:pPr';
671
+ break;
672
+ case 'tablePropertiesChange':
673
+ propElementName = 'w:tblPr';
674
+ break;
675
+ case 'tableExceptionPropertiesChange':
676
+ propElementName = 'w:tblPrEx';
677
+ break;
678
+ case 'tableRowPropertiesChange':
679
+ propElementName = 'w:trPr';
680
+ break;
681
+ case 'tableCellPropertiesChange':
682
+ propElementName = 'w:tcPr';
683
+ break;
684
+ case 'sectionPropertiesChange':
685
+ propElementName = 'w:sectPr';
686
+ break;
687
+ case 'numberingChange':
688
+ propElementName = 'w:numPr';
689
+ break;
690
+ }
691
+
692
+ // Build property children from previousProperties
693
+ const propChildren: XMLElement[] = [];
694
+ if (this.previousProperties) {
695
+ for (const [key, value] of Object.entries(this.previousProperties)) {
696
+ if (typeof value === 'boolean' && value) {
697
+ // Boolean properties (e.g., bold, italic)
698
+ propChildren.push({ name: `w:${key}`, attributes: {}, children: [] });
699
+ } else if (typeof value === 'string' || typeof value === 'number') {
700
+ // Value properties (e.g., font size, color)
701
+ propChildren.push({
702
+ name: `w:${key}`,
703
+ attributes: { 'w:val': value.toString() },
704
+ children: [],
705
+ });
706
+ }
707
+ }
708
+ }
709
+
710
+ return {
711
+ name: propElementName,
712
+ attributes: {},
713
+ children: propChildren,
714
+ };
715
+ }
716
+
717
+ /**
718
+ * Creates XML for a deleted run (uses w:delText or w:delInstrText instead of w:t)
719
+ *
720
+ * **OOXML Requirement:**
721
+ * Per ECMA-376, deleted text must use w:delText element instead of w:t element.
722
+ * For deleted field instructions, w:delInstrText must be used instead.
723
+ * This is required for proper rendering in Microsoft Word's Track Changes mode.
724
+ *
725
+ * **Transformation:**
726
+ * ```xml
727
+ * <!-- Normal run (NOT in deletion) -->
728
+ * <w:r>
729
+ * <w:rPr><w:b/></w:rPr>
730
+ * <w:t>Text</w:t>
731
+ * </w:r>
732
+ *
733
+ * <!-- Deleted run (inside w:del) -->
734
+ * <w:r>
735
+ * <w:rPr><w:b/></w:rPr>
736
+ * <w:delText>Text</w:delText>
737
+ * </w:r>
738
+ *
739
+ * <!-- Deleted field instruction (inside w:del) -->
740
+ * <w:r>
741
+ * <w:delInstrText>MERGEFIELD Name</w:delInstrText>
742
+ * </w:r>
743
+ * ```
744
+ *
745
+ * **Why This Matters:**
746
+ * - w:delText tells Word to render with strikethrough in Track Changes mode
747
+ * - w:delInstrText is specifically for deleted field codes
748
+ * - w:t would render as normal text even inside w:del element
749
+ * - Word will reject documents with w:t inside deletions as malformed
750
+ *
751
+ * **Implementation:**
752
+ * This method gets the run's normal XML and replaces all w:t elements with w:delText
753
+ * or w:delInstrText (for field instructions) while preserving all other properties
754
+ * (formatting, spacing attributes, etc.)
755
+ *
756
+ * @param run - Run containing deleted text
757
+ * @returns XMLElement with w:delText or w:delInstrText instead of w:t
758
+ * @see ECMA-376 Part 1 §17.13.5.14 (Deleted Run Content)
759
+ * @see ECMA-376 Part 1 §22.1.2.27 (w:delText element)
760
+ * @see ECMA-376 Part 1 §22.1.2.26 (w:delInstrText element)
761
+ */
762
+ private createDeletedRunXml(run: Run): XMLElement {
763
+ // Get the regular run XML
764
+ const runXml = run.toXML();
765
+
766
+ // Determine which element to use for deleted text
767
+ // w:delInstrText for field instructions, w:delText for regular text
768
+ const deletedTextElement = this.isFieldInstruction ? 'w:delInstrText' : 'w:delText';
769
+
770
+ // We need to replace text elements with their deleted counterparts:
771
+ // - w:t -> w:delText (or w:delInstrText if isFieldInstruction)
772
+ // - w:instrText -> w:delInstrText (always, regardless of isFieldInstruction flag)
773
+ if (runXml.children) {
774
+ const modifiedChildren = runXml.children.map(child => {
775
+ if (typeof child === 'object') {
776
+ if (child.name === 'w:t') {
777
+ // Replace w:t with appropriate deleted text element
778
+ return {
779
+ ...child,
780
+ name: deletedTextElement,
781
+ };
782
+ } else if (child.name === 'w:instrText') {
783
+ // Replace w:instrText with w:delInstrText
784
+ // Per ECMA-376 §22.1.2.26, deleted field instructions must use w:delInstrText
785
+ return {
786
+ ...child,
787
+ name: 'w:delInstrText',
788
+ };
789
+ }
790
+ }
791
+ return child;
792
+ });
793
+
794
+ return {
795
+ ...runXml,
796
+ children: modifiedChildren,
797
+ };
798
+ }
799
+
800
+ return runXml;
801
+ }
802
+
803
+ /**
804
+ * Creates XML for a deleted hyperlink (transforms nested runs to use w:delText)
805
+ *
806
+ * **OOXML Requirement:**
807
+ * Per ECMA-376, when a hyperlink is inside a w:del element, its nested runs must
808
+ * use w:delText instead of w:t. This transforms the hyperlink's internal run
809
+ * content to comply with Word's Track Changes requirements.
810
+ *
811
+ * **XML Structure:**
812
+ * ```xml
813
+ * <w:del w:id="1" w:author="Author" w:date="...">
814
+ * <w:hyperlink r:id="rId1">
815
+ * <w:r>
816
+ * <w:delText>Link text</w:delText> <!-- Transformed from w:t -->
817
+ * </w:r>
818
+ * </w:hyperlink>
819
+ * </w:del>
820
+ * ```
821
+ *
822
+ * @param hyperlink - Hyperlink containing deleted content
823
+ * @returns XMLElement with nested runs transformed to use w:delText
824
+ */
825
+ /**
826
+ * Creates a hyperlink-wrapped revision XML element.
827
+ * Per ECMA-376, w:hyperlink is NOT a valid child of w:ins/w:del.
828
+ * Instead, w:ins/w:del must be inside w:hyperlink:
829
+ * <w:hyperlink r:id="rId1"><w:ins ...><w:r>...</w:r></w:ins></w:hyperlink>
830
+ */
831
+ private createHyperlinkWrappedRevisionXml(
832
+ hyperlink: import('./Hyperlink').Hyperlink,
833
+ revisionElementName: string,
834
+ revisionAttributes: Record<string, string>
835
+ ): XMLElement {
836
+ const hyperlinkXml = hyperlink.toXML();
837
+
838
+ // Extract runs from the hyperlink
839
+ const runs: XMLElement[] = [];
840
+ if (hyperlinkXml.children) {
841
+ for (const child of hyperlinkXml.children) {
842
+ if (typeof child === 'object' && child.name === 'w:r') {
843
+ if (this.type === 'delete' || this.type === 'moveFrom') {
844
+ runs.push(this.convertRunXmlToDeleted(child));
845
+ } else {
846
+ runs.push(child);
847
+ }
848
+ }
849
+ }
850
+ }
851
+
852
+ // Build: <w:hyperlink ...><w:ins/w:del ...><w:r>...</w:r></w:ins/w:del></w:hyperlink>
853
+ const revisionElement: XMLElement = {
854
+ name: revisionElementName,
855
+ attributes: revisionAttributes,
856
+ children: runs,
857
+ };
858
+
859
+ return {
860
+ name: hyperlinkXml.name,
861
+ attributes: hyperlinkXml.attributes,
862
+ children: [revisionElement],
863
+ };
864
+ }
865
+
866
+ private createDeletedHyperlinkXml(hyperlink: import('./Hyperlink').Hyperlink): XMLElement {
867
+ // Get the hyperlink's normal XML
868
+ const hyperlinkXml = hyperlink.toXML();
869
+
870
+ // Transform nested runs: w:t -> w:delText (or w:delInstrText for field instructions)
871
+ if (hyperlinkXml.children) {
872
+ hyperlinkXml.children = hyperlinkXml.children.map(child => {
873
+ if (typeof child === 'object' && child.name === 'w:r') {
874
+ // Transform the run's text elements
875
+ return this.convertRunXmlToDeleted(child);
876
+ }
877
+ return child;
878
+ });
879
+ }
880
+
881
+ return hyperlinkXml;
882
+ }
883
+
884
+ /**
885
+ * Converts a run XMLElement to use deleted text elements
886
+ * Helper for createDeletedHyperlinkXml
887
+ */
888
+ private convertRunXmlToDeleted(runXml: XMLElement): XMLElement {
889
+ const deletedTextElement = this.isFieldInstruction ? 'w:delInstrText' : 'w:delText';
890
+
891
+ if (!runXml.children) return runXml;
892
+
893
+ const modifiedChildren = runXml.children.map(child => {
894
+ if (typeof child === 'object' && child.name === 'w:t') {
895
+ return {
896
+ ...child,
897
+ name: deletedTextElement,
898
+ };
899
+ }
900
+ return child;
901
+ });
902
+
903
+ return {
904
+ ...runXml,
905
+ children: modifiedChildren,
906
+ };
907
+ }
908
+
909
+ /**
910
+ * Creates an insertion revision
911
+ * @param author - Author who made the insertion
912
+ * @param content - Inserted content (Run, Hyperlink, or arrays thereof)
913
+ * @param date - Optional date (defaults to now)
914
+ * @returns New Revision instance
915
+ */
916
+ static createInsertion(
917
+ author: string,
918
+ content: RevisionContent | RevisionContent[],
919
+ date?: Date
920
+ ): Revision {
921
+ return new Revision({
922
+ author,
923
+ type: 'insert',
924
+ content,
925
+ date,
926
+ });
927
+ }
928
+
929
+ /**
930
+ * Creates a deletion revision
931
+ * @param author - Author who made the deletion
932
+ * @param content - Deleted content (Run, Hyperlink, or arrays thereof)
933
+ * @param date - Optional date (defaults to now)
934
+ * @returns New Revision instance
935
+ */
936
+ static createDeletion(
937
+ author: string,
938
+ content: RevisionContent | RevisionContent[],
939
+ date?: Date
940
+ ): Revision {
941
+ return new Revision({
942
+ author,
943
+ type: 'delete',
944
+ content,
945
+ date,
946
+ });
947
+ }
948
+
949
+ /**
950
+ * Creates a field instruction deletion revision
951
+ * Uses w:delInstrText instead of w:delText for field codes
952
+ * @param author - Author who made the deletion
953
+ * @param content - Deleted field instruction content (Run or array of Runs)
954
+ * @param date - Optional date (defaults to now)
955
+ * @returns New Revision instance
956
+ */
957
+ static createFieldInstructionDeletion(
958
+ author: string,
959
+ content: Run | Run[],
960
+ date?: Date
961
+ ): Revision {
962
+ const revision = new Revision({
963
+ author,
964
+ type: 'delete',
965
+ content,
966
+ date,
967
+ });
968
+ revision.setAsFieldInstruction();
969
+ return revision;
970
+ }
971
+
972
+ /**
973
+ * Creates a revision from text
974
+ * Convenience method that creates a Run from the text
975
+ * @param type - Revision type
976
+ * @param author - Author who made the change
977
+ * @param text - Text content
978
+ * @param date - Optional date (defaults to now)
979
+ * @returns New Revision instance
980
+ */
981
+ static fromText(
982
+ type: RevisionType,
983
+ author: string,
984
+ text: string,
985
+ date?: Date
986
+ ): Revision {
987
+ const run = new Run(text);
988
+ return new Revision({
989
+ author,
990
+ type,
991
+ content: run,
992
+ date,
993
+ });
994
+ }
995
+
996
+ /**
997
+ * Creates a run properties change revision
998
+ * @param author - Author who made the change
999
+ * @param content - Content with changed formatting
1000
+ * @param previousProperties - Previous run properties
1001
+ * @param date - Optional date (defaults to now)
1002
+ * @returns New Revision instance
1003
+ */
1004
+ static createRunPropertiesChange(
1005
+ author: string,
1006
+ content: Run | Run[],
1007
+ previousProperties: Record<string, any>,
1008
+ date?: Date
1009
+ ): Revision {
1010
+ return new Revision({
1011
+ author,
1012
+ type: 'runPropertiesChange',
1013
+ content,
1014
+ previousProperties,
1015
+ date,
1016
+ });
1017
+ }
1018
+
1019
+ /**
1020
+ * Creates a paragraph properties change revision
1021
+ * @param author - Author who made the change
1022
+ * @param content - Paragraph content
1023
+ * @param previousProperties - Previous paragraph properties
1024
+ * @param date - Optional date (defaults to now)
1025
+ * @returns New Revision instance
1026
+ */
1027
+ static createParagraphPropertiesChange(
1028
+ author: string,
1029
+ content: Run | Run[],
1030
+ previousProperties: Record<string, any>,
1031
+ date?: Date
1032
+ ): Revision {
1033
+ return new Revision({
1034
+ author,
1035
+ type: 'paragraphPropertiesChange',
1036
+ content,
1037
+ previousProperties,
1038
+ date,
1039
+ });
1040
+ }
1041
+
1042
+ /**
1043
+ * Creates a table properties change revision
1044
+ * @param author - Author who made the change
1045
+ * @param content - Table content
1046
+ * @param previousProperties - Previous table properties
1047
+ * @param date - Optional date (defaults to now)
1048
+ * @returns New Revision instance
1049
+ */
1050
+ static createTablePropertiesChange(
1051
+ author: string,
1052
+ content: Run | Run[],
1053
+ previousProperties: Record<string, any>,
1054
+ date?: Date
1055
+ ): Revision {
1056
+ return new Revision({
1057
+ author,
1058
+ type: 'tablePropertiesChange',
1059
+ content,
1060
+ previousProperties,
1061
+ date,
1062
+ });
1063
+ }
1064
+
1065
+ /**
1066
+ * Creates a table exception properties change revision
1067
+ * Tracks changes to table properties that override style defaults
1068
+ * @param author - Author who made the change
1069
+ * @param content - Table content
1070
+ * @param previousProperties - Previous table exception properties
1071
+ * @param date - Optional date (defaults to now)
1072
+ * @returns New Revision instance
1073
+ */
1074
+ static createTableExceptionPropertiesChange(
1075
+ author: string,
1076
+ content: Run | Run[],
1077
+ previousProperties: Record<string, any>,
1078
+ date?: Date
1079
+ ): Revision {
1080
+ return new Revision({
1081
+ author,
1082
+ type: 'tableExceptionPropertiesChange',
1083
+ content,
1084
+ previousProperties,
1085
+ date,
1086
+ });
1087
+ }
1088
+
1089
+ /**
1090
+ * Creates a moveFrom revision (source of moved content)
1091
+ * @param author - Author who moved the content
1092
+ * @param content - Content that was moved
1093
+ * @param moveId - Unique move operation ID (links moveFrom and moveTo)
1094
+ * @param date - Optional date (defaults to now)
1095
+ * @returns New Revision instance
1096
+ */
1097
+ static createMoveFrom(
1098
+ author: string,
1099
+ content: Run | Run[],
1100
+ moveId: string,
1101
+ date?: Date
1102
+ ): Revision {
1103
+ return new Revision({
1104
+ author,
1105
+ type: 'moveFrom',
1106
+ content,
1107
+ moveId,
1108
+ date,
1109
+ });
1110
+ }
1111
+
1112
+ /**
1113
+ * Creates a moveTo revision (destination of moved content)
1114
+ * @param author - Author who moved the content
1115
+ * @param content - Content that was moved
1116
+ * @param moveId - Unique move operation ID (links moveFrom and moveTo)
1117
+ * @param date - Optional date (defaults to now)
1118
+ * @returns New Revision instance
1119
+ */
1120
+ static createMoveTo(
1121
+ author: string,
1122
+ content: Run | Run[],
1123
+ moveId: string,
1124
+ date?: Date
1125
+ ): Revision {
1126
+ return new Revision({
1127
+ author,
1128
+ type: 'moveTo',
1129
+ content,
1130
+ moveId,
1131
+ date,
1132
+ });
1133
+ }
1134
+
1135
+ /**
1136
+ * Creates a table cell insertion revision
1137
+ * @param author - Author who inserted the cell
1138
+ * @param content - Cell content
1139
+ * @param date - Optional date (defaults to now)
1140
+ * @returns New Revision instance
1141
+ */
1142
+ static createTableCellInsert(
1143
+ author: string,
1144
+ content: Run | Run[],
1145
+ date?: Date
1146
+ ): Revision {
1147
+ return new Revision({
1148
+ author,
1149
+ type: 'tableCellInsert',
1150
+ content,
1151
+ date,
1152
+ });
1153
+ }
1154
+
1155
+ /**
1156
+ * Creates a table cell deletion revision
1157
+ * @param author - Author who deleted the cell
1158
+ * @param content - Cell content
1159
+ * @param date - Optional date (defaults to now)
1160
+ * @returns New Revision instance
1161
+ */
1162
+ static createTableCellDelete(
1163
+ author: string,
1164
+ content: Run | Run[],
1165
+ date?: Date
1166
+ ): Revision {
1167
+ return new Revision({
1168
+ author,
1169
+ type: 'tableCellDelete',
1170
+ content,
1171
+ date,
1172
+ });
1173
+ }
1174
+
1175
+ /**
1176
+ * Creates a table cell merge revision
1177
+ * @param author - Author who merged cells
1178
+ * @param content - Merged cell content
1179
+ * @param date - Optional date (defaults to now)
1180
+ * @returns New Revision instance
1181
+ */
1182
+ static createTableCellMerge(
1183
+ author: string,
1184
+ content: Run | Run[],
1185
+ date?: Date
1186
+ ): Revision {
1187
+ return new Revision({
1188
+ author,
1189
+ type: 'tableCellMerge',
1190
+ content,
1191
+ date,
1192
+ });
1193
+ }
1194
+
1195
+ /**
1196
+ * Creates a numbering change revision
1197
+ * @param author - Author who changed the numbering
1198
+ * @param content - Content with changed numbering
1199
+ * @param previousProperties - Previous numbering properties
1200
+ * @param date - Optional date (defaults to now)
1201
+ * @returns New Revision instance
1202
+ */
1203
+ static createNumberingChange(
1204
+ author: string,
1205
+ content: Run | Run[],
1206
+ previousProperties: Record<string, any>,
1207
+ date?: Date
1208
+ ): Revision {
1209
+ return new Revision({
1210
+ author,
1211
+ type: 'numberingChange',
1212
+ content,
1213
+ previousProperties,
1214
+ date,
1215
+ });
1216
+ }
1217
+ }