docxmlater 11.0.10 → 12.1.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 (361) hide show
  1. package/README.md +53 -13
  2. package/dist/core/Document.d.ts +29 -3
  3. package/dist/core/Document.d.ts.map +1 -1
  4. package/dist/core/Document.js +733 -170
  5. package/dist/core/Document.js.map +1 -1
  6. package/dist/core/DocumentGenerator.d.ts +1 -0
  7. package/dist/core/DocumentGenerator.d.ts.map +1 -1
  8. package/dist/core/DocumentGenerator.js +77 -25
  9. package/dist/core/DocumentGenerator.js.map +1 -1
  10. package/dist/core/DocumentParser.d.ts +7 -3
  11. package/dist/core/DocumentParser.d.ts.map +1 -1
  12. package/dist/core/DocumentParser.js +427 -81
  13. package/dist/core/DocumentParser.js.map +1 -1
  14. package/dist/core/RelationshipManager.d.ts.map +1 -1
  15. package/dist/core/RelationshipManager.js +2 -2
  16. package/dist/core/RelationshipManager.js.map +1 -1
  17. package/dist/elements/Comment.d.ts +15 -1
  18. package/dist/elements/Comment.d.ts.map +1 -1
  19. package/dist/elements/Comment.js +67 -12
  20. package/dist/elements/Comment.js.map +1 -1
  21. package/dist/elements/CommentManager.d.ts +4 -0
  22. package/dist/elements/CommentManager.d.ts.map +1 -1
  23. package/dist/elements/CommentManager.js +74 -16
  24. package/dist/elements/CommentManager.js.map +1 -1
  25. package/dist/elements/EndnoteManager.d.ts.map +1 -1
  26. package/dist/elements/EndnoteManager.js.map +1 -1
  27. package/dist/elements/Field.d.ts +10 -1
  28. package/dist/elements/Field.d.ts.map +1 -1
  29. package/dist/elements/Field.js +76 -34
  30. package/dist/elements/Field.js.map +1 -1
  31. package/dist/elements/FieldHelpers.d.ts +1 -0
  32. package/dist/elements/FieldHelpers.d.ts.map +1 -1
  33. package/dist/elements/FieldHelpers.js +8 -4
  34. package/dist/elements/FieldHelpers.js.map +1 -1
  35. package/dist/elements/Footer.d.ts +3 -1
  36. package/dist/elements/Footer.d.ts.map +1 -1
  37. package/dist/elements/Footer.js +39 -53
  38. package/dist/elements/Footer.js.map +1 -1
  39. package/dist/elements/FootnoteManager.d.ts.map +1 -1
  40. package/dist/elements/FootnoteManager.js.map +1 -1
  41. package/dist/elements/Header.d.ts +3 -1
  42. package/dist/elements/Header.d.ts.map +1 -1
  43. package/dist/elements/Header.js +39 -53
  44. package/dist/elements/Header.js.map +1 -1
  45. package/dist/elements/HeaderFooterManager.d.ts +4 -2
  46. package/dist/elements/HeaderFooterManager.d.ts.map +1 -1
  47. package/dist/elements/HeaderFooterManager.js +36 -6
  48. package/dist/elements/HeaderFooterManager.js.map +1 -1
  49. package/dist/elements/Hyperlink.d.ts +6 -1
  50. package/dist/elements/Hyperlink.d.ts.map +1 -1
  51. package/dist/elements/Hyperlink.js +69 -44
  52. package/dist/elements/Hyperlink.js.map +1 -1
  53. package/dist/elements/Image.d.ts.map +1 -1
  54. package/dist/elements/Image.js +33 -6
  55. package/dist/elements/Image.js.map +1 -1
  56. package/dist/elements/ImageManager.d.ts +1 -0
  57. package/dist/elements/ImageManager.d.ts.map +1 -1
  58. package/dist/elements/ImageManager.js +11 -0
  59. package/dist/elements/ImageManager.js.map +1 -1
  60. package/dist/elements/Paragraph.d.ts +3 -0
  61. package/dist/elements/Paragraph.d.ts.map +1 -1
  62. package/dist/elements/Paragraph.js +91 -26
  63. package/dist/elements/Paragraph.js.map +1 -1
  64. package/dist/elements/Revision.d.ts +4 -0
  65. package/dist/elements/Revision.d.ts.map +1 -1
  66. package/dist/elements/Revision.js +369 -29
  67. package/dist/elements/Revision.js.map +1 -1
  68. package/dist/elements/Run.d.ts +1 -0
  69. package/dist/elements/Run.d.ts.map +1 -1
  70. package/dist/elements/Run.js +24 -4
  71. package/dist/elements/Run.js.map +1 -1
  72. package/dist/elements/Section.d.ts.map +1 -1
  73. package/dist/elements/Section.js +17 -7
  74. package/dist/elements/Section.js.map +1 -1
  75. package/dist/elements/Shape.d.ts.map +1 -1
  76. package/dist/elements/Shape.js +50 -42
  77. package/dist/elements/Shape.js.map +1 -1
  78. package/dist/elements/StructuredDocumentTag.d.ts +9 -1
  79. package/dist/elements/StructuredDocumentTag.d.ts.map +1 -1
  80. package/dist/elements/StructuredDocumentTag.js +46 -6
  81. package/dist/elements/StructuredDocumentTag.js.map +1 -1
  82. package/dist/elements/Table.d.ts +2 -0
  83. package/dist/elements/Table.d.ts.map +1 -1
  84. package/dist/elements/Table.js +90 -42
  85. package/dist/elements/Table.js.map +1 -1
  86. package/dist/elements/TableCell.d.ts +1 -0
  87. package/dist/elements/TableCell.d.ts.map +1 -1
  88. package/dist/elements/TableCell.js +32 -13
  89. package/dist/elements/TableCell.js.map +1 -1
  90. package/dist/elements/TableOfContents.d.ts.map +1 -1
  91. package/dist/elements/TableOfContents.js +5 -7
  92. package/dist/elements/TableOfContents.js.map +1 -1
  93. package/dist/elements/TableRow.d.ts +1 -0
  94. package/dist/elements/TableRow.d.ts.map +1 -1
  95. package/dist/elements/TableRow.js +16 -1
  96. package/dist/elements/TableRow.js.map +1 -1
  97. package/dist/elements/TextBox.d.ts.map +1 -1
  98. package/dist/elements/TextBox.js +55 -42
  99. package/dist/elements/TextBox.js.map +1 -1
  100. package/dist/esm/core/Document.js +735 -172
  101. package/dist/esm/core/Document.js.map +1 -1
  102. package/dist/esm/core/DocumentGenerator.js +77 -25
  103. package/dist/esm/core/DocumentGenerator.js.map +1 -1
  104. package/dist/esm/core/DocumentParser.js +427 -81
  105. package/dist/esm/core/DocumentParser.js.map +1 -1
  106. package/dist/esm/core/RelationshipManager.js +2 -2
  107. package/dist/esm/core/RelationshipManager.js.map +1 -1
  108. package/dist/esm/elements/Comment.js +67 -12
  109. package/dist/esm/elements/Comment.js.map +1 -1
  110. package/dist/esm/elements/CommentManager.js +74 -16
  111. package/dist/esm/elements/CommentManager.js.map +1 -1
  112. package/dist/esm/elements/EndnoteManager.js.map +1 -1
  113. package/dist/esm/elements/Field.js +77 -35
  114. package/dist/esm/elements/Field.js.map +1 -1
  115. package/dist/esm/elements/FieldHelpers.js +7 -4
  116. package/dist/esm/elements/FieldHelpers.js.map +1 -1
  117. package/dist/esm/elements/Footer.js +39 -53
  118. package/dist/esm/elements/Footer.js.map +1 -1
  119. package/dist/esm/elements/FootnoteManager.js.map +1 -1
  120. package/dist/esm/elements/Header.js +39 -53
  121. package/dist/esm/elements/Header.js.map +1 -1
  122. package/dist/esm/elements/HeaderFooterManager.js +36 -6
  123. package/dist/esm/elements/HeaderFooterManager.js.map +1 -1
  124. package/dist/esm/elements/Hyperlink.js +69 -44
  125. package/dist/esm/elements/Hyperlink.js.map +1 -1
  126. package/dist/esm/elements/Image.js +33 -6
  127. package/dist/esm/elements/Image.js.map +1 -1
  128. package/dist/esm/elements/ImageManager.js +11 -0
  129. package/dist/esm/elements/ImageManager.js.map +1 -1
  130. package/dist/esm/elements/Paragraph.js +91 -26
  131. package/dist/esm/elements/Paragraph.js.map +1 -1
  132. package/dist/esm/elements/Revision.js +369 -29
  133. package/dist/esm/elements/Revision.js.map +1 -1
  134. package/dist/esm/elements/Run.js +24 -4
  135. package/dist/esm/elements/Run.js.map +1 -1
  136. package/dist/esm/elements/Section.js +17 -7
  137. package/dist/esm/elements/Section.js.map +1 -1
  138. package/dist/esm/elements/Shape.js +50 -42
  139. package/dist/esm/elements/Shape.js.map +1 -1
  140. package/dist/esm/elements/StructuredDocumentTag.js +46 -6
  141. package/dist/esm/elements/StructuredDocumentTag.js.map +1 -1
  142. package/dist/esm/elements/Table.js +90 -42
  143. package/dist/esm/elements/Table.js.map +1 -1
  144. package/dist/esm/elements/TableCell.js +32 -13
  145. package/dist/esm/elements/TableCell.js.map +1 -1
  146. package/dist/esm/elements/TableOfContents.js +5 -7
  147. package/dist/esm/elements/TableOfContents.js.map +1 -1
  148. package/dist/esm/elements/TableRow.js +16 -1
  149. package/dist/esm/elements/TableRow.js.map +1 -1
  150. package/dist/esm/elements/TextBox.js +55 -42
  151. package/dist/esm/elements/TextBox.js.map +1 -1
  152. package/dist/esm/formatting/AbstractNumbering.js +1 -1
  153. package/dist/esm/formatting/AbstractNumbering.js.map +1 -1
  154. package/dist/esm/formatting/NumberingLevel.js +8 -6
  155. package/dist/esm/formatting/NumberingLevel.js.map +1 -1
  156. package/dist/esm/formatting/NumberingManager.js +16 -1
  157. package/dist/esm/formatting/NumberingManager.js.map +1 -1
  158. package/dist/esm/formatting/Style.js +14 -0
  159. package/dist/esm/formatting/Style.js.map +1 -1
  160. package/dist/esm/formatting/StylesManager.js +14 -2
  161. package/dist/esm/formatting/StylesManager.js.map +1 -1
  162. package/dist/esm/helpers/CleanupHelper.js +103 -26
  163. package/dist/esm/helpers/CleanupHelper.js.map +1 -1
  164. package/dist/esm/images/ImageOptimizer.js +52 -4
  165. package/dist/esm/images/ImageOptimizer.js.map +1 -1
  166. package/dist/esm/index.js +1 -0
  167. package/dist/esm/index.js.map +1 -1
  168. package/dist/esm/internal.js +1 -1
  169. package/dist/esm/internal.js.map +1 -1
  170. package/dist/esm/processors/CompatibilityUpgrader.js +7 -1
  171. package/dist/esm/processors/CompatibilityUpgrader.js.map +1 -1
  172. package/dist/esm/processors/InMemoryRevisionAcceptor.js +134 -13
  173. package/dist/esm/processors/InMemoryRevisionAcceptor.js.map +1 -1
  174. package/dist/esm/processors/RevisionWalker.js +223 -39
  175. package/dist/esm/processors/RevisionWalker.js.map +1 -1
  176. package/dist/esm/processors/SelectiveRevisionAcceptor.js +116 -17
  177. package/dist/esm/processors/SelectiveRevisionAcceptor.js.map +1 -1
  178. package/dist/esm/processors/acceptRevisions.js +20 -11
  179. package/dist/esm/processors/acceptRevisions.js.map +1 -1
  180. package/dist/esm/processors/cnfStyleDecoder.js +7 -7
  181. package/dist/esm/processors/cnfStyleDecoder.js.map +1 -1
  182. package/dist/esm/processors/stripTrackedChanges.js +16 -5
  183. package/dist/esm/processors/stripTrackedChanges.js.map +1 -1
  184. package/dist/esm/utils/deepClone.js +24 -11
  185. package/dist/esm/utils/deepClone.js.map +1 -1
  186. package/dist/esm/utils/units.js +1 -1
  187. package/dist/esm/utils/units.js.map +1 -1
  188. package/dist/esm/utils/validation.js +11 -23
  189. package/dist/esm/utils/validation.js.map +1 -1
  190. package/dist/esm/utils/xmlSanitization.js +131 -7
  191. package/dist/esm/utils/xmlSanitization.js.map +1 -1
  192. package/dist/esm/validation/RevisionAutoFixer.js +69 -55
  193. package/dist/esm/validation/RevisionAutoFixer.js.map +1 -1
  194. package/dist/esm/validation/RevisionValidator.js +24 -20
  195. package/dist/esm/validation/RevisionValidator.js.map +1 -1
  196. package/dist/esm/xml/XMLBuilder.js +52 -20
  197. package/dist/esm/xml/XMLBuilder.js.map +1 -1
  198. package/dist/esm/xml/XMLParser.js +55 -13
  199. package/dist/esm/xml/XMLParser.js.map +1 -1
  200. package/dist/esm/zip/ZipHandler.js +37 -13
  201. package/dist/esm/zip/ZipHandler.js.map +1 -1
  202. package/dist/esm/zip/ZipReader.js +53 -6
  203. package/dist/esm/zip/ZipReader.js.map +1 -1
  204. package/dist/esm/zip/errors.js +7 -0
  205. package/dist/esm/zip/errors.js.map +1 -1
  206. package/dist/esm/zip/types.js +4 -0
  207. package/dist/esm/zip/types.js.map +1 -1
  208. package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
  209. package/dist/formatting/AbstractNumbering.js +1 -1
  210. package/dist/formatting/AbstractNumbering.js.map +1 -1
  211. package/dist/formatting/NumberingLevel.d.ts +1 -1
  212. package/dist/formatting/NumberingLevel.d.ts.map +1 -1
  213. package/dist/formatting/NumberingLevel.js +8 -6
  214. package/dist/formatting/NumberingLevel.js.map +1 -1
  215. package/dist/formatting/NumberingManager.d.ts.map +1 -1
  216. package/dist/formatting/NumberingManager.js +16 -1
  217. package/dist/formatting/NumberingManager.js.map +1 -1
  218. package/dist/formatting/Style.d.ts.map +1 -1
  219. package/dist/formatting/Style.js +14 -0
  220. package/dist/formatting/Style.js.map +1 -1
  221. package/dist/formatting/StylesManager.d.ts +2 -0
  222. package/dist/formatting/StylesManager.d.ts.map +1 -1
  223. package/dist/formatting/StylesManager.js +14 -2
  224. package/dist/formatting/StylesManager.js.map +1 -1
  225. package/dist/helpers/CleanupHelper.d.ts.map +1 -1
  226. package/dist/helpers/CleanupHelper.js +103 -26
  227. package/dist/helpers/CleanupHelper.js.map +1 -1
  228. package/dist/images/ImageOptimizer.d.ts.map +1 -1
  229. package/dist/images/ImageOptimizer.js +52 -4
  230. package/dist/images/ImageOptimizer.js.map +1 -1
  231. package/dist/index.d.ts +3 -1
  232. package/dist/index.d.ts.map +1 -1
  233. package/dist/index.js +4 -2
  234. package/dist/index.js.map +1 -1
  235. package/dist/internal.d.ts +1 -1
  236. package/dist/internal.d.ts.map +1 -1
  237. package/dist/internal.js +2 -1
  238. package/dist/internal.js.map +1 -1
  239. package/dist/processors/CompatibilityUpgrader.d.ts.map +1 -1
  240. package/dist/processors/CompatibilityUpgrader.js +7 -1
  241. package/dist/processors/CompatibilityUpgrader.js.map +1 -1
  242. package/dist/processors/InMemoryRevisionAcceptor.d.ts +1 -0
  243. package/dist/processors/InMemoryRevisionAcceptor.d.ts.map +1 -1
  244. package/dist/processors/InMemoryRevisionAcceptor.js +135 -13
  245. package/dist/processors/InMemoryRevisionAcceptor.js.map +1 -1
  246. package/dist/processors/RevisionWalker.d.ts +9 -3
  247. package/dist/processors/RevisionWalker.d.ts.map +1 -1
  248. package/dist/processors/RevisionWalker.js +223 -39
  249. package/dist/processors/RevisionWalker.js.map +1 -1
  250. package/dist/processors/SelectiveRevisionAcceptor.d.ts.map +1 -1
  251. package/dist/processors/SelectiveRevisionAcceptor.js +116 -17
  252. package/dist/processors/SelectiveRevisionAcceptor.js.map +1 -1
  253. package/dist/processors/acceptRevisions.d.ts +1 -0
  254. package/dist/processors/acceptRevisions.d.ts.map +1 -1
  255. package/dist/processors/acceptRevisions.js +21 -11
  256. package/dist/processors/acceptRevisions.js.map +1 -1
  257. package/dist/processors/cnfStyleDecoder.d.ts.map +1 -1
  258. package/dist/processors/cnfStyleDecoder.js +7 -7
  259. package/dist/processors/cnfStyleDecoder.js.map +1 -1
  260. package/dist/processors/stripTrackedChanges.d.ts.map +1 -1
  261. package/dist/processors/stripTrackedChanges.js +16 -5
  262. package/dist/processors/stripTrackedChanges.js.map +1 -1
  263. package/dist/utils/deepClone.d.ts.map +1 -1
  264. package/dist/utils/deepClone.js +24 -11
  265. package/dist/utils/deepClone.js.map +1 -1
  266. package/dist/utils/units.d.ts.map +1 -1
  267. package/dist/utils/units.js +1 -1
  268. package/dist/utils/units.js.map +1 -1
  269. package/dist/utils/validation.d.ts.map +1 -1
  270. package/dist/utils/validation.js +11 -23
  271. package/dist/utils/validation.js.map +1 -1
  272. package/dist/utils/xmlSanitization.d.ts +2 -0
  273. package/dist/utils/xmlSanitization.d.ts.map +1 -1
  274. package/dist/utils/xmlSanitization.js +133 -7
  275. package/dist/utils/xmlSanitization.js.map +1 -1
  276. package/dist/validation/RevisionAutoFixer.d.ts +6 -2
  277. package/dist/validation/RevisionAutoFixer.d.ts.map +1 -1
  278. package/dist/validation/RevisionAutoFixer.js +68 -54
  279. package/dist/validation/RevisionAutoFixer.js.map +1 -1
  280. package/dist/validation/RevisionValidator.d.ts +2 -0
  281. package/dist/validation/RevisionValidator.d.ts.map +1 -1
  282. package/dist/validation/RevisionValidator.js +26 -21
  283. package/dist/validation/RevisionValidator.js.map +1 -1
  284. package/dist/xml/XMLBuilder.d.ts +1 -0
  285. package/dist/xml/XMLBuilder.d.ts.map +1 -1
  286. package/dist/xml/XMLBuilder.js +52 -20
  287. package/dist/xml/XMLBuilder.js.map +1 -1
  288. package/dist/xml/XMLParser.d.ts +1 -0
  289. package/dist/xml/XMLParser.d.ts.map +1 -1
  290. package/dist/xml/XMLParser.js +55 -13
  291. package/dist/xml/XMLParser.js.map +1 -1
  292. package/dist/zip/ZipHandler.d.ts.map +1 -1
  293. package/dist/zip/ZipHandler.js +37 -13
  294. package/dist/zip/ZipHandler.js.map +1 -1
  295. package/dist/zip/ZipReader.d.ts.map +1 -1
  296. package/dist/zip/ZipReader.js +52 -5
  297. package/dist/zip/ZipReader.js.map +1 -1
  298. package/dist/zip/errors.d.ts +3 -0
  299. package/dist/zip/errors.d.ts.map +1 -1
  300. package/dist/zip/errors.js +9 -1
  301. package/dist/zip/errors.js.map +1 -1
  302. package/dist/zip/types.d.ts +4 -0
  303. package/dist/zip/types.d.ts.map +1 -1
  304. package/dist/zip/types.js +4 -0
  305. package/dist/zip/types.js.map +1 -1
  306. package/package.json +2 -2
  307. package/src/core/Document.ts +1184 -242
  308. package/src/core/DocumentGenerator.ts +106 -26
  309. package/src/core/DocumentParser.ts +681 -114
  310. package/src/core/RelationshipManager.ts +446 -442
  311. package/src/elements/Comment.ts +123 -18
  312. package/src/elements/CommentManager.ts +121 -22
  313. package/src/elements/EndnoteManager.ts +4 -1
  314. package/src/elements/Field.ts +134 -43
  315. package/src/elements/FieldHelpers.ts +20 -4
  316. package/src/elements/Footer.ts +62 -67
  317. package/src/elements/FootnoteManager.ts +4 -1
  318. package/src/elements/Header.ts +62 -67
  319. package/src/elements/HeaderFooterManager.ts +56 -8
  320. package/src/elements/Hyperlink.ts +150 -55
  321. package/src/elements/Image.ts +51 -7
  322. package/src/elements/ImageManager.ts +24 -0
  323. package/src/elements/Paragraph.ts +161 -40
  324. package/src/elements/Revision.ts +446 -47
  325. package/src/elements/Run.ts +44 -6
  326. package/src/elements/Section.ts +25 -9
  327. package/src/elements/Shape.ts +52 -44
  328. package/src/elements/StructuredDocumentTag.ts +83 -8
  329. package/src/elements/Table.ts +151 -50
  330. package/src/elements/TableCell.ts +57 -17
  331. package/src/elements/TableOfContents.ts +10 -9
  332. package/src/elements/TableRow.ts +35 -3
  333. package/src/elements/TextBox.ts +58 -43
  334. package/src/formatting/AbstractNumbering.ts +4 -2
  335. package/src/formatting/NumberingLevel.ts +50 -12
  336. package/src/formatting/NumberingManager.ts +32 -3
  337. package/src/formatting/Style.ts +14 -0
  338. package/src/formatting/StylesManager.ts +29 -2
  339. package/src/helpers/CleanupHelper.ts +122 -30
  340. package/src/images/ImageOptimizer.ts +64 -5
  341. package/src/index.ts +7 -0
  342. package/src/internal.ts +1 -0
  343. package/src/processors/CompatibilityUpgrader.ts +15 -2
  344. package/src/processors/InMemoryRevisionAcceptor.ts +276 -17
  345. package/src/processors/RevisionWalker.ts +390 -46
  346. package/src/processors/SelectiveRevisionAcceptor.ts +164 -28
  347. package/src/processors/acceptRevisions.ts +67 -17
  348. package/src/processors/cnfStyleDecoder.ts +18 -12
  349. package/src/processors/stripTrackedChanges.ts +47 -10
  350. package/src/utils/deepClone.ts +48 -14
  351. package/src/utils/units.ts +3 -1
  352. package/src/utils/validation.ts +30 -32
  353. package/src/utils/xmlSanitization.ts +218 -22
  354. package/src/validation/RevisionAutoFixer.ts +109 -65
  355. package/src/validation/RevisionValidator.ts +48 -23
  356. package/src/xml/XMLBuilder.ts +82 -22
  357. package/src/xml/XMLParser.ts +87 -20
  358. package/src/zip/ZipHandler.ts +61 -21
  359. package/src/zip/ZipReader.ts +135 -13
  360. package/src/zip/errors.ts +15 -0
  361. package/src/zip/types.ts +44 -2
@@ -30,9 +30,18 @@ const REVISION_ELEMENTS = {
30
30
  'w:customXmlMoveToRangeEnd',
31
31
  ],
32
32
  };
33
+ const PRESERVED_ON_RESTORE = {
34
+ 'w:pPr': { keys: ['w:rPr', 'w:sectPr'], position: 'after' },
35
+ 'w:sectPr': { keys: ['w:headerReference', 'w:footerReference'], position: 'before' },
36
+ };
37
+ const DELETED_TEXT_RENAMES = {
38
+ 'w:delText': 'w:t',
39
+ 'w:delInstrText': 'w:instrText',
40
+ };
33
41
  class RevisionWalker {
34
42
  static processTree(obj, options) {
35
43
  const opts = {
44
+ mode: options?.mode ?? 'accept',
36
45
  acceptInsertions: options?.acceptInsertions ?? true,
37
46
  acceptDeletions: options?.acceptDeletions ?? true,
38
47
  acceptMoves: options?.acceptMoves ?? true,
@@ -40,6 +49,9 @@ class RevisionWalker {
40
49
  };
41
50
  const clone = RevisionWalker.deepClone(obj);
42
51
  RevisionWalker.walkAndTransform(clone, opts);
52
+ if (opts.mode === 'reject' && opts.acceptDeletions) {
53
+ RevisionWalker.convertDeletedTextToNormal(clone);
54
+ }
43
55
  return clone;
44
56
  }
45
57
  static deepClone(obj) {
@@ -59,8 +71,21 @@ class RevisionWalker {
59
71
  if (obj === null || typeof obj !== 'object') {
60
72
  return;
61
73
  }
62
- if (options.acceptDeletions && obj['w:tr']) {
63
- RevisionWalker.filterDeletedRows(obj);
74
+ if (options.mode === 'reject') {
75
+ if (options.acceptInsertions && obj['w:tbl']) {
76
+ RevisionWalker.removeFullyMarkedTables(obj, 'w:ins');
77
+ }
78
+ if (options.acceptInsertions && obj['w:tr']) {
79
+ RevisionWalker.filterMarkedRows(obj, 'w:ins');
80
+ }
81
+ }
82
+ else {
83
+ if (options.acceptDeletions && obj['w:tbl']) {
84
+ RevisionWalker.removeFullyMarkedTables(obj, 'w:del');
85
+ }
86
+ if (options.acceptDeletions && obj['w:tr']) {
87
+ RevisionWalker.filterMarkedRows(obj, 'w:del');
88
+ }
64
89
  }
65
90
  const keys = Object.keys(obj).filter((k) => !k.startsWith('@_') && k !== '#text' && k !== '_orderedChildren');
66
91
  for (const key of keys) {
@@ -76,70 +101,125 @@ class RevisionWalker {
76
101
  }
77
102
  RevisionWalker.processRevisions(obj, options);
78
103
  }
79
- static filterDeletedRows(tbl) {
104
+ static filterMarkedRows(tbl, marker) {
80
105
  const rows = tbl['w:tr'];
81
- const isRowDeleted = (row) => {
106
+ const isRowMarked = (row) => {
82
107
  if (!row || typeof row !== 'object')
83
108
  return false;
84
109
  const trPr = row['w:trPr'];
85
110
  if (!trPr || typeof trPr !== 'object')
86
111
  return false;
87
- return !!trPr['w:del'];
112
+ return !!trPr[marker];
88
113
  };
89
114
  if (Array.isArray(rows)) {
90
- const kept = rows.filter((r) => !isRowDeleted(r));
91
- if (kept.length !== rows.length) {
92
- if (kept.length === 0) {
93
- delete tbl['w:tr'];
94
- }
95
- else {
96
- tbl['w:tr'] = kept;
97
- }
115
+ const removedIndices = new Set();
116
+ for (let i = 0; i < rows.length; i++) {
117
+ if (isRowMarked(rows[i]))
118
+ removedIndices.add(i);
119
+ }
120
+ if (removedIndices.size === 0)
121
+ return;
122
+ const kept = rows.filter((_, i) => !removedIndices.has(i));
123
+ if (kept.length === 0) {
124
+ delete tbl['w:tr'];
125
+ }
126
+ else {
127
+ tbl['w:tr'] = kept;
98
128
  }
129
+ RevisionWalker.dropOrderedChildEntries(tbl, 'w:tr', removedIndices);
99
130
  }
100
- else if (isRowDeleted(rows)) {
131
+ else if (isRowMarked(rows)) {
101
132
  delete tbl['w:tr'];
133
+ RevisionWalker.dropOrderedChildEntries(tbl, 'w:tr', new Set([0]));
102
134
  }
103
135
  }
136
+ static removeFullyMarkedTables(parent, marker) {
137
+ const tables = parent['w:tbl'];
138
+ const survivingWrappers = marker === 'w:del' ? ['w:ins', 'w:moveTo'] : ['w:del', 'w:moveFrom'];
139
+ const becomesRowless = (tbl) => {
140
+ if (!tbl || typeof tbl !== 'object' || tbl['w:tr'] === undefined)
141
+ return false;
142
+ RevisionWalker.filterMarkedRows(tbl, marker);
143
+ return (tbl['w:tr'] === undefined &&
144
+ !survivingWrappers.some((w) => tbl[w]) &&
145
+ !tbl['w:sdt'] &&
146
+ !tbl['w:customXml']);
147
+ };
148
+ if (Array.isArray(tables)) {
149
+ const removedIndices = new Set();
150
+ for (let i = 0; i < tables.length; i++) {
151
+ if (becomesRowless(tables[i]))
152
+ removedIndices.add(i);
153
+ }
154
+ if (removedIndices.size === 0)
155
+ return;
156
+ const kept = tables.filter((_, i) => !removedIndices.has(i));
157
+ if (kept.length === 0) {
158
+ delete parent['w:tbl'];
159
+ }
160
+ else {
161
+ parent['w:tbl'] = kept;
162
+ }
163
+ RevisionWalker.dropOrderedChildEntries(parent, 'w:tbl', removedIndices);
164
+ }
165
+ else if (becomesRowless(tables)) {
166
+ delete parent['w:tbl'];
167
+ RevisionWalker.dropOrderedChildEntries(parent, 'w:tbl', new Set([0]));
168
+ }
169
+ }
170
+ static dropOrderedChildEntries(parent, type, removedIndices) {
171
+ if (!parent._orderedChildren)
172
+ return;
173
+ parent._orderedChildren = parent._orderedChildren.filter((c) => c.type !== type || !removedIndices.has(c.index));
174
+ RevisionWalker.reindexOrderedChildren(parent._orderedChildren);
175
+ }
104
176
  static processRevisions(parent, options) {
105
177
  if (!parent || typeof parent !== 'object') {
106
178
  return;
107
179
  }
108
180
  const keysToProcess = Object.keys(parent).filter((k) => !k.startsWith('@_') && k !== '#text' && k !== '_orderedChildren');
109
181
  for (const key of keysToProcess) {
110
- if (RevisionWalker.shouldUnwrap(key, options)) {
111
- RevisionWalker.unwrapAllElements(parent, key);
112
- }
113
- else if (RevisionWalker.shouldRemove(key, options)) {
114
- RevisionWalker.removeAllElements(parent, key);
182
+ switch (RevisionWalker.getActionForKey(key, options)) {
183
+ case 'unwrap':
184
+ RevisionWalker.unwrapAllElements(parent, key);
185
+ break;
186
+ case 'remove':
187
+ RevisionWalker.removeAllElements(parent, key);
188
+ break;
189
+ case 'restore':
190
+ RevisionWalker.restorePropertyChange(parent, key);
191
+ break;
192
+ case 'none':
193
+ break;
115
194
  }
116
195
  }
117
196
  }
118
- static shouldUnwrap(key, options) {
119
- if (REVISION_ELEMENTS.UNWRAP.includes(key)) {
120
- if (key === 'w:ins' && !options.acceptInsertions)
121
- return false;
122
- if (key === 'w:moveTo' && !options.acceptMoves)
123
- return false;
124
- return true;
125
- }
126
- return false;
127
- }
128
- static shouldRemove(key, options) {
129
- if (REVISION_ELEMENTS.REMOVE.includes(key)) {
130
- if (key === 'w:del' && !options.acceptDeletions)
131
- return false;
132
- if (key === 'w:moveFrom' && !options.acceptMoves)
133
- return false;
134
- return true;
197
+ static getActionForKey(key, options) {
198
+ const reject = options.mode === 'reject';
199
+ const isUnwrap = REVISION_ELEMENTS.UNWRAP.includes(key);
200
+ const isRemove = REVISION_ELEMENTS.REMOVE.includes(key);
201
+ if (isUnwrap || isRemove) {
202
+ const gate = key === 'w:ins'
203
+ ? options.acceptInsertions
204
+ : key === 'w:del'
205
+ ? options.acceptDeletions
206
+ : options.acceptMoves;
207
+ if (!gate)
208
+ return 'none';
209
+ const keepContent = reject ? isRemove : isUnwrap;
210
+ return keepContent ? 'unwrap' : 'remove';
135
211
  }
136
212
  if (REVISION_ELEMENTS.PROPERTY_CHANGES.includes(key)) {
137
- return options.acceptPropertyChanges;
213
+ if (!options.acceptPropertyChanges)
214
+ return 'none';
215
+ if (reject && key !== 'w:numberingChange')
216
+ return 'restore';
217
+ return 'remove';
138
218
  }
139
219
  if (REVISION_ELEMENTS.RANGE_MARKERS.includes(key)) {
140
- return true;
220
+ return 'remove';
141
221
  }
142
- return false;
222
+ return 'none';
143
223
  }
144
224
  static unwrapAllElements(parent, key) {
145
225
  const elements = parent[key];
@@ -245,6 +325,110 @@ class RevisionWalker {
245
325
  }
246
326
  delete parent[key];
247
327
  }
328
+ static restorePropertyChange(parent, changeKey) {
329
+ const changeRaw = parent[changeKey];
330
+ if (!changeRaw)
331
+ return;
332
+ const changeEl = Array.isArray(changeRaw) ? changeRaw[0] : changeRaw;
333
+ const previousKey = changeKey.replace(/Change$/, '');
334
+ const previousRaw = changeEl && typeof changeEl === 'object' ? changeEl[previousKey] : undefined;
335
+ if (previousRaw === undefined) {
336
+ RevisionWalker.removeAllElements(parent, changeKey);
337
+ return;
338
+ }
339
+ const previousEl = Array.isArray(previousRaw) ? previousRaw[0] : previousRaw;
340
+ const preserve = PRESERVED_ON_RESTORE[previousKey];
341
+ const preserveKeys = preserve?.keys ?? [];
342
+ const snapshotChildren = previousEl && typeof previousEl === 'object'
343
+ ? RevisionWalker.getOrderedChildList(previousEl).filter((c) => !preserveKeys.includes(c.type))
344
+ : [];
345
+ const preservedChildren = preserveKeys.length
346
+ ? RevisionWalker.getOrderedChildList(parent).filter((c) => preserveKeys.includes(c.type) && c.type !== changeKey)
347
+ : [];
348
+ const newChildren = preserve?.position === 'before'
349
+ ? [...preservedChildren, ...snapshotChildren]
350
+ : [...snapshotChildren, ...preservedChildren];
351
+ RevisionWalker.rebuildChildren(parent, newChildren);
352
+ }
353
+ static rebuildChildren(parent, ordered) {
354
+ for (const k of Object.keys(parent)) {
355
+ if (!k.startsWith('@_') && k !== '#text' && k !== '_orderedChildren') {
356
+ delete parent[k];
357
+ }
358
+ }
359
+ const grouped = new Map();
360
+ for (const { type, element } of ordered) {
361
+ if (!grouped.has(type))
362
+ grouped.set(type, []);
363
+ grouped.get(type).push(element);
364
+ }
365
+ for (const [type, elements] of grouped) {
366
+ parent[type] = elements.length === 1 ? elements[0] : elements;
367
+ }
368
+ const orderedChildren = [];
369
+ const counters = new Map();
370
+ for (const { type } of ordered) {
371
+ const idx = counters.get(type) || 0;
372
+ counters.set(type, idx + 1);
373
+ orderedChildren.push({ type, index: idx });
374
+ }
375
+ if (orderedChildren.length > 0) {
376
+ parent._orderedChildren = orderedChildren;
377
+ }
378
+ else {
379
+ delete parent._orderedChildren;
380
+ }
381
+ }
382
+ static getOrderedChildList(el) {
383
+ const result = [];
384
+ const ordered = el._orderedChildren;
385
+ if (Array.isArray(ordered) && ordered.length > 0) {
386
+ const counters = new Map();
387
+ for (const entry of ordered) {
388
+ const { type } = entry;
389
+ const idx = counters.get(type) || 0;
390
+ counters.set(type, idx + 1);
391
+ const value = el[type];
392
+ if (value === undefined)
393
+ continue;
394
+ const arr = Array.isArray(value) ? value : [value];
395
+ if (idx < arr.length)
396
+ result.push({ type, element: arr[idx] });
397
+ }
398
+ return result;
399
+ }
400
+ for (const key of Object.keys(el)) {
401
+ if (key.startsWith('@_') || key === '#text' || key === '_orderedChildren')
402
+ continue;
403
+ const value = el[key];
404
+ const arr = Array.isArray(value) ? value : [value];
405
+ for (const element of arr)
406
+ result.push({ type: key, element });
407
+ }
408
+ return result;
409
+ }
410
+ static convertDeletedTextToNormal(obj) {
411
+ if (obj === null || typeof obj !== 'object')
412
+ return;
413
+ if (Array.isArray(obj)) {
414
+ for (const item of obj)
415
+ RevisionWalker.convertDeletedTextToNormal(item);
416
+ return;
417
+ }
418
+ const hasDeletedText = Object.keys(obj).some((k) => k in DELETED_TEXT_RENAMES);
419
+ if (hasDeletedText) {
420
+ const ordered = RevisionWalker.getOrderedChildList(obj).map((child) => ({
421
+ type: DELETED_TEXT_RENAMES[child.type] ?? child.type,
422
+ element: child.element,
423
+ }));
424
+ RevisionWalker.rebuildChildren(obj, ordered);
425
+ }
426
+ for (const key of Object.keys(obj)) {
427
+ if (key.startsWith('@_') || key === '#text' || key === '_orderedChildren')
428
+ continue;
429
+ RevisionWalker.convertDeletedTextToNormal(obj[key]);
430
+ }
431
+ }
248
432
  static mergeIntoParent(parent, childKey, childValue) {
249
433
  if (parent[childKey] === undefined) {
250
434
  parent[childKey] = childValue;
@@ -1 +1 @@
1
- {"version":3,"file":"RevisionWalker.js","sourceRoot":"","sources":["../../src/processors/RevisionWalker.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * RevisionWalker - DOM-based tree walker for accepting tracked changes\n *\n * Replaces the fragile RegEx-based revision acceptance with a robust\n * DOM-based approach that properly handles nested elements and preserves\n * element ordering.\n *\n * @module RevisionWalker\n */\n\nimport { ParsedXMLObject } from '../xml/XMLParser.js';\n\n/**\n * Options for controlling which revision types to accept\n */\nexport interface RevisionWalkerOptions {\n /** Keep content, remove w:ins wrapper (default: true) */\n acceptInsertions?: boolean;\n /** Remove w:del and content entirely (default: true) */\n acceptDeletions?: boolean;\n /** Handle w:moveFrom/w:moveTo (default: true) */\n acceptMoves?: boolean;\n /** Remove *Change elements (default: true) */\n acceptPropertyChanges?: boolean;\n}\n\n/**\n * Structure for tracking element order\n */\ninterface OrderedChildInfo {\n type: string;\n index: number;\n}\n\n/**\n * Revision element categories\n */\nconst REVISION_ELEMENTS = {\n /** Elements to unwrap (keep content, remove wrapper) */\n UNWRAP: ['w:ins', 'w:moveTo'],\n\n /** Elements to remove entirely (with content) */\n REMOVE: ['w:del', 'w:moveFrom'],\n\n /** Property change tracking elements */\n PROPERTY_CHANGES: [\n 'w:rPrChange',\n 'w:pPrChange',\n 'w:tblPrChange',\n 'w:tcPrChange',\n 'w:trPrChange',\n 'w:sectPrChange',\n 'w:tblGridChange',\n 'w:numberingChange',\n 'w:tblPrExChange',\n ],\n\n /** Range marker elements */\n RANGE_MARKERS: [\n 'w:moveFromRangeStart',\n 'w:moveFromRangeEnd',\n 'w:moveToRangeStart',\n 'w:moveToRangeEnd',\n 'w:customXmlInsRangeStart',\n 'w:customXmlInsRangeEnd',\n 'w:customXmlDelRangeStart',\n 'w:customXmlDelRangeEnd',\n 'w:customXmlMoveFromRangeStart',\n 'w:customXmlMoveFromRangeEnd',\n 'w:customXmlMoveToRangeStart',\n 'w:customXmlMoveToRangeEnd',\n ],\n};\n\n/**\n * DOM-based tree walker for accepting Word document revisions\n *\n * This class processes a parsed XML object tree (from XMLParser.parseToObject())\n * and accepts all tracked changes by:\n * - Unwrapping insertions (w:ins, w:moveTo) - keeping content\n * - Removing deletions (w:del, w:moveFrom) - discarding content\n * - Removing property changes (*Change elements)\n * - Removing range markers\n *\n * Element order is preserved using the _orderedChildren metadata.\n */\nexport class RevisionWalker {\n /**\n * Process a parsed XML object tree and accept all revisions\n *\n * @param obj - Parsed XML object from XMLParser.parseToObject()\n * @param options - Options controlling which revisions to accept\n * @returns New object tree with revisions accepted\n *\n * @example\n * ```typescript\n * const parsed = XMLParser.parseToObject(documentXml);\n * const clean = RevisionWalker.processTree(parsed);\n * ```\n */\n static processTree(obj: ParsedXMLObject, options?: RevisionWalkerOptions): ParsedXMLObject {\n const opts: Required<RevisionWalkerOptions> = {\n acceptInsertions: options?.acceptInsertions ?? true,\n acceptDeletions: options?.acceptDeletions ?? true,\n acceptMoves: options?.acceptMoves ?? true,\n acceptPropertyChanges: options?.acceptPropertyChanges ?? true,\n };\n\n // Deep clone the object to avoid mutating the original\n const clone = RevisionWalker.deepClone(obj);\n\n // Walk and transform the tree\n RevisionWalker.walkAndTransform(clone, opts);\n\n return clone;\n }\n\n /**\n * Deep clone an object\n */\n private static deepClone(obj: any): any {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => RevisionWalker.deepClone(item));\n }\n\n const clone: any = {};\n for (const key of Object.keys(obj)) {\n clone[key] = RevisionWalker.deepClone(obj[key]);\n }\n return clone;\n }\n\n /**\n * Recursively walk and transform the object tree\n * Processes children first (depth-first) to handle nested revisions\n */\n private static walkAndTransform(obj: any, options: Required<RevisionWalkerOptions>): void {\n if (obj === null || typeof obj !== 'object') {\n return;\n }\n\n // Pre-recursion: row-level tracked deletions (CT_TrPr > w:del per\n // §17.13.5.14). Must run BEFORE the depth-first recursion — otherwise\n // processRevisions in trPr would strip the w:del marker before we can\n // detect it at the table level. The default `w:del` removal in\n // processRevisions only strips the marker itself, leaving a zombie\n // empty row; per spec, accepting the deletion removes the entire row.\n if (options.acceptDeletions && obj['w:tr']) {\n RevisionWalker.filterDeletedRows(obj);\n }\n\n // Get keys to process (excluding metadata keys)\n const keys = Object.keys(obj).filter(\n (k) => !k.startsWith('@_') && k !== '#text' && k !== '_orderedChildren'\n );\n\n // First pass: recurse into children (depth-first)\n for (const key of keys) {\n const value = obj[key];\n if (Array.isArray(value)) {\n for (const item of value) {\n RevisionWalker.walkAndTransform(item, options);\n }\n } else if (typeof value === 'object' && value !== null) {\n RevisionWalker.walkAndTransform(value, options);\n }\n }\n\n // Second pass: process revision elements at this level\n // We need to iterate carefully because we're modifying the object\n RevisionWalker.processRevisions(obj, options);\n }\n\n /**\n * Remove `<w:tr>` entries whose `<w:trPr>` contains a self-closing\n * `<w:del/>` row-level deletion marker. Operates on the parsed-object\n * representation (arrays when multiple, single object otherwise).\n */\n private static filterDeletedRows(tbl: any): void {\n const rows = tbl['w:tr'];\n const isRowDeleted = (row: any): boolean => {\n if (!row || typeof row !== 'object') return false;\n const trPr = row['w:trPr'];\n if (!trPr || typeof trPr !== 'object') return false;\n // w:del at row level is a CT_TrackChange (no children). When absent\n // the parser leaves no key; when present it's a self-closing tag\n // parsed as an object with only @_w:id/@_w:author/@_w:date keys.\n return !!trPr['w:del'];\n };\n\n if (Array.isArray(rows)) {\n const kept = rows.filter((r) => !isRowDeleted(r));\n if (kept.length !== rows.length) {\n if (kept.length === 0) {\n delete tbl['w:tr'];\n } else {\n tbl['w:tr'] = kept;\n }\n }\n } else if (isRowDeleted(rows)) {\n delete tbl['w:tr'];\n }\n }\n\n /**\n * Process revision elements at the current level\n */\n private static processRevisions(parent: any, options: Required<RevisionWalkerOptions>): void {\n if (!parent || typeof parent !== 'object') {\n return;\n }\n\n const keysToProcess = Object.keys(parent).filter(\n (k) => !k.startsWith('@_') && k !== '#text' && k !== '_orderedChildren'\n );\n\n for (const key of keysToProcess) {\n // Check if this is a revision element\n if (RevisionWalker.shouldUnwrap(key, options)) {\n RevisionWalker.unwrapAllElements(parent, key);\n } else if (RevisionWalker.shouldRemove(key, options)) {\n RevisionWalker.removeAllElements(parent, key);\n }\n }\n }\n\n /**\n * Check if an element should be unwrapped (content kept)\n */\n private static shouldUnwrap(key: string, options: Required<RevisionWalkerOptions>): boolean {\n if (REVISION_ELEMENTS.UNWRAP.includes(key)) {\n if (key === 'w:ins' && !options.acceptInsertions) return false;\n if (key === 'w:moveTo' && !options.acceptMoves) return false;\n return true;\n }\n return false;\n }\n\n /**\n * Check if an element should be removed (content discarded)\n */\n private static shouldRemove(key: string, options: Required<RevisionWalkerOptions>): boolean {\n if (REVISION_ELEMENTS.REMOVE.includes(key)) {\n if (key === 'w:del' && !options.acceptDeletions) return false;\n if (key === 'w:moveFrom' && !options.acceptMoves) return false;\n return true;\n }\n if (REVISION_ELEMENTS.PROPERTY_CHANGES.includes(key)) {\n return options.acceptPropertyChanges;\n }\n if (REVISION_ELEMENTS.RANGE_MARKERS.includes(key)) {\n return true; // Always remove range markers\n }\n return false;\n }\n\n /**\n * Unwrap all elements of a given type, promoting their children to parent\n *\n * This is the most complex operation in RevisionWalker. When we unwrap a\n * revision element like w:ins, we need to:\n * 1. Extract the children from inside w:ins\n * 2. Insert them at the correct position in the parent's element arrays\n * 3. Update _orderedChildren to reflect the new structure\n *\n * The key challenge is maintaining correct element order. For example:\n * Before: <w:tbl><w:tr>Row1</w:tr><w:ins><w:tr>Row2</w:tr></w:ins><w:tr>Row3</w:tr></w:tbl>\n * After: <w:tbl><w:tr>Row1</w:tr><w:tr>Row2</w:tr><w:tr>Row3</w:tr></w:tbl>\n */\n private static unwrapAllElements(parent: any, key: string): void {\n const elements = parent[key];\n if (!elements) return;\n\n const elementArray = Array.isArray(elements) ? elements : [elements];\n\n // Build a complete ordered list of child elements by walking _orderedChildren\n // This captures the intended order before we modify anything\n const orderedElements: { type: string; element: any }[] = [];\n\n if (parent._orderedChildren) {\n // Track how many of each type we've seen to get correct array index\n const typeCounters = new Map<string, number>();\n let unwrappedIndex = 0;\n\n for (const entry of parent._orderedChildren) {\n const { type } = entry;\n\n if (type === key) {\n // This is a revision element - extract its children in order\n const revElement = elementArray[unwrappedIndex];\n unwrappedIndex++;\n\n if (revElement && typeof revElement === 'object') {\n if (revElement._orderedChildren) {\n // Use the revision element's _orderedChildren for correct order\n const childCounters = new Map<string, number>();\n for (const childEntry of revElement._orderedChildren) {\n const childType = childEntry.type;\n const childIdx = childCounters.get(childType) || 0;\n childCounters.set(childType, childIdx + 1);\n\n const childElements = revElement[childType];\n if (childElements) {\n const childArray = Array.isArray(childElements) ? childElements : [childElements];\n if (childIdx < childArray.length) {\n orderedElements.push({\n type: childType,\n element: childArray[childIdx],\n });\n }\n }\n }\n } else {\n // No _orderedChildren, extract children in object key order\n const childKeys = Object.keys(revElement).filter(\n (k) => !k.startsWith('@_') && k !== '#text' && k !== '_orderedChildren'\n );\n for (const childKey of childKeys) {\n const childValue = revElement[childKey];\n const childArray = Array.isArray(childValue) ? childValue : [childValue];\n for (const child of childArray) {\n orderedElements.push({ type: childKey, element: child });\n }\n }\n }\n }\n } else {\n // Regular element - get it from the parent\n const idx = typeCounters.get(type) || 0;\n typeCounters.set(type, idx + 1);\n\n const parentElements = parent[type];\n if (parentElements) {\n const parentArray = Array.isArray(parentElements) ? parentElements : [parentElements];\n if (idx < parentArray.length) {\n orderedElements.push({ type, element: parentArray[idx] });\n }\n }\n }\n }\n }\n\n // Remove the revision wrapper\n delete parent[key];\n\n // If we have ordered elements, rebuild the arrays in correct order\n if (orderedElements.length > 0) {\n // Group elements by type\n const rebuiltArrays = new Map<string, any[]>();\n\n for (const { type, element } of orderedElements) {\n if (!rebuiltArrays.has(type)) {\n rebuiltArrays.set(type, []);\n }\n rebuiltArrays.get(type)!.push(element);\n }\n\n // Update parent with rebuilt arrays\n for (const [type, elements] of rebuiltArrays) {\n if (elements.length === 1) {\n parent[type] = elements[0];\n } else {\n parent[type] = elements;\n }\n }\n\n // Rebuild _orderedChildren\n const newOrderedChildren: OrderedChildInfo[] = [];\n const typeCounters = new Map<string, number>();\n\n for (const { type } of orderedElements) {\n const idx = typeCounters.get(type) || 0;\n typeCounters.set(type, idx + 1);\n newOrderedChildren.push({ type, index: idx });\n }\n\n parent._orderedChildren = newOrderedChildren;\n } else {\n // Fallback for when there's no _orderedChildren - just merge\n for (const element of elementArray) {\n if (!element || typeof element !== 'object') continue;\n\n const elementKeys = Object.keys(element).filter(\n (k) => !k.startsWith('@_') && k !== '#text' && k !== '_orderedChildren'\n );\n\n for (const childKey of elementKeys) {\n RevisionWalker.mergeIntoParent(parent, childKey, element[childKey]);\n }\n }\n }\n }\n\n /**\n * Remove all elements of a given type (including their content)\n */\n private static removeAllElements(parent: any, key: string): void {\n if (!parent[key]) return;\n\n // Update _orderedChildren before removing\n if (parent._orderedChildren) {\n parent._orderedChildren = parent._orderedChildren.filter(\n (c: OrderedChildInfo) => c.type !== key\n );\n // Re-index remaining elements of same types\n RevisionWalker.reindexOrderedChildren(parent._orderedChildren);\n }\n\n // Remove the element\n delete parent[key];\n }\n\n /**\n * Merge a child value into the parent, handling arrays properly\n */\n private static mergeIntoParent(parent: any, childKey: string, childValue: any): void {\n if (parent[childKey] === undefined) {\n // No existing value, just assign\n parent[childKey] = childValue;\n } else {\n // Existing value, need to merge\n const existing = parent[childKey];\n const incoming = Array.isArray(childValue) ? childValue : [childValue];\n\n if (Array.isArray(existing)) {\n parent[childKey] = [...existing, ...incoming];\n } else {\n parent[childKey] = [existing, ...incoming];\n }\n }\n }\n\n /**\n * Re-index _orderedChildren to ensure indices are sequential per type\n */\n private static reindexOrderedChildren(orderedChildren: OrderedChildInfo[]): void {\n const typeCounters = new Map<string, number>();\n\n for (const entry of orderedChildren) {\n const currentIndex = typeCounters.get(entry.type) || 0;\n entry.index = currentIndex;\n typeCounters.set(entry.type, currentIndex + 1);\n }\n }\n\n /**\n * Check if an element is a revision-related element (any type)\n */\n static isRevisionElement(key: string): boolean {\n return (\n REVISION_ELEMENTS.UNWRAP.includes(key) ||\n REVISION_ELEMENTS.REMOVE.includes(key) ||\n REVISION_ELEMENTS.PROPERTY_CHANGES.includes(key) ||\n REVISION_ELEMENTS.RANGE_MARKERS.includes(key)\n );\n }\n\n /**\n * Get revision element categories (for external use/testing)\n */\n static getRevisionElementCategories(): typeof REVISION_ELEMENTS {\n return { ...REVISION_ELEMENTS };\n }\n}\n"]}
1
+ {"version":3,"file":"RevisionWalker.js","sourceRoot":"","sources":["../../src/processors/RevisionWalker.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * RevisionWalker - DOM-based tree walker for accepting tracked changes\n *\n * Replaces the fragile RegEx-based revision acceptance with a robust\n * DOM-based approach that properly handles nested elements and preserves\n * element ordering.\n *\n * @module RevisionWalker\n */\n\nimport { ParsedXMLObject } from '../xml/XMLParser.js';\n\n/**\n * Options for controlling which revision types to process\n */\nexport interface RevisionWalkerOptions {\n /**\n * Direction of processing (default: 'accept').\n *\n * - 'accept': keep inserted content, discard deleted content (the post-edit\n * document).\n * - 'reject': discard inserted content, restore deleted content and previous\n * formatting (the original pre-edit document — the exact inverse of accept).\n */\n mode?: 'accept' | 'reject';\n /**\n * Process insertions. In 'accept' mode w:ins is unwrapped (content kept); in\n * 'reject' mode w:ins is removed (content discarded). Inserted rows/tables are\n * removed under 'reject'. (default: true)\n */\n acceptInsertions?: boolean;\n /**\n * Process deletions. In 'accept' mode w:del is removed (content discarded); in\n * 'reject' mode w:del is unwrapped and w:delText restored to w:t. Deleted\n * rows/tables are removed under 'accept'. (default: true)\n */\n acceptDeletions?: boolean;\n /** Handle w:moveFrom/w:moveTo (default: true) */\n acceptMoves?: boolean;\n /**\n * Process *Change elements. In 'accept' mode they are removed (current\n * formatting kept); in 'reject' mode the previous formatting stored inside the\n * change is restored. (default: true)\n */\n acceptPropertyChanges?: boolean;\n}\n\n/** Action to take on a revision element at a given level. */\ntype RevisionAction = 'unwrap' | 'remove' | 'restore' | 'none';\n\n/**\n * Structure for tracking element order\n */\ninterface OrderedChildInfo {\n type: string;\n index: number;\n}\n\n/**\n * Revision element categories\n */\nconst REVISION_ELEMENTS = {\n /** Elements to unwrap (keep content, remove wrapper) */\n UNWRAP: ['w:ins', 'w:moveTo'],\n\n /** Elements to remove entirely (with content) */\n REMOVE: ['w:del', 'w:moveFrom'],\n\n /** Property change tracking elements */\n PROPERTY_CHANGES: [\n 'w:rPrChange',\n 'w:pPrChange',\n 'w:tblPrChange',\n 'w:tcPrChange',\n 'w:trPrChange',\n 'w:sectPrChange',\n 'w:tblGridChange',\n 'w:numberingChange',\n 'w:tblPrExChange',\n ],\n\n /** Range marker elements */\n RANGE_MARKERS: [\n 'w:moveFromRangeStart',\n 'w:moveFromRangeEnd',\n 'w:moveToRangeStart',\n 'w:moveToRangeEnd',\n 'w:customXmlInsRangeStart',\n 'w:customXmlInsRangeEnd',\n 'w:customXmlDelRangeStart',\n 'w:customXmlDelRangeEnd',\n 'w:customXmlMoveFromRangeStart',\n 'w:customXmlMoveFromRangeEnd',\n 'w:customXmlMoveToRangeStart',\n 'w:customXmlMoveToRangeEnd',\n ],\n};\n\n/**\n * Children that are tracked independently of a property-change snapshot and\n * must be carried over (not wiped) when rejecting that change restores the\n * previous properties. Keyed by the wrapper element; `position` is where they\n * sit in the wrapper's ECMA-376 child order relative to the restored snapshot:\n *\n * - CT_PPr (§17.3.1.26): the paragraph-mark run properties (`w:rPr`) and the\n * section properties (`w:sectPr`) follow the base paragraph properties, and a\n * `w:pPrChange` snapshot is a CT_PPrBase that contains neither.\n * - CT_SectPr (§17.6.17): the header/footer references PRECEDE the section base\n * contents, and a `w:sectPrChange` snapshot is a CT_SectPrBase that contains\n * neither — so they must be prepended or the section loses its headers/footers.\n */\nconst PRESERVED_ON_RESTORE: Record<string, { keys: string[]; position: 'before' | 'after' }> = {\n 'w:pPr': { keys: ['w:rPr', 'w:sectPr'], position: 'after' },\n 'w:sectPr': { keys: ['w:headerReference', 'w:footerReference'], position: 'before' },\n};\n\n/**\n * Deleted run-content elements and the live elements they restore to when a\n * deletion is rejected (§17.3.3.7 w:delText is structurally CT_Text, identical\n * to w:t; w:delInstrText likewise mirrors w:instrText).\n */\nconst DELETED_TEXT_RENAMES: Record<string, string> = {\n 'w:delText': 'w:t',\n 'w:delInstrText': 'w:instrText',\n};\n\n/**\n * DOM-based tree walker for accepting Word document revisions\n *\n * This class processes a parsed XML object tree (from XMLParser.parseToObject())\n * and accepts all tracked changes by:\n * - Unwrapping insertions (w:ins, w:moveTo) - keeping content\n * - Removing deletions (w:del, w:moveFrom) - discarding content\n * - Removing property changes (*Change elements)\n * - Removing range markers\n *\n * Element order is preserved using the _orderedChildren metadata.\n */\nexport class RevisionWalker {\n /**\n * Process a parsed XML object tree and accept all revisions\n *\n * @param obj - Parsed XML object from XMLParser.parseToObject()\n * @param options - Options controlling which revisions to accept\n * @returns New object tree with revisions accepted\n *\n * @example\n * ```typescript\n * const parsed = XMLParser.parseToObject(documentXml);\n * const clean = RevisionWalker.processTree(parsed);\n * ```\n */\n static processTree(obj: ParsedXMLObject, options?: RevisionWalkerOptions): ParsedXMLObject {\n const opts: Required<RevisionWalkerOptions> = {\n mode: options?.mode ?? 'accept',\n acceptInsertions: options?.acceptInsertions ?? true,\n acceptDeletions: options?.acceptDeletions ?? true,\n acceptMoves: options?.acceptMoves ?? true,\n acceptPropertyChanges: options?.acceptPropertyChanges ?? true,\n };\n\n // Deep clone the object to avoid mutating the original\n const clone = RevisionWalker.deepClone(obj);\n\n // Walk and transform the tree\n RevisionWalker.walkAndTransform(clone, opts);\n\n // Reject restores deleted content by unwrapping w:del; the runs inside a\n // deletion carry their text in w:delText (and field codes in\n // w:delInstrText). Once unwrapped they are live content again, so convert\n // those back to the normal w:t / w:instrText elements. (§17.3.3.7)\n if (opts.mode === 'reject' && opts.acceptDeletions) {\n RevisionWalker.convertDeletedTextToNormal(clone);\n }\n\n return clone;\n }\n\n /**\n * Deep clone an object\n */\n private static deepClone(obj: any): any {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => RevisionWalker.deepClone(item));\n }\n\n const clone: any = {};\n for (const key of Object.keys(obj)) {\n clone[key] = RevisionWalker.deepClone(obj[key]);\n }\n return clone;\n }\n\n /**\n * Recursively walk and transform the object tree\n * Processes children first (depth-first) to handle nested revisions\n */\n private static walkAndTransform(obj: any, options: Required<RevisionWalkerOptions>): void {\n if (obj === null || typeof obj !== 'object') {\n return;\n }\n\n // Pre-recursion: row-level tracked deletions (CT_TrPr > w:del per\n // §17.13.5.14). Must run BEFORE the depth-first recursion — otherwise\n // processRevisions in trPr would strip the w:del marker before we can\n // detect it at the table level. The default `w:del` removal in\n // processRevisions only strips the marker itself, leaving a zombie\n // empty row; per spec, accepting the deletion removes the entire row.\n // Tables are checked from the parent first: a table whose rows are ALL\n // tracked-deleted must be removed entirely (a row-less w:tbl violates\n // §17.4.38's at-least-one-row requirement and Word's Accept All drops\n // the whole table), and only the parent can remove the w:tbl itself.\n // Reject is the mirror image: a row whose w:trPr carries a self-closing\n // w:ins marker was added by the edit and must be removed to revert to the\n // original (gated on acceptInsertions, since this undoes an insertion). A\n // table whose rows are ALL insert-marked is removed entirely, mirroring the\n // accept-side at-least-one-row handling.\n if (options.mode === 'reject') {\n if (options.acceptInsertions && obj['w:tbl']) {\n RevisionWalker.removeFullyMarkedTables(obj, 'w:ins');\n }\n if (options.acceptInsertions && obj['w:tr']) {\n RevisionWalker.filterMarkedRows(obj, 'w:ins');\n }\n } else {\n if (options.acceptDeletions && obj['w:tbl']) {\n RevisionWalker.removeFullyMarkedTables(obj, 'w:del');\n }\n if (options.acceptDeletions && obj['w:tr']) {\n RevisionWalker.filterMarkedRows(obj, 'w:del');\n }\n }\n\n // Get keys to process (excluding metadata keys)\n const keys = Object.keys(obj).filter(\n (k) => !k.startsWith('@_') && k !== '#text' && k !== '_orderedChildren'\n );\n\n // First pass: recurse into children (depth-first)\n for (const key of keys) {\n const value = obj[key];\n if (Array.isArray(value)) {\n for (const item of value) {\n RevisionWalker.walkAndTransform(item, options);\n }\n } else if (typeof value === 'object' && value !== null) {\n RevisionWalker.walkAndTransform(value, options);\n }\n }\n\n // Second pass: process revision elements at this level\n // We need to iterate carefully because we're modifying the object\n RevisionWalker.processRevisions(obj, options);\n }\n\n /**\n * Remove `<w:tr>` entries whose `<w:trPr>` contains a self-closing row-level\n * tracking marker. `marker` is `w:del` when accepting (drop deleted rows) or\n * `w:ins` when rejecting (drop inserted rows). Operates on the parsed-object\n * representation (arrays when multiple, single object otherwise).\n */\n private static filterMarkedRows(tbl: any, marker: 'w:del' | 'w:ins'): void {\n const rows = tbl['w:tr'];\n const isRowMarked = (row: any): boolean => {\n if (!row || typeof row !== 'object') return false;\n const trPr = row['w:trPr'];\n if (!trPr || typeof trPr !== 'object') return false;\n // The row-level marker is a CT_TrackChange (no children). When absent\n // the parser leaves no key; when present it's a self-closing tag\n // parsed as an object with only @_w:id/@_w:author/@_w:date keys.\n return !!trPr[marker];\n };\n\n if (Array.isArray(rows)) {\n const removedIndices = new Set<number>();\n for (let i = 0; i < rows.length; i++) {\n if (isRowMarked(rows[i])) removedIndices.add(i);\n }\n if (removedIndices.size === 0) return;\n const kept = rows.filter((_, i) => !removedIndices.has(i));\n if (kept.length === 0) {\n delete tbl['w:tr'];\n } else {\n tbl['w:tr'] = kept;\n }\n RevisionWalker.dropOrderedChildEntries(tbl, 'w:tr', removedIndices);\n } else if (isRowMarked(rows)) {\n delete tbl['w:tr'];\n RevisionWalker.dropOrderedChildEntries(tbl, 'w:tr', new Set([0]));\n }\n }\n\n /**\n * Remove `<w:tbl>` children whose rows are ALL marked with the given\n * row-level tracking marker (`w:del` when accepting, `w:ins` when rejecting).\n *\n * Runs at the table's parent because filterMarkedRows (invoked on the table\n * itself) has no reference back to the container holding the `w:tbl` key.\n * Skips tables that still carry potential row containers — the wrappers that\n * SURVIVE this direction (w:ins/w:moveTo when accepting deletions,\n * w:del/w:moveFrom when rejecting insertions), plus w:sdt / w:customXml —\n * since their rows only materialize as direct `w:tr` children later, when the\n * wrappers are unwrapped during recursion.\n */\n private static removeFullyMarkedTables(parent: any, marker: 'w:del' | 'w:ins'): void {\n const tables = parent['w:tbl'];\n // Wrappers whose rows survive in this direction must not be treated as\n // \"rowless\": accept keeps w:ins/w:moveTo content, reject keeps w:del/\n // w:moveFrom content.\n const survivingWrappers: string[] =\n marker === 'w:del' ? ['w:ins', 'w:moveTo'] : ['w:del', 'w:moveFrom'];\n const becomesRowless = (tbl: any): boolean => {\n // Tables with no rows at all are pre-existing structures, not the\n // result of a tracked change — leave them untouched.\n if (!tbl || typeof tbl !== 'object' || tbl['w:tr'] === undefined) return false;\n RevisionWalker.filterMarkedRows(tbl, marker);\n return (\n tbl['w:tr'] === undefined &&\n !survivingWrappers.some((w) => tbl[w]) &&\n !tbl['w:sdt'] &&\n !tbl['w:customXml']\n );\n };\n\n if (Array.isArray(tables)) {\n const removedIndices = new Set<number>();\n for (let i = 0; i < tables.length; i++) {\n if (becomesRowless(tables[i])) removedIndices.add(i);\n }\n if (removedIndices.size === 0) return;\n const kept = tables.filter((_: any, i: number) => !removedIndices.has(i));\n if (kept.length === 0) {\n delete parent['w:tbl'];\n } else {\n parent['w:tbl'] = kept;\n }\n RevisionWalker.dropOrderedChildEntries(parent, 'w:tbl', removedIndices);\n } else if (becomesRowless(tables)) {\n delete parent['w:tbl'];\n RevisionWalker.dropOrderedChildEntries(parent, 'w:tbl', new Set([0]));\n }\n }\n\n /**\n * Drop specific {type, index} entries from `_orderedChildren` and\n * re-index the survivors. The serializer maps each entry onto the\n * element array by index, so stale entries left after filtering would\n * shift surviving elements relative to inter-element siblings (e.g. a\n * w:bookmarkEnd between table rows) or silently drop the tail.\n */\n private static dropOrderedChildEntries(\n parent: any,\n type: string,\n removedIndices: Set<number>\n ): void {\n if (!parent._orderedChildren) return;\n parent._orderedChildren = parent._orderedChildren.filter(\n (c: OrderedChildInfo) => c.type !== type || !removedIndices.has(c.index)\n );\n RevisionWalker.reindexOrderedChildren(parent._orderedChildren);\n }\n\n /**\n * Process revision elements at the current level\n */\n private static processRevisions(parent: any, options: Required<RevisionWalkerOptions>): void {\n if (!parent || typeof parent !== 'object') {\n return;\n }\n\n const keysToProcess = Object.keys(parent).filter(\n (k) => !k.startsWith('@_') && k !== '#text' && k !== '_orderedChildren'\n );\n\n for (const key of keysToProcess) {\n switch (RevisionWalker.getActionForKey(key, options)) {\n case 'unwrap':\n RevisionWalker.unwrapAllElements(parent, key);\n break;\n case 'remove':\n RevisionWalker.removeAllElements(parent, key);\n break;\n case 'restore':\n RevisionWalker.restorePropertyChange(parent, key);\n break;\n case 'none':\n break;\n }\n }\n }\n\n /**\n * Resolve what to do with a revision element of the given key, honouring the\n * processing direction. Accept and reject are exact inverses for content\n * revisions; property changes are removed on accept and restored on reject.\n */\n private static getActionForKey(\n key: string,\n options: Required<RevisionWalkerOptions>\n ): RevisionAction {\n const reject = options.mode === 'reject';\n\n // Content revisions are driven off REVISION_ELEMENTS so membership stays a\n // single source of truth (shared with isRevisionElement). On accept, UNWRAP\n // keeps content and REMOVE discards it; reject is the exact inverse.\n const isUnwrap = REVISION_ELEMENTS.UNWRAP.includes(key);\n const isRemove = REVISION_ELEMENTS.REMOVE.includes(key);\n if (isUnwrap || isRemove) {\n // Per-key gating: w:ins ↔ insertions, w:del ↔ deletions, w:moveTo/\n // w:moveFrom ↔ moves.\n const gate =\n key === 'w:ins'\n ? options.acceptInsertions\n : key === 'w:del'\n ? options.acceptDeletions\n : options.acceptMoves;\n if (!gate) return 'none';\n const keepContent = reject ? isRemove : isUnwrap;\n return keepContent ? 'unwrap' : 'remove';\n }\n if (REVISION_ELEMENTS.PROPERTY_CHANGES.includes(key)) {\n if (!options.acceptPropertyChanges) return 'none';\n // w:numberingChange (CT_TrackChangeNumbering) is a legacy attribute-only\n // marker with no embedded previous-properties element, so there is\n // nothing to restore — drop it in both directions.\n if (reject && key !== 'w:numberingChange') return 'restore';\n return 'remove';\n }\n if (REVISION_ELEMENTS.RANGE_MARKERS.includes(key)) {\n return 'remove'; // Always remove range markers\n }\n return 'none';\n }\n\n /**\n * Unwrap all elements of a given type, promoting their children to parent\n *\n * This is the most complex operation in RevisionWalker. When we unwrap a\n * revision element like w:ins, we need to:\n * 1. Extract the children from inside w:ins\n * 2. Insert them at the correct position in the parent's element arrays\n * 3. Update _orderedChildren to reflect the new structure\n *\n * The key challenge is maintaining correct element order. For example:\n * Before: <w:tbl><w:tr>Row1</w:tr><w:ins><w:tr>Row2</w:tr></w:ins><w:tr>Row3</w:tr></w:tbl>\n * After: <w:tbl><w:tr>Row1</w:tr><w:tr>Row2</w:tr><w:tr>Row3</w:tr></w:tbl>\n */\n private static unwrapAllElements(parent: any, key: string): void {\n const elements = parent[key];\n if (!elements) return;\n\n const elementArray = Array.isArray(elements) ? elements : [elements];\n\n // Build a complete ordered list of child elements by walking _orderedChildren\n // This captures the intended order before we modify anything\n const orderedElements: { type: string; element: any }[] = [];\n\n if (parent._orderedChildren) {\n // Track how many of each type we've seen to get correct array index\n const typeCounters = new Map<string, number>();\n let unwrappedIndex = 0;\n\n for (const entry of parent._orderedChildren) {\n const { type } = entry;\n\n if (type === key) {\n // This is a revision element - extract its children in order\n const revElement = elementArray[unwrappedIndex];\n unwrappedIndex++;\n\n if (revElement && typeof revElement === 'object') {\n if (revElement._orderedChildren) {\n // Use the revision element's _orderedChildren for correct order\n const childCounters = new Map<string, number>();\n for (const childEntry of revElement._orderedChildren) {\n const childType = childEntry.type;\n const childIdx = childCounters.get(childType) || 0;\n childCounters.set(childType, childIdx + 1);\n\n const childElements = revElement[childType];\n if (childElements) {\n const childArray = Array.isArray(childElements) ? childElements : [childElements];\n if (childIdx < childArray.length) {\n orderedElements.push({\n type: childType,\n element: childArray[childIdx],\n });\n }\n }\n }\n } else {\n // No _orderedChildren, extract children in object key order\n const childKeys = Object.keys(revElement).filter(\n (k) => !k.startsWith('@_') && k !== '#text' && k !== '_orderedChildren'\n );\n for (const childKey of childKeys) {\n const childValue = revElement[childKey];\n const childArray = Array.isArray(childValue) ? childValue : [childValue];\n for (const child of childArray) {\n orderedElements.push({ type: childKey, element: child });\n }\n }\n }\n }\n } else {\n // Regular element - get it from the parent\n const idx = typeCounters.get(type) || 0;\n typeCounters.set(type, idx + 1);\n\n const parentElements = parent[type];\n if (parentElements) {\n const parentArray = Array.isArray(parentElements) ? parentElements : [parentElements];\n if (idx < parentArray.length) {\n orderedElements.push({ type, element: parentArray[idx] });\n }\n }\n }\n }\n }\n\n // Remove the revision wrapper\n delete parent[key];\n\n // If we have ordered elements, rebuild the arrays in correct order\n if (orderedElements.length > 0) {\n // Group elements by type\n const rebuiltArrays = new Map<string, any[]>();\n\n for (const { type, element } of orderedElements) {\n if (!rebuiltArrays.has(type)) {\n rebuiltArrays.set(type, []);\n }\n rebuiltArrays.get(type)!.push(element);\n }\n\n // Update parent with rebuilt arrays\n for (const [type, elements] of rebuiltArrays) {\n if (elements.length === 1) {\n parent[type] = elements[0];\n } else {\n parent[type] = elements;\n }\n }\n\n // Rebuild _orderedChildren\n const newOrderedChildren: OrderedChildInfo[] = [];\n const typeCounters = new Map<string, number>();\n\n for (const { type } of orderedElements) {\n const idx = typeCounters.get(type) || 0;\n typeCounters.set(type, idx + 1);\n newOrderedChildren.push({ type, index: idx });\n }\n\n parent._orderedChildren = newOrderedChildren;\n } else {\n // Fallback for when there's no _orderedChildren - just merge\n for (const element of elementArray) {\n if (!element || typeof element !== 'object') continue;\n\n const elementKeys = Object.keys(element).filter(\n (k) => !k.startsWith('@_') && k !== '#text' && k !== '_orderedChildren'\n );\n\n for (const childKey of elementKeys) {\n RevisionWalker.mergeIntoParent(parent, childKey, element[childKey]);\n }\n }\n }\n }\n\n /**\n * Remove all elements of a given type (including their content)\n */\n private static removeAllElements(parent: any, key: string): void {\n if (!parent[key]) return;\n\n // Update _orderedChildren before removing\n if (parent._orderedChildren) {\n parent._orderedChildren = parent._orderedChildren.filter(\n (c: OrderedChildInfo) => c.type !== key\n );\n // Re-index remaining elements of same types\n RevisionWalker.reindexOrderedChildren(parent._orderedChildren);\n }\n\n // Remove the element\n delete parent[key];\n }\n\n /**\n * Restore the previous formatting recorded by a property-change element\n * (reject direction). A change such as `w:rPrChange` lives inside the\n * properties wrapper it tracks (`w:rPr`) and embeds the complete previous\n * wrapper as a child:\n *\n * <w:rPr><w:b/><w:rPrChange><w:rPr><w:i/></w:rPr></w:rPrChange></w:rPr>\n *\n * Rejecting it replaces the current direct formatting (`w:b`) with the\n * embedded previous formatting (`w:i`) and drops the change marker. Children\n * that are tracked independently of the snapshot — e.g. a paragraph's mark\n * run properties / section properties, or a section's header/footer\n * references (see {@link PRESERVED_ON_RESTORE}) — are carried over from the\n * current wrapper in their correct schema position rather than discarded.\n *\n * @param parent - the properties wrapper containing the change element\n * @param changeKey - the change element key, e.g. 'w:rPrChange'\n */\n private static restorePropertyChange(parent: any, changeKey: string): void {\n const changeRaw = parent[changeKey];\n if (!changeRaw) return;\n const changeEl = Array.isArray(changeRaw) ? changeRaw[0] : changeRaw;\n\n // 'w:rPrChange' -> 'w:rPr', 'w:tblGridChange' -> 'w:tblGrid', etc.\n const previousKey = changeKey.replace(/Change$/, '');\n const previousRaw =\n changeEl && typeof changeEl === 'object' ? changeEl[previousKey] : undefined;\n\n // Malformed change with no embedded previous-properties snapshot: there is\n // nothing to restore, so drop just the marker and leave the current\n // formatting intact rather than emptying the wrapper.\n if (previousRaw === undefined) {\n RevisionWalker.removeAllElements(parent, changeKey);\n return;\n }\n const previousEl = Array.isArray(previousRaw) ? previousRaw[0] : previousRaw;\n\n const preserve = PRESERVED_ON_RESTORE[previousKey];\n const preserveKeys = preserve?.keys ?? [];\n\n // Snapshot children become the restored formatting (minus any preserved\n // keys it might redundantly carry).\n const snapshotChildren =\n previousEl && typeof previousEl === 'object'\n ? RevisionWalker.getOrderedChildList(previousEl).filter(\n (c) => !preserveKeys.includes(c.type)\n )\n : [];\n\n // Preserved children are read from the CURRENT wrapper in their existing\n // document order (captured before the wrapper is cleared below).\n const preservedChildren = preserveKeys.length\n ? RevisionWalker.getOrderedChildList(parent).filter(\n (c) => preserveKeys.includes(c.type) && c.type !== changeKey\n )\n : [];\n\n const newChildren =\n preserve?.position === 'before'\n ? [...preservedChildren, ...snapshotChildren]\n : [...snapshotChildren, ...preservedChildren];\n\n RevisionWalker.rebuildChildren(parent, newChildren);\n }\n\n /**\n * Replace all non-metadata children of `parent` with the supplied ordered\n * `{type, element}` list, regrouping per-type arrays and rebuilding\n * `_orderedChildren` so the serializer emits them in the given order.\n * Attributes (`@_*`) and `#text` are left untouched.\n */\n private static rebuildChildren(parent: any, ordered: { type: string; element: any }[]): void {\n for (const k of Object.keys(parent)) {\n if (!k.startsWith('@_') && k !== '#text' && k !== '_orderedChildren') {\n delete parent[k];\n }\n }\n\n const grouped = new Map<string, any[]>();\n for (const { type, element } of ordered) {\n if (!grouped.has(type)) grouped.set(type, []);\n grouped.get(type)!.push(element);\n }\n for (const [type, elements] of grouped) {\n parent[type] = elements.length === 1 ? elements[0] : elements;\n }\n\n const orderedChildren: OrderedChildInfo[] = [];\n const counters = new Map<string, number>();\n for (const { type } of ordered) {\n const idx = counters.get(type) || 0;\n counters.set(type, idx + 1);\n orderedChildren.push({ type, index: idx });\n }\n if (orderedChildren.length > 0) {\n parent._orderedChildren = orderedChildren;\n } else {\n delete parent._orderedChildren;\n }\n }\n\n /**\n * Flatten an element's children into an ordered `{type, element}` list,\n * honouring `_orderedChildren` when present and falling back to key order.\n */\n private static getOrderedChildList(el: any): { type: string; element: any }[] {\n const result: { type: string; element: any }[] = [];\n const ordered = el._orderedChildren as OrderedChildInfo[] | undefined;\n\n if (Array.isArray(ordered) && ordered.length > 0) {\n const counters = new Map<string, number>();\n for (const entry of ordered) {\n const { type } = entry;\n const idx = counters.get(type) || 0;\n counters.set(type, idx + 1);\n const value = el[type];\n if (value === undefined) continue;\n const arr = Array.isArray(value) ? value : [value];\n if (idx < arr.length) result.push({ type, element: arr[idx] });\n }\n return result;\n }\n\n for (const key of Object.keys(el)) {\n if (key.startsWith('@_') || key === '#text' || key === '_orderedChildren') continue;\n const value = el[key];\n const arr = Array.isArray(value) ? value : [value];\n for (const element of arr) result.push({ type: key, element });\n }\n return result;\n }\n\n /**\n * Convert restored deleted text back to live text throughout the tree\n * (reject direction). After w:del unwrapping, the runs that were deleted\n * still hold their text in w:delText / w:delInstrText; rename those to the\n * normal w:t / w:instrText so the content is real again, fixing any\n * `_orderedChildren` type references as we go.\n */\n private static convertDeletedTextToNormal(obj: any): void {\n if (obj === null || typeof obj !== 'object') return;\n\n if (Array.isArray(obj)) {\n for (const item of obj) RevisionWalker.convertDeletedTextToNormal(item);\n return;\n }\n\n // When this node carries any deleted-text element, rebuild its children\n // from the document-ordered list with the deleted-text keys renamed. Going\n // through the ordered list keeps text in its original position even if a\n // run holds both a w:delText and a live w:t (CT_R permits interleaving).\n const hasDeletedText = Object.keys(obj).some((k) => k in DELETED_TEXT_RENAMES);\n if (hasDeletedText) {\n const ordered = RevisionWalker.getOrderedChildList(obj).map((child) => ({\n type: DELETED_TEXT_RENAMES[child.type] ?? child.type,\n element: child.element,\n }));\n RevisionWalker.rebuildChildren(obj, ordered);\n }\n\n for (const key of Object.keys(obj)) {\n if (key.startsWith('@_') || key === '#text' || key === '_orderedChildren') continue;\n RevisionWalker.convertDeletedTextToNormal(obj[key]);\n }\n }\n\n /**\n * Merge a child value into the parent, handling arrays properly\n */\n private static mergeIntoParent(parent: any, childKey: string, childValue: any): void {\n if (parent[childKey] === undefined) {\n // No existing value, just assign\n parent[childKey] = childValue;\n } else {\n // Existing value, need to merge\n const existing = parent[childKey];\n const incoming = Array.isArray(childValue) ? childValue : [childValue];\n\n if (Array.isArray(existing)) {\n parent[childKey] = [...existing, ...incoming];\n } else {\n parent[childKey] = [existing, ...incoming];\n }\n }\n }\n\n /**\n * Re-index _orderedChildren to ensure indices are sequential per type\n */\n private static reindexOrderedChildren(orderedChildren: OrderedChildInfo[]): void {\n const typeCounters = new Map<string, number>();\n\n for (const entry of orderedChildren) {\n const currentIndex = typeCounters.get(entry.type) || 0;\n entry.index = currentIndex;\n typeCounters.set(entry.type, currentIndex + 1);\n }\n }\n\n /**\n * Check if an element is a revision-related element (any type)\n */\n static isRevisionElement(key: string): boolean {\n return (\n REVISION_ELEMENTS.UNWRAP.includes(key) ||\n REVISION_ELEMENTS.REMOVE.includes(key) ||\n REVISION_ELEMENTS.PROPERTY_CHANGES.includes(key) ||\n REVISION_ELEMENTS.RANGE_MARKERS.includes(key)\n );\n }\n\n /**\n * Get revision element categories (for external use/testing)\n */\n static getRevisionElementCategories(): typeof REVISION_ELEMENTS {\n return { ...REVISION_ELEMENTS };\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"SelectiveRevisionAcceptor.d.ts","sourceRoot":"","sources":["../../src/processors/SelectiveRevisionAcceptor.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAY,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAIjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAKhE,MAAM,WAAW,qBAAqB;IAEpC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEnB,SAAS,EAAE,MAAM,EAAE,CAAC;IAEpB,OAAO,EAAE;QACP,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAMD,qBAAa,yBAAyB;IAUpC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,GAAG,qBAAqB;IA4DhF,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,GAAG,qBAAqB;IA0DhF,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAiFhC,OAAO,CAAC,MAAM,CAAC,yBAAyB;IAmExC,OAAO,CAAC,MAAM,CAAC,qBAAqB;IA8CpC,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAmDjC,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAwDjC,MAAM,CAAC,OAAO,CACZ,GAAG,EAAE,QAAQ,EACb,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAC1B,qBAAqB;IAYxB,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,qBAAqB;IAW3E,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,qBAAqB;IAW3E,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,qBAAqB;IAWhF,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,qBAAqB;IAWhF,MAAM,CAAC,gBAAgB,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,GAAG,qBAAqB;IAazE,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,GAAG,qBAAqB;IAYxE,MAAM,CAAC,oBAAoB,CAAC,GAAG,EAAE,QAAQ,GAAG,qBAAqB;IAUjE,MAAM,CAAC,mBAAmB,CAAC,GAAG,EAAE,QAAQ,GAAG,qBAAqB;IAUhE,MAAM,CAAC,uBAAuB,CAAC,GAAG,EAAE,QAAQ,GAAG,qBAAqB;IAUpE,MAAM,CAAC,wBAAwB,CAAC,GAAG,EAAE,QAAQ,GAAG,qBAAqB;IAOrE,OAAO,CAAC,MAAM,CAAC,eAAe;IAuD9B,OAAO,CAAC,MAAM,CAAC,mBAAmB;CA8BnC"}
1
+ {"version":3,"file":"SelectiveRevisionAcceptor.d.ts","sourceRoot":"","sources":["../../src/processors/SelectiveRevisionAcceptor.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAY,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAIjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAMhE,MAAM,WAAW,qBAAqB;IAEpC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEnB,SAAS,EAAE,MAAM,EAAE,CAAC;IAEpB,OAAO,EAAE;QACP,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAMD,qBAAa,yBAAyB;IAUpC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,GAAG,qBAAqB;IA0EhF,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,GAAG,qBAAqB;IA0DhF,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAiFhC,OAAO,CAAC,MAAM,CAAC,yBAAyB;IA4ExC,OAAO,CAAC,MAAM,CAAC,qBAAqB;IA8CpC,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAwDjC,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAsGjC,MAAM,CAAC,OAAO,CACZ,GAAG,EAAE,QAAQ,EACb,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAC1B,qBAAqB;IAyExB,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,qBAAqB;IAW3E,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,qBAAqB;IAW3E,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,qBAAqB;IAWhF,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,qBAAqB;IAWhF,MAAM,CAAC,gBAAgB,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,GAAG,qBAAqB;IAazE,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,GAAG,qBAAqB;IAYxE,MAAM,CAAC,oBAAoB,CAAC,GAAG,EAAE,QAAQ,GAAG,qBAAqB;IAUjE,MAAM,CAAC,mBAAmB,CAAC,GAAG,EAAE,QAAQ,GAAG,qBAAqB;IAUhE,MAAM,CAAC,uBAAuB,CAAC,GAAG,EAAE,QAAQ,GAAG,qBAAqB;IAUpE,MAAM,CAAC,wBAAwB,CAAC,GAAG,EAAE,QAAQ,GAAG,qBAAqB;IAOrE,OAAO,CAAC,MAAM,CAAC,eAAe;IAuD9B,OAAO,CAAC,MAAM,CAAC,mBAAmB;CA8BnC"}