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
@@ -1 +1 @@
1
- {"version":3,"file":"Hyperlink.js","sourceRoot":"","sources":["../../../src/elements/Hyperlink.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Hyperlink - Represents a hyperlink in a Word document\n *\n * Hyperlinks can be external (to websites, files) or internal (to bookmarks within the document).\n * They are represented using the `<w:hyperlink>` element.\n *\n * ## Important: Relationship ID Requirement\n *\n * **External hyperlinks REQUIRE a relationship ID to be set before XML generation.**\n * Per ECMA-376 Part 1 §17.16.22, `<w:hyperlink>` elements with external targets must have\n * an `r:id` attribute that references a relationship in `word/_rels/document.xml.rels`.\n *\n * ### Correct Usage Pattern:\n *\n * ```typescript\n * // RECOMMENDED: Use Document.save() - automatically handles relationships\n * const doc = Document.create();\n * const para = doc.createParagraph();\n * para.addHyperlink(Hyperlink.createExternal('https://example.com', 'Link'));\n * await doc.save('document.docx'); // ✅ Relationships auto-registered\n * ```\n *\n * ### Manual Relationship Registration (Advanced):\n *\n * ```typescript\n * const link = Hyperlink.createExternal('https://example.com', 'Link');\n * const relationship = relationshipManager.addHyperlink('https://example.com');\n * link.setRelationshipId(relationship.getId());\n * link.toXML(); // ✅ Now valid\n * ```\n *\n * ### What NOT to Do:\n *\n * ```typescript\n * const link = Hyperlink.createExternal('https://example.com', 'Link');\n * link.toXML(); // ❌ ERROR: Missing relationship ID\n * ```\n *\n * ## Internal Hyperlinks\n *\n * Internal hyperlinks (bookmarks) do NOT require relationships:\n *\n * ```typescript\n * const link = Hyperlink.createInternal('Section1', 'Go to Section 1');\n * link.toXML(); // ✅ Valid - uses w:anchor attribute\n * ```\n *\n * @see {@link https://www.ecma-international.org/publications-and-standards/standards/ecma-376/ | ECMA-376 Part 1 §17.16.22}\n */\n\nimport { XMLElement } from '../xml/XMLBuilder.js';\nimport { Run, RunFormatting } from './Run.js';\nimport { Revision } from './Revision.js';\nimport { validateRunText, sanitizeHyperlinkUrl } from '../utils/validation.js';\nimport { defaultLogger } from '../utils/logger.js';\n\n/**\n * Hyperlink properties\n */\nexport interface HyperlinkProperties {\n /** Hyperlink URL (for external links) */\n url?: string;\n /** Bookmark anchor (for internal links) */\n anchor?: string;\n /** Display text (optional for empty/invisible hyperlinks) */\n text?: string;\n /** Text formatting */\n formatting?: RunFormatting;\n /** Tooltip text */\n tooltip?: string;\n /** Relationship ID (set by Document when saving) */\n relationshipId?: string;\n /** Whether this is an empty/invisible hyperlink with no display text */\n isEmpty?: boolean;\n /** Target frame attribute (e.g., \"_blank\" for new window) */\n tgtFrame?: string;\n /** History tracking attribute */\n history?: string;\n /** Document location for within-document navigation in external files (ECMA-376 §17.16.22) */\n docLocation?: string;\n}\n\n/**\n * Represents a hyperlink\n */\nexport class Hyperlink {\n private url?: string;\n private anchor?: string;\n private text: string;\n private run: Run;\n private tooltip?: string;\n private relationshipId?: string;\n private formatting: RunFormatting;\n /** Whether this is an empty/invisible hyperlink with no display text */\n private _isEmpty = false;\n /** Target frame attribute (e.g., \"_blank\" for new window) */\n private tgtFrame?: string;\n /** History tracking attribute */\n private history?: string;\n /** Document location for within-document navigation in external files */\n private docLocation?: string;\n /** Tracking context for automatic change tracking */\n private trackingContext?: import('../tracking/TrackingContext.js').TrackingContext;\n /** Parent paragraph reference for automatic tracking */\n private _parentParagraph?: import('./Paragraph.js').Paragraph;\n /** Baseline formatting captured before first tracked formatting change */\n private _preTrackingFormatting?: RunFormatting;\n\n /**\n * Creates a new hyperlink\n *\n * **Note:** A hyperlink must have either a URL (external) or anchor (internal), but not both.\n * If both are provided, the URL takes precedence and a warning is logged.\n *\n * @param properties Hyperlink properties\n */\n constructor(properties: HyperlinkProperties) {\n this.url = properties.url;\n this.anchor = properties.anchor;\n this.tooltip = properties.tooltip;\n this.relationshipId = properties.relationshipId;\n this.tgtFrame = properties.tgtFrame;\n this.history = properties.history;\n this.docLocation = properties.docLocation;\n this._isEmpty = properties.isEmpty ?? false;\n\n // VALIDATION: Warn about hybrid links (url + anchor)\n if (this.url && this.anchor) {\n defaultLogger.warn(\n `DocXML Warning: Hyperlink has both URL (\"${this.url}\") and anchor (\"${this.anchor}\"). ` +\n `This is ambiguous per ECMA-376 spec. URL will take precedence. ` +\n `Use Hyperlink.createExternal() or Hyperlink.createInternal() to avoid ambiguity.`\n );\n }\n\n // Handle empty/invisible hyperlinks (no display text)\n if (this._isEmpty) {\n this.text = '';\n this.formatting = {};\n this.run = new Run('', {});\n return;\n }\n\n // Text fallback: properties.text → url → 'Link'\n // NOTE: Do NOT use anchor (bookmark ID) as display text - it should only be used for navigation\n // Using bookmark IDs as visible text causes TOC corruption (Issue: TOC shows \"HEADING=II.MNKE7E8NA385_\" instead of proper headings)\n this.text = properties.text || this.url || 'Link';\n\n // Validate text for XML patterns\n // Default to auto-cleaning XML patterns unless explicitly disabled (matches Run behavior)\n const validation = validateRunText(this.text, {\n context: 'Hyperlink text',\n autoClean: properties.formatting?.cleanXmlFromText !== false,\n warnToConsole: true,\n });\n\n // Use cleaned text if available and cleaning was requested\n if (validation.cleanedText) {\n this.text = validation.cleanedText;\n }\n\n // Create run with default hyperlink styling (Verdana 12pt blue underlined)\n this.formatting = {\n font: 'Verdana',\n size: 12,\n color: '0000FF', // Standard hyperlink blue\n underline: 'single',\n ...properties.formatting,\n };\n\n this.run = new Run(this.text, this.formatting);\n }\n\n /**\n * Sets the tracking context for automatic change tracking.\n * Called by Document when track changes is enabled.\n * @internal\n */\n _setTrackingContext(context: import('../tracking/TrackingContext.js').TrackingContext): void {\n this.trackingContext = context;\n }\n\n /**\n * Sets the parent paragraph reference for automatic tracking.\n * Called by Paragraph when hyperlink is added.\n * @internal\n */\n _setParentParagraph(paragraph: import('./Paragraph.js').Paragraph): void {\n this._parentParagraph = paragraph;\n }\n\n /**\n * Gets the parent paragraph reference.\n * @internal\n */\n _getParentParagraph(): import('./Paragraph.js').Paragraph | undefined {\n return this._parentParagraph;\n }\n\n /**\n * Applies an rPrChange to the inner Run, tracking the delta between\n * the baseline formatting and the current formatting.\n *\n * On first call, captures `previousFormatting` as the baseline.\n * Subsequent calls always compare against the same baseline so that\n * multiple sequential formatting changes produce a single merged rPrChange.\n *\n * @internal\n */\n private _applyFormattingRPrChange(previousFormatting: RunFormatting): void {\n // Capture baseline on first tracked formatting change\n if (!this._preTrackingFormatting) {\n this._preTrackingFormatting = { ...previousFormatting };\n }\n\n // Build previousProperties from the baseline (only changed keys)\n const baseline = this._preTrackingFormatting;\n const current = this.formatting;\n const previousProperties: Partial<RunFormatting> = {};\n let hasChanges = false;\n\n for (const key of Object.keys(baseline) as (keyof RunFormatting)[]) {\n if (baseline[key] !== current[key]) {\n (previousProperties as Record<string, unknown>)[key] = baseline[key];\n hasChanges = true;\n }\n }\n // Also check for keys in current that weren't in baseline (new properties)\n for (const key of Object.keys(current) as (keyof RunFormatting)[]) {\n if (!(key in baseline) && current[key] !== undefined) {\n // Property didn't exist before — previous value is undefined\n (previousProperties as Record<string, unknown>)[key] = undefined;\n hasChanges = true;\n }\n }\n\n if (!hasChanges) return;\n\n const revisionId = this.trackingContext!.getRevisionManager().consumeNextId();\n const author = this.trackingContext!.getAuthor();\n\n this.run.setPropertyChangeRevision({\n id: revisionId,\n author,\n date: new Date(),\n previousProperties,\n });\n }\n\n /**\n * Gets the hyperlink URL\n */\n getUrl(): string | undefined {\n return this.url;\n }\n\n /**\n * Gets the complete URL including any anchor fragment.\n *\n * For external links that also have an anchor (e.g., internal bookmark within external page),\n * this returns the URL with the anchor appended as a fragment.\n * For internal-only links (anchor without URL), returns undefined.\n *\n * Note: As of v7.2.0, DocumentParser automatically combines external URLs with anchors\n * during parsing, so getUrl() typically returns the full URL. This method is provided\n * for cases where URL and anchor are set separately via the API.\n *\n * @returns The complete URL with fragment, or undefined for internal-only links\n *\n * @example\n * ```typescript\n * // External link with anchor fragment\n * const link = new Hyperlink({ url: 'https://example.com/', anchor: '!/view?id=123', text: 'Link' });\n * link.getUrl(); // 'https://example.com/'\n * link.getAnchor(); // '!/view?id=123'\n * link.getFullUrl(); // 'https://example.com/#!/view?id=123'\n *\n * // External link without anchor\n * const link2 = Hyperlink.createExternal('https://example.com/page', 'Link');\n * link2.getFullUrl(); // 'https://example.com/page'\n *\n * // Internal link (bookmark reference)\n * const link3 = Hyperlink.createInternal('Section1', 'Go to Section 1');\n * link3.getFullUrl(); // undefined\n * ```\n */\n getFullUrl(): string | undefined {\n if (this.url && this.anchor) {\n return this.url + '#' + this.anchor;\n }\n return this.url;\n }\n\n /**\n * Gets the anchor (for internal links)\n */\n getAnchor(): string | undefined {\n return this.anchor;\n }\n\n /**\n * Returns whether this is an empty/invisible hyperlink (has no display text).\n * Empty hyperlinks are self-closing elements in the XML.\n */\n isEmpty(): boolean {\n return this._isEmpty;\n }\n\n /**\n * Gets the target frame attribute (e.g., \"_blank\" for new window)\n */\n getTgtFrame(): string | undefined {\n return this.tgtFrame;\n }\n\n /**\n * Gets the history tracking attribute\n */\n getHistory(): string | undefined {\n return this.history;\n }\n\n /**\n * Sets the target frame attribute\n * @param tgtFrame Target frame (e.g., \"_blank\" for new window)\n */\n setTgtFrame(tgtFrame: string | undefined): this {\n this.tgtFrame = tgtFrame;\n return this;\n }\n\n /**\n * Sets the history tracking attribute\n * @param history History value (e.g., \"1\" to add to history)\n */\n setHistory(history: string | undefined): this {\n this.history = history;\n return this;\n }\n\n /**\n * Gets the document location attribute (ECMA-376 §17.16.22)\n */\n getDocLocation(): string | undefined {\n return this.docLocation;\n }\n\n /**\n * Sets the document location for within-document navigation in external files\n * @param docLocation Location string\n */\n setDocLocation(docLocation: string | undefined): this {\n this.docLocation = docLocation;\n return this;\n }\n\n /**\n * Gets the display text\n *\n * This method delegates to the internal run to ensure the returned text\n * is always accurate and matches what will be in the generated XML,\n * per ECMA-376 Part 1 §17.16.22.\n *\n * @returns The display text including any special characters (tabs, breaks, etc.)\n */\n getText(): string {\n return this.run.getText();\n }\n\n /**\n * Sets the display text\n */\n setText(text: string): this {\n // Validate text for XML patterns\n // Default to auto-cleaning unless explicitly disabled (matches Run behavior)\n const validation = validateRunText(text, {\n context: 'Hyperlink.setText',\n autoClean: this.formatting.cleanXmlFromText !== false,\n warnToConsole: true,\n });\n\n // Use cleaned text if available\n const cleanedText = validation.cleanedText || text;\n\n const previousValue = this.text;\n\n // Skip if text unchanged\n if (previousValue === cleanedText) {\n return this;\n }\n\n // If tracking enabled AND has parent paragraph, create delete/insert revision pair\n if (this.trackingContext?.isEnabled() && this._parentParagraph) {\n const author = this.trackingContext.getAuthor();\n\n // Clone current state for deletion (before applying changes)\n const oldHyperlink = this.clone();\n\n // Apply the change to this hyperlink\n this.text = cleanedText;\n this.run.setText(cleanedText);\n\n // Create delete/insert revision pair\n const deletion = Revision.createDeletion(author, [oldHyperlink]);\n const insertion = Revision.createInsertion(author, [this]);\n\n // Replace this hyperlink with the revision pair in parent paragraph\n this._parentParagraph.replaceContent(this, [deletion, insertion]);\n\n // Clear parent reference since we're now inside a revision\n this._parentParagraph = undefined;\n\n // Clear baseline formatting (fresh start inside insertion)\n this._preTrackingFormatting = undefined;\n\n return this;\n }\n\n // Non-tracking path (original behavior)\n this.text = cleanedText;\n this.run.setText(cleanedText);\n return this;\n }\n\n /**\n * Sets the internal run directly (for advanced use cases like TOC parsing)\n * Used by DocumentParser to preserve run content (tabs, breaks, etc.)\n * @param run - The run to use for this hyperlink\n */\n setRun(run: Run): this {\n this.run = run;\n this.text = run.getText();\n return this;\n }\n\n /**\n * Gets the tooltip\n */\n getTooltip(): string | undefined {\n return this.tooltip;\n }\n\n /**\n * Sets the tooltip\n */\n setTooltip(tooltip: string): this {\n const previousValue = this.tooltip;\n\n // Skip if tooltip unchanged\n if (previousValue === tooltip) {\n return this;\n }\n\n // If tracking enabled AND has parent paragraph, create delete/insert revision pair\n // Tooltip is a w:hyperlink attribute — no OOXML property-change element exists for it\n if (this.trackingContext?.isEnabled() && this._parentParagraph) {\n const author = this.trackingContext.getAuthor();\n\n // Clone current state for deletion (before applying changes)\n const oldHyperlink = this.clone();\n\n // Apply the change to this hyperlink\n this.tooltip = tooltip;\n\n // Create delete/insert revision pair\n const deletion = Revision.createDeletion(author, [oldHyperlink]);\n const insertion = Revision.createInsertion(author, [this]);\n\n // Replace this hyperlink with the revision pair in parent paragraph\n this._parentParagraph.replaceContent(this, [deletion, insertion]);\n\n // Clear parent reference since we're now inside a revision\n this._parentParagraph = undefined;\n\n // Clear baseline formatting (fresh start inside insertion)\n this._preTrackingFormatting = undefined;\n\n return this;\n }\n\n // Non-tracking path\n this.tooltip = tooltip;\n return this;\n }\n\n /**\n * Gets the relationship ID\n */\n getRelationshipId(): string | undefined {\n return this.relationshipId;\n }\n\n /**\n * Sets the relationship ID (called by Document during save)\n */\n setRelationshipId(id: string): this {\n this.relationshipId = id;\n return this;\n }\n\n /**\n * Sets or updates the hyperlink URL\n *\n * When URL is updated, we mark that the relationship needs updating.\n * The actual relationship update happens during Document.save() to ensure\n * proper coordination with the RelationshipManager.\n *\n * **Important:** This method maintains the relationship ID but flags it for update.\n * The RelationshipManager will update the existing relationship's target URL\n * during save, preventing orphaned relationships per ECMA-376 §17.16.22.\n *\n * @param url - The new URL (or undefined to clear)\n * @returns This hyperlink for chaining\n * @throws {Error} If clearing URL would create empty hyperlink (no URL and no anchor)\n *\n * @example\n * ```typescript\n * const link = Hyperlink.createExternal('https://old.com', 'Link');\n * link.setUrl('https://new.com'); // Marks for relationship update\n * await doc.save('updated.docx'); // Updates relationship target\n * ```\n */\n setUrl(url: string | undefined): this {\n // Validate that clearing URL doesn't create empty hyperlink\n if (!url && !this.anchor) {\n throw new Error(\n `Cannot set URL to undefined: Hyperlink \"${this.run.getText()}\" has no anchor. ` +\n `Clearing the URL would create an invalid hyperlink per ECMA-376 §17.16.22. ` +\n `Either provide a new URL or delete the hyperlink entirely.`\n );\n }\n\n // Save old URL before updating (for text fallback logic)\n const oldUrl = this.url;\n\n // Skip if URL unchanged (optimization)\n if (oldUrl === url) {\n return this;\n }\n\n // If tracking enabled AND has parent paragraph, create revision pair\n // OOXML has no w:hyperlinkChange element - Word tracks hyperlink changes as delete/insert pairs\n if (this.trackingContext?.isEnabled() && this._parentParagraph) {\n const author = this.trackingContext.getAuthor();\n\n // Clone current state for deletion (before applying changes)\n const oldHyperlink = this.clone();\n\n // Apply the change to this hyperlink\n this.url = url;\n this.relationshipId = undefined;\n if (this.run.getText() === oldUrl) {\n this.text = url || this.anchor || 'Link';\n this.run.setText(this.text);\n }\n\n // Create delete/insert revision pair\n const deletion = Revision.createDeletion(author, [oldHyperlink]);\n const insertion = Revision.createInsertion(author, [this]);\n\n // Replace this hyperlink with the revision pair in parent paragraph\n this._parentParagraph.replaceContent(this, [deletion, insertion]);\n\n // Clear parent reference since we're now inside a revision\n this._parentParagraph = undefined;\n\n return this;\n }\n\n // Non-tracking path (original behavior)\n this.url = url;\n\n // Clear the relationship ID so it will be re-registered during save\n // This ensures the relationship target is updated to point to the new URL\n this.relationshipId = undefined;\n\n // Update text ONLY if it was auto-generated from the old URL\n // This preserves user-provided text (even if it's \"Link\")\n // Use run.getText() to ensure we check the actual current text, not stale cache\n if (this.run.getText() === oldUrl) {\n this.text = url || this.anchor || 'Link';\n this.run.setText(this.text);\n }\n\n return this;\n }\n\n /**\n * Sets the anchor (for internal links)\n * @param anchor Bookmark name to link to\n * @returns This hyperlink for chaining\n * @throws {Error} If clearing anchor would create empty hyperlink (no URL and no anchor)\n * @example\n * ```typescript\n * const link = Hyperlink.createInternal('OldBookmark', 'Go there');\n * link.setAnchor('NewBookmark'); // Update internal link target\n * ```\n */\n setAnchor(anchor: string | undefined): this {\n // Validate that clearing anchor doesn't create empty hyperlink\n if (!anchor && !this.url) {\n throw new Error(\n `Cannot set anchor to undefined: Hyperlink \"${this.run.getText()}\" has no URL. ` +\n `Clearing the anchor would create an invalid hyperlink per ECMA-376 §17.16.22. ` +\n `Either provide a new anchor or delete the hyperlink entirely.`\n );\n }\n\n // Save old anchor before updating\n const oldAnchor = this.anchor;\n\n // Skip if anchor unchanged (optimization)\n if (oldAnchor === anchor) {\n return this;\n }\n\n // If tracking enabled AND has parent paragraph, create revision pair\n // OOXML has no w:hyperlinkChange element - Word tracks hyperlink changes as delete/insert pairs\n if (this.trackingContext?.isEnabled() && this._parentParagraph) {\n const author = this.trackingContext.getAuthor();\n\n // Clone current state for deletion (before applying changes)\n const oldHyperlink = this.clone();\n\n // Apply the change to this hyperlink\n this.anchor = anchor;\n if (anchor && this.url) {\n defaultLogger.warn(\n `DocXML Warning: Setting anchor \"${anchor}\" on hyperlink that has URL \"${this.url}\". ` +\n `Clearing URL to make this an internal link. Use separate hyperlinks for external and internal links.`\n );\n this.url = undefined;\n this.relationshipId = undefined;\n }\n if (this.run.getText() === oldAnchor) {\n this.text = anchor || this.url || 'Link';\n this.run.setText(this.text);\n }\n\n // Create delete/insert revision pair\n const deletion = Revision.createDeletion(author, [oldHyperlink]);\n const insertion = Revision.createInsertion(author, [this]);\n\n // Replace this hyperlink with the revision pair in parent paragraph\n this._parentParagraph.replaceContent(this, [deletion, insertion]);\n\n // Clear parent reference since we're now inside a revision\n this._parentParagraph = undefined;\n\n return this;\n }\n\n // Non-tracking path (original behavior)\n this.anchor = anchor;\n\n // If converting from external to internal, clear URL and relationship\n if (anchor && this.url) {\n defaultLogger.warn(\n `DocXML Warning: Setting anchor \"${anchor}\" on hyperlink that has URL \"${this.url}\". ` +\n `Clearing URL to make this an internal link. Use separate hyperlinks for external and internal links.`\n );\n this.url = undefined;\n this.relationshipId = undefined;\n }\n\n // Update text ONLY if it was auto-generated from the old anchor\n // Use run.getText() to ensure we check the actual current text, not stale cache\n if (this.run.getText() === oldAnchor) {\n this.text = anchor || this.url || 'Link';\n this.run.setText(this.text);\n }\n\n return this;\n }\n\n /**\n * Gets the run\n */\n getRun(): Run {\n return this.run;\n }\n\n /**\n * Sets run formatting\n *\n * @param formatting - The formatting to apply\n * @param options - Optional settings\n * @param options.replace - If true, replaces ALL existing formatting instead of merging.\n * Use this when you want to clear inherited styles like characterStyle.\n *\n * @example\n * ```typescript\n * // Merge mode (default): adds/updates properties while preserving others\n * hyperlink.setFormatting({ bold: true });\n *\n * // Replace mode: clears all existing formatting and applies only the new properties\n * hyperlink.setFormatting({ font: \"Verdana\", size: 12 }, { replace: true });\n * ```\n */\n setFormatting(formatting: RunFormatting, options?: { replace?: boolean }): this {\n // Update stored formatting\n const previousFormatting = { ...this.formatting };\n if (options?.replace) {\n // Replace mode: new formatting replaces ALL existing properties\n this.formatting = { ...formatting };\n } else {\n // Merge mode (default, backwards-compatible): merge with existing\n this.formatting = { ...this.formatting, ...formatting };\n }\n // Create new run with updated formatting, preserving current text\n const currentText = this.run.getText();\n this.run = new Run(currentText, this.formatting);\n this.text = currentText; // Keep cache in sync\n if (this.trackingContext?.isEnabled()) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Gets run formatting (returns this hyperlink for fluent API)\n * @returns This hyperlink for method chaining\n *\n * @example\n * ```typescript\n * hyperlink.getFormatting().setColor('0563C1').setUnderline('single');\n * ```\n */\n getFormatting(): this {\n return this;\n }\n\n /**\n * Gets the raw formatting object (for direct access)\n * @returns RunFormatting object\n */\n getRawFormatting(): RunFormatting {\n return this.formatting;\n }\n\n // ============================================================================\n // Individual Formatting Getters\n // ============================================================================\n\n /**\n * Gets the text color\n * @returns Color hex string or undefined\n */\n getColor(): string | undefined {\n return this.formatting.color;\n }\n\n /**\n * Gets the underline style\n * @returns Underline style or undefined\n */\n getUnderline(): string | boolean | undefined {\n return this.formatting.underline;\n }\n\n /**\n * Gets whether the hyperlink is bold\n * @returns True if bold, false otherwise\n */\n getBold(): boolean {\n return this.formatting.bold ?? false;\n }\n\n /**\n * Gets whether the hyperlink is italic\n * @returns True if italic, false otherwise\n */\n getItalic(): boolean {\n return this.formatting.italic ?? false;\n }\n\n /**\n * Gets the font family\n * @returns Font name or undefined\n */\n getFont(): string | undefined {\n return this.formatting.font;\n }\n\n /**\n * Gets the font size\n * @returns Font size in points or undefined\n */\n getSize(): number | undefined {\n return this.formatting.size;\n }\n\n /**\n * Sets text color\n * @param color Color in hex format (e.g., '0563C1')\n * @returns This hyperlink for chaining\n */\n setColor(color: string): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.color = color;\n this.run = new Run(this.text, this.formatting);\n if (this.trackingContext?.isEnabled() && previousFormatting.color !== color) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Sets underline style\n * @param underline Underline style ('single', 'double', etc.)\n * @returns This hyperlink for chaining\n */\n setUnderline(underline: boolean | 'single' | 'double' | 'dotted' | 'thick' | 'dash'): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.underline = underline;\n this.run = new Run(this.text, this.formatting);\n if (this.trackingContext?.isEnabled() && previousFormatting.underline !== underline) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Sets bold formatting\n * @param bold Bold state (default: true)\n * @returns This hyperlink for chaining\n */\n setBold(bold = true): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.bold = bold;\n this.run = new Run(this.text, this.formatting);\n if (this.trackingContext?.isEnabled() && previousFormatting.bold !== bold) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Sets italic formatting\n * @param italic Italic state (default: true)\n * @returns This hyperlink for chaining\n */\n setItalic(italic = true): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.italic = italic;\n this.run = new Run(this.text, this.formatting);\n if (this.trackingContext?.isEnabled() && previousFormatting.italic !== italic) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Sets font family\n * @param font Font name (e.g., 'Arial', 'Verdana')\n * @returns This hyperlink for chaining\n */\n setFont(font: string): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.font = font;\n this.run = new Run(this.text, this.formatting);\n if (this.trackingContext?.isEnabled() && previousFormatting.font !== font) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Sets font size\n * @param size Font size in points (e.g., 12, 14)\n * @returns This hyperlink for chaining\n */\n setSize(size: number): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.size = size;\n this.run = new Run(this.text, this.formatting);\n if (this.trackingContext?.isEnabled() && previousFormatting.size !== size) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Validates the hyperlink URL and optionally fixes common issues\n *\n * Performs validation and fixing of hyperlink URLs including:\n * - Checking URL accessibility (HTTP HEAD request for external links)\n * - Fixing common URL issues (missing protocol, double slashes, spaces)\n * - Validating internal bookmark references\n * - Detecting broken links\n *\n * **Note:** This method is async due to network requests for accessibility checks.\n *\n * @param options - Validation options\n * @returns Promise with validation results\n *\n * @example\n * ```typescript\n * // Basic URL fixing without network check\n * const result = await link.validateAndFix({\n * fixCommonIssues: true,\n * checkAccessibility: false\n * });\n * console.log(`Fixed: ${result.fixed.join(', ')}`);\n *\n * // Full validation with accessibility check\n * const validation = await link.validateAndFix({\n * checkAccessibility: true,\n * timeout: 5000\n * });\n * if (!validation.valid) {\n * console.log(`Issues: ${validation.issues.join(', ')}`);\n * }\n *\n * // Batch validate all hyperlinks in document\n * for (const { hyperlink } of doc.getHyperlinks()) {\n * const result = await hyperlink.validateAndFix();\n * if (result.fixed.length > 0) {\n * console.log(`Fixed ${hyperlink.getUrl()}: ${result.fixed.join(', ')}`);\n * }\n * }\n * ```\n */\n async validateAndFix(options?: {\n checkAccessibility?: boolean;\n fixCommonIssues?: boolean;\n timeout?: number;\n bookmarkManager?: { hasBookmark(name: string): boolean };\n }): Promise<{\n valid: boolean;\n issues: string[];\n fixed: string[];\n originalUrl?: string;\n fixedUrl?: string;\n }> {\n const {\n checkAccessibility = false,\n fixCommonIssues = true,\n timeout = 5000,\n bookmarkManager,\n } = options || {};\n\n const issues: string[] = [];\n const fixed: string[] = [];\n let fixedUrl = this.url;\n const originalUrl = this.url;\n\n // Internal link validation (bookmarks)\n if (this.anchor) {\n if (bookmarkManager) {\n const bookmarkExists = bookmarkManager.hasBookmark(this.anchor);\n if (!bookmarkExists) {\n issues.push(`Internal bookmark \"${this.anchor}\" not found`);\n }\n }\n return {\n valid: issues.length === 0,\n issues,\n fixed,\n originalUrl,\n };\n }\n\n // External link validation\n if (!this.url) {\n issues.push('No URL or anchor specified');\n return { valid: false, issues, fixed, originalUrl };\n }\n\n // Fix common issues\n if (fixCommonIssues && fixedUrl) {\n // Fix 0: Strip browser extension URL prefixes\n const sanitizeResult = sanitizeHyperlinkUrl(fixedUrl);\n if (sanitizeResult) {\n fixedUrl = sanitizeResult.url;\n fixed.push(...sanitizeResult.fixes);\n }\n\n // Fix 1: Add missing protocol\n if (!/^[a-z]+:\\/\\//i.exec(fixedUrl)) {\n fixedUrl = 'https://' + fixedUrl;\n fixed.push('Added missing protocol (https://)');\n }\n\n // Fix 2: Fix double slashes (except after protocol)\n const protocolMatch = /^([a-z]+:\\/\\/)/i.exec(fixedUrl);\n if (protocolMatch?.[1]) {\n const protocol = protocolMatch[1];\n const rest = fixedUrl.substring(protocol.length);\n const fixedRest = rest.replace(/\\/\\//g, '/');\n if (rest !== fixedRest) {\n fixedUrl = protocol + fixedRest;\n fixed.push('Fixed double slashes');\n }\n }\n\n // Fix 3: Encode spaces\n if (fixedUrl.includes(' ')) {\n fixedUrl = fixedUrl.replace(/ /g, '%20');\n fixed.push('Encoded spaces as %20');\n }\n\n // Fix 4: Remove trailing slashes for non-root URLs\n if (/^https?:\\/\\/[^/]+\\/.+\\/$/.exec(fixedUrl)) {\n fixedUrl = fixedUrl.replace(/\\/$/, '');\n fixed.push('Removed trailing slash');\n }\n\n // Fix 5: Fix common typos\n fixedUrl = fixedUrl.replace(/^http:\\/\\//i, 'https://'); // Prefer HTTPS\n if (fixedUrl !== this.url && fixedUrl.startsWith('https://')) {\n fixed.push('Upgraded HTTP to HTTPS');\n }\n\n // Update URL if fixes were applied\n if (fixedUrl !== this.url) {\n this.setUrl(fixedUrl);\n }\n }\n\n // Check accessibility (HTTP HEAD request)\n if (checkAccessibility && fixedUrl?.match(/^https?:\\/\\//i)) {\n // Check if fetch is available (Node.js 18+ or browser)\n if (typeof fetch === 'undefined') {\n issues.push('Network validation unavailable: fetch API not supported in this environment');\n } else {\n try {\n // Use fetch with AbortController for timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n const response = await fetch(fixedUrl, {\n method: 'HEAD',\n signal: controller.signal,\n redirect: 'follow',\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n issues.push(`HTTP ${response.status}: ${response.statusText || 'Error'}`);\n }\n } catch (error: unknown) {\n // Type guard for error objects with name and message properties\n const isErrorWithName = (err: unknown): err is { name: string } => {\n return typeof err === 'object' && err !== null && 'name' in err;\n };\n const isErrorWithMessage = (err: unknown): err is { message: string } => {\n return typeof err === 'object' && err !== null && 'message' in err;\n };\n\n if (isErrorWithName(error) && error.name === 'AbortError') {\n issues.push(`Timeout after ${timeout}ms`);\n } else if (isErrorWithMessage(error) && error.message?.includes('fetch')) {\n issues.push(`Unreachable: ${error.message}`);\n } else if (isErrorWithMessage(error)) {\n issues.push(`Network error: ${error.message}`);\n } else {\n issues.push('Network error: Unknown error');\n }\n }\n }\n }\n\n return {\n valid: issues.length === 0,\n issues,\n fixed,\n originalUrl,\n fixedUrl: fixedUrl !== originalUrl ? fixedUrl : undefined,\n };\n }\n\n /**\n * Resets hyperlink formatting to standard style (Calibri, blue, underline)\n * This is useful for fixing corrupted hyperlinks from Google Docs or other sources\n * @returns this for method chaining\n */\n resetToStandardFormatting(): this {\n const standardFormatting: RunFormatting = {\n font: 'Verdana',\n color: '0000FF', // Standard hyperlink blue\n underline: 'single',\n // Clear any other formatting that might be causing issues\n bold: false,\n italic: false,\n strike: false,\n };\n\n this.setFormatting(standardFormatting);\n return this;\n }\n\n /**\n * Checks if this is an external link\n */\n isExternal(): boolean {\n return this.url !== undefined;\n }\n\n /**\n * Checks if this is an internal link (anchor)\n */\n isInternal(): boolean {\n return this.anchor !== undefined;\n }\n\n /**\n * Creates a deep copy of this hyperlink\n *\n * This is useful for preserving the original state before modifications,\n * particularly when creating tracked changes (revisions) where both the\n * old and new states need to be preserved.\n *\n * @returns A new Hyperlink instance with the same properties\n *\n * @example\n * ```typescript\n * // Clone before modifying for tracked changes\n * const originalLink = hyperlink.clone();\n * hyperlink.setUrl('https://new-url.com');\n * hyperlink.setText('New Text');\n *\n * // Now originalLink has old URL/text, hyperlink has new\n * const deletion = Revision.createDeletion(author, [originalLink]);\n * const insertion = Revision.createInsertion(author, [hyperlink]);\n * ```\n */\n clone(): Hyperlink {\n const cloned = new Hyperlink({\n url: this.url,\n anchor: this.anchor,\n text: this.text,\n tooltip: this.tooltip,\n relationshipId: this.relationshipId,\n formatting: { ...this.formatting },\n tgtFrame: this.tgtFrame,\n history: this.history,\n docLocation: this.docLocation,\n });\n\n // Copy the run with its formatting\n if (this.run) {\n cloned.run = new Run(this.run.getText(), { ...this.run.getFormatting() });\n\n // Preserve rPrChange from the original run (formatting tracked changes)\n const existingRPrChange = this.run.getPropertyChangeRevision();\n if (existingRPrChange) {\n cloned.run.setPropertyChangeRevision({ ...existingRPrChange });\n }\n }\n\n return cloned;\n }\n\n /**\n * Generates XML for the hyperlink\n *\n * **CRITICAL:** For external links, relationshipId MUST be set before calling toXML().\n * This happens automatically when saving via Document.save(), but manual usage requires\n * registering the hyperlink with RelationshipManager first.\n *\n * @throws {Error} If external link (has url) is missing relationshipId\n * @throws {Error} If hyperlink has neither url nor anchor (empty hyperlink)\n */\n toXML(): XMLElement {\n // VALIDATION: Hyperlink must have url OR anchor (unless it's an empty hyperlink with relationshipId)\n if (!this.url && !this.anchor && !this.relationshipId) {\n throw new Error(\n 'CRITICAL: Hyperlink must have either a URL (external link), anchor (internal link), or relationshipId. ' +\n 'Cannot generate valid XML for hyperlink without destination.'\n );\n }\n\n // VALIDATION: External links MUST have relationship ID\n // Per ECMA-376 Part 1 §17.16.22, <w:hyperlink> with external target requires r:id attribute\n if (this.url && !this.relationshipId) {\n throw new Error(\n `CRITICAL: External hyperlink to \"${this.url}\" is missing relationship ID. ` +\n `This would create an invalid OpenXML document per ECMA-376 §17.16.22. ` +\n `Solution: Use Document.save() which automatically registers relationships, ` +\n `or manually call relationshipManager.addHyperlink(url) and set the relationship ID.`\n );\n }\n\n const attributes: Record<string, string> = {};\n\n // External link - add relationship ID\n if (this.relationshipId) {\n attributes['r:id'] = this.relationshipId;\n }\n\n // Internal link - uses anchor\n if (this.anchor) {\n attributes['w:anchor'] = this.anchor;\n }\n\n // Tooltip - explicitly escape attribute value for safety\n // XMLBuilder will handle escaping, but we document this for clarity\n if (this.tooltip) {\n // Note: XMLBuilder.elementToString() will escape this via escapeXmlAttribute()\n // when generating the actual XML string. We store the raw value here.\n attributes['w:tooltip'] = this.tooltip;\n }\n\n // Target frame attribute (e.g., \"_blank\" for new window)\n if (this.tgtFrame) {\n attributes['w:tgtFrame'] = this.tgtFrame;\n }\n\n // History tracking attribute (CT_OnOff per ECMA-376 §17.16.22).\n // Use `!== undefined` rather than a truthy check so explicit \"0\" /\n // \"false\" / \"off\" overrides survive round-trip — the parser\n // normalises to \"1\"/\"0\", but external callers may still set any\n // ST_OnOff literal.\n if (this.history !== undefined) {\n attributes['w:history'] = this.history;\n }\n\n // Document location attribute (ECMA-376 §17.16.22)\n if (this.docLocation) {\n attributes['w:docLocation'] = this.docLocation;\n }\n\n // Empty/invisible hyperlinks have no children (self-closing element)\n if (this._isEmpty) {\n return {\n name: 'w:hyperlink',\n attributes,\n children: [],\n };\n }\n\n // Generate run XML\n const runXml = this.run.toXML();\n\n return {\n name: 'w:hyperlink',\n attributes,\n children: [runXml],\n };\n }\n\n /**\n * Creates an external hyperlink\n * @param url The URL\n * @param text Display text\n * @param formatting Optional formatting\n */\n static createExternal(url: string, text: string, formatting?: RunFormatting): Hyperlink {\n return new Hyperlink({ url, text, formatting });\n }\n\n /**\n * Creates an internal hyperlink (to a bookmark)\n * @param anchor Bookmark name\n * @param text Display text\n * @param formatting Optional formatting\n */\n static createInternal(anchor: string, text: string, formatting?: RunFormatting): Hyperlink {\n return new Hyperlink({ anchor, text, formatting });\n }\n\n /**\n * Creates a web link (convenience method for URLs)\n * @param url The URL\n * @param text Display text (defaults to URL)\n * @param formatting Optional formatting\n */\n static createWebLink(url: string, text?: string, formatting?: RunFormatting): Hyperlink {\n return new Hyperlink({\n url,\n text: text || url,\n formatting,\n });\n }\n\n /**\n * Creates an email link\n * @param email Email address\n * @param text Display text (defaults to email)\n * @param formatting Optional formatting\n */\n static createEmail(email: string, text?: string, formatting?: RunFormatting): Hyperlink {\n return new Hyperlink({\n url: `mailto:${email}`,\n text: text || email,\n formatting,\n });\n }\n\n /**\n * Creates a hyperlink with properties\n * @param properties Hyperlink properties\n */\n static create(properties: HyperlinkProperties): Hyperlink {\n return new Hyperlink(properties);\n }\n}\n"]}
1
+ {"version":3,"file":"Hyperlink.js","sourceRoot":"","sources":["../../../src/elements/Hyperlink.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Hyperlink - Represents a hyperlink in a Word document\n *\n * Hyperlinks can be external (to websites, files) or internal (to bookmarks within the document).\n * They are represented using the `<w:hyperlink>` element.\n *\n * ## Important: Relationship ID Requirement\n *\n * **External hyperlinks REQUIRE a relationship ID to be set before XML generation.**\n * Per ECMA-376 Part 1 §17.16.22, `<w:hyperlink>` elements with external targets must have\n * an `r:id` attribute that references a relationship in `word/_rels/document.xml.rels`.\n *\n * ### Correct Usage Pattern:\n *\n * ```typescript\n * // RECOMMENDED: Use Document.save() - automatically handles relationships\n * const doc = Document.create();\n * const para = doc.createParagraph();\n * para.addHyperlink(Hyperlink.createExternal('https://example.com', 'Link'));\n * await doc.save('document.docx'); // ✅ Relationships auto-registered\n * ```\n *\n * ### Manual Relationship Registration (Advanced):\n *\n * ```typescript\n * const link = Hyperlink.createExternal('https://example.com', 'Link');\n * const relationship = relationshipManager.addHyperlink('https://example.com');\n * link.setRelationshipId(relationship.getId());\n * link.toXML(); // ✅ Now valid\n * ```\n *\n * ### What NOT to Do:\n *\n * ```typescript\n * const link = Hyperlink.createExternal('https://example.com', 'Link');\n * link.toXML(); // ❌ ERROR: Missing relationship ID\n * ```\n *\n * ## Internal Hyperlinks\n *\n * Internal hyperlinks (bookmarks) do NOT require relationships:\n *\n * ```typescript\n * const link = Hyperlink.createInternal('Section1', 'Go to Section 1');\n * link.toXML(); // ✅ Valid - uses w:anchor attribute\n * ```\n *\n * @see {@link https://www.ecma-international.org/publications-and-standards/standards/ecma-376/ | ECMA-376 Part 1 §17.16.22}\n */\n\nimport { XMLElement } from '../xml/XMLBuilder.js';\nimport { Run, RunFormatting } from './Run.js';\nimport { Revision } from './Revision.js';\nimport { validateRunText, sanitizeHyperlinkUrl } from '../utils/validation.js';\nimport { defaultLogger } from '../utils/logger.js';\n\n/**\n * Hyperlink properties\n */\nexport interface HyperlinkProperties {\n /** Hyperlink URL (for external links) */\n url?: string;\n /** Bookmark anchor (for internal links) */\n anchor?: string;\n /** Display text (optional for empty/invisible hyperlinks) */\n text?: string;\n /** Text formatting */\n formatting?: RunFormatting;\n /**\n * Use the supplied formatting exactly as given instead of layering it over\n * the default hyperlink styling. Set when the formatting comes from parsed\n * XML, so load→save does not inject direct formatting that overrides the\n * document's Hyperlink character style.\n */\n preserveFormatting?: boolean;\n /** Tooltip text */\n tooltip?: string;\n /** Relationship ID (set by Document when saving) */\n relationshipId?: string;\n /** Whether this is an empty/invisible hyperlink with no display text */\n isEmpty?: boolean;\n /** Target frame attribute (e.g., \"_blank\" for new window) */\n tgtFrame?: string;\n /** History tracking attribute */\n history?: string;\n /** Document location for within-document navigation in external files (ECMA-376 §17.16.22) */\n docLocation?: string;\n}\n\n/**\n * Represents a hyperlink\n */\nexport class Hyperlink {\n private url?: string;\n private anchor?: string;\n private text: string;\n /**\n * Display-text runs. Word splits hyperlink text into multiple runs when\n * formatting varies mid-link, so a single-run model would drop per-run\n * formatting on round-trip. Always holds at least one run.\n */\n private runs: Run[];\n private tooltip?: string;\n private relationshipId?: string;\n private formatting: RunFormatting;\n /** Whether this is an empty/invisible hyperlink with no display text */\n private _isEmpty = false;\n /** Target frame attribute (e.g., \"_blank\" for new window) */\n private tgtFrame?: string;\n /** History tracking attribute */\n private history?: string;\n /** Document location for within-document navigation in external files */\n private docLocation?: string;\n /** Tracking context for automatic change tracking */\n private trackingContext?: import('../tracking/TrackingContext.js').TrackingContext;\n /** Parent paragraph reference for automatic tracking */\n private _parentParagraph?: import('./Paragraph.js').Paragraph;\n /** Baseline formatting captured before first tracked formatting change */\n private _preTrackingFormatting?: RunFormatting;\n\n /**\n * Creates a new hyperlink\n *\n * **Note:** A hyperlink must have either a URL (external) or anchor (internal), but not both.\n * If both are provided, the URL takes precedence and a warning is logged.\n *\n * @param properties Hyperlink properties\n */\n constructor(properties: HyperlinkProperties) {\n this.url = properties.url;\n this.anchor = properties.anchor;\n this.tooltip = properties.tooltip;\n this.relationshipId = properties.relationshipId;\n this.tgtFrame = properties.tgtFrame;\n this.history = properties.history;\n this.docLocation = properties.docLocation;\n this._isEmpty = properties.isEmpty ?? false;\n\n // VALIDATION: Warn about hybrid links (url + anchor)\n if (this.url && this.anchor) {\n defaultLogger.warn(\n `DocXML Warning: Hyperlink has both URL (\"${this.url}\") and anchor (\"${this.anchor}\"). ` +\n `This is ambiguous per ECMA-376 spec. URL will take precedence. ` +\n `Use Hyperlink.createExternal() or Hyperlink.createInternal() to avoid ambiguity.`\n );\n }\n\n // Handle empty/invisible hyperlinks (no display text)\n if (this._isEmpty) {\n this.text = '';\n this.formatting = {};\n this.runs = [new Run('', {})];\n return;\n }\n\n // Text fallback: properties.text → url → 'Link'\n // NOTE: Do NOT use anchor (bookmark ID) as display text - it should only be used for navigation\n // Using bookmark IDs as visible text causes TOC corruption (Issue: TOC shows \"HEADING=II.MNKE7E8NA385_\" instead of proper headings)\n this.text = properties.text || this.url || 'Link';\n\n // Validate text for XML patterns\n // Default to auto-cleaning XML patterns unless explicitly disabled (matches Run behavior)\n const validation = validateRunText(this.text, {\n context: 'Hyperlink text',\n autoClean: properties.formatting?.cleanXmlFromText !== false,\n warnToConsole: true,\n });\n\n // Use cleaned text if available and cleaning was requested\n if (validation.cleanedText) {\n this.text = validation.cleanedText;\n }\n\n // Default hyperlink styling (Verdana 12pt blue underlined) is for\n // programmatically created links. Parsed links must keep exactly the\n // formatting found in the source XML — merging these defaults underneath\n // would add direct formatting that overrides the document's Hyperlink\n // character style on round-trip.\n this.formatting = properties.preserveFormatting\n ? { ...properties.formatting }\n : {\n font: 'Verdana',\n size: 12,\n color: '0000FF', // Standard hyperlink blue\n underline: 'single',\n ...properties.formatting,\n };\n\n this.runs = [new Run(this.text, this.formatting)];\n }\n\n /**\n * Sets the tracking context for automatic change tracking.\n * Called by Document when track changes is enabled.\n * @internal\n */\n _setTrackingContext(context: import('../tracking/TrackingContext.js').TrackingContext): void {\n this.trackingContext = context;\n }\n\n /**\n * Sets the parent paragraph reference for automatic tracking.\n * Called by Paragraph when hyperlink is added.\n * @internal\n */\n _setParentParagraph(paragraph: import('./Paragraph.js').Paragraph): void {\n this._parentParagraph = paragraph;\n }\n\n /**\n * Gets the parent paragraph reference.\n * @internal\n */\n _getParentParagraph(): import('./Paragraph.js').Paragraph | undefined {\n return this._parentParagraph;\n }\n\n /**\n * Applies an rPrChange to the inner Run, tracking the delta between\n * the baseline formatting and the current formatting.\n *\n * On first call, captures `previousFormatting` as the baseline.\n * Subsequent calls always compare against the same baseline so that\n * multiple sequential formatting changes produce a single merged rPrChange.\n *\n * @internal\n */\n private _applyFormattingRPrChange(previousFormatting: RunFormatting): void {\n // Capture baseline on first tracked formatting change\n if (!this._preTrackingFormatting) {\n this._preTrackingFormatting = { ...previousFormatting };\n }\n\n // Build previousProperties from the baseline (only changed keys)\n const baseline = this._preTrackingFormatting;\n const current = this.formatting;\n const previousProperties: Partial<RunFormatting> = {};\n let hasChanges = false;\n\n for (const key of Object.keys(baseline) as (keyof RunFormatting)[]) {\n if (baseline[key] !== current[key]) {\n (previousProperties as Record<string, unknown>)[key] = baseline[key];\n hasChanges = true;\n }\n }\n // Also check for keys in current that weren't in baseline (new properties)\n for (const key of Object.keys(current) as (keyof RunFormatting)[]) {\n if (!(key in baseline) && current[key] !== undefined) {\n // Property didn't exist before — previous value is undefined\n (previousProperties as Record<string, unknown>)[key] = undefined;\n hasChanges = true;\n }\n }\n\n if (!hasChanges) return;\n\n const revisionId = this.trackingContext!.getRevisionManager().consumeNextId();\n const author = this.trackingContext!.getAuthor();\n\n this.runs[0]!.setPropertyChangeRevision({\n id: revisionId,\n author,\n date: new Date(),\n previousProperties,\n });\n }\n\n /**\n * Gets the hyperlink URL\n */\n getUrl(): string | undefined {\n return this.url;\n }\n\n /**\n * Gets the complete URL including any anchor fragment.\n *\n * For external links that also have an anchor (e.g., internal bookmark within external page),\n * this returns the URL with the anchor appended as a fragment.\n * For internal-only links (anchor without URL), returns undefined.\n *\n * Note: As of v7.2.0, DocumentParser automatically combines external URLs with anchors\n * during parsing, so getUrl() typically returns the full URL. This method is provided\n * for cases where URL and anchor are set separately via the API.\n *\n * @returns The complete URL with fragment, or undefined for internal-only links\n *\n * @example\n * ```typescript\n * // External link with anchor fragment\n * const link = new Hyperlink({ url: 'https://example.com/', anchor: '!/view?id=123', text: 'Link' });\n * link.getUrl(); // 'https://example.com/'\n * link.getAnchor(); // '!/view?id=123'\n * link.getFullUrl(); // 'https://example.com/#!/view?id=123'\n *\n * // External link without anchor\n * const link2 = Hyperlink.createExternal('https://example.com/page', 'Link');\n * link2.getFullUrl(); // 'https://example.com/page'\n *\n * // Internal link (bookmark reference)\n * const link3 = Hyperlink.createInternal('Section1', 'Go to Section 1');\n * link3.getFullUrl(); // undefined\n * ```\n */\n getFullUrl(): string | undefined {\n if (this.url && this.anchor) {\n return this.url + '#' + this.anchor;\n }\n return this.url;\n }\n\n /**\n * Gets the anchor (for internal links)\n */\n getAnchor(): string | undefined {\n return this.anchor;\n }\n\n /**\n * Returns whether this is an empty/invisible hyperlink (has no display text).\n * Empty hyperlinks are self-closing elements in the XML.\n */\n isEmpty(): boolean {\n return this._isEmpty;\n }\n\n /**\n * Gets the target frame attribute (e.g., \"_blank\" for new window)\n */\n getTgtFrame(): string | undefined {\n return this.tgtFrame;\n }\n\n /**\n * Gets the history tracking attribute\n */\n getHistory(): string | undefined {\n return this.history;\n }\n\n /**\n * Sets the target frame attribute\n * @param tgtFrame Target frame (e.g., \"_blank\" for new window)\n */\n setTgtFrame(tgtFrame: string | undefined): this {\n this.tgtFrame = tgtFrame;\n return this;\n }\n\n /**\n * Sets the history tracking attribute\n * @param history History value (e.g., \"1\" to add to history)\n */\n setHistory(history: string | undefined): this {\n this.history = history;\n return this;\n }\n\n /**\n * Gets the document location attribute (ECMA-376 §17.16.22)\n */\n getDocLocation(): string | undefined {\n return this.docLocation;\n }\n\n /**\n * Sets the document location for within-document navigation in external files\n * @param docLocation Location string\n */\n setDocLocation(docLocation: string | undefined): this {\n this.docLocation = docLocation;\n return this;\n }\n\n /**\n * Gets the display text\n *\n * This method delegates to the internal runs to ensure the returned text\n * is always accurate and matches what will be in the generated XML,\n * per ECMA-376 Part 1 §17.16.22. Multi-run hyperlinks concatenate the\n * text of every run in document order.\n *\n * @returns The display text including any special characters (tabs, breaks, etc.)\n */\n getText(): string {\n return this.runs.map((run) => run.getText()).join('');\n }\n\n /**\n * Replaces the display text. Collapses to a single run (keeping the first\n * run's formatting) because the caller-supplied text supersedes any\n * per-run split the source document had.\n */\n private replaceRunText(text: string): void {\n const first = this.runs[0]!;\n first.setText(text);\n this.runs = [first];\n }\n\n /**\n * Sets the display text\n */\n setText(text: string): this {\n // Validate text for XML patterns\n // Default to auto-cleaning unless explicitly disabled (matches Run behavior)\n const validation = validateRunText(text, {\n context: 'Hyperlink.setText',\n autoClean: this.formatting.cleanXmlFromText !== false,\n warnToConsole: true,\n });\n\n // Use cleaned text if available.\n // `??` (not `||`) so a cleaned result of '' (input that was entirely XML\n // markup) is kept rather than falling back to the original markup-laden text.\n const cleanedText = validation.cleanedText ?? text;\n\n const previousValue = this.text;\n\n // Assigning display text clears the empty/invisible flag — otherwise\n // toXML() would keep emitting a childless w:hyperlink and silently drop\n // the text that was just set.\n this._isEmpty = false;\n\n // Skip if text unchanged\n if (previousValue === cleanedText) {\n return this;\n }\n\n // If tracking enabled AND has parent paragraph, create delete/insert revision pair\n if (this.trackingContext?.isEnabled() && this._parentParagraph) {\n const author = this.trackingContext.getAuthor();\n\n // Clone current state for deletion (before applying changes)\n const oldHyperlink = this.clone();\n\n // Apply the change to this hyperlink\n this.text = cleanedText;\n this.replaceRunText(cleanedText);\n\n // Create delete/insert revision pair\n const deletion = Revision.createDeletion(author, [oldHyperlink]);\n const insertion = Revision.createInsertion(author, [this]);\n\n // Replace this hyperlink with the revision pair in parent paragraph\n this._parentParagraph.replaceContent(this, [deletion, insertion]);\n\n // Clear parent reference since we're now inside a revision\n this._parentParagraph = undefined;\n\n // Clear baseline formatting (fresh start inside insertion)\n this._preTrackingFormatting = undefined;\n\n return this;\n }\n\n // Non-tracking path (original behavior)\n this.text = cleanedText;\n this.replaceRunText(cleanedText);\n return this;\n }\n\n /**\n * Sets the internal run directly (for advanced use cases like TOC parsing)\n * Used by DocumentParser to preserve run content (tabs, breaks, etc.)\n * @param run - The run to use for this hyperlink\n */\n setRun(run: Run): this {\n this.runs = [run];\n this.text = run.getText();\n return this;\n }\n\n /**\n * Replaces all runs of this hyperlink (multi-run display text)\n * Used by DocumentParser when a w:hyperlink holds multiple w:r children —\n * Word splits the display text into one run per formatting change, and\n * each run must keep its own rPr for round-trip fidelity.\n * @param runs - Runs in document order (ignored if empty)\n */\n setRuns(runs: Run[]): this {\n if (runs.length === 0) {\n return this;\n }\n this.runs = [...runs];\n this.text = this.getText();\n return this;\n }\n\n /**\n * Gets all runs carrying the display text\n * Single-run hyperlinks return a one-element array.\n */\n getRuns(): Run[] {\n return [...this.runs];\n }\n\n /**\n * Gets the tooltip\n */\n getTooltip(): string | undefined {\n return this.tooltip;\n }\n\n /**\n * Sets the tooltip\n */\n setTooltip(tooltip: string): this {\n const previousValue = this.tooltip;\n\n // Skip if tooltip unchanged\n if (previousValue === tooltip) {\n return this;\n }\n\n // If tracking enabled AND has parent paragraph, create delete/insert revision pair\n // Tooltip is a w:hyperlink attribute — no OOXML property-change element exists for it\n if (this.trackingContext?.isEnabled() && this._parentParagraph) {\n const author = this.trackingContext.getAuthor();\n\n // Clone current state for deletion (before applying changes)\n const oldHyperlink = this.clone();\n\n // Apply the change to this hyperlink\n this.tooltip = tooltip;\n\n // Create delete/insert revision pair\n const deletion = Revision.createDeletion(author, [oldHyperlink]);\n const insertion = Revision.createInsertion(author, [this]);\n\n // Replace this hyperlink with the revision pair in parent paragraph\n this._parentParagraph.replaceContent(this, [deletion, insertion]);\n\n // Clear parent reference since we're now inside a revision\n this._parentParagraph = undefined;\n\n // Clear baseline formatting (fresh start inside insertion)\n this._preTrackingFormatting = undefined;\n\n return this;\n }\n\n // Non-tracking path\n this.tooltip = tooltip;\n return this;\n }\n\n /**\n * Gets the relationship ID\n */\n getRelationshipId(): string | undefined {\n return this.relationshipId;\n }\n\n /**\n * Sets the relationship ID (called by Document during save)\n */\n setRelationshipId(id: string): this {\n this.relationshipId = id;\n return this;\n }\n\n /**\n * Sets or updates the hyperlink URL\n *\n * When URL is updated, we mark that the relationship needs updating.\n * The actual relationship update happens during Document.save() to ensure\n * proper coordination with the RelationshipManager.\n *\n * **Important:** This method maintains the relationship ID but flags it for update.\n * The RelationshipManager will update the existing relationship's target URL\n * during save, preventing orphaned relationships per ECMA-376 §17.16.22.\n *\n * @param url - The new URL (or undefined to clear)\n * @returns This hyperlink for chaining\n * @throws {Error} If clearing URL would create empty hyperlink (no URL and no anchor)\n *\n * @example\n * ```typescript\n * const link = Hyperlink.createExternal('https://old.com', 'Link');\n * link.setUrl('https://new.com'); // Marks for relationship update\n * await doc.save('updated.docx'); // Updates relationship target\n * ```\n */\n setUrl(url: string | undefined): this {\n // Validate that clearing URL doesn't create empty hyperlink\n if (!url && !this.anchor) {\n throw new Error(\n `Cannot set URL to undefined: Hyperlink \"${this.getText()}\" has no anchor. ` +\n `Clearing the URL would create an invalid hyperlink per ECMA-376 §17.16.22. ` +\n `Either provide a new URL or delete the hyperlink entirely.`\n );\n }\n\n // Save old URL before updating (for text fallback logic)\n const oldUrl = this.url;\n\n // Skip if URL unchanged (optimization)\n if (oldUrl === url) {\n return this;\n }\n\n // If tracking enabled AND has parent paragraph, create revision pair\n // OOXML has no w:hyperlinkChange element - Word tracks hyperlink changes as delete/insert pairs\n if (this.trackingContext?.isEnabled() && this._parentParagraph) {\n const author = this.trackingContext.getAuthor();\n\n // Clone current state for deletion (before applying changes)\n const oldHyperlink = this.clone();\n\n // Apply the change to this hyperlink\n this.url = url;\n this.relationshipId = undefined;\n if (this.getText() === oldUrl) {\n this.text = url || this.anchor || 'Link';\n this.replaceRunText(this.text);\n }\n\n // Create delete/insert revision pair\n const deletion = Revision.createDeletion(author, [oldHyperlink]);\n const insertion = Revision.createInsertion(author, [this]);\n\n // Replace this hyperlink with the revision pair in parent paragraph\n this._parentParagraph.replaceContent(this, [deletion, insertion]);\n\n // Clear parent reference since we're now inside a revision\n this._parentParagraph = undefined;\n\n return this;\n }\n\n // Non-tracking path (original behavior)\n this.url = url;\n\n // Clear the relationship ID so it will be re-registered during save\n // This ensures the relationship target is updated to point to the new URL\n this.relationshipId = undefined;\n\n // Update text ONLY if it was auto-generated from the old URL\n // This preserves user-provided text (even if it's \"Link\")\n // Use getText() to ensure we check the actual current text, not stale cache\n if (this.getText() === oldUrl) {\n this.text = url || this.anchor || 'Link';\n this.replaceRunText(this.text);\n }\n\n return this;\n }\n\n /**\n * Sets the anchor (for internal links)\n * @param anchor Bookmark name to link to\n * @returns This hyperlink for chaining\n * @throws {Error} If clearing anchor would create empty hyperlink (no URL and no anchor)\n * @example\n * ```typescript\n * const link = Hyperlink.createInternal('OldBookmark', 'Go there');\n * link.setAnchor('NewBookmark'); // Update internal link target\n * ```\n */\n setAnchor(anchor: string | undefined): this {\n // Validate that clearing anchor doesn't create empty hyperlink\n if (!anchor && !this.url) {\n throw new Error(\n `Cannot set anchor to undefined: Hyperlink \"${this.getText()}\" has no URL. ` +\n `Clearing the anchor would create an invalid hyperlink per ECMA-376 §17.16.22. ` +\n `Either provide a new anchor or delete the hyperlink entirely.`\n );\n }\n\n // Save old anchor before updating\n const oldAnchor = this.anchor;\n\n // Skip if anchor unchanged (optimization)\n if (oldAnchor === anchor) {\n return this;\n }\n\n // If tracking enabled AND has parent paragraph, create revision pair\n // OOXML has no w:hyperlinkChange element - Word tracks hyperlink changes as delete/insert pairs\n if (this.trackingContext?.isEnabled() && this._parentParagraph) {\n const author = this.trackingContext.getAuthor();\n\n // Clone current state for deletion (before applying changes)\n const oldHyperlink = this.clone();\n\n // Apply the change to this hyperlink\n this.anchor = anchor;\n if (anchor && this.url) {\n defaultLogger.warn(\n `DocXML Warning: Setting anchor \"${anchor}\" on hyperlink that has URL \"${this.url}\". ` +\n `Clearing URL to make this an internal link. Use separate hyperlinks for external and internal links.`\n );\n this.url = undefined;\n this.relationshipId = undefined;\n }\n if (this.getText() === oldAnchor) {\n this.text = anchor || this.url || 'Link';\n this.replaceRunText(this.text);\n }\n\n // Create delete/insert revision pair\n const deletion = Revision.createDeletion(author, [oldHyperlink]);\n const insertion = Revision.createInsertion(author, [this]);\n\n // Replace this hyperlink with the revision pair in parent paragraph\n this._parentParagraph.replaceContent(this, [deletion, insertion]);\n\n // Clear parent reference since we're now inside a revision\n this._parentParagraph = undefined;\n\n return this;\n }\n\n // Non-tracking path (original behavior)\n this.anchor = anchor;\n\n // If converting from external to internal, clear URL and relationship\n if (anchor && this.url) {\n defaultLogger.warn(\n `DocXML Warning: Setting anchor \"${anchor}\" on hyperlink that has URL \"${this.url}\". ` +\n `Clearing URL to make this an internal link. Use separate hyperlinks for external and internal links.`\n );\n this.url = undefined;\n this.relationshipId = undefined;\n }\n\n // Update text ONLY if it was auto-generated from the old anchor\n // Use getText() to ensure we check the actual current text, not stale cache\n if (this.getText() === oldAnchor) {\n this.text = anchor || this.url || 'Link';\n this.replaceRunText(this.text);\n }\n\n return this;\n }\n\n /**\n * Gets the run\n * Multi-run hyperlinks return the first run — use getRuns() for all of them.\n */\n getRun(): Run {\n return this.runs[0]!;\n }\n\n /**\n * Sets run formatting\n *\n * @param formatting - The formatting to apply\n * @param options - Optional settings\n * @param options.replace - If true, replaces ALL existing formatting instead of merging.\n * Use this when you want to clear inherited styles like characterStyle.\n *\n * @example\n * ```typescript\n * // Merge mode (default): adds/updates properties while preserving others\n * hyperlink.setFormatting({ bold: true });\n *\n * // Replace mode: clears all existing formatting and applies only the new properties\n * hyperlink.setFormatting({ font: \"Verdana\", size: 12 }, { replace: true });\n * ```\n */\n setFormatting(formatting: RunFormatting, options?: { replace?: boolean }): this {\n // Update stored formatting\n const previousFormatting = { ...this.formatting };\n if (options?.replace) {\n // Replace mode: new formatting replaces ALL existing properties\n this.formatting = { ...formatting };\n } else {\n // Merge mode (default, backwards-compatible): merge with existing\n this.formatting = { ...this.formatting, ...formatting };\n }\n // Rebuild every run, layering the patch over each run's own rPr so\n // multi-run links keep per-run distinctions the caller did not touch.\n // Replace mode discards per-run rPr by design.\n this.runs = this.runs.map((run) =>\n Run.createFromContent(\n run.getContent(),\n options?.replace ? { ...formatting } : { ...run.getFormatting(), ...formatting }\n )\n );\n this.text = this.getText(); // Keep cache in sync\n if (this.trackingContext?.isEnabled()) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Layers a formatting patch over every display-text run. Content is\n * rebuilt via Run.createFromContent so tabs/breaks survive, and each\n * run keeps its other rPr values — stamping the hyperlink-level\n * formatting over them would erase per-run formatting in multi-run links.\n */\n private patchRunFormatting(patch: RunFormatting): void {\n this.runs = this.runs.map((run) =>\n Run.createFromContent(run.getContent(), { ...run.getFormatting(), ...patch })\n );\n }\n\n /**\n * Gets run formatting (returns this hyperlink for fluent API)\n * @returns This hyperlink for method chaining\n *\n * @example\n * ```typescript\n * hyperlink.getFormatting().setColor('0563C1').setUnderline('single');\n * ```\n */\n getFormatting(): this {\n return this;\n }\n\n /**\n * Gets the raw formatting object (for direct access)\n * @returns RunFormatting object\n */\n getRawFormatting(): RunFormatting {\n return this.formatting;\n }\n\n // ============================================================================\n // Individual Formatting Getters\n // ============================================================================\n\n /**\n * Gets the text color\n * @returns Color hex string or undefined\n */\n getColor(): string | undefined {\n return this.formatting.color;\n }\n\n /**\n * Gets the underline style\n * @returns Underline style or undefined\n */\n getUnderline(): string | boolean | undefined {\n return this.formatting.underline;\n }\n\n /**\n * Gets whether the hyperlink is bold\n * @returns True if bold, false otherwise\n */\n getBold(): boolean {\n return this.formatting.bold ?? false;\n }\n\n /**\n * Gets whether the hyperlink is italic\n * @returns True if italic, false otherwise\n */\n getItalic(): boolean {\n return this.formatting.italic ?? false;\n }\n\n /**\n * Gets the font family\n * @returns Font name or undefined\n */\n getFont(): string | undefined {\n return this.formatting.font;\n }\n\n /**\n * Gets the font size\n * @returns Font size in points or undefined\n */\n getSize(): number | undefined {\n return this.formatting.size;\n }\n\n /**\n * Sets text color\n * @param color Color in hex format (e.g., '0563C1')\n * @returns This hyperlink for chaining\n */\n setColor(color: string): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.color = color;\n this.patchRunFormatting({ color });\n if (this.trackingContext?.isEnabled() && previousFormatting.color !== color) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Sets underline style\n * @param underline Underline style ('single', 'double', etc.)\n * @returns This hyperlink for chaining\n */\n setUnderline(underline: boolean | 'single' | 'double' | 'dotted' | 'thick' | 'dash'): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.underline = underline;\n this.patchRunFormatting({ underline });\n if (this.trackingContext?.isEnabled() && previousFormatting.underline !== underline) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Sets bold formatting\n * @param bold Bold state (default: true)\n * @returns This hyperlink for chaining\n */\n setBold(bold = true): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.bold = bold;\n this.patchRunFormatting({ bold });\n if (this.trackingContext?.isEnabled() && previousFormatting.bold !== bold) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Sets italic formatting\n * @param italic Italic state (default: true)\n * @returns This hyperlink for chaining\n */\n setItalic(italic = true): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.italic = italic;\n this.patchRunFormatting({ italic });\n if (this.trackingContext?.isEnabled() && previousFormatting.italic !== italic) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Sets font family\n * @param font Font name (e.g., 'Arial', 'Verdana')\n * @returns This hyperlink for chaining\n */\n setFont(font: string): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.font = font;\n this.patchRunFormatting({ font });\n if (this.trackingContext?.isEnabled() && previousFormatting.font !== font) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Sets font size\n * @param size Font size in points (e.g., 12, 14)\n * @returns This hyperlink for chaining\n */\n setSize(size: number): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.size = size;\n this.patchRunFormatting({ size });\n if (this.trackingContext?.isEnabled() && previousFormatting.size !== size) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Validates the hyperlink URL and optionally fixes common issues\n *\n * Performs validation and fixing of hyperlink URLs including:\n * - Checking URL accessibility (HTTP HEAD request for external links)\n * - Fixing common URL issues (missing protocol, double slashes, spaces)\n * - Validating internal bookmark references\n * - Detecting broken links\n *\n * **Note:** This method is async due to network requests for accessibility checks.\n *\n * @param options - Validation options\n * @returns Promise with validation results\n *\n * @example\n * ```typescript\n * // Basic URL fixing without network check\n * const result = await link.validateAndFix({\n * fixCommonIssues: true,\n * checkAccessibility: false\n * });\n * console.log(`Fixed: ${result.fixed.join(', ')}`);\n *\n * // Full validation with accessibility check\n * const validation = await link.validateAndFix({\n * checkAccessibility: true,\n * timeout: 5000\n * });\n * if (!validation.valid) {\n * console.log(`Issues: ${validation.issues.join(', ')}`);\n * }\n *\n * // Batch validate all hyperlinks in document\n * for (const { hyperlink } of doc.getHyperlinks()) {\n * const result = await hyperlink.validateAndFix();\n * if (result.fixed.length > 0) {\n * console.log(`Fixed ${hyperlink.getUrl()}: ${result.fixed.join(', ')}`);\n * }\n * }\n * ```\n */\n async validateAndFix(options?: {\n checkAccessibility?: boolean;\n fixCommonIssues?: boolean;\n timeout?: number;\n bookmarkManager?: { hasBookmark(name: string): boolean };\n }): Promise<{\n valid: boolean;\n issues: string[];\n fixed: string[];\n originalUrl?: string;\n fixedUrl?: string;\n }> {\n const {\n checkAccessibility = false,\n fixCommonIssues = true,\n timeout = 5000,\n bookmarkManager,\n } = options || {};\n\n const issues: string[] = [];\n const fixed: string[] = [];\n let fixedUrl = this.url;\n const originalUrl = this.url;\n\n // Internal link validation (bookmarks)\n if (this.anchor) {\n if (bookmarkManager) {\n const bookmarkExists = bookmarkManager.hasBookmark(this.anchor);\n if (!bookmarkExists) {\n issues.push(`Internal bookmark \"${this.anchor}\" not found`);\n }\n }\n return {\n valid: issues.length === 0,\n issues,\n fixed,\n originalUrl,\n };\n }\n\n // External link validation\n if (!this.url) {\n issues.push('No URL or anchor specified');\n return { valid: false, issues, fixed, originalUrl };\n }\n\n // Fix common issues\n if (fixCommonIssues && fixedUrl) {\n // Fix 0: Strip browser extension URL prefixes\n const sanitizeResult = sanitizeHyperlinkUrl(fixedUrl);\n if (sanitizeResult) {\n fixedUrl = sanitizeResult.url;\n fixed.push(...sanitizeResult.fixes);\n }\n\n // Fix 1: Add missing protocol\n if (!/^[a-z]+:\\/\\//i.exec(fixedUrl)) {\n fixedUrl = 'https://' + fixedUrl;\n fixed.push('Added missing protocol (https://)');\n }\n\n // Fix 2: Fix double slashes (except after protocol)\n const protocolMatch = /^([a-z]+:\\/\\/)/i.exec(fixedUrl);\n if (protocolMatch?.[1]) {\n const protocol = protocolMatch[1];\n const rest = fixedUrl.substring(protocol.length);\n const fixedRest = rest.replace(/\\/\\//g, '/');\n if (rest !== fixedRest) {\n fixedUrl = protocol + fixedRest;\n fixed.push('Fixed double slashes');\n }\n }\n\n // Fix 3: Encode spaces\n if (fixedUrl.includes(' ')) {\n fixedUrl = fixedUrl.replace(/ /g, '%20');\n fixed.push('Encoded spaces as %20');\n }\n\n // Fix 4: Remove trailing slashes for non-root URLs\n if (/^https?:\\/\\/[^/]+\\/.+\\/$/.exec(fixedUrl)) {\n fixedUrl = fixedUrl.replace(/\\/$/, '');\n fixed.push('Removed trailing slash');\n }\n\n // Fix 5: Fix common typos\n // Compare against the value immediately before this replace (not this.url)\n // so 'Upgraded HTTP to HTTPS' is reported only when the http→https\n // rewrite actually fired — an earlier fix (space encoding, double-slash\n // collapse) on an already-https URL must not trigger this message.\n const beforeUpgrade = fixedUrl;\n fixedUrl = fixedUrl.replace(/^http:\\/\\//i, 'https://'); // Prefer HTTPS\n if (fixedUrl !== beforeUpgrade) {\n fixed.push('Upgraded HTTP to HTTPS');\n }\n\n // Update URL if fixes were applied\n if (fixedUrl !== this.url) {\n this.setUrl(fixedUrl);\n }\n }\n\n // Check accessibility (HTTP HEAD request)\n if (checkAccessibility && fixedUrl?.match(/^https?:\\/\\//i)) {\n // Check if fetch is available (Node.js 18+ or browser)\n if (typeof fetch === 'undefined') {\n issues.push('Network validation unavailable: fetch API not supported in this environment');\n } else {\n try {\n // Use fetch with AbortController for timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n const response = await fetch(fixedUrl, {\n method: 'HEAD',\n signal: controller.signal,\n redirect: 'follow',\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n issues.push(`HTTP ${response.status}: ${response.statusText || 'Error'}`);\n }\n } catch (error: unknown) {\n // Type guard for error objects with name and message properties\n const isErrorWithName = (err: unknown): err is { name: string } => {\n return typeof err === 'object' && err !== null && 'name' in err;\n };\n const isErrorWithMessage = (err: unknown): err is { message: string } => {\n return typeof err === 'object' && err !== null && 'message' in err;\n };\n\n if (isErrorWithName(error) && error.name === 'AbortError') {\n issues.push(`Timeout after ${timeout}ms`);\n } else if (isErrorWithMessage(error) && error.message?.includes('fetch')) {\n issues.push(`Unreachable: ${error.message}`);\n } else if (isErrorWithMessage(error)) {\n issues.push(`Network error: ${error.message}`);\n } else {\n issues.push('Network error: Unknown error');\n }\n }\n }\n }\n\n return {\n valid: issues.length === 0,\n issues,\n fixed,\n originalUrl,\n fixedUrl: fixedUrl !== originalUrl ? fixedUrl : undefined,\n };\n }\n\n /**\n * Resets hyperlink formatting to standard style (Calibri, blue, underline)\n * This is useful for fixing corrupted hyperlinks from Google Docs or other sources\n * @returns this for method chaining\n */\n resetToStandardFormatting(): this {\n const standardFormatting: RunFormatting = {\n font: 'Verdana',\n color: '0000FF', // Standard hyperlink blue\n underline: 'single',\n // Clear any other formatting that might be causing issues\n bold: false,\n italic: false,\n strike: false,\n };\n\n this.setFormatting(standardFormatting);\n return this;\n }\n\n /**\n * Checks if this is an external link\n */\n isExternal(): boolean {\n return this.url !== undefined;\n }\n\n /**\n * Checks if this is an internal link (anchor)\n */\n isInternal(): boolean {\n return this.anchor !== undefined;\n }\n\n /**\n * Creates a deep copy of this hyperlink\n *\n * This is useful for preserving the original state before modifications,\n * particularly when creating tracked changes (revisions) where both the\n * old and new states need to be preserved.\n *\n * @returns A new Hyperlink instance with the same properties\n *\n * @example\n * ```typescript\n * // Clone before modifying for tracked changes\n * const originalLink = hyperlink.clone();\n * hyperlink.setUrl('https://new-url.com');\n * hyperlink.setText('New Text');\n *\n * // Now originalLink has old URL/text, hyperlink has new\n * const deletion = Revision.createDeletion(author, [originalLink]);\n * const insertion = Revision.createInsertion(author, [hyperlink]);\n * ```\n */\n clone(): Hyperlink {\n const cloned = new Hyperlink({\n url: this.url,\n anchor: this.anchor,\n text: this.text,\n tooltip: this.tooltip,\n relationshipId: this.relationshipId,\n formatting: { ...this.formatting },\n // this.formatting is already fully resolved — re-merging constructor\n // defaults would resurrect styling the original no longer carries\n preserveFormatting: true,\n tgtFrame: this.tgtFrame,\n history: this.history,\n docLocation: this.docLocation,\n // Carry the empty/invisible flag so a clone of a self-closing hyperlink\n // serializes self-closing too (matters for the deletion half of tracked\n // changes, which snapshots the source via clone()).\n isEmpty: this._isEmpty,\n });\n\n // Copy every run with its content and formatting (multi-run links keep\n // one cloned run per source run)\n cloned.runs = this.runs.map((run) => {\n const copy = run.clone();\n\n // Preserve rPrChange from the original run (formatting tracked changes)\n // — Run.clone() copies content/formatting but not the revision\n const existingRPrChange = run.getPropertyChangeRevision();\n if (existingRPrChange) {\n copy.setPropertyChangeRevision({ ...existingRPrChange });\n }\n return copy;\n });\n cloned.text = cloned.getText();\n\n return cloned;\n }\n\n /**\n * Generates XML for the hyperlink\n *\n * **CRITICAL:** For external links, relationshipId MUST be set before calling toXML().\n * This happens automatically when saving via Document.save(), but manual usage requires\n * registering the hyperlink with RelationshipManager first.\n *\n * @throws {Error} If external link (has url) is missing relationshipId\n * @throws {Error} If hyperlink has neither url nor anchor (empty hyperlink)\n */\n toXML(): XMLElement {\n // VALIDATION: Hyperlink must have url OR anchor (unless it's an empty hyperlink with relationshipId)\n if (!this.url && !this.anchor && !this.relationshipId) {\n throw new Error(\n 'CRITICAL: Hyperlink must have either a URL (external link), anchor (internal link), or relationshipId. ' +\n 'Cannot generate valid XML for hyperlink without destination.'\n );\n }\n\n // VALIDATION: External links MUST have relationship ID\n // Per ECMA-376 Part 1 §17.16.22, <w:hyperlink> with external target requires r:id attribute\n if (this.url && !this.relationshipId) {\n throw new Error(\n `CRITICAL: External hyperlink to \"${this.url}\" is missing relationship ID. ` +\n `This would create an invalid OpenXML document per ECMA-376 §17.16.22. ` +\n `Solution: Use Document.save() which automatically registers relationships, ` +\n `or manually call relationshipManager.addHyperlink(url) and set the relationship ID.`\n );\n }\n\n const attributes: Record<string, string> = {};\n\n // External link - add relationship ID\n if (this.relationshipId) {\n attributes['r:id'] = this.relationshipId;\n }\n\n // Internal link - uses anchor\n if (this.anchor) {\n attributes['w:anchor'] = this.anchor;\n }\n\n // Tooltip - explicitly escape attribute value for safety\n // XMLBuilder will handle escaping, but we document this for clarity\n if (this.tooltip) {\n // Note: XMLBuilder.elementToString() will escape this via escapeXmlAttribute()\n // when generating the actual XML string. We store the raw value here.\n attributes['w:tooltip'] = this.tooltip;\n }\n\n // Target frame attribute (e.g., \"_blank\" for new window)\n if (this.tgtFrame) {\n attributes['w:tgtFrame'] = this.tgtFrame;\n }\n\n // History tracking attribute (CT_OnOff per ECMA-376 §17.16.22).\n // Use `!== undefined` rather than a truthy check so explicit \"0\" /\n // \"false\" / \"off\" overrides survive round-trip — the parser\n // normalises to \"1\"/\"0\", but external callers may still set any\n // ST_OnOff literal.\n if (this.history !== undefined) {\n attributes['w:history'] = this.history;\n }\n\n // Document location attribute (ECMA-376 §17.16.22)\n if (this.docLocation) {\n attributes['w:docLocation'] = this.docLocation;\n }\n\n // Empty/invisible hyperlinks have no children (self-closing element)\n if (this._isEmpty) {\n return {\n name: 'w:hyperlink',\n attributes,\n children: [],\n };\n }\n\n // One <w:r> child per run, each with its own <w:rPr> — collapsing to a\n // single run would drop per-run formatting in multi-run display text\n return {\n name: 'w:hyperlink',\n attributes,\n children: this.runs.map((run) => run.toXML()),\n };\n }\n\n /**\n * Creates an external hyperlink\n * @param url The URL\n * @param text Display text\n * @param formatting Optional formatting\n */\n static createExternal(url: string, text: string, formatting?: RunFormatting): Hyperlink {\n return new Hyperlink({ url, text, formatting });\n }\n\n /**\n * Creates an internal hyperlink (to a bookmark)\n * @param anchor Bookmark name\n * @param text Display text\n * @param formatting Optional formatting\n */\n static createInternal(anchor: string, text: string, formatting?: RunFormatting): Hyperlink {\n return new Hyperlink({ anchor, text, formatting });\n }\n\n /**\n * Creates a web link (convenience method for URLs)\n * @param url The URL\n * @param text Display text (defaults to URL)\n * @param formatting Optional formatting\n */\n static createWebLink(url: string, text?: string, formatting?: RunFormatting): Hyperlink {\n return new Hyperlink({\n url,\n text: text || url,\n formatting,\n });\n }\n\n /**\n * Creates an email link\n * @param email Email address\n * @param text Display text (defaults to email)\n * @param formatting Optional formatting\n */\n static createEmail(email: string, text?: string, formatting?: RunFormatting): Hyperlink {\n return new Hyperlink({\n url: `mailto:${email}`,\n text: text || email,\n formatting,\n });\n }\n\n /**\n * Creates a hyperlink with properties\n * @param properties Hyperlink properties\n */\n static create(properties: HyperlinkProperties): Hyperlink {\n return new Hyperlink(properties);\n }\n}\n"]}
@@ -518,6 +518,7 @@ export class Image {
518
518
  this.height = Math.round(width * ratio);
519
519
  }
520
520
  this.width = width;
521
+ this._mutated = true;
521
522
  return this;
522
523
  }
523
524
  setHeight(height, maintainAspectRatio = true) {
@@ -526,6 +527,7 @@ export class Image {
526
527
  this.width = Math.round(height * ratio);
527
528
  }
528
529
  this.height = height;
530
+ this._mutated = true;
529
531
  return this;
530
532
  }
531
533
  setSize(width, height) {
@@ -557,6 +559,7 @@ export class Image {
557
559
  }
558
560
  setAltText(altText) {
559
561
  this.description = altText;
562
+ this._mutated = true;
560
563
  return this;
561
564
  }
562
565
  getAltText() {
@@ -564,6 +567,7 @@ export class Image {
564
567
  }
565
568
  setTitle(title) {
566
569
  this.title = title;
570
+ this._mutated = true;
567
571
  return this;
568
572
  }
569
573
  getTitle() {
@@ -571,9 +575,7 @@ export class Image {
571
575
  }
572
576
  rotate(degrees) {
573
577
  this.rotation = ((degrees % 360) + 360) % 360;
574
- if (this.rotation === 90 || this.rotation === 270) {
575
- [this.width, this.height] = [this.height, this.width];
576
- }
578
+ this._mutated = true;
577
579
  return this;
578
580
  }
579
581
  getRotation() {
@@ -581,6 +583,7 @@ export class Image {
581
583
  }
582
584
  setFlipH(flip) {
583
585
  this.flipH = flip;
586
+ this._mutated = true;
584
587
  return this;
585
588
  }
586
589
  getFlipH() {
@@ -588,6 +591,7 @@ export class Image {
588
591
  }
589
592
  setFlipV(flip) {
590
593
  this.flipV = flip;
594
+ this._mutated = true;
591
595
  return this;
592
596
  }
593
597
  getFlipV() {
@@ -598,6 +602,7 @@ export class Image {
598
602
  }
599
603
  setPresetGeometry(geom) {
600
604
  this.presetGeometry = geom;
605
+ this._mutated = true;
601
606
  return this;
602
607
  }
603
608
  getCompressionState() {
@@ -605,6 +610,7 @@ export class Image {
605
610
  }
606
611
  setCompressionState(state) {
607
612
  this.compressionState = state;
613
+ this._mutated = true;
608
614
  return this;
609
615
  }
610
616
  getBwMode() {
@@ -612,6 +618,7 @@ export class Image {
612
618
  }
613
619
  setBwMode(mode) {
614
620
  this.bwMode = mode;
621
+ this._mutated = true;
615
622
  return this;
616
623
  }
617
624
  getInlineDistT() {
@@ -631,6 +638,7 @@ export class Image {
631
638
  this.inlineDistB = distB;
632
639
  this.inlineDistL = distL;
633
640
  this.inlineDistR = distR;
641
+ this._mutated = true;
634
642
  return this;
635
643
  }
636
644
  getNoChangeAspect() {
@@ -638,6 +646,7 @@ export class Image {
638
646
  }
639
647
  setNoChangeAspect(val) {
640
648
  this.noChangeAspect = val;
649
+ this._mutated = true;
641
650
  return this;
642
651
  }
643
652
  getHidden() {
@@ -645,6 +654,7 @@ export class Image {
645
654
  }
646
655
  setHidden(val) {
647
656
  this.hidden = val;
657
+ this._mutated = true;
648
658
  return this;
649
659
  }
650
660
  getBlipFillDpi() {
@@ -652,6 +662,7 @@ export class Image {
652
662
  }
653
663
  setBlipFillDpi(dpi) {
654
664
  this.blipFillDpi = dpi;
665
+ this._mutated = true;
655
666
  return this;
656
667
  }
657
668
  getBlipFillRotWithShape() {
@@ -659,6 +670,7 @@ export class Image {
659
670
  }
660
671
  setBlipFillRotWithShape(val) {
661
672
  this.blipFillRotWithShape = val;
673
+ this._mutated = true;
662
674
  return this;
663
675
  }
664
676
  getPicLocks() {
@@ -666,6 +678,7 @@ export class Image {
666
678
  }
667
679
  setPicLocks(locks) {
668
680
  this.picLocks = locks;
681
+ this._mutated = true;
669
682
  return this;
670
683
  }
671
684
  getPicNonVisualProps() {
@@ -673,6 +686,7 @@ export class Image {
673
686
  }
674
687
  setPicNonVisualProps(props) {
675
688
  this.picNonVisualProps = props;
689
+ this._mutated = true;
676
690
  return this;
677
691
  }
678
692
  getIsLinked() {
@@ -680,6 +694,7 @@ export class Image {
680
694
  }
681
695
  setIsLinked(val) {
682
696
  this.isLinked = val;
697
+ this._mutated = true;
683
698
  return this;
684
699
  }
685
700
  getSvgRelationshipId() {
@@ -687,6 +702,7 @@ export class Image {
687
702
  }
688
703
  setSvgRelationshipId(id) {
689
704
  this.svgRelationshipId = id;
705
+ this._mutated = true;
690
706
  return this;
691
707
  }
692
708
  _setRawPassthrough(slot, xml) {
@@ -703,6 +719,7 @@ export class Image {
703
719
  }
704
720
  setEffectExtent(left, top, right, bottom) {
705
721
  this.effectExtent = { left, top, right, bottom };
722
+ this._mutated = true;
706
723
  return this;
707
724
  }
708
725
  getEffectExtent() {
@@ -717,6 +734,7 @@ export class Image {
717
734
  distanceLeft: distances?.left,
718
735
  distanceRight: distances?.right,
719
736
  };
737
+ this._mutated = true;
720
738
  return this;
721
739
  }
722
740
  getWrap() {
@@ -734,6 +752,7 @@ export class Image {
734
752
  this.validatePositionOffset(horizontal.offset, 'horizontal');
735
753
  this.validatePositionOffset(vertical.offset, 'vertical');
736
754
  this.position = { horizontal, vertical };
755
+ this._mutated = true;
737
756
  return this;
738
757
  }
739
758
  getPosition() {
@@ -760,6 +779,7 @@ export class Image {
760
779
  }
761
780
  setAnchor(options) {
762
781
  this.anchor = options;
782
+ this._mutated = true;
763
783
  return this;
764
784
  }
765
785
  getAnchor() {
@@ -768,6 +788,7 @@ export class Image {
768
788
  setCrop(left, top, right, bottom) {
769
789
  const clamp = (val) => Math.max(0, Math.min(100, val));
770
790
  this.crop = { left: clamp(left), top: clamp(top), right: clamp(right), bottom: clamp(bottom) };
791
+ this._mutated = true;
771
792
  return this;
772
793
  }
773
794
  getCrop() {
@@ -783,6 +804,7 @@ export class Image {
783
804
  ? Math.max(0, Math.min(100, options.transparency))
784
805
  : undefined,
785
806
  };
807
+ this._mutated = true;
786
808
  return this;
787
809
  }
788
810
  getEffects() {
@@ -878,6 +900,7 @@ export class Image {
878
900
  setBehindText(behind = true) {
879
901
  if (this.anchor) {
880
902
  this.anchor.behindDoc = behind;
903
+ this._mutated = true;
881
904
  }
882
905
  else {
883
906
  this.setAnchor({
@@ -915,6 +938,7 @@ export class Image {
915
938
  removeBorder() {
916
939
  this.border = undefined;
917
940
  this._rawPassthrough.delete('zero-width-ln');
941
+ this._mutated = true;
918
942
  return this;
919
943
  }
920
944
  applyTwoPixelBlackBorder() {
@@ -1190,8 +1214,6 @@ export class Image {
1190
1214
  wrapAttrs.distL = this.wrap.distanceLeft;
1191
1215
  if (this.wrap.distanceRight !== undefined)
1192
1216
  wrapAttrs.distR = this.wrap.distanceRight;
1193
- if (this.wrap.side)
1194
- wrapAttrs.wrapText = this.wrap.side;
1195
1217
  let wrapElementName;
1196
1218
  switch (this.wrap.type) {
1197
1219
  case 'square':
@@ -1212,6 +1234,11 @@ export class Image {
1212
1234
  default:
1213
1235
  wrapElementName = 'wrapSquare';
1214
1236
  }
1237
+ if (wrapElementName === 'wrapSquare' ||
1238
+ wrapElementName === 'wrapTight' ||
1239
+ wrapElementName === 'wrapThrough') {
1240
+ wrapAttrs.wrapText = this.wrap.side ?? 'bothSides';
1241
+ }
1215
1242
  const wrapChildren = [];
1216
1243
  if (this._rawPassthrough.has('wrap-polygon')) {
1217
1244
  wrapChildren.push({
@@ -1253,7 +1280,7 @@ export class Image {
1253
1280
  locked: this.anchor?.locked ? 1 : 0,
1254
1281
  layoutInCell: this.anchor?.layoutInCell ? 1 : 0,
1255
1282
  allowOverlap: this.anchor?.allowOverlap ? 1 : 0,
1256
- relativeHeight: this.anchor?.relativeHeight,
1283
+ relativeHeight: this.anchor?.relativeHeight ?? 251658240,
1257
1284
  simplePos: this.anchor?.simplePos ? '1' : '0',
1258
1285
  distT: (this.anchor?.distT ?? 0).toString(),
1259
1286
  distB: (this.anchor?.distB ?? 0).toString(),