docxmlater 11.0.10 → 12.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -13
- package/dist/core/Document.d.ts +29 -3
- package/dist/core/Document.d.ts.map +1 -1
- package/dist/core/Document.js +733 -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 +735 -172
- 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 +223 -39
- 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/acceptRevisions.js +20 -11
- package/dist/esm/processors/acceptRevisions.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 +9 -3
- package/dist/processors/RevisionWalker.d.ts.map +1 -1
- package/dist/processors/RevisionWalker.js +223 -39
- 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/acceptRevisions.d.ts +1 -0
- package/dist/processors/acceptRevisions.d.ts.map +1 -1
- package/dist/processors/acceptRevisions.js +21 -11
- package/dist/processors/acceptRevisions.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 +1184 -242
- 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 +390 -46
- package/src/processors/SelectiveRevisionAcceptor.ts +164 -28
- package/src/processors/acceptRevisions.ts +67 -17
- 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
package/src/elements/Field.ts
CHANGED
|
@@ -6,11 +6,12 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { XMLElement } from '../xml/XMLBuilder.js';
|
|
9
|
-
import { RunFormatting, FormFieldData } from './Run.js';
|
|
9
|
+
import { Run, RunFormatting, FormFieldData } from './Run.js';
|
|
10
10
|
import {
|
|
11
11
|
ParsedHyperlinkInstruction,
|
|
12
12
|
parseHyperlinkInstruction,
|
|
13
13
|
isHyperlinkInstruction,
|
|
14
|
+
escapeFieldArgument,
|
|
14
15
|
} from './FieldHelpers.js';
|
|
15
16
|
import type { Revision } from './Revision.js';
|
|
16
17
|
import { pointsToHalfPoints } from '../utils/units.js';
|
|
@@ -74,6 +75,15 @@ export interface FieldProperties {
|
|
|
74
75
|
dirty?: boolean;
|
|
75
76
|
}
|
|
76
77
|
|
|
78
|
+
/**
|
|
79
|
+
* One run of a simple field's cached result: the text Word last computed
|
|
80
|
+
* for the field plus the run formatting it was displayed with.
|
|
81
|
+
*/
|
|
82
|
+
export interface CachedFieldResultRun {
|
|
83
|
+
text: string;
|
|
84
|
+
formatting?: RunFormatting;
|
|
85
|
+
}
|
|
86
|
+
|
|
77
87
|
/**
|
|
78
88
|
* Represents a dynamic field
|
|
79
89
|
*/
|
|
@@ -83,6 +93,21 @@ export class Field {
|
|
|
83
93
|
private formatting?: RunFormatting;
|
|
84
94
|
private fldLock?: boolean;
|
|
85
95
|
private dirty?: boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Cached field result emitted as the fldSimple run text. For fields like
|
|
98
|
+
* HYPERLINK the visible text is NOT derivable from the instruction, so
|
|
99
|
+
* without this Word would display a generic placeholder until the user
|
|
100
|
+
* manually refreshes fields (F9).
|
|
101
|
+
*/
|
|
102
|
+
private cachedResult?: string;
|
|
103
|
+
/**
|
|
104
|
+
* Per-run cached result parsed from a loaded `<w:fldSimple>`. Per
|
|
105
|
+
* ECMA-376 §17.16.16 CT_SimpleField, the child runs hold the field's
|
|
106
|
+
* current (cached) result — Word does not refresh fields on open by
|
|
107
|
+
* default, so discarding them replaces the user-visible text with a
|
|
108
|
+
* synthetic placeholder. Takes precedence over `cachedResult` in toXML().
|
|
109
|
+
*/
|
|
110
|
+
private cachedResultRuns?: CachedFieldResultRun[];
|
|
86
111
|
|
|
87
112
|
/**
|
|
88
113
|
* Creates a new field
|
|
@@ -160,6 +185,36 @@ export class Field {
|
|
|
160
185
|
return this.formatting;
|
|
161
186
|
}
|
|
162
187
|
|
|
188
|
+
/**
|
|
189
|
+
* Sets the cached field result as plain text (single run; the field's
|
|
190
|
+
* own formatting applies). Clears any per-run cached result.
|
|
191
|
+
*/
|
|
192
|
+
setCachedResult(text: string): this {
|
|
193
|
+
this.cachedResult = text;
|
|
194
|
+
this.cachedResultRuns = undefined;
|
|
195
|
+
return this;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Sets the cached field result as individual runs so per-run formatting
|
|
200
|
+
* from a parsed document survives round-trip.
|
|
201
|
+
*/
|
|
202
|
+
setCachedResultRuns(runs: CachedFieldResultRun[]): this {
|
|
203
|
+
this.cachedResultRuns = runs.length > 0 ? [...runs] : undefined;
|
|
204
|
+
return this;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Gets the cached field result text (concatenated across runs), or
|
|
209
|
+
* undefined when the field has no cached result.
|
|
210
|
+
*/
|
|
211
|
+
getCachedResult(): string | undefined {
|
|
212
|
+
if (this.cachedResultRuns) {
|
|
213
|
+
return this.cachedResultRuns.map((run) => run.text).join('');
|
|
214
|
+
}
|
|
215
|
+
return this.cachedResult;
|
|
216
|
+
}
|
|
217
|
+
|
|
163
218
|
/**
|
|
164
219
|
* Checks if this field is a HYPERLINK field
|
|
165
220
|
* @returns True if the field type is HYPERLINK or instruction starts with HYPERLINK
|
|
@@ -190,21 +245,49 @@ export class Field {
|
|
|
190
245
|
* The fldSimple element should be added directly to paragraph children (not wrapped in w:r).
|
|
191
246
|
*/
|
|
192
247
|
toXML(): XMLElement {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
248
|
+
let resultRuns: XMLElement[];
|
|
249
|
+
if (this.cachedResultRuns) {
|
|
250
|
+
// Re-emit the parsed cached result runs verbatim: per ECMA-376
|
|
251
|
+
// §17.16.16 they ARE the field's current result, and Word does not
|
|
252
|
+
// refresh fields on open by default — substituting a placeholder
|
|
253
|
+
// would corrupt the visible content. Field-level formatting (e.g.
|
|
254
|
+
// setColor after parse) is layered over each run's own formatting
|
|
255
|
+
// so programmatic styling still takes effect.
|
|
256
|
+
resultRuns = this.cachedResultRuns.map((cached) => {
|
|
257
|
+
const children: XMLElement[] = [];
|
|
258
|
+
const merged =
|
|
259
|
+
cached.formatting || this.formatting
|
|
260
|
+
? { ...cached.formatting, ...this.formatting }
|
|
261
|
+
: undefined;
|
|
262
|
+
const rPr = merged ? Run.generateRunPropertiesXML(merged) : null;
|
|
263
|
+
if (rPr) {
|
|
264
|
+
children.push(rPr);
|
|
265
|
+
}
|
|
266
|
+
children.push({
|
|
267
|
+
name: 'w:t',
|
|
268
|
+
attributes: { 'xml:space': 'preserve' },
|
|
269
|
+
children: [cached.text],
|
|
270
|
+
});
|
|
271
|
+
return { name: 'w:r', children };
|
|
272
|
+
});
|
|
273
|
+
} else {
|
|
274
|
+
// Build the inner run with optional formatting
|
|
275
|
+
const runChildren: XMLElement[] = [];
|
|
276
|
+
if (this.formatting) {
|
|
277
|
+
runChildren.push(this.createRunProperties());
|
|
278
|
+
}
|
|
279
|
+
// Per ECMA-376 §22.1.2.33 CT_Text, `xml:space="preserve"` is the
|
|
280
|
+
// standard sentinel that stops XML processors from collapsing leading /
|
|
281
|
+
// trailing whitespace in the text content. Run.ts always emits it;
|
|
282
|
+
// emit it here too so field placeholders with spaces (e.g. localized
|
|
283
|
+
// date formats like "1 Jan 2026") survive XML round-trip intact.
|
|
284
|
+
runChildren.push({
|
|
285
|
+
name: 'w:t',
|
|
286
|
+
attributes: { 'xml:space': 'preserve' },
|
|
287
|
+
children: [this.cachedResult ?? this.getPlaceholderText()],
|
|
288
|
+
});
|
|
289
|
+
resultRuns = [{ name: 'w:r', children: runChildren }];
|
|
197
290
|
}
|
|
198
|
-
// Per ECMA-376 §22.1.2.33 CT_Text, `xml:space="preserve"` is the
|
|
199
|
-
// standard sentinel that stops XML processors from collapsing leading /
|
|
200
|
-
// trailing whitespace in the text content. Run.ts always emits it;
|
|
201
|
-
// emit it here too so field placeholders with spaces (e.g. localized
|
|
202
|
-
// date formats like "1 Jan 2026") survive XML round-trip intact.
|
|
203
|
-
runChildren.push({
|
|
204
|
-
name: 'w:t',
|
|
205
|
-
attributes: { 'xml:space': 'preserve' },
|
|
206
|
-
children: [this.getPlaceholderText()],
|
|
207
|
-
});
|
|
208
291
|
|
|
209
292
|
// CT_SimpleField (§17.16.16) carries two ST_OnOff attributes beyond
|
|
210
293
|
// the required w:instr: w:fldLock (locked against updates) and
|
|
@@ -224,12 +307,7 @@ export class Field {
|
|
|
224
307
|
return {
|
|
225
308
|
name: 'w:fldSimple',
|
|
226
309
|
attributes: fldSimpleAttrs,
|
|
227
|
-
children:
|
|
228
|
-
{
|
|
229
|
-
name: 'w:r',
|
|
230
|
-
children: runChildren,
|
|
231
|
-
},
|
|
232
|
-
],
|
|
310
|
+
children: resultRuns,
|
|
233
311
|
};
|
|
234
312
|
}
|
|
235
313
|
|
|
@@ -481,23 +559,25 @@ export class Field {
|
|
|
481
559
|
*/
|
|
482
560
|
static createHyperlink(
|
|
483
561
|
url: string,
|
|
484
|
-
|
|
562
|
+
displayText: string = url,
|
|
485
563
|
tooltip?: string,
|
|
486
564
|
formatting?: RunFormatting
|
|
487
565
|
): Field {
|
|
488
|
-
let instruction = `HYPERLINK "${url}"`;
|
|
566
|
+
let instruction = `HYPERLINK "${escapeFieldArgument(url)}"`;
|
|
489
567
|
|
|
490
568
|
if (tooltip) {
|
|
491
|
-
instruction += ` \\o "${tooltip}"`;
|
|
569
|
+
instruction += ` \\o "${escapeFieldArgument(tooltip)}"`;
|
|
492
570
|
}
|
|
493
571
|
|
|
494
572
|
instruction += ' \\* MERGEFORMAT';
|
|
495
573
|
|
|
496
|
-
|
|
574
|
+
const field = new Field({
|
|
497
575
|
type: 'HYPERLINK',
|
|
498
576
|
instruction,
|
|
499
577
|
formatting,
|
|
500
578
|
});
|
|
579
|
+
field.cachedResult = displayText;
|
|
580
|
+
return field;
|
|
501
581
|
}
|
|
502
582
|
|
|
503
583
|
/**
|
|
@@ -535,7 +615,7 @@ export class Field {
|
|
|
535
615
|
throw new Error('TC level must be between 1 and 9');
|
|
536
616
|
}
|
|
537
617
|
|
|
538
|
-
const instruction = `TC "${text}" \\f C \\l ${level}`;
|
|
618
|
+
const instruction = `TC "${escapeFieldArgument(text)}" \\f C \\l ${level}`;
|
|
539
619
|
|
|
540
620
|
return new Field({
|
|
541
621
|
type: 'TC',
|
|
@@ -551,11 +631,12 @@ export class Field {
|
|
|
551
631
|
* @param formatting Optional run formatting
|
|
552
632
|
*/
|
|
553
633
|
static createXEEntry(text: string, subEntry?: string, formatting?: RunFormatting): Field {
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
634
|
+
// Per ECMA-376 §17.16.5.75 the main-entry/subentry colon separator
|
|
635
|
+
// belongs INSIDE the quoted field-argument ({ XE "Main:Sub" }) —
|
|
636
|
+
// text after the closing quote would be misparsed as stray switches.
|
|
637
|
+
const instruction = subEntry
|
|
638
|
+
? `XE "${escapeFieldArgument(text)}:${escapeFieldArgument(subEntry)}"`
|
|
639
|
+
: `XE "${escapeFieldArgument(text)}"`;
|
|
559
640
|
|
|
560
641
|
return new Field({
|
|
561
642
|
type: 'XE',
|
|
@@ -571,7 +652,7 @@ export class Field {
|
|
|
571
652
|
*/
|
|
572
653
|
static createCustom(instruction: string, formatting?: RunFormatting): Field {
|
|
573
654
|
return new Field({
|
|
574
|
-
type: '
|
|
655
|
+
type: 'CUSTOM',
|
|
575
656
|
instruction,
|
|
576
657
|
formatting,
|
|
577
658
|
});
|
|
@@ -1120,17 +1201,27 @@ export class ComplexField {
|
|
|
1120
1201
|
runs.push(...nestedField.toXML());
|
|
1121
1202
|
}
|
|
1122
1203
|
|
|
1123
|
-
// 3. Separator run
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1204
|
+
// 3. Separator run — only when the field carries a result section.
|
|
1205
|
+
// Per ECMA-376, fields without results (XE/TC markers, never-updated
|
|
1206
|
+
// fields) skip w:fldSep entirely; synthesizing one would break
|
|
1207
|
+
// round-trip fidelity for parsed separator-less fields.
|
|
1208
|
+
const emitsResultSection =
|
|
1209
|
+
this._hasResultSection ||
|
|
1210
|
+
!!this.result ||
|
|
1211
|
+
this.resultContent.length > 0 ||
|
|
1212
|
+
this.resultRevisions.length > 0;
|
|
1213
|
+
if (emitsResultSection) {
|
|
1214
|
+
runs.push({
|
|
1215
|
+
name: 'w:r',
|
|
1216
|
+
children: [
|
|
1217
|
+
{
|
|
1218
|
+
name: 'w:fldChar',
|
|
1219
|
+
attributes: { 'w:fldCharType': 'separate' },
|
|
1220
|
+
selfClosing: true,
|
|
1221
|
+
},
|
|
1222
|
+
],
|
|
1223
|
+
});
|
|
1224
|
+
}
|
|
1134
1225
|
|
|
1135
1226
|
// 4. Result content (prioritize custom XML content, then simple text)
|
|
1136
1227
|
// Design note: For INCLUDEPICTURE fields, the parser stores the w:drawing
|
|
@@ -133,6 +133,22 @@ export function parseHyperlinkInstruction(instruction: string): ParsedHyperlinkI
|
|
|
133
133
|
};
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
+
/**
|
|
137
|
+
* Escapes a value for use inside a quoted field-instruction argument.
|
|
138
|
+
*
|
|
139
|
+
* Per ECMA-376 field-argument syntax (§17.16.4.1), a literal double quote
|
|
140
|
+
* inside a quoted argument must be written as \" and a literal backslash
|
|
141
|
+
* as \\ — otherwise an embedded quote terminates the argument early and
|
|
142
|
+
* the remainder is misparsed as stray switches. The XML layer only
|
|
143
|
+
* escapes XML entities, so this must happen at field-code level.
|
|
144
|
+
*
|
|
145
|
+
* @param value Raw argument text
|
|
146
|
+
* @returns Text safe to interpolate between double quotes in a field code
|
|
147
|
+
*/
|
|
148
|
+
export function escapeFieldArgument(value: string): string {
|
|
149
|
+
return value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
150
|
+
}
|
|
151
|
+
|
|
136
152
|
/**
|
|
137
153
|
* Creates a HYPERLINK field instruction string from components
|
|
138
154
|
*
|
|
@@ -148,14 +164,14 @@ export function parseHyperlinkInstruction(instruction: string): ParsedHyperlinkI
|
|
|
148
164
|
* ```
|
|
149
165
|
*/
|
|
150
166
|
export function buildHyperlinkInstruction(url: string, anchor?: string, tooltip?: string): string {
|
|
151
|
-
let instruction = `HYPERLINK "${url}"`;
|
|
167
|
+
let instruction = `HYPERLINK "${escapeFieldArgument(url)}"`;
|
|
152
168
|
|
|
153
169
|
if (anchor) {
|
|
154
|
-
instruction += ` \\l "${anchor}"`;
|
|
170
|
+
instruction += ` \\l "${escapeFieldArgument(anchor)}"`;
|
|
155
171
|
}
|
|
156
172
|
|
|
157
173
|
if (tooltip) {
|
|
158
|
-
instruction += ` \\o "${tooltip}"`;
|
|
174
|
+
instruction += ` \\o "${escapeFieldArgument(tooltip)}"`;
|
|
159
175
|
}
|
|
160
176
|
|
|
161
177
|
// Always add \h switch for clickable hyperlinks
|
|
@@ -291,7 +307,7 @@ export function createIFField(
|
|
|
291
307
|
trueContent: string,
|
|
292
308
|
falseContent = ''
|
|
293
309
|
): ComplexField {
|
|
294
|
-
const instruction = ` IF ${condition} "${trueContent}" "${falseContent}" `;
|
|
310
|
+
const instruction = ` IF ${condition} "${escapeFieldArgument(trueContent)}" "${escapeFieldArgument(falseContent)}" `;
|
|
295
311
|
|
|
296
312
|
return new ComplexField({
|
|
297
313
|
instruction,
|
package/src/elements/Footer.ts
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* Different footers can be defined for first page, odd pages, and even pages.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { XMLBuilder } from '../xml/XMLBuilder.js';
|
|
9
|
+
import { XMLParser } from '../xml/XMLParser.js';
|
|
9
10
|
import { Paragraph } from './Paragraph.js';
|
|
10
11
|
import { RunFormatting } from './Run.js';
|
|
11
12
|
import { Table } from './Table.js';
|
|
@@ -36,6 +37,12 @@ export class Footer {
|
|
|
36
37
|
private type: FooterType;
|
|
37
38
|
private footerId?: string;
|
|
38
39
|
private rawXML?: string; // Store original XML for preservation
|
|
40
|
+
// Top-level w:p/w:tbl count of the preserved raw XML. DocumentParser calls
|
|
41
|
+
// setRawXML() before repopulating elements from that same XML, so mutators
|
|
42
|
+
// can't simply clear rawXML — they would fire during parsing and lose the
|
|
43
|
+
// preserved bytes. Instead, growth beyond this count is the signal that
|
|
44
|
+
// content was added after load and the preserved XML is stale.
|
|
45
|
+
private rawXmlBlockCount = Number.MAX_SAFE_INTEGER;
|
|
39
46
|
|
|
40
47
|
/**
|
|
41
48
|
* Creates a new footer
|
|
@@ -51,9 +58,43 @@ export class Footer {
|
|
|
51
58
|
*/
|
|
52
59
|
setRawXML(xml: string): this {
|
|
53
60
|
this.rawXML = xml;
|
|
61
|
+
this.rawXmlBlockCount = Footer.countTopLevelBlocks(xml);
|
|
54
62
|
return this;
|
|
55
63
|
}
|
|
56
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Counts the top-level w:p/w:tbl children of a raw footer part.
|
|
67
|
+
* Parsing populates this.elements from exactly those blocks, so the count
|
|
68
|
+
* is the baseline against which mutators detect post-load additions.
|
|
69
|
+
*/
|
|
70
|
+
private static countTopLevelBlocks(xml: string): number {
|
|
71
|
+
try {
|
|
72
|
+
const parsed = XMLParser.parseToObject(xml) as Record<string, unknown>;
|
|
73
|
+
const root = parsed?.['w:ftr'];
|
|
74
|
+
if (!root || typeof root !== 'object') {
|
|
75
|
+
return 0;
|
|
76
|
+
}
|
|
77
|
+
const count = (node: unknown): number =>
|
|
78
|
+
node === undefined ? 0 : Array.isArray(node) ? node.length : 1;
|
|
79
|
+
const rootObj = root as Record<string, unknown>;
|
|
80
|
+
return count(rootObj['w:p']) + count(rootObj['w:tbl']);
|
|
81
|
+
} catch {
|
|
82
|
+
// Unparseable part: never invalidate, keep the preserved bytes
|
|
83
|
+
return Number.MAX_SAFE_INTEGER;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Drops the preserved raw XML once content grows beyond what that XML
|
|
89
|
+
* already contains, so toXML() regenerates from elements and post-load
|
|
90
|
+
* edits are not silently discarded on save.
|
|
91
|
+
*/
|
|
92
|
+
private invalidateRawXmlOnGrowth(): void {
|
|
93
|
+
if (this.rawXML !== undefined && this.elements.length > this.rawXmlBlockCount) {
|
|
94
|
+
this.rawXML = undefined;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
57
98
|
/**
|
|
58
99
|
* Gets the raw XML content if available
|
|
59
100
|
*/
|
|
@@ -90,6 +131,7 @@ export class Footer {
|
|
|
90
131
|
*/
|
|
91
132
|
addParagraph(paragraph: Paragraph): this {
|
|
92
133
|
this.elements.push(paragraph);
|
|
134
|
+
this.invalidateRawXmlOnGrowth();
|
|
93
135
|
return this;
|
|
94
136
|
}
|
|
95
137
|
|
|
@@ -103,6 +145,7 @@ export class Footer {
|
|
|
103
145
|
para.addText(text);
|
|
104
146
|
}
|
|
105
147
|
this.elements.push(para);
|
|
148
|
+
this.invalidateRawXmlOnGrowth();
|
|
106
149
|
return para;
|
|
107
150
|
}
|
|
108
151
|
|
|
@@ -125,6 +168,7 @@ export class Footer {
|
|
|
125
168
|
const para = new Paragraph();
|
|
126
169
|
para.addText(text, formatting);
|
|
127
170
|
this.elements.push(para);
|
|
171
|
+
this.invalidateRawXmlOnGrowth();
|
|
128
172
|
return para;
|
|
129
173
|
}
|
|
130
174
|
|
|
@@ -134,6 +178,7 @@ export class Footer {
|
|
|
134
178
|
*/
|
|
135
179
|
addTable(table: Table): this {
|
|
136
180
|
this.elements.push(table);
|
|
181
|
+
this.invalidateRawXmlOnGrowth();
|
|
137
182
|
return this;
|
|
138
183
|
}
|
|
139
184
|
|
|
@@ -145,6 +190,7 @@ export class Footer {
|
|
|
145
190
|
createTable(rows: number, columns: number): Table {
|
|
146
191
|
const table = new Table(rows, columns);
|
|
147
192
|
this.elements.push(table);
|
|
193
|
+
this.invalidateRawXmlOnGrowth();
|
|
148
194
|
return table;
|
|
149
195
|
}
|
|
150
196
|
|
|
@@ -181,76 +227,25 @@ export class Footer {
|
|
|
181
227
|
return this.rawXML;
|
|
182
228
|
}
|
|
183
229
|
|
|
184
|
-
//
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
let xml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n';
|
|
188
|
-
xml += '<w:ftr xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" ';
|
|
189
|
-
xml += 'xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">\n';
|
|
190
|
-
|
|
191
|
-
// Add elements
|
|
192
|
-
for (const element of elementXmls) {
|
|
193
|
-
xml += this.renderElement(element, 1);
|
|
194
|
-
}
|
|
230
|
+
// Serialize through XMLBuilder so text and attribute values are
|
|
231
|
+
// XML-escaped and rawXml passthrough children are honored
|
|
232
|
+
const children = this.elements.map((el) => el.toXML());
|
|
195
233
|
|
|
196
|
-
//
|
|
197
|
-
if (
|
|
198
|
-
|
|
234
|
+
// ECMA-376 requires block-level content in w:ftr
|
|
235
|
+
if (children.length === 0) {
|
|
236
|
+
children.push(XMLBuilder.w('p'));
|
|
199
237
|
}
|
|
200
238
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
* Renders an XML element to string with indentation
|
|
208
|
-
*/
|
|
209
|
-
private renderElement(element: XMLElement, indent: number): string {
|
|
210
|
-
const spaces = ' '.repeat(indent);
|
|
211
|
-
let xml = '';
|
|
212
|
-
|
|
213
|
-
if (element.selfClosing) {
|
|
214
|
-
xml += `${spaces}<${element.name}`;
|
|
215
|
-
if (element.attributes) {
|
|
216
|
-
for (const [key, value] of Object.entries(element.attributes)) {
|
|
217
|
-
xml += ` ${key}="${value}"`;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
xml += '/>\n';
|
|
221
|
-
} else {
|
|
222
|
-
xml += `${spaces}<${element.name}`;
|
|
223
|
-
if (element.attributes) {
|
|
224
|
-
for (const [key, value] of Object.entries(element.attributes)) {
|
|
225
|
-
xml += ` ${key}="${value}"`;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
xml += '>';
|
|
229
|
-
|
|
230
|
-
if (element.children && element.children.length > 0) {
|
|
231
|
-
const hasOnlyText = element.children.every((c) => typeof c === 'string');
|
|
232
|
-
|
|
233
|
-
if (hasOnlyText) {
|
|
234
|
-
// Inline text content
|
|
235
|
-
xml += element.children.join('');
|
|
236
|
-
} else {
|
|
237
|
-
// Block-level children
|
|
238
|
-
xml += '\n';
|
|
239
|
-
for (const child of element.children) {
|
|
240
|
-
if (typeof child === 'string') {
|
|
241
|
-
xml += spaces + ' ' + child + '\n';
|
|
242
|
-
} else {
|
|
243
|
-
xml += this.renderElement(child, indent + 1);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
xml += spaces;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
xml += `</${element.name}>\n`;
|
|
251
|
-
}
|
|
239
|
+
const namespaces: Record<string, string> = {
|
|
240
|
+
...XMLBuilder.createNamespaces(),
|
|
241
|
+
// Extension namespaces (w14:paraId etc. on regenerated paragraphs)
|
|
242
|
+
// must be declared ignorable or Word rejects the part
|
|
243
|
+
'mc:Ignorable': 'w14 w15 wp14 asvg',
|
|
244
|
+
};
|
|
252
245
|
|
|
253
|
-
|
|
246
|
+
const builder = new XMLBuilder();
|
|
247
|
+
builder.element('w:ftr', namespaces, children);
|
|
248
|
+
return builder.build(true);
|
|
254
249
|
}
|
|
255
250
|
|
|
256
251
|
/**
|
|
@@ -130,7 +130,10 @@ export class FootnoteManager {
|
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
/**
|
|
133
|
-
* Removes a footnote
|
|
133
|
+
* Removes a footnote from the model only. Does not touch body
|
|
134
|
+
* w:footnoteReference runs or the document's dirty flags — callers going
|
|
135
|
+
* through a Document should use Document.removeFootnote(), which also
|
|
136
|
+
* strips the matching references and forces footnotes.xml regeneration.
|
|
134
137
|
* @param id Footnote ID
|
|
135
138
|
* @returns True if removed, false if not found or if it's a special type
|
|
136
139
|
*/
|