docxmlater 10.0.4 → 10.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/Document.d.ts +22 -0
- package/dist/core/Document.d.ts.map +1 -1
- package/dist/core/Document.js +170 -26
- package/dist/core/Document.js.map +1 -1
- package/dist/core/DocumentParser.d.ts.map +1 -1
- package/dist/core/DocumentParser.js +71 -6
- package/dist/core/DocumentParser.js.map +1 -1
- package/dist/elements/Hyperlink.d.ts +6 -0
- package/dist/elements/Hyperlink.d.ts.map +1 -1
- package/dist/elements/Hyperlink.js +23 -0
- package/dist/elements/Hyperlink.js.map +1 -1
- package/dist/elements/StructuredDocumentTag.d.ts +23 -1
- package/dist/elements/StructuredDocumentTag.d.ts.map +1 -1
- package/dist/elements/StructuredDocumentTag.js +97 -0
- package/dist/elements/StructuredDocumentTag.js.map +1 -1
- package/dist/elements/TableCell.d.ts +5 -0
- package/dist/elements/TableCell.d.ts.map +1 -1
- package/dist/elements/TableCell.js +13 -0
- package/dist/elements/TableCell.js.map +1 -1
- package/dist/elements/TableRow.d.ts +3 -0
- package/dist/elements/TableRow.d.ts.map +1 -1
- package/dist/elements/TableRow.js +10 -0
- package/dist/elements/TableRow.js.map +1 -1
- package/dist/formatting/AbstractNumbering.d.ts +4 -0
- package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
- package/dist/formatting/AbstractNumbering.js +15 -0
- package/dist/formatting/AbstractNumbering.js.map +1 -1
- package/dist/formatting/NumberingInstance.d.ts +6 -0
- package/dist/formatting/NumberingInstance.d.ts.map +1 -1
- package/dist/formatting/NumberingInstance.js +55 -1
- package/dist/formatting/NumberingInstance.js.map +1 -1
- package/dist/formatting/NumberingLevel.d.ts +4 -1
- package/dist/formatting/NumberingLevel.d.ts.map +1 -1
- package/dist/formatting/NumberingLevel.js +17 -0
- package/dist/formatting/NumberingLevel.js.map +1 -1
- package/dist/formatting/Style.d.ts +6 -0
- package/dist/formatting/Style.d.ts.map +1 -1
- package/dist/formatting/Style.js +20 -0
- package/dist/formatting/Style.js.map +1 -1
- package/dist/formatting/StylesManager.d.ts +23 -0
- package/dist/formatting/StylesManager.d.ts.map +1 -1
- package/dist/formatting/StylesManager.js +65 -0
- package/dist/formatting/StylesManager.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/tracking/DocumentTrackingContext.d.ts.map +1 -1
- package/dist/tracking/DocumentTrackingContext.js +30 -7
- package/dist/tracking/DocumentTrackingContext.js.map +1 -1
- package/package.json +1 -1
- package/src/core/Document.ts +287 -31
- package/src/core/DocumentParser.ts +88 -7
- package/src/elements/Hyperlink.ts +47 -0
- package/src/elements/StructuredDocumentTag.ts +230 -1
- package/src/elements/TableCell.ts +36 -1
- package/src/elements/TableRow.ts +24 -1
- package/src/formatting/AbstractNumbering.ts +31 -0
- package/src/formatting/NumberingInstance.ts +88 -1
- package/src/formatting/NumberingLevel.ts +37 -3
- package/src/formatting/Style.ts +46 -0
- package/src/formatting/StylesManager.ts +125 -0
- package/src/index.ts +2 -2
- package/src/tracking/DocumentTrackingContext.ts +38 -7
|
@@ -10,6 +10,7 @@ export interface HyperlinkProperties {
|
|
|
10
10
|
isEmpty?: boolean;
|
|
11
11
|
tgtFrame?: string;
|
|
12
12
|
history?: string;
|
|
13
|
+
docLocation?: string;
|
|
13
14
|
}
|
|
14
15
|
export declare class Hyperlink {
|
|
15
16
|
private url?;
|
|
@@ -22,6 +23,7 @@ export declare class Hyperlink {
|
|
|
22
23
|
private _isEmpty;
|
|
23
24
|
private tgtFrame?;
|
|
24
25
|
private history?;
|
|
26
|
+
private docLocation?;
|
|
25
27
|
private trackingContext?;
|
|
26
28
|
private _parentParagraph?;
|
|
27
29
|
constructor(properties: HyperlinkProperties);
|
|
@@ -34,6 +36,10 @@ export declare class Hyperlink {
|
|
|
34
36
|
isEmpty(): boolean;
|
|
35
37
|
getTgtFrame(): string | undefined;
|
|
36
38
|
getHistory(): string | undefined;
|
|
39
|
+
setTgtFrame(tgtFrame: string | undefined): this;
|
|
40
|
+
setHistory(history: string | undefined): this;
|
|
41
|
+
getDocLocation(): string | undefined;
|
|
42
|
+
setDocLocation(docLocation: string | undefined): this;
|
|
37
43
|
getText(): string;
|
|
38
44
|
setText(text: string): this;
|
|
39
45
|
setRun(run: Run): this;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Hyperlink.d.ts","sourceRoot":"","sources":["../../src/elements/Hyperlink.ts"],"names":[],"mappings":"AAkDA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAQ3C,MAAM,WAAW,mBAAmB;IAElC,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,UAAU,CAAC,EAAE,aAAa,CAAC;IAE3B,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,OAAO,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"Hyperlink.d.ts","sourceRoot":"","sources":["../../src/elements/Hyperlink.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,7 @@ class Hyperlink {
|
|
|
16
16
|
_isEmpty = false;
|
|
17
17
|
tgtFrame;
|
|
18
18
|
history;
|
|
19
|
+
docLocation;
|
|
19
20
|
trackingContext;
|
|
20
21
|
_parentParagraph;
|
|
21
22
|
constructor(properties) {
|
|
@@ -25,6 +26,7 @@ class Hyperlink {
|
|
|
25
26
|
this.relationshipId = properties.relationshipId;
|
|
26
27
|
this.tgtFrame = properties.tgtFrame;
|
|
27
28
|
this.history = properties.history;
|
|
29
|
+
this.docLocation = properties.docLocation;
|
|
28
30
|
this._isEmpty = properties.isEmpty ?? false;
|
|
29
31
|
if (this.url && this.anchor) {
|
|
30
32
|
logger_1.defaultLogger.warn(`DocXML Warning: Hyperlink has both URL ("${this.url}") and anchor ("${this.anchor}"). ` +
|
|
@@ -85,6 +87,21 @@ class Hyperlink {
|
|
|
85
87
|
getHistory() {
|
|
86
88
|
return this.history;
|
|
87
89
|
}
|
|
90
|
+
setTgtFrame(tgtFrame) {
|
|
91
|
+
this.tgtFrame = tgtFrame;
|
|
92
|
+
return this;
|
|
93
|
+
}
|
|
94
|
+
setHistory(history) {
|
|
95
|
+
this.history = history;
|
|
96
|
+
return this;
|
|
97
|
+
}
|
|
98
|
+
getDocLocation() {
|
|
99
|
+
return this.docLocation;
|
|
100
|
+
}
|
|
101
|
+
setDocLocation(docLocation) {
|
|
102
|
+
this.docLocation = docLocation;
|
|
103
|
+
return this;
|
|
104
|
+
}
|
|
88
105
|
getText() {
|
|
89
106
|
return this.run.getText();
|
|
90
107
|
}
|
|
@@ -429,6 +446,9 @@ class Hyperlink {
|
|
|
429
446
|
tooltip: this.tooltip,
|
|
430
447
|
relationshipId: this.relationshipId,
|
|
431
448
|
formatting: { ...this.formatting },
|
|
449
|
+
tgtFrame: this.tgtFrame,
|
|
450
|
+
history: this.history,
|
|
451
|
+
docLocation: this.docLocation,
|
|
432
452
|
});
|
|
433
453
|
if (this.run) {
|
|
434
454
|
cloned.run = new Run_1.Run(this.run.getText(), { ...this.run.getFormatting() });
|
|
@@ -462,6 +482,9 @@ class Hyperlink {
|
|
|
462
482
|
if (this.history) {
|
|
463
483
|
attributes["w:history"] = this.history;
|
|
464
484
|
}
|
|
485
|
+
if (this.docLocation) {
|
|
486
|
+
attributes["w:docLocation"] = this.docLocation;
|
|
487
|
+
}
|
|
465
488
|
if (this._isEmpty) {
|
|
466
489
|
return {
|
|
467
490
|
name: "w:hyperlink",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Hyperlink.js","sourceRoot":"","sources":["../../src/elements/Hyperlink.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * Hyperlink - Represents a hyperlink in a Word document\r\n *\r\n * Hyperlinks can be external (to websites, files) or internal (to bookmarks within the document).\r\n * They are represented using the `<w:hyperlink>` element.\r\n *\r\n * ## Important: Relationship ID Requirement\r\n *\r\n * **External hyperlinks REQUIRE a relationship ID to be set before XML generation.**\r\n * Per ECMA-376 Part 1 §17.16.22, `<w:hyperlink>` elements with external targets must have\r\n * an `r:id` attribute that references a relationship in `word/_rels/document.xml.rels`.\r\n *\r\n * ### Correct Usage Pattern:\r\n *\r\n * ```typescript\r\n * // RECOMMENDED: Use Document.save() - automatically handles relationships\r\n * const doc = Document.create();\r\n * const para = doc.createParagraph();\r\n * para.addHyperlink(Hyperlink.createExternal('https://example.com', 'Link'));\r\n * await doc.save('document.docx'); // ✅ Relationships auto-registered\r\n * ```\r\n *\r\n * ### Manual Relationship Registration (Advanced):\r\n *\r\n * ```typescript\r\n * const link = Hyperlink.createExternal('https://example.com', 'Link');\r\n * const relationship = relationshipManager.addHyperlink('https://example.com');\r\n * link.setRelationshipId(relationship.getId());\r\n * link.toXML(); // ✅ Now valid\r\n * ```\r\n *\r\n * ### What NOT to Do:\r\n *\r\n * ```typescript\r\n * const link = Hyperlink.createExternal('https://example.com', 'Link');\r\n * link.toXML(); // ❌ ERROR: Missing relationship ID\r\n * ```\r\n *\r\n * ## Internal Hyperlinks\r\n *\r\n * Internal hyperlinks (bookmarks) do NOT require relationships:\r\n *\r\n * ```typescript\r\n * const link = Hyperlink.createInternal('Section1', 'Go to Section 1');\r\n * link.toXML(); // ✅ Valid - uses w:anchor attribute\r\n * ```\r\n *\r\n * @see {@link https://www.ecma-international.org/publications-and-standards/standards/ecma-376/ | ECMA-376 Part 1 §17.16.22}\r\n */\r\n\r\nimport { XMLElement } from \"../xml/XMLBuilder\";\r\nimport { Run, RunFormatting } from \"./Run\";\r\nimport { Revision } from \"./Revision\";\r\nimport { validateRunText } from \"../utils/validation\";\r\nimport { defaultLogger } from \"../utils/logger\";\r\n\r\n/**\r\n * Hyperlink properties\r\n */\r\nexport interface HyperlinkProperties {\r\n /** Hyperlink URL (for external links) */\r\n url?: string;\r\n /** Bookmark anchor (for internal links) */\r\n anchor?: string;\r\n /** Display text (optional for empty/invisible hyperlinks) */\r\n text?: string;\r\n /** Text formatting */\r\n formatting?: RunFormatting;\r\n /** Tooltip text */\r\n tooltip?: string;\r\n /** Relationship ID (set by Document when saving) */\r\n relationshipId?: string;\r\n /** Whether this is an empty/invisible hyperlink with no display text */\r\n isEmpty?: boolean;\r\n /** Target frame attribute (e.g., \"_blank\" for new window) */\r\n tgtFrame?: string;\r\n /** History tracking attribute */\r\n history?: string;\r\n}\r\n\r\n/**\r\n * Represents a hyperlink\r\n */\r\nexport class Hyperlink {\r\n private url?: string;\r\n private anchor?: string;\r\n private text: string;\r\n private run: Run;\r\n private tooltip?: string;\r\n private relationshipId?: string;\r\n private formatting: RunFormatting;\r\n /** Whether this is an empty/invisible hyperlink with no display text */\r\n private _isEmpty = false;\r\n /** Target frame attribute (e.g., \"_blank\" for new window) */\r\n private tgtFrame?: string;\r\n /** History tracking attribute */\r\n private history?: string;\r\n /** Tracking context for automatic change tracking */\r\n private trackingContext?: import('../tracking/TrackingContext').TrackingContext;\r\n /** Parent paragraph reference for automatic tracking */\r\n private _parentParagraph?: import('./Paragraph').Paragraph;\r\n\r\n /**\r\n * Creates a new hyperlink\r\n *\r\n * **Note:** A hyperlink must have either a URL (external) or anchor (internal), but not both.\r\n * If both are provided, the URL takes precedence and a warning is logged.\r\n *\r\n * @param properties Hyperlink properties\r\n */\r\n constructor(properties: HyperlinkProperties) {\r\n this.url = properties.url;\r\n this.anchor = properties.anchor;\r\n this.tooltip = properties.tooltip;\r\n this.relationshipId = properties.relationshipId;\r\n this.tgtFrame = properties.tgtFrame;\r\n this.history = properties.history;\r\n this._isEmpty = properties.isEmpty ?? false;\r\n\r\n // VALIDATION: Warn about hybrid links (url + anchor)\r\n if (this.url && this.anchor) {\r\n defaultLogger.warn(\r\n `DocXML Warning: Hyperlink has both URL (\"${this.url}\") and anchor (\"${this.anchor}\"). ` +\r\n `This is ambiguous per ECMA-376 spec. URL will take precedence. ` +\r\n `Use Hyperlink.createExternal() or Hyperlink.createInternal() to avoid ambiguity.`\r\n );\r\n }\r\n\r\n // Handle empty/invisible hyperlinks (no display text)\r\n if (this._isEmpty) {\r\n this.text = \"\";\r\n this.formatting = {};\r\n this.run = new Run(\"\", {});\r\n return;\r\n }\r\n\r\n // Text fallback: properties.text → url → 'Link'\r\n // NOTE: Do NOT use anchor (bookmark ID) as display text - it should only be used for navigation\r\n // Using bookmark IDs as visible text causes TOC corruption (Issue: TOC shows \"HEADING=II.MNKE7E8NA385_\" instead of proper headings)\r\n this.text = properties.text || this.url || \"Link\";\r\n\r\n // Validate text for XML patterns\r\n // Default to auto-cleaning XML patterns unless explicitly disabled (matches Run behavior)\r\n const validation = validateRunText(this.text, {\r\n context: \"Hyperlink text\",\r\n autoClean: properties.formatting?.cleanXmlFromText !== false,\r\n warnToConsole: true,\r\n });\r\n\r\n // Use cleaned text if available and cleaning was requested\r\n if (validation.cleanedText) {\r\n this.text = validation.cleanedText;\r\n }\r\n\r\n // Create run with default hyperlink styling (Verdana 12pt blue underlined)\r\n this.formatting = {\r\n font: \"Verdana\",\r\n size: 12,\r\n color: \"0000FF\", // Standard hyperlink blue\r\n underline: \"single\",\r\n ...properties.formatting,\r\n };\r\n\r\n this.run = new Run(this.text, this.formatting);\r\n }\r\n\r\n /**\r\n * Sets the tracking context for automatic change tracking.\r\n * Called by Document when track changes is enabled.\r\n * @internal\r\n */\r\n _setTrackingContext(context: import('../tracking/TrackingContext').TrackingContext): void {\r\n this.trackingContext = context;\r\n }\r\n\r\n /**\r\n * Sets the parent paragraph reference for automatic tracking.\r\n * Called by Paragraph when hyperlink is added.\r\n * @internal\r\n */\r\n _setParentParagraph(paragraph: import('./Paragraph').Paragraph): void {\r\n this._parentParagraph = paragraph;\r\n }\r\n\r\n /**\r\n * Gets the parent paragraph reference.\r\n * @internal\r\n */\r\n _getParentParagraph(): import('./Paragraph').Paragraph | undefined {\r\n return this._parentParagraph;\r\n }\r\n\r\n /**\r\n * Gets the hyperlink URL\r\n */\r\n getUrl(): string | undefined {\r\n return this.url;\r\n }\r\n\r\n /**\r\n * Gets the complete URL including any anchor fragment.\r\n *\r\n * For external links that also have an anchor (e.g., internal bookmark within external page),\r\n * this returns the URL with the anchor appended as a fragment.\r\n * For internal-only links (anchor without URL), returns undefined.\r\n *\r\n * Note: As of v7.2.0, DocumentParser automatically combines external URLs with anchors\r\n * during parsing, so getUrl() typically returns the full URL. This method is provided\r\n * for cases where URL and anchor are set separately via the API.\r\n *\r\n * @returns The complete URL with fragment, or undefined for internal-only links\r\n *\r\n * @example\r\n * ```typescript\r\n * // External link with anchor fragment\r\n * const link = new Hyperlink({ url: 'https://example.com/', anchor: '!/view?id=123', text: 'Link' });\r\n * link.getUrl(); // 'https://example.com/'\r\n * link.getAnchor(); // '!/view?id=123'\r\n * link.getFullUrl(); // 'https://example.com/#!/view?id=123'\r\n *\r\n * // External link without anchor\r\n * const link2 = Hyperlink.createExternal('https://example.com/page', 'Link');\r\n * link2.getFullUrl(); // 'https://example.com/page'\r\n *\r\n * // Internal link (bookmark reference)\r\n * const link3 = Hyperlink.createInternal('Section1', 'Go to Section 1');\r\n * link3.getFullUrl(); // undefined\r\n * ```\r\n */\r\n getFullUrl(): string | undefined {\r\n if (this.url && this.anchor) {\r\n return this.url + '#' + this.anchor;\r\n }\r\n return this.url;\r\n }\r\n\r\n /**\r\n * Gets the anchor (for internal links)\r\n */\r\n getAnchor(): string | undefined {\r\n return this.anchor;\r\n }\r\n\r\n /**\r\n * Returns whether this is an empty/invisible hyperlink (has no display text).\r\n * Empty hyperlinks are self-closing elements in the XML.\r\n */\r\n isEmpty(): boolean {\r\n return this._isEmpty;\r\n }\r\n\r\n /**\r\n * Gets the target frame attribute (e.g., \"_blank\" for new window)\r\n */\r\n getTgtFrame(): string | undefined {\r\n return this.tgtFrame;\r\n }\r\n\r\n /**\r\n * Gets the history tracking attribute\r\n */\r\n getHistory(): string | undefined {\r\n return this.history;\r\n }\r\n\r\n /**\r\n * Gets the display text\r\n *\r\n * This method delegates to the internal run to ensure the returned text\r\n * is always accurate and matches what will be in the generated XML,\r\n * per ECMA-376 Part 1 §17.16.22.\r\n *\r\n * @returns The display text including any special characters (tabs, breaks, etc.)\r\n */\r\n getText(): string {\r\n return this.run.getText();\r\n }\r\n\r\n /**\r\n * Sets the display text\r\n */\r\n setText(text: string): this {\r\n // Validate text for XML patterns\r\n // Default to auto-cleaning unless explicitly disabled (matches Run behavior)\r\n const validation = validateRunText(text, {\r\n context: \"Hyperlink.setText\",\r\n autoClean: this.formatting.cleanXmlFromText !== false,\r\n warnToConsole: true,\r\n });\r\n\r\n // Use cleaned text if available\r\n const cleanedText = validation.cleanedText || text;\r\n\r\n const previousValue = this.text;\r\n this.text = cleanedText;\r\n this.run.setText(cleanedText); // Run.setText also validates\r\n if (this.trackingContext?.isEnabled() && previousValue !== cleanedText) {\r\n this.trackingContext.trackHyperlinkChange(this, 'text', previousValue, cleanedText);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets the internal run directly (for advanced use cases like TOC parsing)\r\n * Used by DocumentParser to preserve run content (tabs, breaks, etc.)\r\n * @param run - The run to use for this hyperlink\r\n */\r\n setRun(run: Run): this {\r\n this.run = run;\r\n this.text = run.getText();\r\n return this;\r\n }\r\n\r\n /**\r\n * Gets the tooltip\r\n */\r\n getTooltip(): string | undefined {\r\n return this.tooltip;\r\n }\r\n\r\n /**\r\n * Sets the tooltip\r\n */\r\n setTooltip(tooltip: string): this {\r\n const previousValue = this.tooltip;\r\n this.tooltip = tooltip;\r\n if (this.trackingContext?.isEnabled() && previousValue !== tooltip) {\r\n this.trackingContext.trackHyperlinkChange(this, 'tooltip', previousValue, tooltip);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Gets the relationship ID\r\n */\r\n getRelationshipId(): string | undefined {\r\n return this.relationshipId;\r\n }\r\n\r\n /**\r\n * Sets the relationship ID (called by Document during save)\r\n */\r\n setRelationshipId(id: string): this {\r\n this.relationshipId = id;\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets or updates the hyperlink URL\r\n *\r\n * When URL is updated, we mark that the relationship needs updating.\r\n * The actual relationship update happens during Document.save() to ensure\r\n * proper coordination with the RelationshipManager.\r\n *\r\n * **Important:** This method maintains the relationship ID but flags it for update.\r\n * The RelationshipManager will update the existing relationship's target URL\r\n * during save, preventing orphaned relationships per ECMA-376 §17.16.22.\r\n *\r\n * @param url - The new URL (or undefined to clear)\r\n * @returns This hyperlink for chaining\r\n * @throws {Error} If clearing URL would create empty hyperlink (no URL and no anchor)\r\n *\r\n * @example\r\n * ```typescript\r\n * const link = Hyperlink.createExternal('https://old.com', 'Link');\r\n * link.setUrl('https://new.com'); // Marks for relationship update\r\n * await doc.save('updated.docx'); // Updates relationship target\r\n * ```\r\n */\r\n setUrl(url: string | undefined): this {\r\n // Validate that clearing URL doesn't create empty hyperlink\r\n if (!url && !this.anchor) {\r\n throw new Error(\r\n `Cannot set URL to undefined: Hyperlink \"${this.run.getText()}\" has no anchor. ` +\r\n `Clearing the URL would create an invalid hyperlink per ECMA-376 §17.16.22. ` +\r\n `Either provide a new URL or delete the hyperlink entirely.`\r\n );\r\n }\r\n\r\n // Save old URL before updating (for text fallback logic)\r\n const oldUrl = this.url;\r\n\r\n // Skip if URL unchanged (optimization)\r\n if (oldUrl === url) {\r\n return this;\r\n }\r\n\r\n // If tracking enabled AND has parent paragraph, create revision pair\r\n // OOXML has no w:hyperlinkChange element - Word tracks hyperlink changes as delete/insert pairs\r\n if (this.trackingContext?.isEnabled() && this._parentParagraph) {\r\n const author = this.trackingContext.getAuthor();\r\n\r\n // Clone current state for deletion (before applying changes)\r\n const oldHyperlink = this.clone();\r\n\r\n // Apply the change to this hyperlink\r\n this.url = url;\r\n this.relationshipId = undefined;\r\n if (this.run.getText() === oldUrl) {\r\n this.text = url || this.anchor || \"Link\";\r\n this.run.setText(this.text);\r\n }\r\n\r\n // Create delete/insert revision pair\r\n const deletion = Revision.createDeletion(author, [oldHyperlink]);\r\n const insertion = Revision.createInsertion(author, [this]);\r\n\r\n // Replace this hyperlink with the revision pair in parent paragraph\r\n this._parentParagraph.replaceContent(this, [deletion, insertion]);\r\n\r\n // Clear parent reference since we're now inside a revision\r\n this._parentParagraph = undefined;\r\n\r\n return this;\r\n }\r\n\r\n // Non-tracking path (original behavior)\r\n this.url = url;\r\n\r\n // Clear the relationship ID so it will be re-registered during save\r\n // This ensures the relationship target is updated to point to the new URL\r\n this.relationshipId = undefined;\r\n\r\n // Update text ONLY if it was auto-generated from the old URL\r\n // This preserves user-provided text (even if it's \"Link\")\r\n // Use run.getText() to ensure we check the actual current text, not stale cache\r\n if (this.run.getText() === oldUrl) {\r\n this.text = url || this.anchor || \"Link\";\r\n this.run.setText(this.text);\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets the anchor (for internal links)\r\n * @param anchor Bookmark name to link to\r\n * @returns This hyperlink for chaining\r\n * @throws {Error} If clearing anchor would create empty hyperlink (no URL and no anchor)\r\n * @example\r\n * ```typescript\r\n * const link = Hyperlink.createInternal('OldBookmark', 'Go there');\r\n * link.setAnchor('NewBookmark'); // Update internal link target\r\n * ```\r\n */\r\n setAnchor(anchor: string | undefined): this {\r\n // Validate that clearing anchor doesn't create empty hyperlink\r\n if (!anchor && !this.url) {\r\n throw new Error(\r\n `Cannot set anchor to undefined: Hyperlink \"${this.run.getText()}\" has no URL. ` +\r\n `Clearing the anchor would create an invalid hyperlink per ECMA-376 §17.16.22. ` +\r\n `Either provide a new anchor or delete the hyperlink entirely.`\r\n );\r\n }\r\n\r\n // Save old anchor before updating\r\n const oldAnchor = this.anchor;\r\n\r\n // Skip if anchor unchanged (optimization)\r\n if (oldAnchor === anchor) {\r\n return this;\r\n }\r\n\r\n // If tracking enabled AND has parent paragraph, create revision pair\r\n // OOXML has no w:hyperlinkChange element - Word tracks hyperlink changes as delete/insert pairs\r\n if (this.trackingContext?.isEnabled() && this._parentParagraph) {\r\n const author = this.trackingContext.getAuthor();\r\n\r\n // Clone current state for deletion (before applying changes)\r\n const oldHyperlink = this.clone();\r\n\r\n // Apply the change to this hyperlink\r\n this.anchor = anchor;\r\n if (anchor && this.url) {\r\n defaultLogger.warn(\r\n `DocXML Warning: Setting anchor \"${anchor}\" on hyperlink that has URL \"${this.url}\". ` +\r\n `Clearing URL to make this an internal link. Use separate hyperlinks for external and internal links.`\r\n );\r\n this.url = undefined;\r\n this.relationshipId = undefined;\r\n }\r\n if (this.run.getText() === oldAnchor) {\r\n this.text = anchor || this.url || \"Link\";\r\n this.run.setText(this.text);\r\n }\r\n\r\n // Create delete/insert revision pair\r\n const deletion = Revision.createDeletion(author, [oldHyperlink]);\r\n const insertion = Revision.createInsertion(author, [this]);\r\n\r\n // Replace this hyperlink with the revision pair in parent paragraph\r\n this._parentParagraph.replaceContent(this, [deletion, insertion]);\r\n\r\n // Clear parent reference since we're now inside a revision\r\n this._parentParagraph = undefined;\r\n\r\n return this;\r\n }\r\n\r\n // Non-tracking path (original behavior)\r\n this.anchor = anchor;\r\n\r\n // If converting from external to internal, clear URL and relationship\r\n if (anchor && this.url) {\r\n defaultLogger.warn(\r\n `DocXML Warning: Setting anchor \"${anchor}\" on hyperlink that has URL \"${this.url}\". ` +\r\n `Clearing URL to make this an internal link. Use separate hyperlinks for external and internal links.`\r\n );\r\n this.url = undefined;\r\n this.relationshipId = undefined;\r\n }\r\n\r\n // Update text ONLY if it was auto-generated from the old anchor\r\n // Use run.getText() to ensure we check the actual current text, not stale cache\r\n if (this.run.getText() === oldAnchor) {\r\n this.text = anchor || this.url || \"Link\";\r\n this.run.setText(this.text);\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Gets the run\r\n */\r\n getRun(): Run {\r\n return this.run;\r\n }\r\n\r\n /**\r\n * Sets run formatting\r\n *\r\n * @param formatting - The formatting to apply\r\n * @param options - Optional settings\r\n * @param options.replace - If true, replaces ALL existing formatting instead of merging.\r\n * Use this when you want to clear inherited styles like characterStyle.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Merge mode (default): adds/updates properties while preserving others\r\n * hyperlink.setFormatting({ bold: true });\r\n *\r\n * // Replace mode: clears all existing formatting and applies only the new properties\r\n * hyperlink.setFormatting({ font: \"Verdana\", size: 12 }, { replace: true });\r\n * ```\r\n */\r\n setFormatting(formatting: RunFormatting, options?: { replace?: boolean }): this {\r\n // Update stored formatting\r\n const previousValue = { ...this.formatting };\r\n if (options?.replace) {\r\n // Replace mode: new formatting replaces ALL existing properties\r\n this.formatting = { ...formatting };\r\n } else {\r\n // Merge mode (default, backwards-compatible): merge with existing\r\n this.formatting = { ...this.formatting, ...formatting };\r\n }\r\n // Create new run with updated formatting, preserving current text\r\n const currentText = this.run.getText();\r\n this.run = new Run(currentText, this.formatting);\r\n this.text = currentText; // Keep cache in sync\r\n if (this.trackingContext?.isEnabled()) {\r\n this.trackingContext.trackHyperlinkChange(this, 'formatting', previousValue, this.formatting);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Gets run formatting (returns this hyperlink for fluent API)\r\n * @returns This hyperlink for method chaining\r\n *\r\n * @example\r\n * ```typescript\r\n * hyperlink.getFormatting().setColor('0563C1').setUnderline('single');\r\n * ```\r\n */\r\n getFormatting(): this {\r\n return this;\r\n }\r\n\r\n /**\r\n * Gets the raw formatting object (for direct access)\r\n * @returns RunFormatting object\r\n */\r\n getRawFormatting(): RunFormatting {\r\n return this.formatting;\r\n }\r\n\r\n // ============================================================================\r\n // Individual Formatting Getters\r\n // ============================================================================\r\n\r\n /**\r\n * Gets the text color\r\n * @returns Color hex string or undefined\r\n */\r\n getColor(): string | undefined {\r\n return this.formatting.color;\r\n }\r\n\r\n /**\r\n * Gets the underline style\r\n * @returns Underline style or undefined\r\n */\r\n getUnderline(): string | boolean | undefined {\r\n return this.formatting.underline;\r\n }\r\n\r\n /**\r\n * Gets whether the hyperlink is bold\r\n * @returns True if bold, false otherwise\r\n */\r\n getBold(): boolean {\r\n return this.formatting.bold ?? false;\r\n }\r\n\r\n /**\r\n * Gets whether the hyperlink is italic\r\n * @returns True if italic, false otherwise\r\n */\r\n getItalic(): boolean {\r\n return this.formatting.italic ?? false;\r\n }\r\n\r\n /**\r\n * Gets the font family\r\n * @returns Font name or undefined\r\n */\r\n getFont(): string | undefined {\r\n return this.formatting.font;\r\n }\r\n\r\n /**\r\n * Gets the font size\r\n * @returns Font size in points or undefined\r\n */\r\n getSize(): number | undefined {\r\n return this.formatting.size;\r\n }\r\n\r\n /**\r\n * Sets text color\r\n * @param color Color in hex format (e.g., '0563C1')\r\n * @returns This hyperlink for chaining\r\n */\r\n setColor(color: string): this {\r\n const previousValue = this.formatting.color;\r\n this.formatting.color = color;\r\n this.run = new Run(this.text, this.formatting);\r\n if (this.trackingContext?.isEnabled() && previousValue !== color) {\r\n this.trackingContext.trackHyperlinkChange(this, 'color', previousValue, color);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets underline style\r\n * @param underline Underline style ('single', 'double', etc.)\r\n * @returns This hyperlink for chaining\r\n */\r\n setUnderline(underline: boolean | \"single\" | \"double\" | \"dotted\" | \"thick\" | \"dash\"): this {\r\n const previousValue = this.formatting.underline;\r\n this.formatting.underline = underline;\r\n this.run = new Run(this.text, this.formatting);\r\n if (this.trackingContext?.isEnabled() && previousValue !== underline) {\r\n this.trackingContext.trackHyperlinkChange(this, 'underline', previousValue, underline);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets bold formatting\r\n * @param bold Bold state (default: true)\r\n * @returns This hyperlink for chaining\r\n */\r\n setBold(bold = true): this {\r\n const previousValue = this.formatting.bold;\r\n this.formatting.bold = bold;\r\n this.run = new Run(this.text, this.formatting);\r\n if (this.trackingContext?.isEnabled() && previousValue !== bold) {\r\n this.trackingContext.trackHyperlinkChange(this, 'bold', previousValue, bold);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets italic formatting\r\n * @param italic Italic state (default: true)\r\n * @returns This hyperlink for chaining\r\n */\r\n setItalic(italic = true): this {\r\n const previousValue = this.formatting.italic;\r\n this.formatting.italic = italic;\r\n this.run = new Run(this.text, this.formatting);\r\n if (this.trackingContext?.isEnabled() && previousValue !== italic) {\r\n this.trackingContext.trackHyperlinkChange(this, 'italic', previousValue, italic);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets font family\r\n * @param font Font name (e.g., 'Arial', 'Verdana')\r\n * @returns This hyperlink for chaining\r\n */\r\n setFont(font: string): this {\r\n const previousValue = this.formatting.font;\r\n this.formatting.font = font;\r\n this.run = new Run(this.text, this.formatting);\r\n if (this.trackingContext?.isEnabled() && previousValue !== font) {\r\n this.trackingContext.trackHyperlinkChange(this, 'font', previousValue, font);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets font size\r\n * @param size Font size in points (e.g., 12, 14)\r\n * @returns This hyperlink for chaining\r\n */\r\n setSize(size: number): this {\r\n const previousValue = this.formatting.size;\r\n this.formatting.size = size;\r\n this.run = new Run(this.text, this.formatting);\r\n if (this.trackingContext?.isEnabled() && previousValue !== size) {\r\n this.trackingContext.trackHyperlinkChange(this, 'size', previousValue, size);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Validates the hyperlink URL and optionally fixes common issues\r\n *\r\n * Performs validation and fixing of hyperlink URLs including:\r\n * - Checking URL accessibility (HTTP HEAD request for external links)\r\n * - Fixing common URL issues (missing protocol, double slashes, spaces)\r\n * - Validating internal bookmark references\r\n * - Detecting broken links\r\n *\r\n * **Note:** This method is async due to network requests for accessibility checks.\r\n *\r\n * @param options - Validation options\r\n * @returns Promise with validation results\r\n *\r\n * @example\r\n * ```typescript\r\n * // Basic URL fixing without network check\r\n * const result = await link.validateAndFix({\r\n * fixCommonIssues: true,\r\n * checkAccessibility: false\r\n * });\r\n * console.log(`Fixed: ${result.fixed.join(', ')}`);\r\n *\r\n * // Full validation with accessibility check\r\n * const validation = await link.validateAndFix({\r\n * checkAccessibility: true,\r\n * timeout: 5000\r\n * });\r\n * if (!validation.valid) {\r\n * console.log(`Issues: ${validation.issues.join(', ')}`);\r\n * }\r\n *\r\n * // Batch validate all hyperlinks in document\r\n * for (const { hyperlink } of doc.getHyperlinks()) {\r\n * const result = await hyperlink.validateAndFix();\r\n * if (result.fixed.length > 0) {\r\n * console.log(`Fixed ${hyperlink.getUrl()}: ${result.fixed.join(', ')}`);\r\n * }\r\n * }\r\n * ```\r\n */\r\n async validateAndFix(options?: {\r\n checkAccessibility?: boolean;\r\n fixCommonIssues?: boolean;\r\n timeout?: number;\r\n bookmarkManager?: { hasBookmark(name: string): boolean };\r\n }): Promise<{\r\n valid: boolean;\r\n issues: string[];\r\n fixed: string[];\r\n originalUrl?: string;\r\n fixedUrl?: string;\r\n }> {\r\n const {\r\n checkAccessibility = false,\r\n fixCommonIssues = true,\r\n timeout = 5000,\r\n bookmarkManager,\r\n } = options || {};\r\n\r\n const issues: string[] = [];\r\n const fixed: string[] = [];\r\n let fixedUrl = this.url;\r\n const originalUrl = this.url;\r\n\r\n // Internal link validation (bookmarks)\r\n if (this.anchor) {\r\n if (bookmarkManager) {\r\n const bookmarkExists = bookmarkManager.hasBookmark(this.anchor);\r\n if (!bookmarkExists) {\r\n issues.push(`Internal bookmark \"${this.anchor}\" not found`);\r\n }\r\n }\r\n return {\r\n valid: issues.length === 0,\r\n issues,\r\n fixed,\r\n originalUrl,\r\n };\r\n }\r\n\r\n // External link validation\r\n if (!this.url) {\r\n issues.push(\"No URL or anchor specified\");\r\n return { valid: false, issues, fixed, originalUrl };\r\n }\r\n\r\n // Fix common issues\r\n if (fixCommonIssues && fixedUrl) {\r\n // Fix 1: Add missing protocol\r\n if (!(/^[a-z]+:\\/\\//i.exec(fixedUrl))) {\r\n fixedUrl = \"https://\" + fixedUrl;\r\n fixed.push(\"Added missing protocol (https://)\");\r\n }\r\n\r\n // Fix 2: Fix double slashes (except after protocol)\r\n const protocolMatch = /^([a-z]+:\\/\\/)/i.exec(fixedUrl);\r\n if (protocolMatch?.[1]) {\r\n const protocol = protocolMatch[1];\r\n const rest = fixedUrl.substring(protocol.length);\r\n const fixedRest = rest.replace(/\\/\\//g, \"/\");\r\n if (rest !== fixedRest) {\r\n fixedUrl = protocol + fixedRest;\r\n fixed.push(\"Fixed double slashes\");\r\n }\r\n }\r\n\r\n // Fix 3: Encode spaces\r\n if (fixedUrl.includes(\" \")) {\r\n fixedUrl = fixedUrl.replace(/ /g, \"%20\");\r\n fixed.push(\"Encoded spaces as %20\");\r\n }\r\n\r\n // Fix 4: Remove trailing slashes for non-root URLs\r\n if (/^https?:\\/\\/[^/]+\\/.+\\/$/.exec(fixedUrl)) {\r\n fixedUrl = fixedUrl.replace(/\\/$/, \"\");\r\n fixed.push(\"Removed trailing slash\");\r\n }\r\n\r\n // Fix 5: Fix common typos\r\n fixedUrl = fixedUrl.replace(/^http:\\/\\//i, \"https://\"); // Prefer HTTPS\r\n if (fixedUrl !== this.url && fixedUrl.startsWith(\"https://\")) {\r\n fixed.push(\"Upgraded HTTP to HTTPS\");\r\n }\r\n\r\n // Update URL if fixes were applied\r\n if (fixedUrl !== this.url) {\r\n this.setUrl(fixedUrl);\r\n }\r\n }\r\n\r\n // Check accessibility (HTTP HEAD request)\r\n if (checkAccessibility && fixedUrl?.match(/^https?:\\/\\//i)) {\r\n // Check if fetch is available (Node.js 18+ or browser)\r\n if (typeof fetch === \"undefined\") {\r\n issues.push(\r\n \"Network validation unavailable: fetch API not supported in this environment\"\r\n );\r\n } else {\r\n try {\r\n // Use fetch with AbortController for timeout\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), timeout);\r\n\r\n const response = await fetch(fixedUrl, {\r\n method: \"HEAD\",\r\n signal: controller.signal,\r\n redirect: \"follow\",\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (!response.ok) {\r\n issues.push(\r\n `HTTP ${response.status}: ${response.statusText || \"Error\"}`\r\n );\r\n }\r\n } catch (error: unknown) {\r\n // Type guard for error objects with name and message properties\r\n const isErrorWithName = (err: unknown): err is { name: string } => {\r\n return typeof err === \"object\" && err !== null && \"name\" in err;\r\n };\r\n const isErrorWithMessage = (\r\n err: unknown\r\n ): err is { message: string } => {\r\n return typeof err === \"object\" && err !== null && \"message\" in err;\r\n };\r\n\r\n if (isErrorWithName(error) && error.name === \"AbortError\") {\r\n issues.push(`Timeout after ${timeout}ms`);\r\n } else if (\r\n isErrorWithMessage(error) &&\r\n error.message?.includes(\"fetch\")\r\n ) {\r\n issues.push(`Unreachable: ${error.message}`);\r\n } else if (isErrorWithMessage(error)) {\r\n issues.push(`Network error: ${error.message}`);\r\n } else {\r\n issues.push(\"Network error: Unknown error\");\r\n }\r\n }\r\n }\r\n }\r\n\r\n return {\r\n valid: issues.length === 0,\r\n issues,\r\n fixed,\r\n originalUrl,\r\n fixedUrl: fixedUrl !== originalUrl ? fixedUrl : undefined,\r\n };\r\n }\r\n\r\n /**\r\n * Resets hyperlink formatting to standard style (Calibri, blue, underline)\r\n * This is useful for fixing corrupted hyperlinks from Google Docs or other sources\r\n * @returns this for method chaining\r\n */\r\n resetToStandardFormatting(): this {\r\n const standardFormatting: RunFormatting = {\r\n font: \"Verdana\",\r\n color: \"0000FF\", // Standard hyperlink blue\r\n underline: \"single\",\r\n // Clear any other formatting that might be causing issues\r\n bold: false,\r\n italic: false,\r\n strike: false,\r\n };\r\n\r\n this.setFormatting(standardFormatting);\r\n return this;\r\n }\r\n\r\n /**\r\n * Checks if this is an external link\r\n */\r\n isExternal(): boolean {\r\n return this.url !== undefined;\r\n }\r\n\r\n /**\r\n * Checks if this is an internal link (anchor)\r\n */\r\n isInternal(): boolean {\r\n return this.anchor !== undefined;\r\n }\r\n\r\n /**\r\n * Creates a deep copy of this hyperlink\r\n *\r\n * This is useful for preserving the original state before modifications,\r\n * particularly when creating tracked changes (revisions) where both the\r\n * old and new states need to be preserved.\r\n *\r\n * @returns A new Hyperlink instance with the same properties\r\n *\r\n * @example\r\n * ```typescript\r\n * // Clone before modifying for tracked changes\r\n * const originalLink = hyperlink.clone();\r\n * hyperlink.setUrl('https://new-url.com');\r\n * hyperlink.setText('New Text');\r\n *\r\n * // Now originalLink has old URL/text, hyperlink has new\r\n * const deletion = Revision.createDeletion(author, [originalLink]);\r\n * const insertion = Revision.createInsertion(author, [hyperlink]);\r\n * ```\r\n */\r\n clone(): Hyperlink {\r\n const cloned = new Hyperlink({\r\n url: this.url,\r\n anchor: this.anchor,\r\n text: this.text,\r\n tooltip: this.tooltip,\r\n relationshipId: this.relationshipId,\r\n formatting: { ...this.formatting },\r\n });\r\n\r\n // Copy the run with its formatting\r\n if (this.run) {\r\n cloned.run = new Run(this.run.getText(), { ...this.run.getFormatting() });\r\n }\r\n\r\n return cloned;\r\n }\r\n\r\n /**\r\n * Generates XML for the hyperlink\r\n *\r\n * **CRITICAL:** For external links, relationshipId MUST be set before calling toXML().\r\n * This happens automatically when saving via Document.save(), but manual usage requires\r\n * registering the hyperlink with RelationshipManager first.\r\n *\r\n * @throws {Error} If external link (has url) is missing relationshipId\r\n * @throws {Error} If hyperlink has neither url nor anchor (empty hyperlink)\r\n */\r\n toXML(): XMLElement {\r\n // VALIDATION: Hyperlink must have url OR anchor (unless it's an empty hyperlink with relationshipId)\r\n if (!this.url && !this.anchor && !this.relationshipId) {\r\n throw new Error(\r\n \"CRITICAL: Hyperlink must have either a URL (external link), anchor (internal link), or relationshipId. \" +\r\n \"Cannot generate valid XML for hyperlink without destination.\"\r\n );\r\n }\r\n\r\n // VALIDATION: External links MUST have relationship ID\r\n // Per ECMA-376 Part 1 §17.16.22, <w:hyperlink> with external target requires r:id attribute\r\n if (this.url && !this.relationshipId) {\r\n throw new Error(\r\n `CRITICAL: External hyperlink to \"${this.url}\" is missing relationship ID. ` +\r\n `This would create an invalid OpenXML document per ECMA-376 §17.16.22. ` +\r\n `Solution: Use Document.save() which automatically registers relationships, ` +\r\n `or manually call relationshipManager.addHyperlink(url) and set the relationship ID.`\r\n );\r\n }\r\n\r\n const attributes: Record<string, string> = {};\r\n\r\n // External link - add relationship ID\r\n if (this.relationshipId) {\r\n attributes[\"r:id\"] = this.relationshipId;\r\n }\r\n\r\n // Internal link - uses anchor\r\n if (this.anchor) {\r\n attributes[\"w:anchor\"] = this.anchor;\r\n }\r\n\r\n // Tooltip - explicitly escape attribute value for safety\r\n // XMLBuilder will handle escaping, but we document this for clarity\r\n if (this.tooltip) {\r\n // Note: XMLBuilder.elementToString() will escape this via escapeXmlAttribute()\r\n // when generating the actual XML string. We store the raw value here.\r\n attributes[\"w:tooltip\"] = this.tooltip;\r\n }\r\n\r\n // Target frame attribute (e.g., \"_blank\" for new window)\r\n if (this.tgtFrame) {\r\n attributes[\"w:tgtFrame\"] = this.tgtFrame;\r\n }\r\n\r\n // History tracking attribute\r\n if (this.history) {\r\n attributes[\"w:history\"] = this.history;\r\n }\r\n\r\n // Empty/invisible hyperlinks have no children (self-closing element)\r\n if (this._isEmpty) {\r\n return {\r\n name: \"w:hyperlink\",\r\n attributes,\r\n children: [],\r\n };\r\n }\r\n\r\n // Generate run XML\r\n const runXml = this.run.toXML();\r\n\r\n return {\r\n name: \"w:hyperlink\",\r\n attributes,\r\n children: [runXml],\r\n };\r\n }\r\n\r\n /**\r\n * Creates an external hyperlink\r\n * @param url The URL\r\n * @param text Display text\r\n * @param formatting Optional formatting\r\n */\r\n static createExternal(\r\n url: string,\r\n text: string,\r\n formatting?: RunFormatting\r\n ): Hyperlink {\r\n return new Hyperlink({ url, text, formatting });\r\n }\r\n\r\n /**\r\n * Creates an internal hyperlink (to a bookmark)\r\n * @param anchor Bookmark name\r\n * @param text Display text\r\n * @param formatting Optional formatting\r\n */\r\n static createInternal(\r\n anchor: string,\r\n text: string,\r\n formatting?: RunFormatting\r\n ): Hyperlink {\r\n return new Hyperlink({ anchor, text, formatting });\r\n }\r\n\r\n /**\r\n * Creates a web link (convenience method for URLs)\r\n * @param url The URL\r\n * @param text Display text (defaults to URL)\r\n * @param formatting Optional formatting\r\n */\r\n static createWebLink(\r\n url: string,\r\n text?: string,\r\n formatting?: RunFormatting\r\n ): Hyperlink {\r\n return new Hyperlink({\r\n url,\r\n text: text || url,\r\n formatting,\r\n });\r\n }\r\n\r\n /**\r\n * Creates an email link\r\n * @param email Email address\r\n * @param text Display text (defaults to email)\r\n * @param formatting Optional formatting\r\n */\r\n static createEmail(\r\n email: string,\r\n text?: string,\r\n formatting?: RunFormatting\r\n ): Hyperlink {\r\n return new Hyperlink({\r\n url: `mailto:${email}`,\r\n text: text || email,\r\n formatting,\r\n });\r\n }\r\n\r\n /**\r\n * Creates a hyperlink with properties\r\n * @param properties Hyperlink properties\r\n */\r\n static create(properties: HyperlinkProperties): Hyperlink {\r\n return new Hyperlink(properties);\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"Hyperlink.js","sourceRoot":"","sources":["../../src/elements/Hyperlink.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * Hyperlink - Represents a hyperlink in a Word document\r\n *\r\n * Hyperlinks can be external (to websites, files) or internal (to bookmarks within the document).\r\n * They are represented using the `<w:hyperlink>` element.\r\n *\r\n * ## Important: Relationship ID Requirement\r\n *\r\n * **External hyperlinks REQUIRE a relationship ID to be set before XML generation.**\r\n * Per ECMA-376 Part 1 §17.16.22, `<w:hyperlink>` elements with external targets must have\r\n * an `r:id` attribute that references a relationship in `word/_rels/document.xml.rels`.\r\n *\r\n * ### Correct Usage Pattern:\r\n *\r\n * ```typescript\r\n * // RECOMMENDED: Use Document.save() - automatically handles relationships\r\n * const doc = Document.create();\r\n * const para = doc.createParagraph();\r\n * para.addHyperlink(Hyperlink.createExternal('https://example.com', 'Link'));\r\n * await doc.save('document.docx'); // ✅ Relationships auto-registered\r\n * ```\r\n *\r\n * ### Manual Relationship Registration (Advanced):\r\n *\r\n * ```typescript\r\n * const link = Hyperlink.createExternal('https://example.com', 'Link');\r\n * const relationship = relationshipManager.addHyperlink('https://example.com');\r\n * link.setRelationshipId(relationship.getId());\r\n * link.toXML(); // ✅ Now valid\r\n * ```\r\n *\r\n * ### What NOT to Do:\r\n *\r\n * ```typescript\r\n * const link = Hyperlink.createExternal('https://example.com', 'Link');\r\n * link.toXML(); // ❌ ERROR: Missing relationship ID\r\n * ```\r\n *\r\n * ## Internal Hyperlinks\r\n *\r\n * Internal hyperlinks (bookmarks) do NOT require relationships:\r\n *\r\n * ```typescript\r\n * const link = Hyperlink.createInternal('Section1', 'Go to Section 1');\r\n * link.toXML(); // ✅ Valid - uses w:anchor attribute\r\n * ```\r\n *\r\n * @see {@link https://www.ecma-international.org/publications-and-standards/standards/ecma-376/ | ECMA-376 Part 1 §17.16.22}\r\n */\r\n\r\nimport { XMLElement } from \"../xml/XMLBuilder\";\r\nimport { Run, RunFormatting } from \"./Run\";\r\nimport { Revision } from \"./Revision\";\r\nimport { validateRunText } from \"../utils/validation\";\r\nimport { defaultLogger } from \"../utils/logger\";\r\n\r\n/**\r\n * Hyperlink properties\r\n */\r\nexport interface HyperlinkProperties {\r\n /** Hyperlink URL (for external links) */\r\n url?: string;\r\n /** Bookmark anchor (for internal links) */\r\n anchor?: string;\r\n /** Display text (optional for empty/invisible hyperlinks) */\r\n text?: string;\r\n /** Text formatting */\r\n formatting?: RunFormatting;\r\n /** Tooltip text */\r\n tooltip?: string;\r\n /** Relationship ID (set by Document when saving) */\r\n relationshipId?: string;\r\n /** Whether this is an empty/invisible hyperlink with no display text */\r\n isEmpty?: boolean;\r\n /** Target frame attribute (e.g., \"_blank\" for new window) */\r\n tgtFrame?: string;\r\n /** History tracking attribute */\r\n history?: string;\r\n /** Document location for within-document navigation in external files (ECMA-376 §17.16.22) */\r\n docLocation?: string;\r\n}\r\n\r\n/**\r\n * Represents a hyperlink\r\n */\r\nexport class Hyperlink {\r\n private url?: string;\r\n private anchor?: string;\r\n private text: string;\r\n private run: Run;\r\n private tooltip?: string;\r\n private relationshipId?: string;\r\n private formatting: RunFormatting;\r\n /** Whether this is an empty/invisible hyperlink with no display text */\r\n private _isEmpty = false;\r\n /** Target frame attribute (e.g., \"_blank\" for new window) */\r\n private tgtFrame?: string;\r\n /** History tracking attribute */\r\n private history?: string;\r\n /** Document location for within-document navigation in external files */\r\n private docLocation?: string;\r\n /** Tracking context for automatic change tracking */\r\n private trackingContext?: import('../tracking/TrackingContext').TrackingContext;\r\n /** Parent paragraph reference for automatic tracking */\r\n private _parentParagraph?: import('./Paragraph').Paragraph;\r\n\r\n /**\r\n * Creates a new hyperlink\r\n *\r\n * **Note:** A hyperlink must have either a URL (external) or anchor (internal), but not both.\r\n * If both are provided, the URL takes precedence and a warning is logged.\r\n *\r\n * @param properties Hyperlink properties\r\n */\r\n constructor(properties: HyperlinkProperties) {\r\n this.url = properties.url;\r\n this.anchor = properties.anchor;\r\n this.tooltip = properties.tooltip;\r\n this.relationshipId = properties.relationshipId;\r\n this.tgtFrame = properties.tgtFrame;\r\n this.history = properties.history;\r\n this.docLocation = properties.docLocation;\r\n this._isEmpty = properties.isEmpty ?? false;\r\n\r\n // VALIDATION: Warn about hybrid links (url + anchor)\r\n if (this.url && this.anchor) {\r\n defaultLogger.warn(\r\n `DocXML Warning: Hyperlink has both URL (\"${this.url}\") and anchor (\"${this.anchor}\"). ` +\r\n `This is ambiguous per ECMA-376 spec. URL will take precedence. ` +\r\n `Use Hyperlink.createExternal() or Hyperlink.createInternal() to avoid ambiguity.`\r\n );\r\n }\r\n\r\n // Handle empty/invisible hyperlinks (no display text)\r\n if (this._isEmpty) {\r\n this.text = \"\";\r\n this.formatting = {};\r\n this.run = new Run(\"\", {});\r\n return;\r\n }\r\n\r\n // Text fallback: properties.text → url → 'Link'\r\n // NOTE: Do NOT use anchor (bookmark ID) as display text - it should only be used for navigation\r\n // Using bookmark IDs as visible text causes TOC corruption (Issue: TOC shows \"HEADING=II.MNKE7E8NA385_\" instead of proper headings)\r\n this.text = properties.text || this.url || \"Link\";\r\n\r\n // Validate text for XML patterns\r\n // Default to auto-cleaning XML patterns unless explicitly disabled (matches Run behavior)\r\n const validation = validateRunText(this.text, {\r\n context: \"Hyperlink text\",\r\n autoClean: properties.formatting?.cleanXmlFromText !== false,\r\n warnToConsole: true,\r\n });\r\n\r\n // Use cleaned text if available and cleaning was requested\r\n if (validation.cleanedText) {\r\n this.text = validation.cleanedText;\r\n }\r\n\r\n // Create run with default hyperlink styling (Verdana 12pt blue underlined)\r\n this.formatting = {\r\n font: \"Verdana\",\r\n size: 12,\r\n color: \"0000FF\", // Standard hyperlink blue\r\n underline: \"single\",\r\n ...properties.formatting,\r\n };\r\n\r\n this.run = new Run(this.text, this.formatting);\r\n }\r\n\r\n /**\r\n * Sets the tracking context for automatic change tracking.\r\n * Called by Document when track changes is enabled.\r\n * @internal\r\n */\r\n _setTrackingContext(context: import('../tracking/TrackingContext').TrackingContext): void {\r\n this.trackingContext = context;\r\n }\r\n\r\n /**\r\n * Sets the parent paragraph reference for automatic tracking.\r\n * Called by Paragraph when hyperlink is added.\r\n * @internal\r\n */\r\n _setParentParagraph(paragraph: import('./Paragraph').Paragraph): void {\r\n this._parentParagraph = paragraph;\r\n }\r\n\r\n /**\r\n * Gets the parent paragraph reference.\r\n * @internal\r\n */\r\n _getParentParagraph(): import('./Paragraph').Paragraph | undefined {\r\n return this._parentParagraph;\r\n }\r\n\r\n /**\r\n * Gets the hyperlink URL\r\n */\r\n getUrl(): string | undefined {\r\n return this.url;\r\n }\r\n\r\n /**\r\n * Gets the complete URL including any anchor fragment.\r\n *\r\n * For external links that also have an anchor (e.g., internal bookmark within external page),\r\n * this returns the URL with the anchor appended as a fragment.\r\n * For internal-only links (anchor without URL), returns undefined.\r\n *\r\n * Note: As of v7.2.0, DocumentParser automatically combines external URLs with anchors\r\n * during parsing, so getUrl() typically returns the full URL. This method is provided\r\n * for cases where URL and anchor are set separately via the API.\r\n *\r\n * @returns The complete URL with fragment, or undefined for internal-only links\r\n *\r\n * @example\r\n * ```typescript\r\n * // External link with anchor fragment\r\n * const link = new Hyperlink({ url: 'https://example.com/', anchor: '!/view?id=123', text: 'Link' });\r\n * link.getUrl(); // 'https://example.com/'\r\n * link.getAnchor(); // '!/view?id=123'\r\n * link.getFullUrl(); // 'https://example.com/#!/view?id=123'\r\n *\r\n * // External link without anchor\r\n * const link2 = Hyperlink.createExternal('https://example.com/page', 'Link');\r\n * link2.getFullUrl(); // 'https://example.com/page'\r\n *\r\n * // Internal link (bookmark reference)\r\n * const link3 = Hyperlink.createInternal('Section1', 'Go to Section 1');\r\n * link3.getFullUrl(); // undefined\r\n * ```\r\n */\r\n getFullUrl(): string | undefined {\r\n if (this.url && this.anchor) {\r\n return this.url + '#' + this.anchor;\r\n }\r\n return this.url;\r\n }\r\n\r\n /**\r\n * Gets the anchor (for internal links)\r\n */\r\n getAnchor(): string | undefined {\r\n return this.anchor;\r\n }\r\n\r\n /**\r\n * Returns whether this is an empty/invisible hyperlink (has no display text).\r\n * Empty hyperlinks are self-closing elements in the XML.\r\n */\r\n isEmpty(): boolean {\r\n return this._isEmpty;\r\n }\r\n\r\n /**\r\n * Gets the target frame attribute (e.g., \"_blank\" for new window)\r\n */\r\n getTgtFrame(): string | undefined {\r\n return this.tgtFrame;\r\n }\r\n\r\n /**\r\n * Gets the history tracking attribute\r\n */\r\n getHistory(): string | undefined {\r\n return this.history;\r\n }\r\n\r\n /**\r\n * Sets the target frame attribute\r\n * @param tgtFrame Target frame (e.g., \"_blank\" for new window)\r\n */\r\n setTgtFrame(tgtFrame: string | undefined): this {\r\n this.tgtFrame = tgtFrame;\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets the history tracking attribute\r\n * @param history History value (e.g., \"1\" to add to history)\r\n */\r\n setHistory(history: string | undefined): this {\r\n this.history = history;\r\n return this;\r\n }\r\n\r\n /**\r\n * Gets the document location attribute (ECMA-376 §17.16.22)\r\n */\r\n getDocLocation(): string | undefined {\r\n return this.docLocation;\r\n }\r\n\r\n /**\r\n * Sets the document location for within-document navigation in external files\r\n * @param docLocation Location string\r\n */\r\n setDocLocation(docLocation: string | undefined): this {\r\n this.docLocation = docLocation;\r\n return this;\r\n }\r\n\r\n /**\r\n * Gets the display text\r\n *\r\n * This method delegates to the internal run to ensure the returned text\r\n * is always accurate and matches what will be in the generated XML,\r\n * per ECMA-376 Part 1 §17.16.22.\r\n *\r\n * @returns The display text including any special characters (tabs, breaks, etc.)\r\n */\r\n getText(): string {\r\n return this.run.getText();\r\n }\r\n\r\n /**\r\n * Sets the display text\r\n */\r\n setText(text: string): this {\r\n // Validate text for XML patterns\r\n // Default to auto-cleaning unless explicitly disabled (matches Run behavior)\r\n const validation = validateRunText(text, {\r\n context: \"Hyperlink.setText\",\r\n autoClean: this.formatting.cleanXmlFromText !== false,\r\n warnToConsole: true,\r\n });\r\n\r\n // Use cleaned text if available\r\n const cleanedText = validation.cleanedText || text;\r\n\r\n const previousValue = this.text;\r\n this.text = cleanedText;\r\n this.run.setText(cleanedText); // Run.setText also validates\r\n if (this.trackingContext?.isEnabled() && previousValue !== cleanedText) {\r\n this.trackingContext.trackHyperlinkChange(this, 'text', previousValue, cleanedText);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets the internal run directly (for advanced use cases like TOC parsing)\r\n * Used by DocumentParser to preserve run content (tabs, breaks, etc.)\r\n * @param run - The run to use for this hyperlink\r\n */\r\n setRun(run: Run): this {\r\n this.run = run;\r\n this.text = run.getText();\r\n return this;\r\n }\r\n\r\n /**\r\n * Gets the tooltip\r\n */\r\n getTooltip(): string | undefined {\r\n return this.tooltip;\r\n }\r\n\r\n /**\r\n * Sets the tooltip\r\n */\r\n setTooltip(tooltip: string): this {\r\n const previousValue = this.tooltip;\r\n this.tooltip = tooltip;\r\n if (this.trackingContext?.isEnabled() && previousValue !== tooltip) {\r\n this.trackingContext.trackHyperlinkChange(this, 'tooltip', previousValue, tooltip);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Gets the relationship ID\r\n */\r\n getRelationshipId(): string | undefined {\r\n return this.relationshipId;\r\n }\r\n\r\n /**\r\n * Sets the relationship ID (called by Document during save)\r\n */\r\n setRelationshipId(id: string): this {\r\n this.relationshipId = id;\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets or updates the hyperlink URL\r\n *\r\n * When URL is updated, we mark that the relationship needs updating.\r\n * The actual relationship update happens during Document.save() to ensure\r\n * proper coordination with the RelationshipManager.\r\n *\r\n * **Important:** This method maintains the relationship ID but flags it for update.\r\n * The RelationshipManager will update the existing relationship's target URL\r\n * during save, preventing orphaned relationships per ECMA-376 §17.16.22.\r\n *\r\n * @param url - The new URL (or undefined to clear)\r\n * @returns This hyperlink for chaining\r\n * @throws {Error} If clearing URL would create empty hyperlink (no URL and no anchor)\r\n *\r\n * @example\r\n * ```typescript\r\n * const link = Hyperlink.createExternal('https://old.com', 'Link');\r\n * link.setUrl('https://new.com'); // Marks for relationship update\r\n * await doc.save('updated.docx'); // Updates relationship target\r\n * ```\r\n */\r\n setUrl(url: string | undefined): this {\r\n // Validate that clearing URL doesn't create empty hyperlink\r\n if (!url && !this.anchor) {\r\n throw new Error(\r\n `Cannot set URL to undefined: Hyperlink \"${this.run.getText()}\" has no anchor. ` +\r\n `Clearing the URL would create an invalid hyperlink per ECMA-376 §17.16.22. ` +\r\n `Either provide a new URL or delete the hyperlink entirely.`\r\n );\r\n }\r\n\r\n // Save old URL before updating (for text fallback logic)\r\n const oldUrl = this.url;\r\n\r\n // Skip if URL unchanged (optimization)\r\n if (oldUrl === url) {\r\n return this;\r\n }\r\n\r\n // If tracking enabled AND has parent paragraph, create revision pair\r\n // OOXML has no w:hyperlinkChange element - Word tracks hyperlink changes as delete/insert pairs\r\n if (this.trackingContext?.isEnabled() && this._parentParagraph) {\r\n const author = this.trackingContext.getAuthor();\r\n\r\n // Clone current state for deletion (before applying changes)\r\n const oldHyperlink = this.clone();\r\n\r\n // Apply the change to this hyperlink\r\n this.url = url;\r\n this.relationshipId = undefined;\r\n if (this.run.getText() === oldUrl) {\r\n this.text = url || this.anchor || \"Link\";\r\n this.run.setText(this.text);\r\n }\r\n\r\n // Create delete/insert revision pair\r\n const deletion = Revision.createDeletion(author, [oldHyperlink]);\r\n const insertion = Revision.createInsertion(author, [this]);\r\n\r\n // Replace this hyperlink with the revision pair in parent paragraph\r\n this._parentParagraph.replaceContent(this, [deletion, insertion]);\r\n\r\n // Clear parent reference since we're now inside a revision\r\n this._parentParagraph = undefined;\r\n\r\n return this;\r\n }\r\n\r\n // Non-tracking path (original behavior)\r\n this.url = url;\r\n\r\n // Clear the relationship ID so it will be re-registered during save\r\n // This ensures the relationship target is updated to point to the new URL\r\n this.relationshipId = undefined;\r\n\r\n // Update text ONLY if it was auto-generated from the old URL\r\n // This preserves user-provided text (even if it's \"Link\")\r\n // Use run.getText() to ensure we check the actual current text, not stale cache\r\n if (this.run.getText() === oldUrl) {\r\n this.text = url || this.anchor || \"Link\";\r\n this.run.setText(this.text);\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets the anchor (for internal links)\r\n * @param anchor Bookmark name to link to\r\n * @returns This hyperlink for chaining\r\n * @throws {Error} If clearing anchor would create empty hyperlink (no URL and no anchor)\r\n * @example\r\n * ```typescript\r\n * const link = Hyperlink.createInternal('OldBookmark', 'Go there');\r\n * link.setAnchor('NewBookmark'); // Update internal link target\r\n * ```\r\n */\r\n setAnchor(anchor: string | undefined): this {\r\n // Validate that clearing anchor doesn't create empty hyperlink\r\n if (!anchor && !this.url) {\r\n throw new Error(\r\n `Cannot set anchor to undefined: Hyperlink \"${this.run.getText()}\" has no URL. ` +\r\n `Clearing the anchor would create an invalid hyperlink per ECMA-376 §17.16.22. ` +\r\n `Either provide a new anchor or delete the hyperlink entirely.`\r\n );\r\n }\r\n\r\n // Save old anchor before updating\r\n const oldAnchor = this.anchor;\r\n\r\n // Skip if anchor unchanged (optimization)\r\n if (oldAnchor === anchor) {\r\n return this;\r\n }\r\n\r\n // If tracking enabled AND has parent paragraph, create revision pair\r\n // OOXML has no w:hyperlinkChange element - Word tracks hyperlink changes as delete/insert pairs\r\n if (this.trackingContext?.isEnabled() && this._parentParagraph) {\r\n const author = this.trackingContext.getAuthor();\r\n\r\n // Clone current state for deletion (before applying changes)\r\n const oldHyperlink = this.clone();\r\n\r\n // Apply the change to this hyperlink\r\n this.anchor = anchor;\r\n if (anchor && this.url) {\r\n defaultLogger.warn(\r\n `DocXML Warning: Setting anchor \"${anchor}\" on hyperlink that has URL \"${this.url}\". ` +\r\n `Clearing URL to make this an internal link. Use separate hyperlinks for external and internal links.`\r\n );\r\n this.url = undefined;\r\n this.relationshipId = undefined;\r\n }\r\n if (this.run.getText() === oldAnchor) {\r\n this.text = anchor || this.url || \"Link\";\r\n this.run.setText(this.text);\r\n }\r\n\r\n // Create delete/insert revision pair\r\n const deletion = Revision.createDeletion(author, [oldHyperlink]);\r\n const insertion = Revision.createInsertion(author, [this]);\r\n\r\n // Replace this hyperlink with the revision pair in parent paragraph\r\n this._parentParagraph.replaceContent(this, [deletion, insertion]);\r\n\r\n // Clear parent reference since we're now inside a revision\r\n this._parentParagraph = undefined;\r\n\r\n return this;\r\n }\r\n\r\n // Non-tracking path (original behavior)\r\n this.anchor = anchor;\r\n\r\n // If converting from external to internal, clear URL and relationship\r\n if (anchor && this.url) {\r\n defaultLogger.warn(\r\n `DocXML Warning: Setting anchor \"${anchor}\" on hyperlink that has URL \"${this.url}\". ` +\r\n `Clearing URL to make this an internal link. Use separate hyperlinks for external and internal links.`\r\n );\r\n this.url = undefined;\r\n this.relationshipId = undefined;\r\n }\r\n\r\n // Update text ONLY if it was auto-generated from the old anchor\r\n // Use run.getText() to ensure we check the actual current text, not stale cache\r\n if (this.run.getText() === oldAnchor) {\r\n this.text = anchor || this.url || \"Link\";\r\n this.run.setText(this.text);\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Gets the run\r\n */\r\n getRun(): Run {\r\n return this.run;\r\n }\r\n\r\n /**\r\n * Sets run formatting\r\n *\r\n * @param formatting - The formatting to apply\r\n * @param options - Optional settings\r\n * @param options.replace - If true, replaces ALL existing formatting instead of merging.\r\n * Use this when you want to clear inherited styles like characterStyle.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Merge mode (default): adds/updates properties while preserving others\r\n * hyperlink.setFormatting({ bold: true });\r\n *\r\n * // Replace mode: clears all existing formatting and applies only the new properties\r\n * hyperlink.setFormatting({ font: \"Verdana\", size: 12 }, { replace: true });\r\n * ```\r\n */\r\n setFormatting(formatting: RunFormatting, options?: { replace?: boolean }): this {\r\n // Update stored formatting\r\n const previousValue = { ...this.formatting };\r\n if (options?.replace) {\r\n // Replace mode: new formatting replaces ALL existing properties\r\n this.formatting = { ...formatting };\r\n } else {\r\n // Merge mode (default, backwards-compatible): merge with existing\r\n this.formatting = { ...this.formatting, ...formatting };\r\n }\r\n // Create new run with updated formatting, preserving current text\r\n const currentText = this.run.getText();\r\n this.run = new Run(currentText, this.formatting);\r\n this.text = currentText; // Keep cache in sync\r\n if (this.trackingContext?.isEnabled()) {\r\n this.trackingContext.trackHyperlinkChange(this, 'formatting', previousValue, this.formatting);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Gets run formatting (returns this hyperlink for fluent API)\r\n * @returns This hyperlink for method chaining\r\n *\r\n * @example\r\n * ```typescript\r\n * hyperlink.getFormatting().setColor('0563C1').setUnderline('single');\r\n * ```\r\n */\r\n getFormatting(): this {\r\n return this;\r\n }\r\n\r\n /**\r\n * Gets the raw formatting object (for direct access)\r\n * @returns RunFormatting object\r\n */\r\n getRawFormatting(): RunFormatting {\r\n return this.formatting;\r\n }\r\n\r\n // ============================================================================\r\n // Individual Formatting Getters\r\n // ============================================================================\r\n\r\n /**\r\n * Gets the text color\r\n * @returns Color hex string or undefined\r\n */\r\n getColor(): string | undefined {\r\n return this.formatting.color;\r\n }\r\n\r\n /**\r\n * Gets the underline style\r\n * @returns Underline style or undefined\r\n */\r\n getUnderline(): string | boolean | undefined {\r\n return this.formatting.underline;\r\n }\r\n\r\n /**\r\n * Gets whether the hyperlink is bold\r\n * @returns True if bold, false otherwise\r\n */\r\n getBold(): boolean {\r\n return this.formatting.bold ?? false;\r\n }\r\n\r\n /**\r\n * Gets whether the hyperlink is italic\r\n * @returns True if italic, false otherwise\r\n */\r\n getItalic(): boolean {\r\n return this.formatting.italic ?? false;\r\n }\r\n\r\n /**\r\n * Gets the font family\r\n * @returns Font name or undefined\r\n */\r\n getFont(): string | undefined {\r\n return this.formatting.font;\r\n }\r\n\r\n /**\r\n * Gets the font size\r\n * @returns Font size in points or undefined\r\n */\r\n getSize(): number | undefined {\r\n return this.formatting.size;\r\n }\r\n\r\n /**\r\n * Sets text color\r\n * @param color Color in hex format (e.g., '0563C1')\r\n * @returns This hyperlink for chaining\r\n */\r\n setColor(color: string): this {\r\n const previousValue = this.formatting.color;\r\n this.formatting.color = color;\r\n this.run = new Run(this.text, this.formatting);\r\n if (this.trackingContext?.isEnabled() && previousValue !== color) {\r\n this.trackingContext.trackHyperlinkChange(this, 'color', previousValue, color);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets underline style\r\n * @param underline Underline style ('single', 'double', etc.)\r\n * @returns This hyperlink for chaining\r\n */\r\n setUnderline(underline: boolean | \"single\" | \"double\" | \"dotted\" | \"thick\" | \"dash\"): this {\r\n const previousValue = this.formatting.underline;\r\n this.formatting.underline = underline;\r\n this.run = new Run(this.text, this.formatting);\r\n if (this.trackingContext?.isEnabled() && previousValue !== underline) {\r\n this.trackingContext.trackHyperlinkChange(this, 'underline', previousValue, underline);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets bold formatting\r\n * @param bold Bold state (default: true)\r\n * @returns This hyperlink for chaining\r\n */\r\n setBold(bold = true): this {\r\n const previousValue = this.formatting.bold;\r\n this.formatting.bold = bold;\r\n this.run = new Run(this.text, this.formatting);\r\n if (this.trackingContext?.isEnabled() && previousValue !== bold) {\r\n this.trackingContext.trackHyperlinkChange(this, 'bold', previousValue, bold);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets italic formatting\r\n * @param italic Italic state (default: true)\r\n * @returns This hyperlink for chaining\r\n */\r\n setItalic(italic = true): this {\r\n const previousValue = this.formatting.italic;\r\n this.formatting.italic = italic;\r\n this.run = new Run(this.text, this.formatting);\r\n if (this.trackingContext?.isEnabled() && previousValue !== italic) {\r\n this.trackingContext.trackHyperlinkChange(this, 'italic', previousValue, italic);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets font family\r\n * @param font Font name (e.g., 'Arial', 'Verdana')\r\n * @returns This hyperlink for chaining\r\n */\r\n setFont(font: string): this {\r\n const previousValue = this.formatting.font;\r\n this.formatting.font = font;\r\n this.run = new Run(this.text, this.formatting);\r\n if (this.trackingContext?.isEnabled() && previousValue !== font) {\r\n this.trackingContext.trackHyperlinkChange(this, 'font', previousValue, font);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets font size\r\n * @param size Font size in points (e.g., 12, 14)\r\n * @returns This hyperlink for chaining\r\n */\r\n setSize(size: number): this {\r\n const previousValue = this.formatting.size;\r\n this.formatting.size = size;\r\n this.run = new Run(this.text, this.formatting);\r\n if (this.trackingContext?.isEnabled() && previousValue !== size) {\r\n this.trackingContext.trackHyperlinkChange(this, 'size', previousValue, size);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Validates the hyperlink URL and optionally fixes common issues\r\n *\r\n * Performs validation and fixing of hyperlink URLs including:\r\n * - Checking URL accessibility (HTTP HEAD request for external links)\r\n * - Fixing common URL issues (missing protocol, double slashes, spaces)\r\n * - Validating internal bookmark references\r\n * - Detecting broken links\r\n *\r\n * **Note:** This method is async due to network requests for accessibility checks.\r\n *\r\n * @param options - Validation options\r\n * @returns Promise with validation results\r\n *\r\n * @example\r\n * ```typescript\r\n * // Basic URL fixing without network check\r\n * const result = await link.validateAndFix({\r\n * fixCommonIssues: true,\r\n * checkAccessibility: false\r\n * });\r\n * console.log(`Fixed: ${result.fixed.join(', ')}`);\r\n *\r\n * // Full validation with accessibility check\r\n * const validation = await link.validateAndFix({\r\n * checkAccessibility: true,\r\n * timeout: 5000\r\n * });\r\n * if (!validation.valid) {\r\n * console.log(`Issues: ${validation.issues.join(', ')}`);\r\n * }\r\n *\r\n * // Batch validate all hyperlinks in document\r\n * for (const { hyperlink } of doc.getHyperlinks()) {\r\n * const result = await hyperlink.validateAndFix();\r\n * if (result.fixed.length > 0) {\r\n * console.log(`Fixed ${hyperlink.getUrl()}: ${result.fixed.join(', ')}`);\r\n * }\r\n * }\r\n * ```\r\n */\r\n async validateAndFix(options?: {\r\n checkAccessibility?: boolean;\r\n fixCommonIssues?: boolean;\r\n timeout?: number;\r\n bookmarkManager?: { hasBookmark(name: string): boolean };\r\n }): Promise<{\r\n valid: boolean;\r\n issues: string[];\r\n fixed: string[];\r\n originalUrl?: string;\r\n fixedUrl?: string;\r\n }> {\r\n const {\r\n checkAccessibility = false,\r\n fixCommonIssues = true,\r\n timeout = 5000,\r\n bookmarkManager,\r\n } = options || {};\r\n\r\n const issues: string[] = [];\r\n const fixed: string[] = [];\r\n let fixedUrl = this.url;\r\n const originalUrl = this.url;\r\n\r\n // Internal link validation (bookmarks)\r\n if (this.anchor) {\r\n if (bookmarkManager) {\r\n const bookmarkExists = bookmarkManager.hasBookmark(this.anchor);\r\n if (!bookmarkExists) {\r\n issues.push(`Internal bookmark \"${this.anchor}\" not found`);\r\n }\r\n }\r\n return {\r\n valid: issues.length === 0,\r\n issues,\r\n fixed,\r\n originalUrl,\r\n };\r\n }\r\n\r\n // External link validation\r\n if (!this.url) {\r\n issues.push(\"No URL or anchor specified\");\r\n return { valid: false, issues, fixed, originalUrl };\r\n }\r\n\r\n // Fix common issues\r\n if (fixCommonIssues && fixedUrl) {\r\n // Fix 1: Add missing protocol\r\n if (!(/^[a-z]+:\\/\\//i.exec(fixedUrl))) {\r\n fixedUrl = \"https://\" + fixedUrl;\r\n fixed.push(\"Added missing protocol (https://)\");\r\n }\r\n\r\n // Fix 2: Fix double slashes (except after protocol)\r\n const protocolMatch = /^([a-z]+:\\/\\/)/i.exec(fixedUrl);\r\n if (protocolMatch?.[1]) {\r\n const protocol = protocolMatch[1];\r\n const rest = fixedUrl.substring(protocol.length);\r\n const fixedRest = rest.replace(/\\/\\//g, \"/\");\r\n if (rest !== fixedRest) {\r\n fixedUrl = protocol + fixedRest;\r\n fixed.push(\"Fixed double slashes\");\r\n }\r\n }\r\n\r\n // Fix 3: Encode spaces\r\n if (fixedUrl.includes(\" \")) {\r\n fixedUrl = fixedUrl.replace(/ /g, \"%20\");\r\n fixed.push(\"Encoded spaces as %20\");\r\n }\r\n\r\n // Fix 4: Remove trailing slashes for non-root URLs\r\n if (/^https?:\\/\\/[^/]+\\/.+\\/$/.exec(fixedUrl)) {\r\n fixedUrl = fixedUrl.replace(/\\/$/, \"\");\r\n fixed.push(\"Removed trailing slash\");\r\n }\r\n\r\n // Fix 5: Fix common typos\r\n fixedUrl = fixedUrl.replace(/^http:\\/\\//i, \"https://\"); // Prefer HTTPS\r\n if (fixedUrl !== this.url && fixedUrl.startsWith(\"https://\")) {\r\n fixed.push(\"Upgraded HTTP to HTTPS\");\r\n }\r\n\r\n // Update URL if fixes were applied\r\n if (fixedUrl !== this.url) {\r\n this.setUrl(fixedUrl);\r\n }\r\n }\r\n\r\n // Check accessibility (HTTP HEAD request)\r\n if (checkAccessibility && fixedUrl?.match(/^https?:\\/\\//i)) {\r\n // Check if fetch is available (Node.js 18+ or browser)\r\n if (typeof fetch === \"undefined\") {\r\n issues.push(\r\n \"Network validation unavailable: fetch API not supported in this environment\"\r\n );\r\n } else {\r\n try {\r\n // Use fetch with AbortController for timeout\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), timeout);\r\n\r\n const response = await fetch(fixedUrl, {\r\n method: \"HEAD\",\r\n signal: controller.signal,\r\n redirect: \"follow\",\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (!response.ok) {\r\n issues.push(\r\n `HTTP ${response.status}: ${response.statusText || \"Error\"}`\r\n );\r\n }\r\n } catch (error: unknown) {\r\n // Type guard for error objects with name and message properties\r\n const isErrorWithName = (err: unknown): err is { name: string } => {\r\n return typeof err === \"object\" && err !== null && \"name\" in err;\r\n };\r\n const isErrorWithMessage = (\r\n err: unknown\r\n ): err is { message: string } => {\r\n return typeof err === \"object\" && err !== null && \"message\" in err;\r\n };\r\n\r\n if (isErrorWithName(error) && error.name === \"AbortError\") {\r\n issues.push(`Timeout after ${timeout}ms`);\r\n } else if (\r\n isErrorWithMessage(error) &&\r\n error.message?.includes(\"fetch\")\r\n ) {\r\n issues.push(`Unreachable: ${error.message}`);\r\n } else if (isErrorWithMessage(error)) {\r\n issues.push(`Network error: ${error.message}`);\r\n } else {\r\n issues.push(\"Network error: Unknown error\");\r\n }\r\n }\r\n }\r\n }\r\n\r\n return {\r\n valid: issues.length === 0,\r\n issues,\r\n fixed,\r\n originalUrl,\r\n fixedUrl: fixedUrl !== originalUrl ? fixedUrl : undefined,\r\n };\r\n }\r\n\r\n /**\r\n * Resets hyperlink formatting to standard style (Calibri, blue, underline)\r\n * This is useful for fixing corrupted hyperlinks from Google Docs or other sources\r\n * @returns this for method chaining\r\n */\r\n resetToStandardFormatting(): this {\r\n const standardFormatting: RunFormatting = {\r\n font: \"Verdana\",\r\n color: \"0000FF\", // Standard hyperlink blue\r\n underline: \"single\",\r\n // Clear any other formatting that might be causing issues\r\n bold: false,\r\n italic: false,\r\n strike: false,\r\n };\r\n\r\n this.setFormatting(standardFormatting);\r\n return this;\r\n }\r\n\r\n /**\r\n * Checks if this is an external link\r\n */\r\n isExternal(): boolean {\r\n return this.url !== undefined;\r\n }\r\n\r\n /**\r\n * Checks if this is an internal link (anchor)\r\n */\r\n isInternal(): boolean {\r\n return this.anchor !== undefined;\r\n }\r\n\r\n /**\r\n * Creates a deep copy of this hyperlink\r\n *\r\n * This is useful for preserving the original state before modifications,\r\n * particularly when creating tracked changes (revisions) where both the\r\n * old and new states need to be preserved.\r\n *\r\n * @returns A new Hyperlink instance with the same properties\r\n *\r\n * @example\r\n * ```typescript\r\n * // Clone before modifying for tracked changes\r\n * const originalLink = hyperlink.clone();\r\n * hyperlink.setUrl('https://new-url.com');\r\n * hyperlink.setText('New Text');\r\n *\r\n * // Now originalLink has old URL/text, hyperlink has new\r\n * const deletion = Revision.createDeletion(author, [originalLink]);\r\n * const insertion = Revision.createInsertion(author, [hyperlink]);\r\n * ```\r\n */\r\n clone(): Hyperlink {\r\n const cloned = new Hyperlink({\r\n url: this.url,\r\n anchor: this.anchor,\r\n text: this.text,\r\n tooltip: this.tooltip,\r\n relationshipId: this.relationshipId,\r\n formatting: { ...this.formatting },\r\n tgtFrame: this.tgtFrame,\r\n history: this.history,\r\n docLocation: this.docLocation,\r\n });\r\n\r\n // Copy the run with its formatting\r\n if (this.run) {\r\n cloned.run = new Run(this.run.getText(), { ...this.run.getFormatting() });\r\n }\r\n\r\n return cloned;\r\n }\r\n\r\n /**\r\n * Generates XML for the hyperlink\r\n *\r\n * **CRITICAL:** For external links, relationshipId MUST be set before calling toXML().\r\n * This happens automatically when saving via Document.save(), but manual usage requires\r\n * registering the hyperlink with RelationshipManager first.\r\n *\r\n * @throws {Error} If external link (has url) is missing relationshipId\r\n * @throws {Error} If hyperlink has neither url nor anchor (empty hyperlink)\r\n */\r\n toXML(): XMLElement {\r\n // VALIDATION: Hyperlink must have url OR anchor (unless it's an empty hyperlink with relationshipId)\r\n if (!this.url && !this.anchor && !this.relationshipId) {\r\n throw new Error(\r\n \"CRITICAL: Hyperlink must have either a URL (external link), anchor (internal link), or relationshipId. \" +\r\n \"Cannot generate valid XML for hyperlink without destination.\"\r\n );\r\n }\r\n\r\n // VALIDATION: External links MUST have relationship ID\r\n // Per ECMA-376 Part 1 §17.16.22, <w:hyperlink> with external target requires r:id attribute\r\n if (this.url && !this.relationshipId) {\r\n throw new Error(\r\n `CRITICAL: External hyperlink to \"${this.url}\" is missing relationship ID. ` +\r\n `This would create an invalid OpenXML document per ECMA-376 §17.16.22. ` +\r\n `Solution: Use Document.save() which automatically registers relationships, ` +\r\n `or manually call relationshipManager.addHyperlink(url) and set the relationship ID.`\r\n );\r\n }\r\n\r\n const attributes: Record<string, string> = {};\r\n\r\n // External link - add relationship ID\r\n if (this.relationshipId) {\r\n attributes[\"r:id\"] = this.relationshipId;\r\n }\r\n\r\n // Internal link - uses anchor\r\n if (this.anchor) {\r\n attributes[\"w:anchor\"] = this.anchor;\r\n }\r\n\r\n // Tooltip - explicitly escape attribute value for safety\r\n // XMLBuilder will handle escaping, but we document this for clarity\r\n if (this.tooltip) {\r\n // Note: XMLBuilder.elementToString() will escape this via escapeXmlAttribute()\r\n // when generating the actual XML string. We store the raw value here.\r\n attributes[\"w:tooltip\"] = this.tooltip;\r\n }\r\n\r\n // Target frame attribute (e.g., \"_blank\" for new window)\r\n if (this.tgtFrame) {\r\n attributes[\"w:tgtFrame\"] = this.tgtFrame;\r\n }\r\n\r\n // History tracking attribute\r\n if (this.history) {\r\n attributes[\"w:history\"] = this.history;\r\n }\r\n\r\n // Document location attribute (ECMA-376 §17.16.22)\r\n if (this.docLocation) {\r\n attributes[\"w:docLocation\"] = this.docLocation;\r\n }\r\n\r\n // Empty/invisible hyperlinks have no children (self-closing element)\r\n if (this._isEmpty) {\r\n return {\r\n name: \"w:hyperlink\",\r\n attributes,\r\n children: [],\r\n };\r\n }\r\n\r\n // Generate run XML\r\n const runXml = this.run.toXML();\r\n\r\n return {\r\n name: \"w:hyperlink\",\r\n attributes,\r\n children: [runXml],\r\n };\r\n }\r\n\r\n /**\r\n * Creates an external hyperlink\r\n * @param url The URL\r\n * @param text Display text\r\n * @param formatting Optional formatting\r\n */\r\n static createExternal(\r\n url: string,\r\n text: string,\r\n formatting?: RunFormatting\r\n ): Hyperlink {\r\n return new Hyperlink({ url, text, formatting });\r\n }\r\n\r\n /**\r\n * Creates an internal hyperlink (to a bookmark)\r\n * @param anchor Bookmark name\r\n * @param text Display text\r\n * @param formatting Optional formatting\r\n */\r\n static createInternal(\r\n anchor: string,\r\n text: string,\r\n formatting?: RunFormatting\r\n ): Hyperlink {\r\n return new Hyperlink({ anchor, text, formatting });\r\n }\r\n\r\n /**\r\n * Creates a web link (convenience method for URLs)\r\n * @param url The URL\r\n * @param text Display text (defaults to URL)\r\n * @param formatting Optional formatting\r\n */\r\n static createWebLink(\r\n url: string,\r\n text?: string,\r\n formatting?: RunFormatting\r\n ): Hyperlink {\r\n return new Hyperlink({\r\n url,\r\n text: text || url,\r\n formatting,\r\n });\r\n }\r\n\r\n /**\r\n * Creates an email link\r\n * @param email Email address\r\n * @param text Display text (defaults to email)\r\n * @param formatting Optional formatting\r\n */\r\n static createEmail(\r\n email: string,\r\n text?: string,\r\n formatting?: RunFormatting\r\n ): Hyperlink {\r\n return new Hyperlink({\r\n url: `mailto:${email}`,\r\n text: text || email,\r\n formatting,\r\n });\r\n }\r\n\r\n /**\r\n * Creates a hyperlink with properties\r\n * @param properties Hyperlink properties\r\n */\r\n static create(properties: HyperlinkProperties): Hyperlink {\r\n return new Hyperlink(properties);\r\n }\r\n}\r\n"]}
|
|
@@ -2,7 +2,7 @@ import { XMLElement } from "../xml/XMLBuilder";
|
|
|
2
2
|
import { Paragraph } from "./Paragraph";
|
|
3
3
|
import { Table } from "./Table";
|
|
4
4
|
export type SDTLockType = "unlocked" | "sdtLocked" | "contentLocked" | "sdtContentLocked";
|
|
5
|
-
export type ContentControlType = "richText" | "plainText" | "comboBox" | "dropDownList" | "datePicker" | "checkbox" | "picture" | "buildingBlock" | "group";
|
|
5
|
+
export type ContentControlType = "richText" | "plainText" | "comboBox" | "dropDownList" | "datePicker" | "checkbox" | "picture" | "buildingBlock" | "group" | "citation" | "bibliography" | "docPartList" | "equation";
|
|
6
6
|
export interface ListItem {
|
|
7
7
|
displayText: string;
|
|
8
8
|
value: string;
|
|
@@ -32,6 +32,15 @@ export interface CheckboxProperties {
|
|
|
32
32
|
export interface BuildingBlockProperties {
|
|
33
33
|
gallery?: string;
|
|
34
34
|
category?: string;
|
|
35
|
+
isList?: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface SDTPlaceholder {
|
|
38
|
+
docPart: string;
|
|
39
|
+
}
|
|
40
|
+
export interface SDTDataBinding {
|
|
41
|
+
xpath: string;
|
|
42
|
+
prefixMappings?: string;
|
|
43
|
+
storeItemId?: string;
|
|
35
44
|
}
|
|
36
45
|
export interface SDTProperties {
|
|
37
46
|
id?: number;
|
|
@@ -46,6 +55,9 @@ export interface SDTProperties {
|
|
|
46
55
|
datePicker?: DatePickerProperties;
|
|
47
56
|
checkbox?: CheckboxProperties;
|
|
48
57
|
buildingBlock?: BuildingBlockProperties;
|
|
58
|
+
placeholder?: SDTPlaceholder;
|
|
59
|
+
dataBinding?: SDTDataBinding;
|
|
60
|
+
showingPlcHdr?: boolean;
|
|
49
61
|
}
|
|
50
62
|
export type SDTContent = Table | Paragraph | StructuredDocumentTag;
|
|
51
63
|
export declare class StructuredDocumentTag {
|
|
@@ -99,5 +111,15 @@ export declare class StructuredDocumentTag {
|
|
|
99
111
|
unlock(): this;
|
|
100
112
|
isLocked(): boolean;
|
|
101
113
|
isContentEditable(): boolean;
|
|
114
|
+
getPlaceholder(): SDTPlaceholder | undefined;
|
|
115
|
+
setPlaceholder(docPart: string): this;
|
|
116
|
+
getDataBinding(): SDTDataBinding | undefined;
|
|
117
|
+
setDataBinding(xpath: string, prefixMappings?: string, storeItemId?: string): this;
|
|
118
|
+
isShowingPlaceholder(): boolean;
|
|
119
|
+
setShowingPlaceholder(val: boolean): this;
|
|
120
|
+
static createCitation(content?: SDTContent[], properties?: Partial<SDTProperties>): StructuredDocumentTag;
|
|
121
|
+
static createBibliography(content?: SDTContent[], properties?: Partial<SDTProperties>): StructuredDocumentTag;
|
|
122
|
+
static createDocPartList(gallery: string, category: string, content?: SDTContent[], properties?: Partial<SDTProperties>): StructuredDocumentTag;
|
|
123
|
+
static createEquation(content?: SDTContent[], properties?: Partial<SDTProperties>): StructuredDocumentTag;
|
|
102
124
|
}
|
|
103
125
|
//# sourceMappingURL=StructuredDocumentTag.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StructuredDocumentTag.d.ts","sourceRoot":"","sources":["../../src/elements/StructuredDocumentTag.ts"],"names":[],"mappings":"AAQA,OAAO,EAAc,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAKhC,MAAM,MAAM,WAAW,GACnB,UAAU,GACV,WAAW,GACX,eAAe,GACf,kBAAkB,CAAC;AAKvB,MAAM,MAAM,kBAAkB,GAC1B,UAAU,GACV,WAAW,GACX,UAAU,GACV,cAAc,GACd,YAAY,GACZ,UAAU,GACV,SAAS,GACT,eAAe,GACf,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"StructuredDocumentTag.d.ts","sourceRoot":"","sources":["../../src/elements/StructuredDocumentTag.ts"],"names":[],"mappings":"AAQA,OAAO,EAAc,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAKhC,MAAM,MAAM,WAAW,GACnB,UAAU,GACV,WAAW,GACX,eAAe,GACf,kBAAkB,CAAC;AAKvB,MAAM,MAAM,kBAAkB,GAC1B,UAAU,GACV,WAAW,GACX,UAAU,GACV,cAAc,GACd,YAAY,GACZ,UAAU,GACV,SAAS,GACT,eAAe,GACf,OAAO,GACP,UAAU,GACV,cAAc,GACd,aAAa,GACb,UAAU,CAAC;AAKf,MAAM,WAAW,QAAQ;IAEvB,WAAW,EAAE,MAAM,CAAC;IAEpB,KAAK,EAAE,MAAM,CAAC;CACf;AAKD,MAAM,WAAW,mBAAmB;IAElC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAKD,MAAM,WAAW,kBAAkB;IAEjC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAElB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAKD,MAAM,WAAW,sBAAsB;IAErC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAElB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAKD,MAAM,WAAW,oBAAoB;IAEnC,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,QAAQ,CAAC,EAAE,IAAI,CAAC;IAEhB,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,QAAQ,CAAC,EACL,WAAW,GACX,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,MAAM,GACN,QAAQ,CAAC;CACd;AAKD,MAAM,WAAW,kBAAkB;IAEjC,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAKD,MAAM,WAAW,uBAAuB;IAEtC,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAKD,MAAM,WAAW,cAAc;IAE7B,OAAO,EAAE,MAAM,CAAC;CACjB;AAKD,MAAM,WAAW,cAAc;IAE7B,KAAK,EAAE,MAAM,CAAC;IAEd,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAKD,MAAM,WAAW,aAAa;IAE5B,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,IAAI,CAAC,EAAE,WAAW,CAAC;IAEnB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,WAAW,CAAC,EAAE,kBAAkB,CAAC;IAEjC,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAEhC,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAE9B,YAAY,CAAC,EAAE,sBAAsB,CAAC;IAEtC,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAElC,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAE9B,aAAa,CAAC,EAAE,uBAAuB,CAAC;IAExC,WAAW,CAAC,EAAE,cAAc,CAAC;IAE7B,WAAW,CAAC,EAAE,cAAc,CAAC;IAE7B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAKD,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,SAAS,GAAG,qBAAqB,CAAC;AAoBnE,qBAAa,qBAAqB;IAChC,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,OAAO,CAAe;gBAOlB,UAAU,GAAE,aAAkB,EAAE,OAAO,GAAE,UAAU,EAAO;IAStE,KAAK,IAAI,MAAM,GAAG,SAAS;IAQ3B,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IASvB,MAAM,IAAI,MAAM,GAAG,SAAS;IAQ5B,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IASzB,OAAO,IAAI,WAAW,GAAG,SAAS;IAQlC,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IAShC,QAAQ,IAAI,MAAM,GAAG,SAAS;IAQ9B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAS7B,cAAc,IAAI,kBAAkB,GAAG,SAAS;IAQhD,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI;IAS9C,sBAAsB,IAAI,mBAAmB,GAAG,SAAS;IAQzD,sBAAsB,CAAC,UAAU,EAAE,mBAAmB,GAAG,IAAI;IAU7D,qBAAqB,IAAI,kBAAkB,GAAG,SAAS;IAQvD,qBAAqB,CAAC,UAAU,EAAE,kBAAkB,GAAG,IAAI;IAU3D,yBAAyB,IAAI,sBAAsB,GAAG,SAAS;IAQ/D,yBAAyB,CAAC,UAAU,EAAE,sBAAsB,GAAG,IAAI;IAUnE,uBAAuB,IAAI,oBAAoB,GAAG,SAAS;IAQ3D,uBAAuB,CAAC,UAAU,EAAE,oBAAoB,GAAG,IAAI;IAU/D,qBAAqB,IAAI,kBAAkB,GAAG,SAAS;IAQvD,qBAAqB,CAAC,UAAU,EAAE,kBAAkB,GAAG,IAAI;IAU3D,0BAA0B,IAAI,uBAAuB,GAAG,SAAS;IAQjE,gBAAgB,IAAI,uBAAuB,GAAG,SAAS;IAQvD,0BAA0B,CAAC,UAAU,EAAE,uBAAuB,GAAG,IAAI;IAUrE,YAAY,IAAI,QAAQ,EAAE,GAAG,SAAS;IActC,aAAa,IAAI,MAAM,GAAG,SAAS;IAQnC,SAAS,IAAI,OAAO;IASpB,WAAW,IAAI,OAAO;IAStB,YAAY,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI;IAStC,UAAU,IAAI,UAAU,EAAE;IAQ1B,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;IAQrC,YAAY,IAAI,IAAI;IASpB,KAAK,IAAI,UAAU;IAyRnB,MAAM,CAAC,SAAS,CACd,KAAK,EAAE,KAAK,EACZ,GAAG,SAAe,EAClB,IAAI,CAAC,EAAE,WAAW,GACjB,qBAAqB;IAiBxB,MAAM,CAAC,aAAa,CAClB,SAAS,EAAE,SAAS,EACpB,GAAG,CAAC,EAAE,MAAM,GACX,qBAAqB;IAexB,MAAM,CAAC,MAAM,CAAC,UAAU,GAAE,aAAkB,GAAG,qBAAqB;IAUpE,MAAM,CAAC,cAAc,CACnB,OAAO,GAAE,UAAU,EAAO,EAC1B,UAAU,GAAE,OAAO,CAAC,aAAa,CAAM,GACtC,qBAAqB;IAkBxB,MAAM,CAAC,eAAe,CACpB,OAAO,GAAE,UAAU,EAAO,EAC1B,SAAS,UAAQ,EACjB,UAAU,GAAE,OAAO,CAAC,aAAa,CAAM,GACtC,qBAAqB;IAmBxB,MAAM,CAAC,cAAc,CACnB,KAAK,EAAE,QAAQ,EAAE,EACjB,OAAO,GAAE,UAAU,EAAO,EAC1B,UAAU,GAAE,OAAO,CAAC,aAAa,CAAM,GACtC,qBAAqB;IAmBxB,MAAM,CAAC,kBAAkB,CACvB,KAAK,EAAE,QAAQ,EAAE,EACjB,OAAO,GAAE,UAAU,EAAO,EAC1B,UAAU,GAAE,OAAO,CAAC,aAAa,CAAM,GACtC,qBAAqB;IAmBxB,MAAM,CAAC,gBAAgB,CACrB,UAAU,SAAa,EACvB,OAAO,GAAE,UAAU,EAAO,EAC1B,UAAU,GAAE,OAAO,CAAC,aAAa,CAAM,GACtC,qBAAqB;IAmBxB,MAAM,CAAC,cAAc,CACnB,OAAO,UAAQ,EACf,OAAO,GAAE,UAAU,EAAO,EAC1B,UAAU,GAAE,OAAO,CAAC,aAAa,CAAM,GACtC,qBAAqB;IAsBxB,MAAM,CAAC,aAAa,CAClB,OAAO,GAAE,UAAU,EAAO,EAC1B,UAAU,GAAE,OAAO,CAAC,aAAa,CAAM,GACtC,qBAAqB;IAmBxB,MAAM,CAAC,mBAAmB,CACxB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,UAAU,EAAO,EAC1B,UAAU,GAAE,OAAO,CAAC,aAAa,CAAM,GACtC,qBAAqB;IAkBxB,MAAM,CAAC,WAAW,CAChB,OAAO,GAAE,UAAU,EAAO,EAC1B,UAAU,GAAE,OAAO,CAAC,aAAa,CAAM,GACtC,qBAAqB;IAyBxB,MAAM,IAAI,IAAI;IAgBd,QAAQ,IAAI,OAAO;IAkBnB,iBAAiB,IAAI,OAAO;IAQ5B,cAAc,IAAI,cAAc,GAAG,SAAS;IAQ5C,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAQrC,cAAc,IAAI,cAAc,GAAG,SAAS;IAU5C,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;IAQlF,oBAAoB,IAAI,OAAO;IAQ/B,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;IAUzC,MAAM,CAAC,cAAc,CACnB,OAAO,GAAE,UAAU,EAAO,EAC1B,UAAU,GAAE,OAAO,CAAC,aAAa,CAAM,GACtC,qBAAqB;IAgBxB,MAAM,CAAC,kBAAkB,CACvB,OAAO,GAAE,UAAU,EAAO,EAC1B,UAAU,GAAE,OAAO,CAAC,aAAa,CAAM,GACtC,qBAAqB;IAmBxB,MAAM,CAAC,iBAAiB,CACtB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,UAAU,EAAO,EAC1B,UAAU,GAAE,OAAO,CAAC,aAAa,CAAM,GACtC,qBAAqB;IAiBxB,MAAM,CAAC,cAAc,CACnB,OAAO,GAAE,UAAU,EAAO,EAC1B,UAAU,GAAE,OAAO,CAAC,aAAa,CAAM,GACtC,qBAAqB;CAUzB"}
|
|
@@ -143,6 +143,28 @@ class StructuredDocumentTag {
|
|
|
143
143
|
if (this.properties.alias) {
|
|
144
144
|
sdtPrChildren.push(XMLBuilder_1.XMLBuilder.wSelf("alias", { "w:val": this.properties.alias }));
|
|
145
145
|
}
|
|
146
|
+
if (this.properties.placeholder) {
|
|
147
|
+
sdtPrChildren.push(XMLBuilder_1.XMLBuilder.w("placeholder", {}, [
|
|
148
|
+
XMLBuilder_1.XMLBuilder.wSelf("docPart", { "w:val": this.properties.placeholder.docPart }),
|
|
149
|
+
]));
|
|
150
|
+
}
|
|
151
|
+
if (this.properties.showingPlcHdr !== undefined) {
|
|
152
|
+
sdtPrChildren.push(XMLBuilder_1.XMLBuilder.wSelf("showingPlcHdr", {
|
|
153
|
+
"w:val": this.properties.showingPlcHdr ? "true" : "false",
|
|
154
|
+
}));
|
|
155
|
+
}
|
|
156
|
+
if (this.properties.dataBinding) {
|
|
157
|
+
const dbAttrs = {
|
|
158
|
+
"w:xpath": this.properties.dataBinding.xpath,
|
|
159
|
+
};
|
|
160
|
+
if (this.properties.dataBinding.prefixMappings) {
|
|
161
|
+
dbAttrs["w:prefixMappings"] = this.properties.dataBinding.prefixMappings;
|
|
162
|
+
}
|
|
163
|
+
if (this.properties.dataBinding.storeItemId) {
|
|
164
|
+
dbAttrs["w:storeItemID"] = this.properties.dataBinding.storeItemId;
|
|
165
|
+
}
|
|
166
|
+
sdtPrChildren.push(XMLBuilder_1.XMLBuilder.wSelf("dataBinding", dbAttrs));
|
|
167
|
+
}
|
|
146
168
|
if (this.properties.controlType) {
|
|
147
169
|
switch (this.properties.controlType) {
|
|
148
170
|
case "richText":
|
|
@@ -262,6 +284,31 @@ class StructuredDocumentTag {
|
|
|
262
284
|
case "group":
|
|
263
285
|
sdtPrChildren.push(XMLBuilder_1.XMLBuilder.wSelf("group", {}));
|
|
264
286
|
break;
|
|
287
|
+
case "citation":
|
|
288
|
+
sdtPrChildren.push(XMLBuilder_1.XMLBuilder.wSelf("citation", {}));
|
|
289
|
+
break;
|
|
290
|
+
case "bibliography":
|
|
291
|
+
sdtPrChildren.push(XMLBuilder_1.XMLBuilder.wSelf("bibliography", {}));
|
|
292
|
+
break;
|
|
293
|
+
case "equation":
|
|
294
|
+
sdtPrChildren.push(XMLBuilder_1.XMLBuilder.wSelf("equation", {}));
|
|
295
|
+
break;
|
|
296
|
+
case "docPartList":
|
|
297
|
+
if (this.properties.buildingBlock) {
|
|
298
|
+
const dplChildren = [];
|
|
299
|
+
if (this.properties.buildingBlock.gallery) {
|
|
300
|
+
dplChildren.push(XMLBuilder_1.XMLBuilder.wSelf("docPartGallery", {
|
|
301
|
+
"w:val": this.properties.buildingBlock.gallery,
|
|
302
|
+
}));
|
|
303
|
+
}
|
|
304
|
+
if (this.properties.buildingBlock.category) {
|
|
305
|
+
dplChildren.push(XMLBuilder_1.XMLBuilder.wSelf("docPartCategory", {
|
|
306
|
+
"w:val": this.properties.buildingBlock.category,
|
|
307
|
+
}));
|
|
308
|
+
}
|
|
309
|
+
sdtPrChildren.push(XMLBuilder_1.XMLBuilder.w("docPartList", {}, dplChildren));
|
|
310
|
+
}
|
|
311
|
+
break;
|
|
265
312
|
}
|
|
266
313
|
}
|
|
267
314
|
if (sdtPrChildren.length > 0) {
|
|
@@ -378,6 +425,56 @@ class StructuredDocumentTag {
|
|
|
378
425
|
const lock = this.properties.lock;
|
|
379
426
|
return lock !== "contentLocked" && lock !== "sdtContentLocked";
|
|
380
427
|
}
|
|
428
|
+
getPlaceholder() {
|
|
429
|
+
return this.properties.placeholder;
|
|
430
|
+
}
|
|
431
|
+
setPlaceholder(docPart) {
|
|
432
|
+
this.properties.placeholder = { docPart };
|
|
433
|
+
return this;
|
|
434
|
+
}
|
|
435
|
+
getDataBinding() {
|
|
436
|
+
return this.properties.dataBinding;
|
|
437
|
+
}
|
|
438
|
+
setDataBinding(xpath, prefixMappings, storeItemId) {
|
|
439
|
+
this.properties.dataBinding = { xpath, prefixMappings, storeItemId };
|
|
440
|
+
return this;
|
|
441
|
+
}
|
|
442
|
+
isShowingPlaceholder() {
|
|
443
|
+
return this.properties.showingPlcHdr === true;
|
|
444
|
+
}
|
|
445
|
+
setShowingPlaceholder(val) {
|
|
446
|
+
this.properties.showingPlcHdr = val;
|
|
447
|
+
return this;
|
|
448
|
+
}
|
|
449
|
+
static createCitation(content = [], properties = {}) {
|
|
450
|
+
return new StructuredDocumentTag({
|
|
451
|
+
id: Date.now() % 1000000000,
|
|
452
|
+
controlType: "citation",
|
|
453
|
+
...properties,
|
|
454
|
+
}, content);
|
|
455
|
+
}
|
|
456
|
+
static createBibliography(content = [], properties = {}) {
|
|
457
|
+
return new StructuredDocumentTag({
|
|
458
|
+
id: Date.now() % 1000000000,
|
|
459
|
+
controlType: "bibliography",
|
|
460
|
+
...properties,
|
|
461
|
+
}, content);
|
|
462
|
+
}
|
|
463
|
+
static createDocPartList(gallery, category, content = [], properties = {}) {
|
|
464
|
+
return new StructuredDocumentTag({
|
|
465
|
+
id: Date.now() % 1000000000,
|
|
466
|
+
controlType: "docPartList",
|
|
467
|
+
buildingBlock: { gallery, category, isList: true },
|
|
468
|
+
...properties,
|
|
469
|
+
}, content);
|
|
470
|
+
}
|
|
471
|
+
static createEquation(content = [], properties = {}) {
|
|
472
|
+
return new StructuredDocumentTag({
|
|
473
|
+
id: Date.now() % 1000000000,
|
|
474
|
+
controlType: "equation",
|
|
475
|
+
...properties,
|
|
476
|
+
}, content);
|
|
477
|
+
}
|
|
381
478
|
}
|
|
382
479
|
exports.StructuredDocumentTag = StructuredDocumentTag;
|
|
383
480
|
//# sourceMappingURL=StructuredDocumentTag.js.map
|