docxmlater 11.0.10 → 12.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -13
- package/dist/core/Document.d.ts +28 -2
- package/dist/core/Document.d.ts.map +1 -1
- package/dist/core/Document.js +725 -170
- package/dist/core/Document.js.map +1 -1
- package/dist/core/DocumentGenerator.d.ts +1 -0
- package/dist/core/DocumentGenerator.d.ts.map +1 -1
- package/dist/core/DocumentGenerator.js +77 -25
- package/dist/core/DocumentGenerator.js.map +1 -1
- package/dist/core/DocumentParser.d.ts +7 -3
- package/dist/core/DocumentParser.d.ts.map +1 -1
- package/dist/core/DocumentParser.js +427 -81
- package/dist/core/DocumentParser.js.map +1 -1
- package/dist/core/RelationshipManager.d.ts.map +1 -1
- package/dist/core/RelationshipManager.js +2 -2
- package/dist/core/RelationshipManager.js.map +1 -1
- package/dist/elements/Comment.d.ts +15 -1
- package/dist/elements/Comment.d.ts.map +1 -1
- package/dist/elements/Comment.js +67 -12
- package/dist/elements/Comment.js.map +1 -1
- package/dist/elements/CommentManager.d.ts +4 -0
- package/dist/elements/CommentManager.d.ts.map +1 -1
- package/dist/elements/CommentManager.js +74 -16
- package/dist/elements/CommentManager.js.map +1 -1
- package/dist/elements/EndnoteManager.d.ts.map +1 -1
- package/dist/elements/EndnoteManager.js.map +1 -1
- package/dist/elements/Field.d.ts +10 -1
- package/dist/elements/Field.d.ts.map +1 -1
- package/dist/elements/Field.js +76 -34
- package/dist/elements/Field.js.map +1 -1
- package/dist/elements/FieldHelpers.d.ts +1 -0
- package/dist/elements/FieldHelpers.d.ts.map +1 -1
- package/dist/elements/FieldHelpers.js +8 -4
- package/dist/elements/FieldHelpers.js.map +1 -1
- package/dist/elements/Footer.d.ts +3 -1
- package/dist/elements/Footer.d.ts.map +1 -1
- package/dist/elements/Footer.js +39 -53
- package/dist/elements/Footer.js.map +1 -1
- package/dist/elements/FootnoteManager.d.ts.map +1 -1
- package/dist/elements/FootnoteManager.js.map +1 -1
- package/dist/elements/Header.d.ts +3 -1
- package/dist/elements/Header.d.ts.map +1 -1
- package/dist/elements/Header.js +39 -53
- package/dist/elements/Header.js.map +1 -1
- package/dist/elements/HeaderFooterManager.d.ts +4 -2
- package/dist/elements/HeaderFooterManager.d.ts.map +1 -1
- package/dist/elements/HeaderFooterManager.js +36 -6
- package/dist/elements/HeaderFooterManager.js.map +1 -1
- package/dist/elements/Hyperlink.d.ts +6 -1
- package/dist/elements/Hyperlink.d.ts.map +1 -1
- package/dist/elements/Hyperlink.js +69 -44
- package/dist/elements/Hyperlink.js.map +1 -1
- package/dist/elements/Image.d.ts.map +1 -1
- package/dist/elements/Image.js +33 -6
- package/dist/elements/Image.js.map +1 -1
- package/dist/elements/ImageManager.d.ts +1 -0
- package/dist/elements/ImageManager.d.ts.map +1 -1
- package/dist/elements/ImageManager.js +11 -0
- package/dist/elements/ImageManager.js.map +1 -1
- package/dist/elements/Paragraph.d.ts +3 -0
- package/dist/elements/Paragraph.d.ts.map +1 -1
- package/dist/elements/Paragraph.js +91 -26
- package/dist/elements/Paragraph.js.map +1 -1
- package/dist/elements/Revision.d.ts +4 -0
- package/dist/elements/Revision.d.ts.map +1 -1
- package/dist/elements/Revision.js +369 -29
- package/dist/elements/Revision.js.map +1 -1
- package/dist/elements/Run.d.ts +1 -0
- package/dist/elements/Run.d.ts.map +1 -1
- package/dist/elements/Run.js +24 -4
- package/dist/elements/Run.js.map +1 -1
- package/dist/elements/Section.d.ts.map +1 -1
- package/dist/elements/Section.js +17 -7
- package/dist/elements/Section.js.map +1 -1
- package/dist/elements/Shape.d.ts.map +1 -1
- package/dist/elements/Shape.js +50 -42
- package/dist/elements/Shape.js.map +1 -1
- package/dist/elements/StructuredDocumentTag.d.ts +9 -1
- package/dist/elements/StructuredDocumentTag.d.ts.map +1 -1
- package/dist/elements/StructuredDocumentTag.js +46 -6
- package/dist/elements/StructuredDocumentTag.js.map +1 -1
- package/dist/elements/Table.d.ts +2 -0
- package/dist/elements/Table.d.ts.map +1 -1
- package/dist/elements/Table.js +90 -42
- package/dist/elements/Table.js.map +1 -1
- package/dist/elements/TableCell.d.ts +1 -0
- package/dist/elements/TableCell.d.ts.map +1 -1
- package/dist/elements/TableCell.js +32 -13
- package/dist/elements/TableCell.js.map +1 -1
- package/dist/elements/TableOfContents.d.ts.map +1 -1
- package/dist/elements/TableOfContents.js +5 -7
- package/dist/elements/TableOfContents.js.map +1 -1
- package/dist/elements/TableRow.d.ts +1 -0
- package/dist/elements/TableRow.d.ts.map +1 -1
- package/dist/elements/TableRow.js +16 -1
- package/dist/elements/TableRow.js.map +1 -1
- package/dist/elements/TextBox.d.ts.map +1 -1
- package/dist/elements/TextBox.js +55 -42
- package/dist/elements/TextBox.js.map +1 -1
- package/dist/esm/core/Document.js +726 -171
- package/dist/esm/core/Document.js.map +1 -1
- package/dist/esm/core/DocumentGenerator.js +77 -25
- package/dist/esm/core/DocumentGenerator.js.map +1 -1
- package/dist/esm/core/DocumentParser.js +427 -81
- package/dist/esm/core/DocumentParser.js.map +1 -1
- package/dist/esm/core/RelationshipManager.js +2 -2
- package/dist/esm/core/RelationshipManager.js.map +1 -1
- package/dist/esm/elements/Comment.js +67 -12
- package/dist/esm/elements/Comment.js.map +1 -1
- package/dist/esm/elements/CommentManager.js +74 -16
- package/dist/esm/elements/CommentManager.js.map +1 -1
- package/dist/esm/elements/EndnoteManager.js.map +1 -1
- package/dist/esm/elements/Field.js +77 -35
- package/dist/esm/elements/Field.js.map +1 -1
- package/dist/esm/elements/FieldHelpers.js +7 -4
- package/dist/esm/elements/FieldHelpers.js.map +1 -1
- package/dist/esm/elements/Footer.js +39 -53
- package/dist/esm/elements/Footer.js.map +1 -1
- package/dist/esm/elements/FootnoteManager.js.map +1 -1
- package/dist/esm/elements/Header.js +39 -53
- package/dist/esm/elements/Header.js.map +1 -1
- package/dist/esm/elements/HeaderFooterManager.js +36 -6
- package/dist/esm/elements/HeaderFooterManager.js.map +1 -1
- package/dist/esm/elements/Hyperlink.js +69 -44
- package/dist/esm/elements/Hyperlink.js.map +1 -1
- package/dist/esm/elements/Image.js +33 -6
- package/dist/esm/elements/Image.js.map +1 -1
- package/dist/esm/elements/ImageManager.js +11 -0
- package/dist/esm/elements/ImageManager.js.map +1 -1
- package/dist/esm/elements/Paragraph.js +91 -26
- package/dist/esm/elements/Paragraph.js.map +1 -1
- package/dist/esm/elements/Revision.js +369 -29
- package/dist/esm/elements/Revision.js.map +1 -1
- package/dist/esm/elements/Run.js +24 -4
- package/dist/esm/elements/Run.js.map +1 -1
- package/dist/esm/elements/Section.js +17 -7
- package/dist/esm/elements/Section.js.map +1 -1
- package/dist/esm/elements/Shape.js +50 -42
- package/dist/esm/elements/Shape.js.map +1 -1
- package/dist/esm/elements/StructuredDocumentTag.js +46 -6
- package/dist/esm/elements/StructuredDocumentTag.js.map +1 -1
- package/dist/esm/elements/Table.js +90 -42
- package/dist/esm/elements/Table.js.map +1 -1
- package/dist/esm/elements/TableCell.js +32 -13
- package/dist/esm/elements/TableCell.js.map +1 -1
- package/dist/esm/elements/TableOfContents.js +5 -7
- package/dist/esm/elements/TableOfContents.js.map +1 -1
- package/dist/esm/elements/TableRow.js +16 -1
- package/dist/esm/elements/TableRow.js.map +1 -1
- package/dist/esm/elements/TextBox.js +55 -42
- package/dist/esm/elements/TextBox.js.map +1 -1
- package/dist/esm/formatting/AbstractNumbering.js +1 -1
- package/dist/esm/formatting/AbstractNumbering.js.map +1 -1
- package/dist/esm/formatting/NumberingLevel.js +8 -6
- package/dist/esm/formatting/NumberingLevel.js.map +1 -1
- package/dist/esm/formatting/NumberingManager.js +16 -1
- package/dist/esm/formatting/NumberingManager.js.map +1 -1
- package/dist/esm/formatting/Style.js +14 -0
- package/dist/esm/formatting/Style.js.map +1 -1
- package/dist/esm/formatting/StylesManager.js +14 -2
- package/dist/esm/formatting/StylesManager.js.map +1 -1
- package/dist/esm/helpers/CleanupHelper.js +103 -26
- package/dist/esm/helpers/CleanupHelper.js.map +1 -1
- package/dist/esm/images/ImageOptimizer.js +52 -4
- package/dist/esm/images/ImageOptimizer.js.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal.js +1 -1
- package/dist/esm/internal.js.map +1 -1
- package/dist/esm/processors/CompatibilityUpgrader.js +7 -1
- package/dist/esm/processors/CompatibilityUpgrader.js.map +1 -1
- package/dist/esm/processors/InMemoryRevisionAcceptor.js +134 -13
- package/dist/esm/processors/InMemoryRevisionAcceptor.js.map +1 -1
- package/dist/esm/processors/RevisionWalker.js +58 -8
- package/dist/esm/processors/RevisionWalker.js.map +1 -1
- package/dist/esm/processors/SelectiveRevisionAcceptor.js +116 -17
- package/dist/esm/processors/SelectiveRevisionAcceptor.js.map +1 -1
- package/dist/esm/processors/cnfStyleDecoder.js +7 -7
- package/dist/esm/processors/cnfStyleDecoder.js.map +1 -1
- package/dist/esm/processors/stripTrackedChanges.js +16 -5
- package/dist/esm/processors/stripTrackedChanges.js.map +1 -1
- package/dist/esm/utils/deepClone.js +24 -11
- package/dist/esm/utils/deepClone.js.map +1 -1
- package/dist/esm/utils/units.js +1 -1
- package/dist/esm/utils/units.js.map +1 -1
- package/dist/esm/utils/validation.js +11 -23
- package/dist/esm/utils/validation.js.map +1 -1
- package/dist/esm/utils/xmlSanitization.js +131 -7
- package/dist/esm/utils/xmlSanitization.js.map +1 -1
- package/dist/esm/validation/RevisionAutoFixer.js +69 -55
- package/dist/esm/validation/RevisionAutoFixer.js.map +1 -1
- package/dist/esm/validation/RevisionValidator.js +24 -20
- package/dist/esm/validation/RevisionValidator.js.map +1 -1
- package/dist/esm/xml/XMLBuilder.js +52 -20
- package/dist/esm/xml/XMLBuilder.js.map +1 -1
- package/dist/esm/xml/XMLParser.js +55 -13
- package/dist/esm/xml/XMLParser.js.map +1 -1
- package/dist/esm/zip/ZipHandler.js +37 -13
- package/dist/esm/zip/ZipHandler.js.map +1 -1
- package/dist/esm/zip/ZipReader.js +53 -6
- package/dist/esm/zip/ZipReader.js.map +1 -1
- package/dist/esm/zip/errors.js +7 -0
- package/dist/esm/zip/errors.js.map +1 -1
- package/dist/esm/zip/types.js +4 -0
- package/dist/esm/zip/types.js.map +1 -1
- package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
- package/dist/formatting/AbstractNumbering.js +1 -1
- package/dist/formatting/AbstractNumbering.js.map +1 -1
- package/dist/formatting/NumberingLevel.d.ts +1 -1
- package/dist/formatting/NumberingLevel.d.ts.map +1 -1
- package/dist/formatting/NumberingLevel.js +8 -6
- package/dist/formatting/NumberingLevel.js.map +1 -1
- package/dist/formatting/NumberingManager.d.ts.map +1 -1
- package/dist/formatting/NumberingManager.js +16 -1
- package/dist/formatting/NumberingManager.js.map +1 -1
- package/dist/formatting/Style.d.ts.map +1 -1
- package/dist/formatting/Style.js +14 -0
- package/dist/formatting/Style.js.map +1 -1
- package/dist/formatting/StylesManager.d.ts +2 -0
- package/dist/formatting/StylesManager.d.ts.map +1 -1
- package/dist/formatting/StylesManager.js +14 -2
- package/dist/formatting/StylesManager.js.map +1 -1
- package/dist/helpers/CleanupHelper.d.ts.map +1 -1
- package/dist/helpers/CleanupHelper.js +103 -26
- package/dist/helpers/CleanupHelper.js.map +1 -1
- package/dist/images/ImageOptimizer.d.ts.map +1 -1
- package/dist/images/ImageOptimizer.js +52 -4
- package/dist/images/ImageOptimizer.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +2 -1
- package/dist/internal.js.map +1 -1
- package/dist/processors/CompatibilityUpgrader.d.ts.map +1 -1
- package/dist/processors/CompatibilityUpgrader.js +7 -1
- package/dist/processors/CompatibilityUpgrader.js.map +1 -1
- package/dist/processors/InMemoryRevisionAcceptor.d.ts +1 -0
- package/dist/processors/InMemoryRevisionAcceptor.d.ts.map +1 -1
- package/dist/processors/InMemoryRevisionAcceptor.js +135 -13
- package/dist/processors/InMemoryRevisionAcceptor.js.map +1 -1
- package/dist/processors/RevisionWalker.d.ts +2 -0
- package/dist/processors/RevisionWalker.d.ts.map +1 -1
- package/dist/processors/RevisionWalker.js +58 -8
- package/dist/processors/RevisionWalker.js.map +1 -1
- package/dist/processors/SelectiveRevisionAcceptor.d.ts.map +1 -1
- package/dist/processors/SelectiveRevisionAcceptor.js +116 -17
- package/dist/processors/SelectiveRevisionAcceptor.js.map +1 -1
- package/dist/processors/cnfStyleDecoder.d.ts.map +1 -1
- package/dist/processors/cnfStyleDecoder.js +7 -7
- package/dist/processors/cnfStyleDecoder.js.map +1 -1
- package/dist/processors/stripTrackedChanges.d.ts.map +1 -1
- package/dist/processors/stripTrackedChanges.js +16 -5
- package/dist/processors/stripTrackedChanges.js.map +1 -1
- package/dist/utils/deepClone.d.ts.map +1 -1
- package/dist/utils/deepClone.js +24 -11
- package/dist/utils/deepClone.js.map +1 -1
- package/dist/utils/units.d.ts.map +1 -1
- package/dist/utils/units.js +1 -1
- package/dist/utils/units.js.map +1 -1
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +11 -23
- package/dist/utils/validation.js.map +1 -1
- package/dist/utils/xmlSanitization.d.ts +2 -0
- package/dist/utils/xmlSanitization.d.ts.map +1 -1
- package/dist/utils/xmlSanitization.js +133 -7
- package/dist/utils/xmlSanitization.js.map +1 -1
- package/dist/validation/RevisionAutoFixer.d.ts +6 -2
- package/dist/validation/RevisionAutoFixer.d.ts.map +1 -1
- package/dist/validation/RevisionAutoFixer.js +68 -54
- package/dist/validation/RevisionAutoFixer.js.map +1 -1
- package/dist/validation/RevisionValidator.d.ts +2 -0
- package/dist/validation/RevisionValidator.d.ts.map +1 -1
- package/dist/validation/RevisionValidator.js +26 -21
- package/dist/validation/RevisionValidator.js.map +1 -1
- package/dist/xml/XMLBuilder.d.ts +1 -0
- package/dist/xml/XMLBuilder.d.ts.map +1 -1
- package/dist/xml/XMLBuilder.js +52 -20
- package/dist/xml/XMLBuilder.js.map +1 -1
- package/dist/xml/XMLParser.d.ts +1 -0
- package/dist/xml/XMLParser.d.ts.map +1 -1
- package/dist/xml/XMLParser.js +55 -13
- package/dist/xml/XMLParser.js.map +1 -1
- package/dist/zip/ZipHandler.d.ts.map +1 -1
- package/dist/zip/ZipHandler.js +37 -13
- package/dist/zip/ZipHandler.js.map +1 -1
- package/dist/zip/ZipReader.d.ts.map +1 -1
- package/dist/zip/ZipReader.js +52 -5
- package/dist/zip/ZipReader.js.map +1 -1
- package/dist/zip/errors.d.ts +3 -0
- package/dist/zip/errors.d.ts.map +1 -1
- package/dist/zip/errors.js +9 -1
- package/dist/zip/errors.js.map +1 -1
- package/dist/zip/types.d.ts +4 -0
- package/dist/zip/types.d.ts.map +1 -1
- package/dist/zip/types.js +4 -0
- package/dist/zip/types.js.map +1 -1
- package/package.json +2 -2
- package/src/core/Document.ts +1159 -240
- package/src/core/DocumentGenerator.ts +106 -26
- package/src/core/DocumentParser.ts +681 -114
- package/src/core/RelationshipManager.ts +446 -442
- package/src/elements/Comment.ts +123 -18
- package/src/elements/CommentManager.ts +121 -22
- package/src/elements/EndnoteManager.ts +4 -1
- package/src/elements/Field.ts +134 -43
- package/src/elements/FieldHelpers.ts +20 -4
- package/src/elements/Footer.ts +62 -67
- package/src/elements/FootnoteManager.ts +4 -1
- package/src/elements/Header.ts +62 -67
- package/src/elements/HeaderFooterManager.ts +56 -8
- package/src/elements/Hyperlink.ts +150 -55
- package/src/elements/Image.ts +51 -7
- package/src/elements/ImageManager.ts +24 -0
- package/src/elements/Paragraph.ts +161 -40
- package/src/elements/Revision.ts +446 -47
- package/src/elements/Run.ts +44 -6
- package/src/elements/Section.ts +25 -9
- package/src/elements/Shape.ts +52 -44
- package/src/elements/StructuredDocumentTag.ts +83 -8
- package/src/elements/Table.ts +151 -50
- package/src/elements/TableCell.ts +57 -17
- package/src/elements/TableOfContents.ts +10 -9
- package/src/elements/TableRow.ts +35 -3
- package/src/elements/TextBox.ts +58 -43
- package/src/formatting/AbstractNumbering.ts +4 -2
- package/src/formatting/NumberingLevel.ts +50 -12
- package/src/formatting/NumberingManager.ts +32 -3
- package/src/formatting/Style.ts +14 -0
- package/src/formatting/StylesManager.ts +29 -2
- package/src/helpers/CleanupHelper.ts +122 -30
- package/src/images/ImageOptimizer.ts +64 -5
- package/src/index.ts +7 -0
- package/src/internal.ts +1 -0
- package/src/processors/CompatibilityUpgrader.ts +15 -2
- package/src/processors/InMemoryRevisionAcceptor.ts +276 -17
- package/src/processors/RevisionWalker.ts +83 -7
- package/src/processors/SelectiveRevisionAcceptor.ts +164 -28
- package/src/processors/cnfStyleDecoder.ts +18 -12
- package/src/processors/stripTrackedChanges.ts +47 -10
- package/src/utils/deepClone.ts +48 -14
- package/src/utils/units.ts +3 -1
- package/src/utils/validation.ts +30 -32
- package/src/utils/xmlSanitization.ts +218 -22
- package/src/validation/RevisionAutoFixer.ts +109 -65
- package/src/validation/RevisionValidator.ts +48 -23
- package/src/xml/XMLBuilder.ts +82 -22
- package/src/xml/XMLParser.ts +87 -20
- package/src/zip/ZipHandler.ts +61 -21
- package/src/zip/ZipReader.ts +135 -13
- package/src/zip/errors.ts +15 -0
- package/src/zip/types.ts +44 -2
|
@@ -66,6 +66,13 @@ export interface HyperlinkProperties {
|
|
|
66
66
|
text?: string;
|
|
67
67
|
/** Text formatting */
|
|
68
68
|
formatting?: RunFormatting;
|
|
69
|
+
/**
|
|
70
|
+
* Use the supplied formatting exactly as given instead of layering it over
|
|
71
|
+
* the default hyperlink styling. Set when the formatting comes from parsed
|
|
72
|
+
* XML, so load→save does not inject direct formatting that overrides the
|
|
73
|
+
* document's Hyperlink character style.
|
|
74
|
+
*/
|
|
75
|
+
preserveFormatting?: boolean;
|
|
69
76
|
/** Tooltip text */
|
|
70
77
|
tooltip?: string;
|
|
71
78
|
/** Relationship ID (set by Document when saving) */
|
|
@@ -87,7 +94,12 @@ export class Hyperlink {
|
|
|
87
94
|
private url?: string;
|
|
88
95
|
private anchor?: string;
|
|
89
96
|
private text: string;
|
|
90
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Display-text runs. Word splits hyperlink text into multiple runs when
|
|
99
|
+
* formatting varies mid-link, so a single-run model would drop per-run
|
|
100
|
+
* formatting on round-trip. Always holds at least one run.
|
|
101
|
+
*/
|
|
102
|
+
private runs: Run[];
|
|
91
103
|
private tooltip?: string;
|
|
92
104
|
private relationshipId?: string;
|
|
93
105
|
private formatting: RunFormatting;
|
|
@@ -137,7 +149,7 @@ export class Hyperlink {
|
|
|
137
149
|
if (this._isEmpty) {
|
|
138
150
|
this.text = '';
|
|
139
151
|
this.formatting = {};
|
|
140
|
-
this.
|
|
152
|
+
this.runs = [new Run('', {})];
|
|
141
153
|
return;
|
|
142
154
|
}
|
|
143
155
|
|
|
@@ -159,16 +171,22 @@ export class Hyperlink {
|
|
|
159
171
|
this.text = validation.cleanedText;
|
|
160
172
|
}
|
|
161
173
|
|
|
162
|
-
//
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
...properties.formatting
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
174
|
+
// Default hyperlink styling (Verdana 12pt blue underlined) is for
|
|
175
|
+
// programmatically created links. Parsed links must keep exactly the
|
|
176
|
+
// formatting found in the source XML — merging these defaults underneath
|
|
177
|
+
// would add direct formatting that overrides the document's Hyperlink
|
|
178
|
+
// character style on round-trip.
|
|
179
|
+
this.formatting = properties.preserveFormatting
|
|
180
|
+
? { ...properties.formatting }
|
|
181
|
+
: {
|
|
182
|
+
font: 'Verdana',
|
|
183
|
+
size: 12,
|
|
184
|
+
color: '0000FF', // Standard hyperlink blue
|
|
185
|
+
underline: 'single',
|
|
186
|
+
...properties.formatting,
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
this.runs = [new Run(this.text, this.formatting)];
|
|
172
190
|
}
|
|
173
191
|
|
|
174
192
|
/**
|
|
@@ -239,7 +257,7 @@ export class Hyperlink {
|
|
|
239
257
|
const revisionId = this.trackingContext!.getRevisionManager().consumeNextId();
|
|
240
258
|
const author = this.trackingContext!.getAuthor();
|
|
241
259
|
|
|
242
|
-
this.
|
|
260
|
+
this.runs[0]!.setPropertyChangeRevision({
|
|
243
261
|
id: revisionId,
|
|
244
262
|
author,
|
|
245
263
|
date: new Date(),
|
|
@@ -357,14 +375,26 @@ export class Hyperlink {
|
|
|
357
375
|
/**
|
|
358
376
|
* Gets the display text
|
|
359
377
|
*
|
|
360
|
-
* This method delegates to the internal
|
|
378
|
+
* This method delegates to the internal runs to ensure the returned text
|
|
361
379
|
* is always accurate and matches what will be in the generated XML,
|
|
362
|
-
* per ECMA-376 Part 1 §17.16.22.
|
|
380
|
+
* per ECMA-376 Part 1 §17.16.22. Multi-run hyperlinks concatenate the
|
|
381
|
+
* text of every run in document order.
|
|
363
382
|
*
|
|
364
383
|
* @returns The display text including any special characters (tabs, breaks, etc.)
|
|
365
384
|
*/
|
|
366
385
|
getText(): string {
|
|
367
|
-
return this.run.getText();
|
|
386
|
+
return this.runs.map((run) => run.getText()).join('');
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Replaces the display text. Collapses to a single run (keeping the first
|
|
391
|
+
* run's formatting) because the caller-supplied text supersedes any
|
|
392
|
+
* per-run split the source document had.
|
|
393
|
+
*/
|
|
394
|
+
private replaceRunText(text: string): void {
|
|
395
|
+
const first = this.runs[0]!;
|
|
396
|
+
first.setText(text);
|
|
397
|
+
this.runs = [first];
|
|
368
398
|
}
|
|
369
399
|
|
|
370
400
|
/**
|
|
@@ -379,11 +409,18 @@ export class Hyperlink {
|
|
|
379
409
|
warnToConsole: true,
|
|
380
410
|
});
|
|
381
411
|
|
|
382
|
-
// Use cleaned text if available
|
|
383
|
-
|
|
412
|
+
// Use cleaned text if available.
|
|
413
|
+
// `??` (not `||`) so a cleaned result of '' (input that was entirely XML
|
|
414
|
+
// markup) is kept rather than falling back to the original markup-laden text.
|
|
415
|
+
const cleanedText = validation.cleanedText ?? text;
|
|
384
416
|
|
|
385
417
|
const previousValue = this.text;
|
|
386
418
|
|
|
419
|
+
// Assigning display text clears the empty/invisible flag — otherwise
|
|
420
|
+
// toXML() would keep emitting a childless w:hyperlink and silently drop
|
|
421
|
+
// the text that was just set.
|
|
422
|
+
this._isEmpty = false;
|
|
423
|
+
|
|
387
424
|
// Skip if text unchanged
|
|
388
425
|
if (previousValue === cleanedText) {
|
|
389
426
|
return this;
|
|
@@ -398,7 +435,7 @@ export class Hyperlink {
|
|
|
398
435
|
|
|
399
436
|
// Apply the change to this hyperlink
|
|
400
437
|
this.text = cleanedText;
|
|
401
|
-
this.
|
|
438
|
+
this.replaceRunText(cleanedText);
|
|
402
439
|
|
|
403
440
|
// Create delete/insert revision pair
|
|
404
441
|
const deletion = Revision.createDeletion(author, [oldHyperlink]);
|
|
@@ -418,7 +455,7 @@ export class Hyperlink {
|
|
|
418
455
|
|
|
419
456
|
// Non-tracking path (original behavior)
|
|
420
457
|
this.text = cleanedText;
|
|
421
|
-
this.
|
|
458
|
+
this.replaceRunText(cleanedText);
|
|
422
459
|
return this;
|
|
423
460
|
}
|
|
424
461
|
|
|
@@ -428,11 +465,35 @@ export class Hyperlink {
|
|
|
428
465
|
* @param run - The run to use for this hyperlink
|
|
429
466
|
*/
|
|
430
467
|
setRun(run: Run): this {
|
|
431
|
-
this.
|
|
468
|
+
this.runs = [run];
|
|
432
469
|
this.text = run.getText();
|
|
433
470
|
return this;
|
|
434
471
|
}
|
|
435
472
|
|
|
473
|
+
/**
|
|
474
|
+
* Replaces all runs of this hyperlink (multi-run display text)
|
|
475
|
+
* Used by DocumentParser when a w:hyperlink holds multiple w:r children —
|
|
476
|
+
* Word splits the display text into one run per formatting change, and
|
|
477
|
+
* each run must keep its own rPr for round-trip fidelity.
|
|
478
|
+
* @param runs - Runs in document order (ignored if empty)
|
|
479
|
+
*/
|
|
480
|
+
setRuns(runs: Run[]): this {
|
|
481
|
+
if (runs.length === 0) {
|
|
482
|
+
return this;
|
|
483
|
+
}
|
|
484
|
+
this.runs = [...runs];
|
|
485
|
+
this.text = this.getText();
|
|
486
|
+
return this;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Gets all runs carrying the display text
|
|
491
|
+
* Single-run hyperlinks return a one-element array.
|
|
492
|
+
*/
|
|
493
|
+
getRuns(): Run[] {
|
|
494
|
+
return [...this.runs];
|
|
495
|
+
}
|
|
496
|
+
|
|
436
497
|
/**
|
|
437
498
|
* Gets the tooltip
|
|
438
499
|
*/
|
|
@@ -524,7 +585,7 @@ export class Hyperlink {
|
|
|
524
585
|
// Validate that clearing URL doesn't create empty hyperlink
|
|
525
586
|
if (!url && !this.anchor) {
|
|
526
587
|
throw new Error(
|
|
527
|
-
`Cannot set URL to undefined: Hyperlink "${this.
|
|
588
|
+
`Cannot set URL to undefined: Hyperlink "${this.getText()}" has no anchor. ` +
|
|
528
589
|
`Clearing the URL would create an invalid hyperlink per ECMA-376 §17.16.22. ` +
|
|
529
590
|
`Either provide a new URL or delete the hyperlink entirely.`
|
|
530
591
|
);
|
|
@@ -549,9 +610,9 @@ export class Hyperlink {
|
|
|
549
610
|
// Apply the change to this hyperlink
|
|
550
611
|
this.url = url;
|
|
551
612
|
this.relationshipId = undefined;
|
|
552
|
-
if (this.
|
|
613
|
+
if (this.getText() === oldUrl) {
|
|
553
614
|
this.text = url || this.anchor || 'Link';
|
|
554
|
-
this.
|
|
615
|
+
this.replaceRunText(this.text);
|
|
555
616
|
}
|
|
556
617
|
|
|
557
618
|
// Create delete/insert revision pair
|
|
@@ -576,10 +637,10 @@ export class Hyperlink {
|
|
|
576
637
|
|
|
577
638
|
// Update text ONLY if it was auto-generated from the old URL
|
|
578
639
|
// This preserves user-provided text (even if it's "Link")
|
|
579
|
-
// Use
|
|
580
|
-
if (this.
|
|
640
|
+
// Use getText() to ensure we check the actual current text, not stale cache
|
|
641
|
+
if (this.getText() === oldUrl) {
|
|
581
642
|
this.text = url || this.anchor || 'Link';
|
|
582
|
-
this.
|
|
643
|
+
this.replaceRunText(this.text);
|
|
583
644
|
}
|
|
584
645
|
|
|
585
646
|
return this;
|
|
@@ -600,7 +661,7 @@ export class Hyperlink {
|
|
|
600
661
|
// Validate that clearing anchor doesn't create empty hyperlink
|
|
601
662
|
if (!anchor && !this.url) {
|
|
602
663
|
throw new Error(
|
|
603
|
-
`Cannot set anchor to undefined: Hyperlink "${this.
|
|
664
|
+
`Cannot set anchor to undefined: Hyperlink "${this.getText()}" has no URL. ` +
|
|
604
665
|
`Clearing the anchor would create an invalid hyperlink per ECMA-376 §17.16.22. ` +
|
|
605
666
|
`Either provide a new anchor or delete the hyperlink entirely.`
|
|
606
667
|
);
|
|
@@ -632,9 +693,9 @@ export class Hyperlink {
|
|
|
632
693
|
this.url = undefined;
|
|
633
694
|
this.relationshipId = undefined;
|
|
634
695
|
}
|
|
635
|
-
if (this.
|
|
696
|
+
if (this.getText() === oldAnchor) {
|
|
636
697
|
this.text = anchor || this.url || 'Link';
|
|
637
|
-
this.
|
|
698
|
+
this.replaceRunText(this.text);
|
|
638
699
|
}
|
|
639
700
|
|
|
640
701
|
// Create delete/insert revision pair
|
|
@@ -664,10 +725,10 @@ export class Hyperlink {
|
|
|
664
725
|
}
|
|
665
726
|
|
|
666
727
|
// Update text ONLY if it was auto-generated from the old anchor
|
|
667
|
-
// Use
|
|
668
|
-
if (this.
|
|
728
|
+
// Use getText() to ensure we check the actual current text, not stale cache
|
|
729
|
+
if (this.getText() === oldAnchor) {
|
|
669
730
|
this.text = anchor || this.url || 'Link';
|
|
670
|
-
this.
|
|
731
|
+
this.replaceRunText(this.text);
|
|
671
732
|
}
|
|
672
733
|
|
|
673
734
|
return this;
|
|
@@ -675,9 +736,10 @@ export class Hyperlink {
|
|
|
675
736
|
|
|
676
737
|
/**
|
|
677
738
|
* Gets the run
|
|
739
|
+
* Multi-run hyperlinks return the first run — use getRuns() for all of them.
|
|
678
740
|
*/
|
|
679
741
|
getRun(): Run {
|
|
680
|
-
return this.
|
|
742
|
+
return this.runs[0]!;
|
|
681
743
|
}
|
|
682
744
|
|
|
683
745
|
/**
|
|
@@ -707,16 +769,34 @@ export class Hyperlink {
|
|
|
707
769
|
// Merge mode (default, backwards-compatible): merge with existing
|
|
708
770
|
this.formatting = { ...this.formatting, ...formatting };
|
|
709
771
|
}
|
|
710
|
-
//
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
this.
|
|
772
|
+
// Rebuild every run, layering the patch over each run's own rPr so
|
|
773
|
+
// multi-run links keep per-run distinctions the caller did not touch.
|
|
774
|
+
// Replace mode discards per-run rPr by design.
|
|
775
|
+
this.runs = this.runs.map((run) =>
|
|
776
|
+
Run.createFromContent(
|
|
777
|
+
run.getContent(),
|
|
778
|
+
options?.replace ? { ...formatting } : { ...run.getFormatting(), ...formatting }
|
|
779
|
+
)
|
|
780
|
+
);
|
|
781
|
+
this.text = this.getText(); // Keep cache in sync
|
|
714
782
|
if (this.trackingContext?.isEnabled()) {
|
|
715
783
|
this._applyFormattingRPrChange(previousFormatting);
|
|
716
784
|
}
|
|
717
785
|
return this;
|
|
718
786
|
}
|
|
719
787
|
|
|
788
|
+
/**
|
|
789
|
+
* Layers a formatting patch over every display-text run. Content is
|
|
790
|
+
* rebuilt via Run.createFromContent so tabs/breaks survive, and each
|
|
791
|
+
* run keeps its other rPr values — stamping the hyperlink-level
|
|
792
|
+
* formatting over them would erase per-run formatting in multi-run links.
|
|
793
|
+
*/
|
|
794
|
+
private patchRunFormatting(patch: RunFormatting): void {
|
|
795
|
+
this.runs = this.runs.map((run) =>
|
|
796
|
+
Run.createFromContent(run.getContent(), { ...run.getFormatting(), ...patch })
|
|
797
|
+
);
|
|
798
|
+
}
|
|
799
|
+
|
|
720
800
|
/**
|
|
721
801
|
* Gets run formatting (returns this hyperlink for fluent API)
|
|
722
802
|
* @returns This hyperlink for method chaining
|
|
@@ -798,7 +878,7 @@ export class Hyperlink {
|
|
|
798
878
|
setColor(color: string): this {
|
|
799
879
|
const previousFormatting = { ...this.formatting };
|
|
800
880
|
this.formatting.color = color;
|
|
801
|
-
this.
|
|
881
|
+
this.patchRunFormatting({ color });
|
|
802
882
|
if (this.trackingContext?.isEnabled() && previousFormatting.color !== color) {
|
|
803
883
|
this._applyFormattingRPrChange(previousFormatting);
|
|
804
884
|
}
|
|
@@ -813,7 +893,7 @@ export class Hyperlink {
|
|
|
813
893
|
setUnderline(underline: boolean | 'single' | 'double' | 'dotted' | 'thick' | 'dash'): this {
|
|
814
894
|
const previousFormatting = { ...this.formatting };
|
|
815
895
|
this.formatting.underline = underline;
|
|
816
|
-
this.
|
|
896
|
+
this.patchRunFormatting({ underline });
|
|
817
897
|
if (this.trackingContext?.isEnabled() && previousFormatting.underline !== underline) {
|
|
818
898
|
this._applyFormattingRPrChange(previousFormatting);
|
|
819
899
|
}
|
|
@@ -828,7 +908,7 @@ export class Hyperlink {
|
|
|
828
908
|
setBold(bold = true): this {
|
|
829
909
|
const previousFormatting = { ...this.formatting };
|
|
830
910
|
this.formatting.bold = bold;
|
|
831
|
-
this.
|
|
911
|
+
this.patchRunFormatting({ bold });
|
|
832
912
|
if (this.trackingContext?.isEnabled() && previousFormatting.bold !== bold) {
|
|
833
913
|
this._applyFormattingRPrChange(previousFormatting);
|
|
834
914
|
}
|
|
@@ -843,7 +923,7 @@ export class Hyperlink {
|
|
|
843
923
|
setItalic(italic = true): this {
|
|
844
924
|
const previousFormatting = { ...this.formatting };
|
|
845
925
|
this.formatting.italic = italic;
|
|
846
|
-
this.
|
|
926
|
+
this.patchRunFormatting({ italic });
|
|
847
927
|
if (this.trackingContext?.isEnabled() && previousFormatting.italic !== italic) {
|
|
848
928
|
this._applyFormattingRPrChange(previousFormatting);
|
|
849
929
|
}
|
|
@@ -858,7 +938,7 @@ export class Hyperlink {
|
|
|
858
938
|
setFont(font: string): this {
|
|
859
939
|
const previousFormatting = { ...this.formatting };
|
|
860
940
|
this.formatting.font = font;
|
|
861
|
-
this.
|
|
941
|
+
this.patchRunFormatting({ font });
|
|
862
942
|
if (this.trackingContext?.isEnabled() && previousFormatting.font !== font) {
|
|
863
943
|
this._applyFormattingRPrChange(previousFormatting);
|
|
864
944
|
}
|
|
@@ -873,7 +953,7 @@ export class Hyperlink {
|
|
|
873
953
|
setSize(size: number): this {
|
|
874
954
|
const previousFormatting = { ...this.formatting };
|
|
875
955
|
this.formatting.size = size;
|
|
876
|
-
this.
|
|
956
|
+
this.patchRunFormatting({ size });
|
|
877
957
|
if (this.trackingContext?.isEnabled() && previousFormatting.size !== size) {
|
|
878
958
|
this._applyFormattingRPrChange(previousFormatting);
|
|
879
959
|
}
|
|
@@ -1007,8 +1087,13 @@ export class Hyperlink {
|
|
|
1007
1087
|
}
|
|
1008
1088
|
|
|
1009
1089
|
// Fix 5: Fix common typos
|
|
1090
|
+
// Compare against the value immediately before this replace (not this.url)
|
|
1091
|
+
// so 'Upgraded HTTP to HTTPS' is reported only when the http→https
|
|
1092
|
+
// rewrite actually fired — an earlier fix (space encoding, double-slash
|
|
1093
|
+
// collapse) on an already-https URL must not trigger this message.
|
|
1094
|
+
const beforeUpgrade = fixedUrl;
|
|
1010
1095
|
fixedUrl = fixedUrl.replace(/^http:\/\//i, 'https://'); // Prefer HTTPS
|
|
1011
|
-
if (fixedUrl !==
|
|
1096
|
+
if (fixedUrl !== beforeUpgrade) {
|
|
1012
1097
|
fixed.push('Upgraded HTTP to HTTPS');
|
|
1013
1098
|
}
|
|
1014
1099
|
|
|
@@ -1134,21 +1219,32 @@ export class Hyperlink {
|
|
|
1134
1219
|
tooltip: this.tooltip,
|
|
1135
1220
|
relationshipId: this.relationshipId,
|
|
1136
1221
|
formatting: { ...this.formatting },
|
|
1222
|
+
// this.formatting is already fully resolved — re-merging constructor
|
|
1223
|
+
// defaults would resurrect styling the original no longer carries
|
|
1224
|
+
preserveFormatting: true,
|
|
1137
1225
|
tgtFrame: this.tgtFrame,
|
|
1138
1226
|
history: this.history,
|
|
1139
1227
|
docLocation: this.docLocation,
|
|
1228
|
+
// Carry the empty/invisible flag so a clone of a self-closing hyperlink
|
|
1229
|
+
// serializes self-closing too (matters for the deletion half of tracked
|
|
1230
|
+
// changes, which snapshots the source via clone()).
|
|
1231
|
+
isEmpty: this._isEmpty,
|
|
1140
1232
|
});
|
|
1141
1233
|
|
|
1142
|
-
// Copy
|
|
1143
|
-
|
|
1144
|
-
|
|
1234
|
+
// Copy every run with its content and formatting (multi-run links keep
|
|
1235
|
+
// one cloned run per source run)
|
|
1236
|
+
cloned.runs = this.runs.map((run) => {
|
|
1237
|
+
const copy = run.clone();
|
|
1145
1238
|
|
|
1146
1239
|
// Preserve rPrChange from the original run (formatting tracked changes)
|
|
1147
|
-
|
|
1240
|
+
// — Run.clone() copies content/formatting but not the revision
|
|
1241
|
+
const existingRPrChange = run.getPropertyChangeRevision();
|
|
1148
1242
|
if (existingRPrChange) {
|
|
1149
|
-
|
|
1243
|
+
copy.setPropertyChangeRevision({ ...existingRPrChange });
|
|
1150
1244
|
}
|
|
1151
|
-
|
|
1245
|
+
return copy;
|
|
1246
|
+
});
|
|
1247
|
+
cloned.text = cloned.getText();
|
|
1152
1248
|
|
|
1153
1249
|
return cloned;
|
|
1154
1250
|
}
|
|
@@ -1231,13 +1327,12 @@ export class Hyperlink {
|
|
|
1231
1327
|
};
|
|
1232
1328
|
}
|
|
1233
1329
|
|
|
1234
|
-
//
|
|
1235
|
-
|
|
1236
|
-
|
|
1330
|
+
// One <w:r> child per run, each with its own <w:rPr> — collapsing to a
|
|
1331
|
+
// single run would drop per-run formatting in multi-run display text
|
|
1237
1332
|
return {
|
|
1238
1333
|
name: 'w:hyperlink',
|
|
1239
1334
|
attributes,
|
|
1240
|
-
children:
|
|
1335
|
+
children: this.runs.map((run) => run.toXML()),
|
|
1241
1336
|
};
|
|
1242
1337
|
}
|
|
1243
1338
|
|
package/src/elements/Image.ts
CHANGED
|
@@ -335,8 +335,11 @@ export class Image {
|
|
|
335
335
|
private flipV = false;
|
|
336
336
|
private border?: ImageBorder;
|
|
337
337
|
|
|
338
|
-
// Set true when a serialization-affecting setter
|
|
339
|
-
//
|
|
338
|
+
// Set true when a serialization-affecting setter mutates this image after parse,
|
|
339
|
+
// so an owning ImageRun knows to refresh its captured raw run XML. Identity setters
|
|
340
|
+
// the parse/save pipeline invokes on every image (setRelationshipId/setDocPrId) and
|
|
341
|
+
// the parser-internal _setRawPassthrough must NOT set this, or unmodified documents
|
|
342
|
+
// would lose raw-XML round-trip fidelity.
|
|
340
343
|
private _mutated = false;
|
|
341
344
|
|
|
342
345
|
// Group A: Simple attribute preservation (ECMA-376 compliance)
|
|
@@ -967,6 +970,7 @@ export class Image {
|
|
|
967
970
|
this.height = Math.round(width * ratio);
|
|
968
971
|
}
|
|
969
972
|
this.width = width;
|
|
973
|
+
this._mutated = true;
|
|
970
974
|
return this;
|
|
971
975
|
}
|
|
972
976
|
|
|
@@ -976,6 +980,7 @@ export class Image {
|
|
|
976
980
|
this.width = Math.round(height * ratio);
|
|
977
981
|
}
|
|
978
982
|
this.height = height;
|
|
983
|
+
this._mutated = true;
|
|
979
984
|
return this;
|
|
980
985
|
}
|
|
981
986
|
|
|
@@ -1018,6 +1023,7 @@ export class Image {
|
|
|
1018
1023
|
|
|
1019
1024
|
setAltText(altText: string): this {
|
|
1020
1025
|
this.description = altText;
|
|
1026
|
+
this._mutated = true;
|
|
1021
1027
|
return this;
|
|
1022
1028
|
}
|
|
1023
1029
|
|
|
@@ -1027,6 +1033,7 @@ export class Image {
|
|
|
1027
1033
|
|
|
1028
1034
|
setTitle(title: string): this {
|
|
1029
1035
|
this.title = title;
|
|
1036
|
+
this._mutated = true;
|
|
1030
1037
|
return this;
|
|
1031
1038
|
}
|
|
1032
1039
|
|
|
@@ -1035,10 +1042,11 @@ export class Image {
|
|
|
1035
1042
|
}
|
|
1036
1043
|
|
|
1037
1044
|
rotate(degrees: number): this {
|
|
1045
|
+
// wp:extent/a:ext describe the pre-rotation bounding box per ECMA-376
|
|
1046
|
+
// §20.1.7.6 — a:xfrm/@rot rotates about the center, so swapping the
|
|
1047
|
+
// extents for 90/270 would stretch the bitmap before rotating it.
|
|
1038
1048
|
this.rotation = ((degrees % 360) + 360) % 360;
|
|
1039
|
-
|
|
1040
|
-
[this.width, this.height] = [this.height, this.width];
|
|
1041
|
-
}
|
|
1049
|
+
this._mutated = true;
|
|
1042
1050
|
return this;
|
|
1043
1051
|
}
|
|
1044
1052
|
|
|
@@ -1048,6 +1056,7 @@ export class Image {
|
|
|
1048
1056
|
|
|
1049
1057
|
setFlipH(flip: boolean): this {
|
|
1050
1058
|
this.flipH = flip;
|
|
1059
|
+
this._mutated = true;
|
|
1051
1060
|
return this;
|
|
1052
1061
|
}
|
|
1053
1062
|
|
|
@@ -1057,6 +1066,7 @@ export class Image {
|
|
|
1057
1066
|
|
|
1058
1067
|
setFlipV(flip: boolean): this {
|
|
1059
1068
|
this.flipV = flip;
|
|
1069
|
+
this._mutated = true;
|
|
1060
1070
|
return this;
|
|
1061
1071
|
}
|
|
1062
1072
|
|
|
@@ -1071,6 +1081,7 @@ export class Image {
|
|
|
1071
1081
|
}
|
|
1072
1082
|
setPresetGeometry(geom: PresetGeometry): this {
|
|
1073
1083
|
this.presetGeometry = geom;
|
|
1084
|
+
this._mutated = true;
|
|
1074
1085
|
return this;
|
|
1075
1086
|
}
|
|
1076
1087
|
|
|
@@ -1079,6 +1090,7 @@ export class Image {
|
|
|
1079
1090
|
}
|
|
1080
1091
|
setCompressionState(state: BlipCompressionState): this {
|
|
1081
1092
|
this.compressionState = state;
|
|
1093
|
+
this._mutated = true;
|
|
1082
1094
|
return this;
|
|
1083
1095
|
}
|
|
1084
1096
|
|
|
@@ -1087,6 +1099,7 @@ export class Image {
|
|
|
1087
1099
|
}
|
|
1088
1100
|
setBwMode(mode: string): this {
|
|
1089
1101
|
this.bwMode = mode;
|
|
1102
|
+
this._mutated = true;
|
|
1090
1103
|
return this;
|
|
1091
1104
|
}
|
|
1092
1105
|
|
|
@@ -1107,6 +1120,7 @@ export class Image {
|
|
|
1107
1120
|
this.inlineDistB = distB;
|
|
1108
1121
|
this.inlineDistL = distL;
|
|
1109
1122
|
this.inlineDistR = distR;
|
|
1123
|
+
this._mutated = true;
|
|
1110
1124
|
return this;
|
|
1111
1125
|
}
|
|
1112
1126
|
|
|
@@ -1115,6 +1129,7 @@ export class Image {
|
|
|
1115
1129
|
}
|
|
1116
1130
|
setNoChangeAspect(val: boolean): this {
|
|
1117
1131
|
this.noChangeAspect = val;
|
|
1132
|
+
this._mutated = true;
|
|
1118
1133
|
return this;
|
|
1119
1134
|
}
|
|
1120
1135
|
|
|
@@ -1123,6 +1138,7 @@ export class Image {
|
|
|
1123
1138
|
}
|
|
1124
1139
|
setHidden(val: boolean): this {
|
|
1125
1140
|
this.hidden = val;
|
|
1141
|
+
this._mutated = true;
|
|
1126
1142
|
return this;
|
|
1127
1143
|
}
|
|
1128
1144
|
|
|
@@ -1131,6 +1147,7 @@ export class Image {
|
|
|
1131
1147
|
}
|
|
1132
1148
|
setBlipFillDpi(dpi: number | undefined): this {
|
|
1133
1149
|
this.blipFillDpi = dpi;
|
|
1150
|
+
this._mutated = true;
|
|
1134
1151
|
return this;
|
|
1135
1152
|
}
|
|
1136
1153
|
|
|
@@ -1139,6 +1156,7 @@ export class Image {
|
|
|
1139
1156
|
}
|
|
1140
1157
|
setBlipFillRotWithShape(val: boolean | undefined): this {
|
|
1141
1158
|
this.blipFillRotWithShape = val;
|
|
1159
|
+
this._mutated = true;
|
|
1142
1160
|
return this;
|
|
1143
1161
|
}
|
|
1144
1162
|
|
|
@@ -1147,6 +1165,7 @@ export class Image {
|
|
|
1147
1165
|
}
|
|
1148
1166
|
setPicLocks(locks: Partial<Record<PicLockAttribute, boolean>>): this {
|
|
1149
1167
|
this.picLocks = locks;
|
|
1168
|
+
this._mutated = true;
|
|
1150
1169
|
return this;
|
|
1151
1170
|
}
|
|
1152
1171
|
|
|
@@ -1155,6 +1174,7 @@ export class Image {
|
|
|
1155
1174
|
}
|
|
1156
1175
|
setPicNonVisualProps(props: PicNonVisualProperties): this {
|
|
1157
1176
|
this.picNonVisualProps = props;
|
|
1177
|
+
this._mutated = true;
|
|
1158
1178
|
return this;
|
|
1159
1179
|
}
|
|
1160
1180
|
|
|
@@ -1163,6 +1183,7 @@ export class Image {
|
|
|
1163
1183
|
}
|
|
1164
1184
|
setIsLinked(val: boolean): this {
|
|
1165
1185
|
this.isLinked = val;
|
|
1186
|
+
this._mutated = true;
|
|
1166
1187
|
return this;
|
|
1167
1188
|
}
|
|
1168
1189
|
|
|
@@ -1171,6 +1192,7 @@ export class Image {
|
|
|
1171
1192
|
}
|
|
1172
1193
|
setSvgRelationshipId(id: string | undefined): this {
|
|
1173
1194
|
this.svgRelationshipId = id;
|
|
1195
|
+
this._mutated = true;
|
|
1174
1196
|
return this;
|
|
1175
1197
|
}
|
|
1176
1198
|
|
|
@@ -1199,6 +1221,7 @@ export class Image {
|
|
|
1199
1221
|
|
|
1200
1222
|
setEffectExtent(left: number, top: number, right: number, bottom: number): this {
|
|
1201
1223
|
this.effectExtent = { left, top, right, bottom };
|
|
1224
|
+
this._mutated = true;
|
|
1202
1225
|
return this;
|
|
1203
1226
|
}
|
|
1204
1227
|
|
|
@@ -1219,6 +1242,7 @@ export class Image {
|
|
|
1219
1242
|
distanceLeft: distances?.left,
|
|
1220
1243
|
distanceRight: distances?.right,
|
|
1221
1244
|
};
|
|
1245
|
+
this._mutated = true;
|
|
1222
1246
|
return this;
|
|
1223
1247
|
}
|
|
1224
1248
|
|
|
@@ -1278,6 +1302,7 @@ export class Image {
|
|
|
1278
1302
|
this.validatePositionOffset(vertical.offset, 'vertical');
|
|
1279
1303
|
|
|
1280
1304
|
this.position = { horizontal, vertical };
|
|
1305
|
+
this._mutated = true;
|
|
1281
1306
|
return this;
|
|
1282
1307
|
}
|
|
1283
1308
|
|
|
@@ -1341,6 +1366,7 @@ export class Image {
|
|
|
1341
1366
|
|
|
1342
1367
|
setAnchor(options: ImageAnchor): this {
|
|
1343
1368
|
this.anchor = options;
|
|
1369
|
+
this._mutated = true;
|
|
1344
1370
|
return this;
|
|
1345
1371
|
}
|
|
1346
1372
|
|
|
@@ -1351,6 +1377,7 @@ export class Image {
|
|
|
1351
1377
|
setCrop(left: number, top: number, right: number, bottom: number): this {
|
|
1352
1378
|
const clamp = (val: number) => Math.max(0, Math.min(100, val));
|
|
1353
1379
|
this.crop = { left: clamp(left), top: clamp(top), right: clamp(right), bottom: clamp(bottom) };
|
|
1380
|
+
this._mutated = true;
|
|
1354
1381
|
return this;
|
|
1355
1382
|
}
|
|
1356
1383
|
|
|
@@ -1370,6 +1397,7 @@ export class Image {
|
|
|
1370
1397
|
? Math.max(0, Math.min(100, options.transparency))
|
|
1371
1398
|
: undefined,
|
|
1372
1399
|
};
|
|
1400
|
+
this._mutated = true;
|
|
1373
1401
|
return this;
|
|
1374
1402
|
}
|
|
1375
1403
|
|
|
@@ -1476,6 +1504,7 @@ export class Image {
|
|
|
1476
1504
|
setBehindText(behind = true): this {
|
|
1477
1505
|
if (this.anchor) {
|
|
1478
1506
|
this.anchor.behindDoc = behind;
|
|
1507
|
+
this._mutated = true;
|
|
1479
1508
|
} else {
|
|
1480
1509
|
this.setAnchor({
|
|
1481
1510
|
behindDoc: behind,
|
|
@@ -1534,6 +1563,7 @@ export class Image {
|
|
|
1534
1563
|
removeBorder(): this {
|
|
1535
1564
|
this.border = undefined;
|
|
1536
1565
|
this._rawPassthrough.delete('zero-width-ln');
|
|
1566
|
+
this._mutated = true;
|
|
1537
1567
|
return this;
|
|
1538
1568
|
}
|
|
1539
1569
|
|
|
@@ -1898,7 +1928,6 @@ export class Image {
|
|
|
1898
1928
|
if (this.wrap.distanceBottom !== undefined) wrapAttrs.distB = this.wrap.distanceBottom;
|
|
1899
1929
|
if (this.wrap.distanceLeft !== undefined) wrapAttrs.distL = this.wrap.distanceLeft;
|
|
1900
1930
|
if (this.wrap.distanceRight !== undefined) wrapAttrs.distR = this.wrap.distanceRight;
|
|
1901
|
-
if (this.wrap.side) wrapAttrs.wrapText = this.wrap.side;
|
|
1902
1931
|
|
|
1903
1932
|
let wrapElementName: string;
|
|
1904
1933
|
switch (this.wrap.type) {
|
|
@@ -1921,6 +1950,19 @@ export class Image {
|
|
|
1921
1950
|
wrapElementName = 'wrapSquare';
|
|
1922
1951
|
}
|
|
1923
1952
|
|
|
1953
|
+
if (
|
|
1954
|
+
wrapElementName === 'wrapSquare' ||
|
|
1955
|
+
wrapElementName === 'wrapTight' ||
|
|
1956
|
+
wrapElementName === 'wrapThrough'
|
|
1957
|
+
) {
|
|
1958
|
+
// wrapText is use="required" on CT_WrapSquare/CT_WrapTight/CT_WrapThrough,
|
|
1959
|
+
// so default to bothSides when setWrap() was called without a side.
|
|
1960
|
+
wrapAttrs.wrapText = this.wrap.side ?? 'bothSides';
|
|
1961
|
+
}
|
|
1962
|
+
// wrapText is NOT declared on CT_WrapNone or CT_WrapTopBottom — emitting
|
|
1963
|
+
// it there (e.g. from a side defaulted during parse) makes Word report
|
|
1964
|
+
// the document as corrupt, so it is intentionally never set for those.
|
|
1965
|
+
|
|
1924
1966
|
// Group B: Include wrap polygon passthrough as children
|
|
1925
1967
|
const wrapChildren: XMLElement[] = [];
|
|
1926
1968
|
if (this._rawPassthrough.has('wrap-polygon')) {
|
|
@@ -1972,7 +2014,9 @@ export class Image {
|
|
|
1972
2014
|
locked: this.anchor?.locked ? 1 : 0,
|
|
1973
2015
|
layoutInCell: this.anchor?.layoutInCell ? 1 : 0,
|
|
1974
2016
|
allowOverlap: this.anchor?.allowOverlap ? 1 : 0,
|
|
1975
|
-
|
|
2017
|
+
// Required by CT_Anchor even when only setPosition() was called;
|
|
2018
|
+
// matches the parser fallback so position-only floats stay schema-valid.
|
|
2019
|
+
relativeHeight: this.anchor?.relativeHeight ?? 251658240,
|
|
1976
2020
|
simplePos: this.anchor?.simplePos ? '1' : '0',
|
|
1977
2021
|
distT: (this.anchor?.distT ?? 0).toString(),
|
|
1978
2022
|
distB: (this.anchor?.distB ?? 0).toString(),
|