docxmlater 11.0.10 → 12.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (354) hide show
  1. package/README.md +51 -13
  2. package/dist/core/Document.d.ts +28 -2
  3. package/dist/core/Document.d.ts.map +1 -1
  4. package/dist/core/Document.js +725 -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 +726 -171
  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 +58 -8
  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/cnfStyleDecoder.js +7 -7
  179. package/dist/esm/processors/cnfStyleDecoder.js.map +1 -1
  180. package/dist/esm/processors/stripTrackedChanges.js +16 -5
  181. package/dist/esm/processors/stripTrackedChanges.js.map +1 -1
  182. package/dist/esm/utils/deepClone.js +24 -11
  183. package/dist/esm/utils/deepClone.js.map +1 -1
  184. package/dist/esm/utils/units.js +1 -1
  185. package/dist/esm/utils/units.js.map +1 -1
  186. package/dist/esm/utils/validation.js +11 -23
  187. package/dist/esm/utils/validation.js.map +1 -1
  188. package/dist/esm/utils/xmlSanitization.js +131 -7
  189. package/dist/esm/utils/xmlSanitization.js.map +1 -1
  190. package/dist/esm/validation/RevisionAutoFixer.js +69 -55
  191. package/dist/esm/validation/RevisionAutoFixer.js.map +1 -1
  192. package/dist/esm/validation/RevisionValidator.js +24 -20
  193. package/dist/esm/validation/RevisionValidator.js.map +1 -1
  194. package/dist/esm/xml/XMLBuilder.js +52 -20
  195. package/dist/esm/xml/XMLBuilder.js.map +1 -1
  196. package/dist/esm/xml/XMLParser.js +55 -13
  197. package/dist/esm/xml/XMLParser.js.map +1 -1
  198. package/dist/esm/zip/ZipHandler.js +37 -13
  199. package/dist/esm/zip/ZipHandler.js.map +1 -1
  200. package/dist/esm/zip/ZipReader.js +53 -6
  201. package/dist/esm/zip/ZipReader.js.map +1 -1
  202. package/dist/esm/zip/errors.js +7 -0
  203. package/dist/esm/zip/errors.js.map +1 -1
  204. package/dist/esm/zip/types.js +4 -0
  205. package/dist/esm/zip/types.js.map +1 -1
  206. package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
  207. package/dist/formatting/AbstractNumbering.js +1 -1
  208. package/dist/formatting/AbstractNumbering.js.map +1 -1
  209. package/dist/formatting/NumberingLevel.d.ts +1 -1
  210. package/dist/formatting/NumberingLevel.d.ts.map +1 -1
  211. package/dist/formatting/NumberingLevel.js +8 -6
  212. package/dist/formatting/NumberingLevel.js.map +1 -1
  213. package/dist/formatting/NumberingManager.d.ts.map +1 -1
  214. package/dist/formatting/NumberingManager.js +16 -1
  215. package/dist/formatting/NumberingManager.js.map +1 -1
  216. package/dist/formatting/Style.d.ts.map +1 -1
  217. package/dist/formatting/Style.js +14 -0
  218. package/dist/formatting/Style.js.map +1 -1
  219. package/dist/formatting/StylesManager.d.ts +2 -0
  220. package/dist/formatting/StylesManager.d.ts.map +1 -1
  221. package/dist/formatting/StylesManager.js +14 -2
  222. package/dist/formatting/StylesManager.js.map +1 -1
  223. package/dist/helpers/CleanupHelper.d.ts.map +1 -1
  224. package/dist/helpers/CleanupHelper.js +103 -26
  225. package/dist/helpers/CleanupHelper.js.map +1 -1
  226. package/dist/images/ImageOptimizer.d.ts.map +1 -1
  227. package/dist/images/ImageOptimizer.js +52 -4
  228. package/dist/images/ImageOptimizer.js.map +1 -1
  229. package/dist/index.d.ts +3 -1
  230. package/dist/index.d.ts.map +1 -1
  231. package/dist/index.js +4 -2
  232. package/dist/index.js.map +1 -1
  233. package/dist/internal.d.ts +1 -1
  234. package/dist/internal.d.ts.map +1 -1
  235. package/dist/internal.js +2 -1
  236. package/dist/internal.js.map +1 -1
  237. package/dist/processors/CompatibilityUpgrader.d.ts.map +1 -1
  238. package/dist/processors/CompatibilityUpgrader.js +7 -1
  239. package/dist/processors/CompatibilityUpgrader.js.map +1 -1
  240. package/dist/processors/InMemoryRevisionAcceptor.d.ts +1 -0
  241. package/dist/processors/InMemoryRevisionAcceptor.d.ts.map +1 -1
  242. package/dist/processors/InMemoryRevisionAcceptor.js +135 -13
  243. package/dist/processors/InMemoryRevisionAcceptor.js.map +1 -1
  244. package/dist/processors/RevisionWalker.d.ts +2 -0
  245. package/dist/processors/RevisionWalker.d.ts.map +1 -1
  246. package/dist/processors/RevisionWalker.js +58 -8
  247. package/dist/processors/RevisionWalker.js.map +1 -1
  248. package/dist/processors/SelectiveRevisionAcceptor.d.ts.map +1 -1
  249. package/dist/processors/SelectiveRevisionAcceptor.js +116 -17
  250. package/dist/processors/SelectiveRevisionAcceptor.js.map +1 -1
  251. package/dist/processors/cnfStyleDecoder.d.ts.map +1 -1
  252. package/dist/processors/cnfStyleDecoder.js +7 -7
  253. package/dist/processors/cnfStyleDecoder.js.map +1 -1
  254. package/dist/processors/stripTrackedChanges.d.ts.map +1 -1
  255. package/dist/processors/stripTrackedChanges.js +16 -5
  256. package/dist/processors/stripTrackedChanges.js.map +1 -1
  257. package/dist/utils/deepClone.d.ts.map +1 -1
  258. package/dist/utils/deepClone.js +24 -11
  259. package/dist/utils/deepClone.js.map +1 -1
  260. package/dist/utils/units.d.ts.map +1 -1
  261. package/dist/utils/units.js +1 -1
  262. package/dist/utils/units.js.map +1 -1
  263. package/dist/utils/validation.d.ts.map +1 -1
  264. package/dist/utils/validation.js +11 -23
  265. package/dist/utils/validation.js.map +1 -1
  266. package/dist/utils/xmlSanitization.d.ts +2 -0
  267. package/dist/utils/xmlSanitization.d.ts.map +1 -1
  268. package/dist/utils/xmlSanitization.js +133 -7
  269. package/dist/utils/xmlSanitization.js.map +1 -1
  270. package/dist/validation/RevisionAutoFixer.d.ts +6 -2
  271. package/dist/validation/RevisionAutoFixer.d.ts.map +1 -1
  272. package/dist/validation/RevisionAutoFixer.js +68 -54
  273. package/dist/validation/RevisionAutoFixer.js.map +1 -1
  274. package/dist/validation/RevisionValidator.d.ts +2 -0
  275. package/dist/validation/RevisionValidator.d.ts.map +1 -1
  276. package/dist/validation/RevisionValidator.js +26 -21
  277. package/dist/validation/RevisionValidator.js.map +1 -1
  278. package/dist/xml/XMLBuilder.d.ts +1 -0
  279. package/dist/xml/XMLBuilder.d.ts.map +1 -1
  280. package/dist/xml/XMLBuilder.js +52 -20
  281. package/dist/xml/XMLBuilder.js.map +1 -1
  282. package/dist/xml/XMLParser.d.ts +1 -0
  283. package/dist/xml/XMLParser.d.ts.map +1 -1
  284. package/dist/xml/XMLParser.js +55 -13
  285. package/dist/xml/XMLParser.js.map +1 -1
  286. package/dist/zip/ZipHandler.d.ts.map +1 -1
  287. package/dist/zip/ZipHandler.js +37 -13
  288. package/dist/zip/ZipHandler.js.map +1 -1
  289. package/dist/zip/ZipReader.d.ts.map +1 -1
  290. package/dist/zip/ZipReader.js +52 -5
  291. package/dist/zip/ZipReader.js.map +1 -1
  292. package/dist/zip/errors.d.ts +3 -0
  293. package/dist/zip/errors.d.ts.map +1 -1
  294. package/dist/zip/errors.js +9 -1
  295. package/dist/zip/errors.js.map +1 -1
  296. package/dist/zip/types.d.ts +4 -0
  297. package/dist/zip/types.d.ts.map +1 -1
  298. package/dist/zip/types.js +4 -0
  299. package/dist/zip/types.js.map +1 -1
  300. package/package.json +2 -2
  301. package/src/core/Document.ts +1159 -240
  302. package/src/core/DocumentGenerator.ts +106 -26
  303. package/src/core/DocumentParser.ts +681 -114
  304. package/src/core/RelationshipManager.ts +446 -442
  305. package/src/elements/Comment.ts +123 -18
  306. package/src/elements/CommentManager.ts +121 -22
  307. package/src/elements/EndnoteManager.ts +4 -1
  308. package/src/elements/Field.ts +134 -43
  309. package/src/elements/FieldHelpers.ts +20 -4
  310. package/src/elements/Footer.ts +62 -67
  311. package/src/elements/FootnoteManager.ts +4 -1
  312. package/src/elements/Header.ts +62 -67
  313. package/src/elements/HeaderFooterManager.ts +56 -8
  314. package/src/elements/Hyperlink.ts +150 -55
  315. package/src/elements/Image.ts +51 -7
  316. package/src/elements/ImageManager.ts +24 -0
  317. package/src/elements/Paragraph.ts +161 -40
  318. package/src/elements/Revision.ts +446 -47
  319. package/src/elements/Run.ts +44 -6
  320. package/src/elements/Section.ts +25 -9
  321. package/src/elements/Shape.ts +52 -44
  322. package/src/elements/StructuredDocumentTag.ts +83 -8
  323. package/src/elements/Table.ts +151 -50
  324. package/src/elements/TableCell.ts +57 -17
  325. package/src/elements/TableOfContents.ts +10 -9
  326. package/src/elements/TableRow.ts +35 -3
  327. package/src/elements/TextBox.ts +58 -43
  328. package/src/formatting/AbstractNumbering.ts +4 -2
  329. package/src/formatting/NumberingLevel.ts +50 -12
  330. package/src/formatting/NumberingManager.ts +32 -3
  331. package/src/formatting/Style.ts +14 -0
  332. package/src/formatting/StylesManager.ts +29 -2
  333. package/src/helpers/CleanupHelper.ts +122 -30
  334. package/src/images/ImageOptimizer.ts +64 -5
  335. package/src/index.ts +7 -0
  336. package/src/internal.ts +1 -0
  337. package/src/processors/CompatibilityUpgrader.ts +15 -2
  338. package/src/processors/InMemoryRevisionAcceptor.ts +276 -17
  339. package/src/processors/RevisionWalker.ts +83 -7
  340. package/src/processors/SelectiveRevisionAcceptor.ts +164 -28
  341. package/src/processors/cnfStyleDecoder.ts +18 -12
  342. package/src/processors/stripTrackedChanges.ts +47 -10
  343. package/src/utils/deepClone.ts +48 -14
  344. package/src/utils/units.ts +3 -1
  345. package/src/utils/validation.ts +30 -32
  346. package/src/utils/xmlSanitization.ts +218 -22
  347. package/src/validation/RevisionAutoFixer.ts +109 -65
  348. package/src/validation/RevisionValidator.ts +48 -23
  349. package/src/xml/XMLBuilder.ts +82 -22
  350. package/src/xml/XMLParser.ts +87 -20
  351. package/src/zip/ZipHandler.ts +61 -21
  352. package/src/zip/ZipReader.ts +135 -13
  353. package/src/zip/errors.ts +15 -0
  354. package/src/zip/types.ts +44 -2
@@ -1646,8 +1646,13 @@ export class Section {
1646
1646
  * @returns New Section instance with copied properties
1647
1647
  */
1648
1648
  clone(): Section {
1649
- // Deep clone all nested objects
1650
- const clonedProperties: SectionProperties = {};
1649
+ // Spread the full properties object first so every SectionProperties field is
1650
+ // preserved (primitives such as type/titlePage/bidi as well as the fields the
1651
+ // old allow-list silently dropped: footnotePr, endnotePr, noEndnote, formProt,
1652
+ // pageBorders, printerSettingsId, chapStyle, chapSep). Then overwrite the
1653
+ // object-typed fields with deep copies so the clone is independent of the
1654
+ // original. This mirrors the constructor's preserve-everything approach.
1655
+ const clonedProperties: SectionProperties = { ...this.properties };
1651
1656
 
1652
1657
  if (this.properties.pageSize) {
1653
1658
  clonedProperties.pageSize = { ...this.properties.pageSize };
@@ -1693,13 +1698,24 @@ export class Section {
1693
1698
  clonedProperties.lineNumbering = { ...this.properties.lineNumbering };
1694
1699
  }
1695
1700
 
1696
- // Copy primitive properties
1697
- clonedProperties.type = this.properties.type;
1698
- clonedProperties.titlePage = this.properties.titlePage;
1699
- clonedProperties.verticalAlignment = this.properties.verticalAlignment;
1700
- clonedProperties.textDirection = this.properties.textDirection;
1701
- clonedProperties.bidi = this.properties.bidi;
1702
- clonedProperties.rtlGutter = this.properties.rtlGutter;
1701
+ if (this.properties.footnotePr) {
1702
+ clonedProperties.footnotePr = { ...this.properties.footnotePr };
1703
+ }
1704
+
1705
+ if (this.properties.endnotePr) {
1706
+ clonedProperties.endnotePr = { ...this.properties.endnotePr };
1707
+ }
1708
+
1709
+ if (this.properties.pageBorders) {
1710
+ const pb = this.properties.pageBorders;
1711
+ clonedProperties.pageBorders = {
1712
+ ...pb,
1713
+ top: pb.top ? { ...pb.top } : undefined,
1714
+ bottom: pb.bottom ? { ...pb.bottom } : undefined,
1715
+ left: pb.left ? { ...pb.left } : undefined,
1716
+ right: pb.right ? { ...pb.right } : undefined,
1717
+ };
1718
+ }
1703
1719
 
1704
1720
  return new Section(clonedProperties);
1705
1721
  }
@@ -503,58 +503,66 @@ export class Shape {
503
503
  selfClosing: true,
504
504
  });
505
505
 
506
- // Position H (horizontal)
507
- if (this.position) {
508
- const posH = this.position.horizontal;
509
- const posHChildren: XMLElement[] = [];
510
-
511
- if (posH.offset !== undefined) {
512
- posHChildren.push({
513
- name: 'wp:posOffset',
514
- children: [posH.offset.toString()],
515
- });
516
- } else if (posH.alignment) {
517
- posHChildren.push({
518
- name: 'wp:align',
519
- children: [posH.alignment],
520
- });
521
- }
522
-
523
- children.push({
524
- name: 'wp:positionH',
525
- attributes: {
526
- relativeFrom: posH.anchor,
527
- },
528
- children: posHChildren,
506
+ // Position H (horizontal) — required child of wp:anchor per CT_Anchor
507
+ // (minOccurs=1), so fall back to a zero page offset when no explicit
508
+ // position is configured (anchor-only floating shapes)
509
+ const posH = this.position?.horizontal;
510
+ const posHChildren: XMLElement[] = [];
511
+
512
+ if (posH?.offset !== undefined) {
513
+ posHChildren.push({
514
+ name: 'wp:posOffset',
515
+ children: [posH.offset.toString()],
516
+ });
517
+ } else if (posH?.alignment) {
518
+ posHChildren.push({
519
+ name: 'wp:align',
520
+ children: [posH.alignment],
521
+ });
522
+ } else {
523
+ posHChildren.push({
524
+ name: 'wp:posOffset',
525
+ children: ['0'],
529
526
  });
530
527
  }
531
528
 
532
- // Position V (vertical)
533
- if (this.position) {
534
- const posV = this.position.vertical;
535
- const posVChildren: XMLElement[] = [];
529
+ children.push({
530
+ name: 'wp:positionH',
531
+ attributes: {
532
+ relativeFrom: posH?.anchor ?? 'page',
533
+ },
534
+ children: posHChildren,
535
+ });
536
536
 
537
- if (posV.offset !== undefined) {
538
- posVChildren.push({
539
- name: 'wp:posOffset',
540
- children: [posV.offset.toString()],
541
- });
542
- } else if (posV.alignment) {
543
- posVChildren.push({
544
- name: 'wp:align',
545
- children: [posV.alignment],
546
- });
547
- }
537
+ // Position V (vertical) — required child of wp:anchor per CT_Anchor
538
+ const posV = this.position?.vertical;
539
+ const posVChildren: XMLElement[] = [];
548
540
 
549
- children.push({
550
- name: 'wp:positionV',
551
- attributes: {
552
- relativeFrom: posV.anchor,
553
- },
554
- children: posVChildren,
541
+ if (posV?.offset !== undefined) {
542
+ posVChildren.push({
543
+ name: 'wp:posOffset',
544
+ children: [posV.offset.toString()],
545
+ });
546
+ } else if (posV?.alignment) {
547
+ posVChildren.push({
548
+ name: 'wp:align',
549
+ children: [posV.alignment],
550
+ });
551
+ } else {
552
+ posVChildren.push({
553
+ name: 'wp:posOffset',
554
+ children: ['0'],
555
555
  });
556
556
  }
557
557
 
558
+ children.push({
559
+ name: 'wp:positionV',
560
+ attributes: {
561
+ relativeFrom: posV?.anchor ?? 'page',
562
+ },
563
+ children: posVChildren,
564
+ });
565
+
558
566
  // Extent (size)
559
567
  children.push({
560
568
  name: 'wp:extent',
@@ -9,6 +9,8 @@
9
9
  import { XMLBuilder, XMLElement } from '../xml/XMLBuilder.js';
10
10
  import { Paragraph } from './Paragraph.js';
11
11
  import { Table } from './Table.js';
12
+ import { PreservedElement } from './PreservedElement.js';
13
+ import { formatDateForXml } from '../utils/dateFormatting.js';
12
14
 
13
15
  /**
14
16
  * Type of content lock for SDT
@@ -95,6 +97,10 @@ export interface CheckboxProperties {
95
97
  checkedState?: string;
96
98
  /** Character code for unchecked state (default: '2610' - ☐) */
97
99
  uncheckedState?: string;
100
+ /** Font for the checked-state glyph (default: 'MS Gothic') */
101
+ checkedFont?: string;
102
+ /** Font for the unchecked-state glyph (default: 'MS Gothic') */
103
+ uncheckedFont?: string;
98
104
  }
99
105
 
100
106
  /**
@@ -167,8 +173,12 @@ export interface SDTProperties {
167
173
 
168
174
  /**
169
175
  * Content that can be wrapped by an SDT
176
+ *
177
+ * PreservedElement covers CT_SdtContentBlock children outside the modeled
178
+ * set (range markers, w:customXml, math, tracked-change wrappers) so they
179
+ * survive round-trip instead of being dropped on regeneration.
170
180
  */
171
- export type SDTContent = Table | Paragraph | StructuredDocumentTag;
181
+ export type SDTContent = Table | Paragraph | StructuredDocumentTag | PreservedElement;
172
182
 
173
183
  /**
174
184
  * Structured Document Tag class
@@ -191,6 +201,17 @@ export type SDTContent = Table | Paragraph | StructuredDocumentTag;
191
201
  export class StructuredDocumentTag {
192
202
  private properties: SDTProperties;
193
203
  private content: SDTContent[];
204
+ // Original w:sdtPr markup captured at parse time. toXML() rebuilds sdtPr
205
+ // from a modeled subset of CT_SdtPr, which would drop unmodeled children
206
+ // (w:rPr, w15:appearance, w15:color, w:label, w:tabIndex, w:temporary,
207
+ // w15:repeatingSection, ...) on every save — so while no modeled property
208
+ // has been mutated, the captured markup is re-emitted verbatim.
209
+ private rawSdtPrXml?: string;
210
+ // Original w:sdtEndPr markup. Never modeled, so always re-emitted.
211
+ private rawSdtEndPrXml?: string;
212
+ // Once a modeled sdtPr property changes, the preserved markup is stale;
213
+ // fall back to rebuilding sdtPr from the modeled subset.
214
+ private sdtPrMutated = false;
194
215
 
195
216
  /**
196
217
  * Create a new Structured Document Tag
@@ -202,6 +223,16 @@ export class StructuredDocumentTag {
202
223
  this.content = content;
203
224
  }
204
225
 
226
+ /** @internal */
227
+ _setRawSdtPrXml(xml: string): void {
228
+ this.rawSdtPrXml = xml;
229
+ }
230
+
231
+ /** @internal */
232
+ _setRawSdtEndPrXml(xml: string): void {
233
+ this.rawSdtEndPrXml = xml;
234
+ }
235
+
205
236
  /**
206
237
  * Get the SDT ID
207
238
  * @returns SDT ID or undefined
@@ -216,6 +247,7 @@ export class StructuredDocumentTag {
216
247
  */
217
248
  setId(id: number): this {
218
249
  this.properties.id = id;
250
+ this.sdtPrMutated = true;
219
251
  return this;
220
252
  }
221
253
 
@@ -233,6 +265,7 @@ export class StructuredDocumentTag {
233
265
  */
234
266
  setTag(tag: string): this {
235
267
  this.properties.tag = tag;
268
+ this.sdtPrMutated = true;
236
269
  return this;
237
270
  }
238
271
 
@@ -250,6 +283,7 @@ export class StructuredDocumentTag {
250
283
  */
251
284
  setLock(lock: SDTLockType): this {
252
285
  this.properties.lock = lock;
286
+ this.sdtPrMutated = true;
253
287
  return this;
254
288
  }
255
289
 
@@ -267,6 +301,7 @@ export class StructuredDocumentTag {
267
301
  */
268
302
  setAlias(alias: string): this {
269
303
  this.properties.alias = alias;
304
+ this.sdtPrMutated = true;
270
305
  return this;
271
306
  }
272
307
 
@@ -284,6 +319,7 @@ export class StructuredDocumentTag {
284
319
  */
285
320
  setControlType(type: ContentControlType): this {
286
321
  this.properties.controlType = type;
322
+ this.sdtPrMutated = true;
287
323
  return this;
288
324
  }
289
325
 
@@ -302,6 +338,7 @@ export class StructuredDocumentTag {
302
338
  setPlainTextProperties(properties: PlainTextProperties): this {
303
339
  this.properties.controlType = 'plainText';
304
340
  this.properties.plainText = properties;
341
+ this.sdtPrMutated = true;
305
342
  return this;
306
343
  }
307
344
 
@@ -320,6 +357,7 @@ export class StructuredDocumentTag {
320
357
  setComboBoxProperties(properties: ComboBoxProperties): this {
321
358
  this.properties.controlType = 'comboBox';
322
359
  this.properties.comboBox = properties;
360
+ this.sdtPrMutated = true;
323
361
  return this;
324
362
  }
325
363
 
@@ -338,6 +376,7 @@ export class StructuredDocumentTag {
338
376
  setDropDownListProperties(properties: DropDownListProperties): this {
339
377
  this.properties.controlType = 'dropDownList';
340
378
  this.properties.dropDownList = properties;
379
+ this.sdtPrMutated = true;
341
380
  return this;
342
381
  }
343
382
 
@@ -356,6 +395,7 @@ export class StructuredDocumentTag {
356
395
  setDatePickerProperties(properties: DatePickerProperties): this {
357
396
  this.properties.controlType = 'datePicker';
358
397
  this.properties.datePicker = properties;
398
+ this.sdtPrMutated = true;
359
399
  return this;
360
400
  }
361
401
 
@@ -374,6 +414,7 @@ export class StructuredDocumentTag {
374
414
  setCheckboxProperties(properties: CheckboxProperties): this {
375
415
  this.properties.controlType = 'checkbox';
376
416
  this.properties.checkbox = properties;
417
+ this.sdtPrMutated = true;
377
418
  return this;
378
419
  }
379
420
 
@@ -400,6 +441,7 @@ export class StructuredDocumentTag {
400
441
  setBuildingBlockProperties(properties: BuildingBlockProperties): this {
401
442
  this.properties.controlType = 'buildingBlock';
402
443
  this.properties.buildingBlock = properties;
444
+ this.sdtPrMutated = true;
403
445
  return this;
404
446
  }
405
447
 
@@ -449,6 +491,7 @@ export class StructuredDocumentTag {
449
491
  */
450
492
  setTemporary(temporary: boolean): this {
451
493
  this.properties.temporary = temporary;
494
+ this.sdtPrMutated = true;
452
495
  return this;
453
496
  }
454
497
 
@@ -565,7 +608,13 @@ export class StructuredDocumentTag {
565
608
  })
566
609
  );
567
610
  }
568
- sdtPrChildren.push(XMLBuilder.w('comboBox', {}, comboBoxChildren));
611
+ // w:lastValue records the last selected entry (CT_SdtComboBox);
612
+ // dropping it on rebuild loses the control's stored selection.
613
+ const comboBoxAttrs: Record<string, string> = {};
614
+ if (this.properties.comboBox.lastValue !== undefined) {
615
+ comboBoxAttrs['w:lastValue'] = this.properties.comboBox.lastValue;
616
+ }
617
+ sdtPrChildren.push(XMLBuilder.w('comboBox', comboBoxAttrs, comboBoxChildren));
569
618
  }
570
619
  break;
571
620
 
@@ -580,7 +629,12 @@ export class StructuredDocumentTag {
580
629
  })
581
630
  );
582
631
  }
583
- sdtPrChildren.push(XMLBuilder.w('dropDownList', {}, dropDownChildren));
632
+ // Same CT_SdtDropDownList w:lastValue preservation as comboBox.
633
+ const dropDownAttrs: Record<string, string> = {};
634
+ if (this.properties.dropDownList.lastValue !== undefined) {
635
+ dropDownAttrs['w:lastValue'] = this.properties.dropDownList.lastValue;
636
+ }
637
+ sdtPrChildren.push(XMLBuilder.w('dropDownList', dropDownAttrs, dropDownChildren));
584
638
  }
585
639
  break;
586
640
 
@@ -590,7 +644,9 @@ export class StructuredDocumentTag {
590
644
  // storeMappedDataAs, and calendar are child elements with w:val
591
645
  const dateAttrs: Record<string, string> = {};
592
646
  if (this.properties.datePicker.fullDate) {
593
- dateAttrs['w:fullDate'] = this.properties.datePicker.fullDate.toISOString();
647
+ // formatDateForXml strips milliseconds — Word rejects them in
648
+ // ST_DateTime attributes, and toISOString() always emits them.
649
+ dateAttrs['w:fullDate'] = formatDateForXml(this.properties.datePicker.fullDate);
594
650
  }
595
651
  const dateChildren: XMLElement[] = [];
596
652
  if (this.properties.datePicker.dateFormat) {
@@ -635,12 +691,17 @@ export class StructuredDocumentTag {
635
691
  );
636
692
  }
637
693
 
638
- // Add checked state symbol - use w14 namespace per OOXML spec
694
+ // Add checked state symbol - use w14 namespace per OOXML spec.
695
+ // The state pairs a character code with a glyph font
696
+ // (CT_SdtCheckboxSymbol); keep the parsed font so codes authored
697
+ // in e.g. Wingdings are not re-pointed at MS Gothic, where they
698
+ // map to wrong or missing glyphs. MS Gothic is only the default
699
+ // for programmatically created checkboxes (Word's stock symbols).
639
700
  if (this.properties.checkbox.checkedState) {
640
701
  checkboxChildren.push(
641
702
  XMLBuilder.w14Self('checkedState', {
642
703
  'w14:val': this.properties.checkbox.checkedState,
643
- 'w14:font': 'MS Gothic',
704
+ 'w14:font': this.properties.checkbox.checkedFont ?? 'MS Gothic',
644
705
  })
645
706
  );
646
707
  }
@@ -650,7 +711,7 @@ export class StructuredDocumentTag {
650
711
  checkboxChildren.push(
651
712
  XMLBuilder.w14Self('uncheckedState', {
652
713
  'w14:val': this.properties.checkbox.uncheckedState,
653
- 'w14:font': 'MS Gothic',
714
+ 'w14:font': this.properties.checkbox.uncheckedFont ?? 'MS Gothic',
654
715
  })
655
716
  );
656
717
  }
@@ -723,10 +784,20 @@ export class StructuredDocumentTag {
723
784
  }
724
785
  }
725
786
 
726
- if (sdtPrChildren.length > 0) {
787
+ if (this.rawSdtPrXml !== undefined && !this.sdtPrMutated) {
788
+ // The rebuilt sdtPr above only covers the modeled subset of CT_SdtPr;
789
+ // emit the parse-time markup verbatim so unmodeled children survive.
790
+ children.push({ name: '__rawXml', rawXml: this.rawSdtPrXml });
791
+ } else if (sdtPrChildren.length > 0) {
727
792
  children.push(XMLBuilder.w('sdtPr', {}, sdtPrChildren));
728
793
  }
729
794
 
795
+ // w:sdtEndPr has no object model; re-emit the parse-time markup so it
796
+ // is not dropped on save (CT_SdtBlock order: sdtPr, sdtEndPr, sdtContent).
797
+ if (this.rawSdtEndPrXml !== undefined) {
798
+ children.push({ name: '__rawXml', rawXml: this.rawSdtEndPrXml });
799
+ }
800
+
730
801
  // Build sdtContent
731
802
  const sdtContentChildren: XMLElement[] = [];
732
803
  for (const element of this.content) {
@@ -1009,6 +1080,7 @@ export class StructuredDocumentTag {
1009
1080
  */
1010
1081
  unlock(): this {
1011
1082
  delete this.properties.lock;
1083
+ this.sdtPrMutated = true;
1012
1084
  return this;
1013
1085
  }
1014
1086
 
@@ -1055,6 +1127,7 @@ export class StructuredDocumentTag {
1055
1127
  */
1056
1128
  setPlaceholder(docPart: string): this {
1057
1129
  this.properties.placeholder = { docPart };
1130
+ this.sdtPrMutated = true;
1058
1131
  return this;
1059
1132
  }
1060
1133
 
@@ -1073,6 +1146,7 @@ export class StructuredDocumentTag {
1073
1146
  */
1074
1147
  setDataBinding(xpath: string, prefixMappings?: string, storeItemId?: string): this {
1075
1148
  this.properties.dataBinding = { xpath, prefixMappings, storeItemId };
1149
+ this.sdtPrMutated = true;
1076
1150
  return this;
1077
1151
  }
1078
1152
 
@@ -1089,6 +1163,7 @@ export class StructuredDocumentTag {
1089
1163
  */
1090
1164
  setShowingPlaceholder(val: boolean): this {
1091
1165
  this.properties.showingPlcHdr = val;
1166
+ this.sdtPrMutated = true;
1092
1167
  return this;
1093
1168
  }
1094
1169