@docx4j/core-ts 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/README.md +410 -10
  2. package/dist/model/content/Body.d.mts +109 -4
  3. package/dist/model/content/Body.mjs +300 -29
  4. package/dist/model/content/Comment.d.mts +78 -0
  5. package/dist/model/content/Comment.mjs +429 -0
  6. package/dist/model/content/ContentControl.d.mts +173 -0
  7. package/dist/model/content/ContentControl.mjs +638 -0
  8. package/dist/model/content/Font.d.mts +48 -8
  9. package/dist/model/content/Font.mjs +55 -13
  10. package/dist/model/content/InlinePicture.d.mts +103 -0
  11. package/dist/model/content/InlinePicture.mjs +361 -0
  12. package/dist/model/content/List.d.mts +253 -0
  13. package/dist/model/content/List.mjs +778 -0
  14. package/dist/model/content/Paragraph.d.mts +213 -16
  15. package/dist/model/content/Paragraph.mjs +611 -57
  16. package/dist/model/content/Range.d.mts +48 -4
  17. package/dist/model/content/Range.mjs +161 -4
  18. package/dist/model/content/Table.d.mts +130 -0
  19. package/dist/model/content/Table.mjs +429 -0
  20. package/dist/model/content/TrackedChange.d.mts +96 -0
  21. package/dist/model/content/TrackedChange.mjs +352 -0
  22. package/dist/model/content/comments.d.mts +122 -0
  23. package/dist/model/content/comments.mjs +248 -0
  24. package/dist/model/content/index.d.mts +13 -3
  25. package/dist/model/content/index.mjs +15 -3
  26. package/dist/model/content/ooxml.d.mts +17 -0
  27. package/dist/model/content/ooxml.mjs +214 -0
  28. package/dist/model/content/styles.d.mts +21 -0
  29. package/dist/model/content/styles.mjs +86 -0
  30. package/dist/model/content/tracking.d.mts +104 -0
  31. package/dist/model/content/tracking.mjs +313 -0
  32. package/dist/model/content/tree.d.mts +56 -9
  33. package/dist/model/content/tree.mjs +104 -31
  34. package/dist/model/customxml/CustomXmlPart.d.mts +158 -0
  35. package/dist/model/customxml/CustomXmlPart.mjs +415 -0
  36. package/dist/model/customxml/CustomXmlPartCollection.d.mts +68 -0
  37. package/dist/model/customxml/CustomXmlPartCollection.mjs +183 -0
  38. package/dist/model/customxml/XmlMapping.d.mts +46 -0
  39. package/dist/model/customxml/XmlMapping.mjs +98 -0
  40. package/dist/model/customxml/bindings.d.mts +41 -0
  41. package/dist/model/customxml/bindings.mjs +230 -0
  42. package/dist/model/customxml/index.d.mts +7 -0
  43. package/dist/model/customxml/index.mjs +9 -0
  44. package/dist/model/customxml/insert.d.mts +20 -0
  45. package/dist/model/customxml/insert.mjs +22 -0
  46. package/dist/model/customxml/kinds.d.mts +103 -0
  47. package/dist/model/customxml/kinds.mjs +267 -0
  48. package/dist/model/customxml/xpath.d.mts +52 -0
  49. package/dist/model/customxml/xpath.mjs +205 -0
  50. package/dist/model/fonts/CJKToEnglish.d.mts +2 -0
  51. package/dist/model/fonts/CJKToEnglish.mjs +16 -0
  52. package/dist/model/fonts/FontFallback.d.mts +58 -0
  53. package/dist/model/fonts/FontFallback.mjs +219 -0
  54. package/dist/model/fonts/IdentityPlusMapper.d.mts +7 -0
  55. package/dist/model/fonts/IdentityPlusMapper.mjs +19 -0
  56. package/dist/model/fonts/LanguageTagToScriptMapping.d.mts +7 -0
  57. package/dist/model/fonts/LanguageTagToScriptMapping.mjs +67 -0
  58. package/dist/model/fonts/Mapper.d.mts +190 -0
  59. package/dist/model/fonts/Mapper.mjs +481 -0
  60. package/dist/model/fonts/PhysicalFont.d.mts +34 -0
  61. package/dist/model/fonts/PhysicalFont.mjs +62 -0
  62. package/dist/model/fonts/RunFontSelector.d.mts +194 -0
  63. package/dist/model/fonts/RunFontSelector.mjs +441 -0
  64. package/dist/model/fonts/ThemeFonts.d.mts +17 -0
  65. package/dist/model/fonts/ThemeFonts.mjs +76 -0
  66. package/dist/model/fonts/defaultTheme.d.mts +37 -0
  67. package/dist/model/fonts/defaultTheme.mjs +57 -0
  68. package/dist/model/fonts/families.generated.d.mts +11 -0
  69. package/dist/model/fonts/families.generated.mjs +17 -0
  70. package/dist/model/fonts/fontsInUse.d.mts +39 -0
  71. package/dist/model/fonts/fontsInUse.mjs +183 -0
  72. package/dist/model/fonts/index.d.mts +14 -0
  73. package/dist/model/fonts/index.mjs +29 -0
  74. package/dist/model/fonts/lookup.d.mts +5 -0
  75. package/dist/model/fonts/lookup.mjs +12 -0
  76. package/dist/model/fonts/registry.d.mts +31 -0
  77. package/dist/model/fonts/registry.mjs +103 -0
  78. package/dist/model/fonts/scripts.d.mts +2 -0
  79. package/dist/model/fonts/scripts.mjs +78 -0
  80. package/dist/model/fonts/substitutions.generated.d.mts +30 -0
  81. package/dist/model/fonts/substitutions.generated.mjs +12 -0
  82. package/dist/model/fonts/themes.generated.d.mts +6 -0
  83. package/dist/model/fonts/themes.generated.mjs +11 -0
  84. package/dist/model/index.d.mts +5 -0
  85. package/dist/model/index.mjs +13 -1
  86. package/dist/model/listnumbering/Emulator.d.mts +187 -0
  87. package/dist/model/listnumbering/Emulator.mjs +332 -0
  88. package/dist/model/listnumbering/definitions.d.mts +251 -0
  89. package/dist/model/listnumbering/definitions.mjs +571 -0
  90. package/dist/model/listnumbering/formats.d.mts +25 -0
  91. package/dist/model/listnumbering/formats.mjs +320 -0
  92. package/dist/model/listnumbering/index.d.mts +4 -0
  93. package/dist/model/listnumbering/index.mjs +15 -0
  94. package/dist/model/listnumbering/state.d.mts +97 -0
  95. package/dist/model/listnumbering/state.mjs +179 -0
  96. package/dist/model/properties/PropertyResolver.d.mts +216 -0
  97. package/dist/model/properties/PropertyResolver.mjs +524 -0
  98. package/dist/model/properties/catalogue.d.mts +179 -0
  99. package/dist/model/properties/catalogue.mjs +860 -0
  100. package/dist/model/properties/index.d.mts +4 -0
  101. package/dist/model/properties/index.mjs +9 -0
  102. package/dist/model/properties/log.d.mts +7 -0
  103. package/dist/model/properties/log.mjs +25 -0
  104. package/dist/model/properties/styleUtil.d.mts +112 -0
  105. package/dist/model/properties/styleUtil.mjs +359 -0
  106. package/dist/node/index.d.mts +1 -0
  107. package/dist/node/index.mjs +12 -0
  108. package/dist/office-js/document.d.mts +111 -0
  109. package/dist/office-js/document.mjs +267 -0
  110. package/dist/office-js/enums.d.mts +187 -0
  111. package/dist/office-js/enums.mjs +176 -0
  112. package/dist/office-js/errors.d.mts +29 -0
  113. package/dist/office-js/errors.mjs +39 -0
  114. package/dist/office-js/extras.d.mts +5 -0
  115. package/dist/office-js/extras.mjs +29 -0
  116. package/dist/office-js/fragment.d.mts +10 -0
  117. package/dist/office-js/fragment.mjs +23 -0
  118. package/dist/office-js/index.d.mts +183 -0
  119. package/dist/office-js/index.mjs +54 -0
  120. package/dist/office-js/proxy.d.mts +72 -0
  121. package/dist/office-js/proxy.mjs +279 -0
  122. package/dist/office-js/run.d.mts +32 -0
  123. package/dist/office-js/run.mjs +66 -0
  124. package/dist/office-js/supported.d.mts +7 -0
  125. package/dist/office-js/supported.generated.d.mts +1 -0
  126. package/dist/office-js/supported.generated.mjs +235 -0
  127. package/dist/office-js/supported.mjs +53 -0
  128. package/dist/office-js/toApiScript.d.mts +25 -0
  129. package/dist/office-js/toApiScript.mjs +394 -0
  130. package/dist/opc/ContentTypes.d.mts +11 -0
  131. package/dist/opc/ContentTypes.mjs +14 -0
  132. package/dist/opc/DirectoryPartStore.d.mts +47 -0
  133. package/dist/opc/DirectoryPartStore.mjs +123 -0
  134. package/dist/opc/exceptions.d.mts +30 -0
  135. package/dist/opc/exceptions.mjs +38 -0
  136. package/dist/opc/index.d.mts +1 -1
  137. package/dist/opc/index.mjs +1 -1
  138. package/dist/packages/OpcPackage.d.mts +19 -1
  139. package/dist/packages/OpcPackage.mjs +29 -0
  140. package/dist/packages/PresentationMLPackage.d.mts +71 -1
  141. package/dist/packages/PresentationMLPackage.mjs +179 -0
  142. package/dist/packages/SpreadsheetMLPackage.d.mts +30 -1
  143. package/dist/packages/SpreadsheetMLPackage.mjs +78 -0
  144. package/dist/packages/WordprocessingMLPackage.d.mts +124 -2
  145. package/dist/packages/WordprocessingMLPackage.mjs +309 -2
  146. package/dist/packages/index.d.mts +1 -1
  147. package/dist/packages/index.mjs +1 -1
  148. package/dist/parts/DefaultXmlPart.d.mts +18 -0
  149. package/dist/parts/DefaultXmlPart.mjs +34 -5
  150. package/dist/parts/Namespaces.d.mts +18 -0
  151. package/dist/parts/Namespaces.mjs +20 -0
  152. package/dist/parts/Part.d.mts +6 -0
  153. package/dist/parts/Part.mjs +13 -0
  154. package/dist/parts/PartRegistry.mjs +13 -1
  155. package/dist/parts/XmlPart.d.mts +33 -0
  156. package/dist/parts/XmlPart.mjs +105 -2
  157. package/dist/parts/pml/defaults.d.mts +6 -0
  158. package/dist/parts/pml/defaults.mjs +53 -0
  159. package/dist/parts/pml/index.d.mts +66 -3
  160. package/dist/parts/pml/index.mjs +206 -7
  161. package/dist/parts/pml/placeholders.d.mts +71 -0
  162. package/dist/parts/pml/placeholders.mjs +141 -0
  163. package/dist/parts/sml/index.d.mts +80 -1
  164. package/dist/parts/sml/index.mjs +154 -1
  165. package/dist/parts/wml/comments.d.mts +1 -0
  166. package/dist/parts/wml/comments.mjs +179 -0
  167. package/dist/parts/wml/defaultNumbering.d.mts +1 -0
  168. package/dist/parts/wml/defaultNumbering.mjs +216 -0
  169. package/dist/parts/wml/index.d.mts +121 -0
  170. package/dist/parts/wml/index.mjs +291 -0
  171. package/dist/xml/dom.mjs +1 -2
  172. package/package.json +25 -4
@@ -1,6 +1,7 @@
1
1
  import type * as wml from '@docx4j/generated-objects-ts/modules/org_docx4j_wml';
2
2
  import type * as w15 from '@docx4j/generated-objects-ts/modules/org_docx4j_w15';
3
3
  import type * as w16cid from '@docx4j/generated-objects-ts/modules/org_docx4j_w16cid';
4
+ import type * as w16cex from '@docx4j/generated-objects-ts/modules/org_docx4j_w16cex';
4
5
  import type * as wne from '@docx4j/generated-objects-ts/modules/org_docx4j_com_microsoft_schemas_office_word_x2006_wordml';
5
6
  import { XmlPart } from '../XmlPart.mjs';
6
7
  import { Part } from '../Part.mjs';
@@ -8,6 +9,12 @@ import { PartName } from '../../opc/PartName.mjs';
8
9
  import { DefaultXmlPart } from '../DefaultXmlPart.mjs';
9
10
  import { ThemePart } from '../dml/index.mjs';
10
11
  import { Body } from '../../model/content/Body.mjs';
12
+ import type { AbstractListDefinition, ListDefinition } from '../../model/listnumbering/definitions.mjs';
13
+ import { NumberingDefinitions } from '../../model/listnumbering/definitions.mjs';
14
+ import { Emulator } from '../../model/listnumbering/Emulator.mjs';
15
+ import type { NumberingState } from '../../model/listnumbering/state.mjs';
16
+ import { RunFontSelector } from '../../model/fonts/RunFontSelector.mjs';
17
+ import type { Mapper } from '../../model/fonts/Mapper.mjs';
11
18
  /**
12
19
  * Shared by the main document and the glossary document (docx4j DocumentPart): the shortcuts
13
20
  * to styles, numbering, fonts, settings, theme, comments and notes.
@@ -22,6 +29,7 @@ export declare abstract class DocumentPart<T> extends XmlPart<T> {
22
29
  commentsPart: CommentsPart | undefined;
23
30
  commentsExtendedPart: CommentsExtendedPart | undefined;
24
31
  commentsIdsPart: CommentsIdsPart | undefined;
32
+ commentsExtensiblePart: CommentsExtensiblePart | undefined;
25
33
  footnotesPart: FootnotesPart | undefined;
26
34
  endnotesPart: EndnotesPart | undefined;
27
35
  peoplePart: PeoplePart | undefined;
@@ -39,6 +47,49 @@ export declare class MainDocumentPart extends DocumentPart<wml.Document> {
39
47
  /** The Office JS-shaped view of `w:body`; the part must be unmarshalled (`getBody()` does that). */
40
48
  get body(): Body;
41
49
  getBody(): Promise<Body>;
50
+ private fontSelector;
51
+ private fontSelectorPending;
52
+ private fontMapper;
53
+ /**
54
+ * The package's `RunFontSelector`, built once: the property resolver, the theme part's font
55
+ * scheme, the settings part's `w:themeFontLang` and the package's `fonts.defaultTheme`.
56
+ *
57
+ * Asynchronous because it reads the theme and settings parts; `runFontSelector` is the
58
+ * synchronous accessor afterwards. Both parts are read with `readContents()`, so a document
59
+ * whose theme and settings nobody has edited still saves byte for byte.
60
+ */
61
+ getRunFontSelector(): Promise<RunFontSelector>;
62
+ private buildRunFontSelector;
63
+ /** The selector, which must already have been built (`await getRunFontSelector()`). */
64
+ get runFontSelector(): RunFontSelector;
65
+ /** The selector if it has been built, without throwing (what a read with a fallback wants). */
66
+ get runFontSelectorOrUndefined(): RunFontSelector | undefined;
67
+ /**
68
+ * The package's font mapper, populated from {@link fontsInUse} and the font table part
69
+ * (docx4j `WordprocessingMLPackage.getFontMapper` / `setFontMapper`): an
70
+ * `IdentityPlusMapper` over the default font registry unless one is given.
71
+ *
72
+ * @param mapper a mapper of the caller's own, which is then populated and kept
73
+ */
74
+ getFontMapper(mapper?: Mapper): Promise<Mapper>;
75
+ /** Discard the selector and the mapper: the styles, theme or settings changed under us. */
76
+ refreshFonts(): void;
77
+ /**
78
+ * The document font names, as docx4j's `fontsInUse()`: the four slots of every `w:rFonts` on
79
+ * the runs, paragraph marks and content controls of the body, headers, footers, footnotes,
80
+ * endnotes and comments; the styles in use with their `w:basedOn` chains; the numbering
81
+ * levels; the document defaults; and the default font. Theme references are resolved, and a
82
+ * CJK font name is collected by its English name.
83
+ */
84
+ fontsInUse(): Promise<Set<string>>;
85
+ /** The style ids used directly in the document (docx4j `getStylesInUse()`); not those that
86
+ * others are merely based on. */
87
+ getStylesInUse(): Promise<Set<string>>;
88
+ /** The block-level content of each story, in docx4j's order: the body, then the headers and
89
+ * footers, the endnotes, the footnotes and the comments. */
90
+ private stories;
91
+ /** The styles part and its `w:default="1"` style ids, read without costing it its round trip. */
92
+ private styleSource;
42
93
  }
43
94
  /** `/word/glossary/document.xml` (docx4j GlossaryDocumentPart). */
44
95
  export declare class GlossaryDocumentPart extends DocumentPart<wml.GlossaryDocument> {
@@ -47,8 +98,74 @@ export declare class GlossaryDocumentPart extends DocumentPart<wml.GlossaryDocum
47
98
  export declare class StyleDefinitionsPart extends XmlPart<wml.Styles> {
48
99
  constructor(partName?: PartName | string);
49
100
  }
101
+ /**
102
+ * `/word/numbering.xml` (docx4j NumberingDefinitionsPart): the list definitions, the indent a
103
+ * level contributes, and the `Emulator` that turns a paragraph into a label.
104
+ *
105
+ * The definitions are read **privately** (`readContents()`), as the `PropertyResolver` reads the
106
+ * styles, so that a document whose labels are only read still saves byte for byte; where the
107
+ * package already has a resolver the definitions it built are reused, since it needs them for
108
+ * `getInd`. A change to the part is picked up by `WordprocessingMLPackage.refresh()`.
109
+ */
50
110
  export declare class NumberingDefinitionsPart extends XmlPart<wml.Numbering> {
51
111
  constructor(partName?: PartName | string);
112
+ /** The tree `readContents()` gave, kept so the definitions can be rebuilt without re-reading. */
113
+ private privateTree;
114
+ private ownDefinitions;
115
+ private ownDefinitionsFrom;
116
+ private emulator;
117
+ /** The resolver of the package this part belongs to, if it has one built. */
118
+ private get resolver();
119
+ /** The `w:numbering` the definitions are built over: the live tree, or the private read. */
120
+ private get tree();
121
+ /**
122
+ * docx4j `initialiseMaps` and the two maps it fills: every `w:abstractNum` and every `w:num`,
123
+ * with `w:numStyleLink` resolved. Synchronous, so the part's tree must have been read - by
124
+ * {@link getDefinitions}, or by the package's `getPropertyResolver()`.
125
+ */
126
+ get definitions(): NumberingDefinitions;
127
+ /** {@link definitions}, reading the part first where nothing has. */
128
+ getDefinitions(): Promise<NumberingDefinitions>;
129
+ /** `w:abstractNumId` -> the definition. docx4j `getAbstractListDefinitions()`. */
130
+ get abstractListDefinitions(): ReadonlyMap<string, AbstractListDefinition>;
131
+ /** `w:numId` -> the definition. docx4j `getInstanceListDefinitions()`. */
132
+ get instanceListDefinitions(): ReadonlyMap<string, ListDefinition>;
133
+ /** The indent a `w:numPr`'s level contributes. docx4j `getInd(NumPr)`. */
134
+ getInd(numPr: wml.PPrBase.NumPr): wml.PPrBase.Ind | undefined;
135
+ /** The indent a level contributes. docx4j `getInd(String, String)`. */
136
+ getIndOf(numId: string, ilvl: string | undefined): wml.PPrBase.Ind | undefined;
137
+ /** The paragraph style a level is linked to (ECMA-376 17.9.24), or undefined. */
138
+ getLinkedStyleId(numId: string, ilvl: string | undefined): string | undefined;
139
+ /**
140
+ * docx4j `getEmulator([reset])`: the numbering emulator over this part, built once. `reset`
141
+ * gives it a fresh default {@link NumberingState} and re-reads the definitions, as docx4j's
142
+ * does - every list starts again.
143
+ */
144
+ getEmulator(reset?: boolean): Emulator;
145
+ /** The counters the state-less `Emulator` calls use. docx4j `getNumberingState()`. */
146
+ get numberingState(): NumberingState;
147
+ /**
148
+ * Replaces this part's contents with docx4j's default numbering (`numbering.xml` from its
149
+ * resources): abstractNum 0 is Word's bullet set and abstractNum 1 its decimal set, with
150
+ * `w:num` 1 naming the decimal one and `w:num` 2 the bullet one.
151
+ * docx4j `unmarshalDefaultNumbering()`.
152
+ */
153
+ unmarshalDefaultNumbering(): Promise<wml.Numbering>;
154
+ /**
155
+ * Makes the tree the definitions were built over this part's **live** contents, so that an
156
+ * edit to a `w:num` or a `w:lvl` is marshalled on save (CR-002 phase H).
157
+ *
158
+ * The definitions are read privately (`readContents()`), which keeps a document whose labels
159
+ * are only read byte for byte; a write has to give that up. Promoting the tree that is
160
+ * already in hand - rather than unmarshalling the part a second time - is what keeps the
161
+ * `List` views valid across the change: they hold objects of that very tree.
162
+ *
163
+ * Synchronous, since the tree has been read; the part must have been read
164
+ * (`getDefinitions()`, or the package's `getPropertyResolver()`) or unmarshalled first.
165
+ */
166
+ makeLive(): wml.Numbering;
167
+ /** Forgets the definitions and the emulator: the tree has changed under us. */
168
+ refreshDefinitions(): void;
52
169
  }
53
170
  export declare class FontTablePart extends XmlPart<wml.Fonts> {
54
171
  constructor(partName?: PartName | string);
@@ -86,6 +203,10 @@ export declare class CommentsExtendedPart extends XmlPart<w15.CTCommentsEx> {
86
203
  export declare class CommentsIdsPart extends XmlPart<w16cid.CTCommentsIds> {
87
204
  constructor(partName?: PartName | string);
88
205
  }
206
+ /** `/word/commentsExtensible.xml` (w16cex, Word 2018): a durable id and a UTC date per comment. Typed since objects 0.1.3. */
207
+ export declare class CommentsExtensiblePart extends XmlPart<w16cex.CTCommentsExtensible> {
208
+ constructor(partName?: PartName | string);
209
+ }
89
210
  export declare class PeoplePart extends XmlPart<w15.CTPeople> {
90
211
  constructor(partName?: PartName | string);
91
212
  }
@@ -5,7 +5,24 @@ import { DefaultXmlPart } from '../DefaultXmlPart.mjs';
5
5
  import { ThemePart } from '../dml/index.mjs';
6
6
  import { Body } from '../../model/content/Body.mjs';
7
7
  import { Docx4JException } from '../../opc/exceptions.mjs';
8
+ import { NumberingDefinitions } from '../../model/listnumbering/definitions.mjs';
9
+ import { Emulator } from '../../model/listnumbering/Emulator.mjs';
10
+ import { DEFAULT_NUMBERING_XML } from './defaultNumbering.mjs';
11
+ import { RunFontSelector } from '../../model/fonts/RunFontSelector.mjs';
12
+ import { IdentityPlusMapper } from '../../model/fonts/IdentityPlusMapper.mjs';
13
+ import { themeOfSettings } from '../../model/fonts/defaultTheme.mjs';
14
+ import { fontsInUse, walkStories } from '../../model/fonts/fontsInUse.mjs';
8
15
  const bodies = new WeakMap();
16
+ /**
17
+ * Builds the package's `PropertyResolver` if it has one to build, so that the effective reads
18
+ * of a `Body` obtained asynchronously work (CR-001 Phase B step 2). Structural, not by import:
19
+ * a static import of `WordprocessingMLPackage` here would be a runtime cycle.
20
+ */
21
+ async function ensurePropertyResolver(part) {
22
+ var _a;
23
+ const pkg = part.package;
24
+ await ((_a = pkg === null || pkg === void 0 ? void 0 : pkg.getPropertyResolver) === null || _a === void 0 ? void 0 : _a.call(pkg));
25
+ }
9
26
  /** The Body view of a part's block-level container, one per container object. */
10
27
  function bodyOf(part, container, prefix) {
11
28
  if (!container)
@@ -20,6 +37,7 @@ function bodyOf(part, container, prefix) {
20
37
  const W = Namespaces.NS_WORD12;
21
38
  const W15 = 'http://schemas.microsoft.com/office/word/2012/wordml';
22
39
  const W16CID = 'http://schemas.microsoft.com/office/word/2016/wordml/cid';
40
+ const W16CEX = 'http://schemas.microsoft.com/office/word/2018/wordml/cex';
23
41
  const WNE = 'http://schemas.microsoft.com/office/word/2006/wordml';
24
42
  /**
25
43
  * Shared by the main document and the glossary document (docx4j DocumentPart): the shortcuts
@@ -55,6 +73,9 @@ export class DocumentPart extends XmlPart {
55
73
  case Namespaces.COMMENTS_IDS:
56
74
  this.commentsIdsPart = part;
57
75
  return true;
76
+ case Namespaces.COMMENTS_EXTENSIBLE:
77
+ this.commentsExtensiblePart = part;
78
+ return true;
58
79
  case Namespaces.FOOTNOTES:
59
80
  this.footnotesPart = part;
60
81
  return true;
@@ -102,8 +123,139 @@ export class MainDocumentPart extends DocumentPart {
102
123
  }
103
124
  async getBody() {
104
125
  await this.getContents();
126
+ await ensurePropertyResolver(this);
105
127
  return this.body;
106
128
  }
129
+ /**
130
+ * The package's `RunFontSelector`, built once: the property resolver, the theme part's font
131
+ * scheme, the settings part's `w:themeFontLang` and the package's `fonts.defaultTheme`.
132
+ *
133
+ * Asynchronous because it reads the theme and settings parts; `runFontSelector` is the
134
+ * synchronous accessor afterwards. Both parts are read with `readContents()`, so a document
135
+ * whose theme and settings nobody has edited still saves byte for byte.
136
+ */
137
+ async getRunFontSelector() {
138
+ var _a;
139
+ if (this.fontSelector)
140
+ return this.fontSelector;
141
+ (_a = this.fontSelectorPending) !== null && _a !== void 0 ? _a : (this.fontSelectorPending = this.buildRunFontSelector().then((selector) => {
142
+ this.fontSelector = selector;
143
+ this.fontSelectorPending = undefined;
144
+ return selector;
145
+ }));
146
+ return this.fontSelectorPending;
147
+ }
148
+ async buildRunFontSelector() {
149
+ const theme = this.themePart === undefined ? undefined : await readQuietly(this.themePart);
150
+ const settings = this.documentSettingsPart === undefined
151
+ ? undefined : await readQuietly(this.documentSettingsPart);
152
+ const pkg = this.package;
153
+ return new RunFontSelector({
154
+ resolver: pkg === null || pkg === void 0 ? void 0 : pkg.propertyResolverOrUndefined,
155
+ theme,
156
+ themeFontLang: settings === null || settings === void 0 ? void 0 : settings.themeFontLang,
157
+ defaultTheme: themeOfSettings(pkg === null || pkg === void 0 ? void 0 : pkg.fonts),
158
+ });
159
+ }
160
+ /** The selector, which must already have been built (`await getRunFontSelector()`). */
161
+ get runFontSelector() {
162
+ if (!this.fontSelector) {
163
+ throw new Docx4JException('No RunFontSelector yet: await mainDocumentPart.getRunFontSelector()');
164
+ }
165
+ return this.fontSelector;
166
+ }
167
+ /** The selector if it has been built, without throwing (what a read with a fallback wants). */
168
+ get runFontSelectorOrUndefined() {
169
+ return this.fontSelector;
170
+ }
171
+ /**
172
+ * The package's font mapper, populated from {@link fontsInUse} and the font table part
173
+ * (docx4j `WordprocessingMLPackage.getFontMapper` / `setFontMapper`): an
174
+ * `IdentityPlusMapper` over the default font registry unless one is given.
175
+ *
176
+ * @param mapper a mapper of the caller's own, which is then populated and kept
177
+ */
178
+ async getFontMapper(mapper) {
179
+ if (mapper === undefined && this.fontMapper)
180
+ return this.fontMapper;
181
+ const m = mapper !== null && mapper !== void 0 ? mapper : new IdentityPlusMapper();
182
+ m.populate(await this.fontsInUse(), this.fontTablePart === undefined ? undefined : await readQuietly(this.fontTablePart));
183
+ this.fontMapper = m;
184
+ return m;
185
+ }
186
+ /** Discard the selector and the mapper: the styles, theme or settings changed under us. */
187
+ refreshFonts() {
188
+ this.fontSelector = undefined;
189
+ this.fontSelectorPending = undefined;
190
+ this.fontMapper = undefined;
191
+ }
192
+ /**
193
+ * The document font names, as docx4j's `fontsInUse()`: the four slots of every `w:rFonts` on
194
+ * the runs, paragraph marks and content controls of the body, headers, footers, footnotes,
195
+ * endnotes and comments; the styles in use with their `w:basedOn` chains; the numbering
196
+ * levels; the document defaults; and the default font. Theme references are resolved, and a
197
+ * CJK font name is collected by its English name.
198
+ */
199
+ async fontsInUse() {
200
+ const selector = await this.getRunFontSelector();
201
+ const numbering = this.numberingDefinitionsPart === undefined
202
+ ? undefined : await readQuietly(this.numberingDefinitionsPart);
203
+ return fontsInUse(await this.stories(), await this.styleSource(), numbering, selector);
204
+ }
205
+ /** The style ids used directly in the document (docx4j `getStylesInUse()`); not those that
206
+ * others are merely based on. */
207
+ async getStylesInUse() {
208
+ return walkStories(await this.stories(), await this.styleSource(), undefined, false).styles;
209
+ }
210
+ /** The block-level content of each story, in docx4j's order: the body, then the headers and
211
+ * footers, the endnotes, the footnotes and the comments. */
212
+ async stories() {
213
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
214
+ const out = [(_b = (_a = (await this.getContents()).body) === null || _a === void 0 ? void 0 : _a.content) !== null && _b !== void 0 ? _b : []];
215
+ const rp = this.relationshipsPart;
216
+ for (const r of (_c = rp === null || rp === void 0 ? void 0 : rp.relationships.relationship) !== null && _c !== void 0 ? _c : []) {
217
+ const part = rp === null || rp === void 0 ? void 0 : rp.getPart(r);
218
+ if (part instanceof HeaderPart)
219
+ out.push((_e = (_d = (await readQuietly(part))) === null || _d === void 0 ? void 0 : _d.content) !== null && _e !== void 0 ? _e : []);
220
+ else if (part instanceof FooterPart)
221
+ out.push((_g = (_f = (await readQuietly(part))) === null || _f === void 0 ? void 0 : _f.content) !== null && _g !== void 0 ? _g : []);
222
+ }
223
+ if (this.endnotesPart)
224
+ out.push((_j = (_h = (await readQuietly(this.endnotesPart))) === null || _h === void 0 ? void 0 : _h.endnote) !== null && _j !== void 0 ? _j : []);
225
+ if (this.footnotesPart)
226
+ out.push((_l = (_k = (await readQuietly(this.footnotesPart))) === null || _k === void 0 ? void 0 : _k.footnote) !== null && _l !== void 0 ? _l : []);
227
+ if (this.commentsPart)
228
+ out.push((_o = (_m = (await readQuietly(this.commentsPart))) === null || _m === void 0 ? void 0 : _m.comment) !== null && _o !== void 0 ? _o : []);
229
+ return out;
230
+ }
231
+ /** The styles part and its `w:default="1"` style ids, read without costing it its round trip. */
232
+ async styleSource() {
233
+ var _a, _b, _c, _d;
234
+ const styles = this.styleDefinitionsPart === undefined
235
+ ? undefined : await readQuietly(this.styleDefinitionsPart);
236
+ const source = { styles };
237
+ for (const style of (_a = styles === null || styles === void 0 ? void 0 : styles.style) !== null && _a !== void 0 ? _a : []) {
238
+ if (style._default !== true || style.styleId === undefined)
239
+ continue;
240
+ if (style.type === 'paragraph')
241
+ (_b = source.defaultParagraphStyleId) !== null && _b !== void 0 ? _b : (source.defaultParagraphStyleId = style.styleId);
242
+ else if (style.type === 'character')
243
+ (_c = source.defaultCharacterStyleId) !== null && _c !== void 0 ? _c : (source.defaultCharacterStyleId = style.styleId);
244
+ else if (style.type === 'table')
245
+ (_d = source.defaultTableStyleId) !== null && _d !== void 0 ? _d : (source.defaultTableStyleId = style.styleId);
246
+ }
247
+ return source;
248
+ }
249
+ }
250
+ /** `readContents()`, answering undefined for a part that cannot be read: a document with an
251
+ * unreadable theme or settings part still resolves its fonts, as docx4j's selector does. */
252
+ async function readQuietly(part) {
253
+ try {
254
+ return await part.readContents();
255
+ }
256
+ catch {
257
+ return undefined;
258
+ }
107
259
  }
108
260
  /** `/word/glossary/document.xml` (docx4j GlossaryDocumentPart). */
109
261
  export class GlossaryDocumentPart extends DocumentPart {
@@ -116,10 +268,141 @@ export class StyleDefinitionsPart extends XmlPart {
116
268
  super(partName, ContentTypes.WORDPROCESSINGML_STYLES, Namespaces.STYLES, { namespaceURI: W, localPart: 'styles' });
117
269
  }
118
270
  }
271
+ /**
272
+ * `/word/numbering.xml` (docx4j NumberingDefinitionsPart): the list definitions, the indent a
273
+ * level contributes, and the `Emulator` that turns a paragraph into a label.
274
+ *
275
+ * The definitions are read **privately** (`readContents()`), as the `PropertyResolver` reads the
276
+ * styles, so that a document whose labels are only read still saves byte for byte; where the
277
+ * package already has a resolver the definitions it built are reused, since it needs them for
278
+ * `getInd`. A change to the part is picked up by `WordprocessingMLPackage.refresh()`.
279
+ */
119
280
  export class NumberingDefinitionsPart extends XmlPart {
120
281
  constructor(partName = '/word/numbering.xml') {
121
282
  super(partName, ContentTypes.WORDPROCESSINGML_NUMBERING, Namespaces.NUMBERING, { namespaceURI: W, localPart: 'numbering' });
122
283
  }
284
+ /** The resolver of the package this part belongs to, if it has one built. */
285
+ get resolver() {
286
+ var _a;
287
+ return (_a = this.package) === null || _a === void 0 ? void 0 : _a.propertyResolverOrUndefined;
288
+ }
289
+ /** The `w:numbering` the definitions are built over: the live tree, or the private read. */
290
+ get tree() {
291
+ return this.isUnmarshalled ? this.contents : this.privateTree;
292
+ }
293
+ /**
294
+ * docx4j `initialiseMaps` and the two maps it fills: every `w:abstractNum` and every `w:num`,
295
+ * with `w:numStyleLink` resolved. Synchronous, so the part's tree must have been read - by
296
+ * {@link getDefinitions}, or by the package's `getPropertyResolver()`.
297
+ */
298
+ get definitions() {
299
+ const live = this.tree;
300
+ const resolver = this.resolver;
301
+ const shared = resolver === null || resolver === void 0 ? void 0 : resolver.getNumberingDefinitions();
302
+ // the resolver's copy, unless the part has been unmarshalled and edited since it read it
303
+ if (shared !== undefined && (!this.isUnmarshalled || shared.numbering === live))
304
+ return shared;
305
+ if (live === undefined) {
306
+ throw new Docx4JException(`${this.partName} has not been read yet; await getDefinitions() first`);
307
+ }
308
+ if (this.ownDefinitions === undefined || this.ownDefinitionsFrom !== live) {
309
+ this.ownDefinitions = new NumberingDefinitions(live, (styleId) => { var _a; return (_a = this.resolver) === null || _a === void 0 ? void 0 : _a.getStyle(styleId); });
310
+ this.ownDefinitionsFrom = live;
311
+ }
312
+ return this.ownDefinitions;
313
+ }
314
+ /** {@link definitions}, reading the part first where nothing has. */
315
+ async getDefinitions() {
316
+ if (!this.isUnmarshalled && this.privateTree === undefined)
317
+ this.privateTree = await this.readContents();
318
+ return this.definitions;
319
+ }
320
+ /** `w:abstractNumId` -> the definition. docx4j `getAbstractListDefinitions()`. */
321
+ get abstractListDefinitions() {
322
+ return this.definitions.abstractListDefinitions;
323
+ }
324
+ /** `w:numId` -> the definition. docx4j `getInstanceListDefinitions()`. */
325
+ get instanceListDefinitions() {
326
+ return this.definitions.instanceListDefinitions;
327
+ }
328
+ /** The indent a `w:numPr`'s level contributes. docx4j `getInd(NumPr)`. */
329
+ getInd(numPr) {
330
+ return this.definitions.getInd(numPr);
331
+ }
332
+ /** The indent a level contributes. docx4j `getInd(String, String)`. */
333
+ getIndOf(numId, ilvl) {
334
+ return this.definitions.indOf(numId, ilvl);
335
+ }
336
+ /** The paragraph style a level is linked to (ECMA-376 17.9.24), or undefined. */
337
+ getLinkedStyleId(numId, ilvl) {
338
+ return this.definitions.getLinkedStyleId(numId, ilvl);
339
+ }
340
+ /**
341
+ * docx4j `getEmulator([reset])`: the numbering emulator over this part, built once. `reset`
342
+ * gives it a fresh default {@link NumberingState} and re-reads the definitions, as docx4j's
343
+ * does - every list starts again.
344
+ */
345
+ getEmulator(reset = false) {
346
+ if (reset) {
347
+ this.ownDefinitions = undefined;
348
+ this.ownDefinitionsFrom = undefined;
349
+ this.emulator = undefined;
350
+ }
351
+ const definitions = this.definitions;
352
+ if (this.emulator === undefined || this.emulator.definitions !== definitions
353
+ || this.emulator.resolver !== this.resolver) {
354
+ this.emulator = new Emulator(definitions, this.resolver, this.emulator === undefined ? undefined : this.emulator.numberingState);
355
+ }
356
+ return this.emulator;
357
+ }
358
+ /** The counters the state-less `Emulator` calls use. docx4j `getNumberingState()`. */
359
+ get numberingState() {
360
+ return this.getEmulator().numberingState;
361
+ }
362
+ /**
363
+ * Replaces this part's contents with docx4j's default numbering (`numbering.xml` from its
364
+ * resources): abstractNum 0 is Word's bullet set and abstractNum 1 its decimal set, with
365
+ * `w:num` 1 naming the decimal one and `w:num` 2 the bullet one.
366
+ * docx4j `unmarshalDefaultNumbering()`.
367
+ */
368
+ async unmarshalDefaultNumbering() {
369
+ this.setXml(DEFAULT_NUMBERING_XML);
370
+ this.privateTree = undefined;
371
+ this.ownDefinitions = undefined;
372
+ this.ownDefinitionsFrom = undefined;
373
+ this.emulator = undefined;
374
+ return this.getContents();
375
+ }
376
+ /**
377
+ * Makes the tree the definitions were built over this part's **live** contents, so that an
378
+ * edit to a `w:num` or a `w:lvl` is marshalled on save (CR-002 phase H).
379
+ *
380
+ * The definitions are read privately (`readContents()`), which keeps a document whose labels
381
+ * are only read byte for byte; a write has to give that up. Promoting the tree that is
382
+ * already in hand - rather than unmarshalling the part a second time - is what keeps the
383
+ * `List` views valid across the change: they hold objects of that very tree.
384
+ *
385
+ * Synchronous, since the tree has been read; the part must have been read
386
+ * (`getDefinitions()`, or the package's `getPropertyResolver()`) or unmarshalled first.
387
+ */
388
+ makeLive() {
389
+ if (this.isUnmarshalled)
390
+ return this.contents;
391
+ const tree = this.definitions.numbering;
392
+ if (tree === undefined) {
393
+ throw new Docx4JException(`${this.partName} has not been read yet; await getDefinitions() first`);
394
+ }
395
+ this.setContents(tree);
396
+ this.privateTree = undefined;
397
+ return tree;
398
+ }
399
+ /** Forgets the definitions and the emulator: the tree has changed under us. */
400
+ refreshDefinitions() {
401
+ this.privateTree = undefined;
402
+ this.ownDefinitions = undefined;
403
+ this.ownDefinitionsFrom = undefined;
404
+ this.emulator = undefined;
405
+ }
123
406
  }
124
407
  export class FontTablePart extends XmlPart {
125
408
  constructor(partName = '/word/fontTable.xml') {
@@ -147,6 +430,7 @@ export class HeaderPart extends XmlPart {
147
430
  }
148
431
  async getBody() {
149
432
  await this.getContents();
433
+ await ensurePropertyResolver(this);
150
434
  return this.body;
151
435
  }
152
436
  }
@@ -161,6 +445,7 @@ export class FooterPart extends XmlPart {
161
445
  }
162
446
  async getBody() {
163
447
  await this.getContents();
448
+ await ensurePropertyResolver(this);
164
449
  return this.body;
165
450
  }
166
451
  }
@@ -189,6 +474,12 @@ export class CommentsIdsPart extends XmlPart {
189
474
  super(partName, ContentTypes.WORDPROCESSINGML_COMMENTS_IDS, Namespaces.COMMENTS_IDS, { namespaceURI: W16CID, localPart: 'commentsIds' });
190
475
  }
191
476
  }
477
+ /** `/word/commentsExtensible.xml` (w16cex, Word 2018): a durable id and a UTC date per comment. Typed since objects 0.1.3. */
478
+ export class CommentsExtensiblePart extends XmlPart {
479
+ constructor(partName = '/word/commentsExtensible.xml') {
480
+ super(partName, ContentTypes.WORDPROCESSINGML_COMMENTS_EXTENSIBLE, Namespaces.COMMENTS_EXTENSIBLE, { namespaceURI: W16CEX, localPart: 'commentsExtensible' });
481
+ }
482
+ }
192
483
  export class PeoplePart extends XmlPart {
193
484
  constructor(partName = '/word/people.xml') {
194
485
  super(partName, ContentTypes.WORDPROCESSINGML_PEOPLE, Namespaces.OFFICE_2011_PEOPLE, { namespaceURI: W15, localPart: 'people' });
package/dist/xml/dom.mjs CHANGED
@@ -1,6 +1,5 @@
1
1
  // DOM, text and base64 helpers over the runtime's DOM implementation. In Node the runtime brings
2
- // @xmldom/xmldom; in browsers it uses the native DOM. Jsonix.DOM is not in the runtime's typings
3
- // yet (a jsonix CR candidate), hence the cast here, kept to this one module.
2
+ // @xmldom/xmldom; in browsers it uses the native DOM. Jsonix.DOM is typed since @docx4j/jsonix 3.2.1.
4
3
  import { Jsonix } from '@docx4j/generated-objects-ts';
5
4
  const DOM = Jsonix.DOM;
6
5
  /** The declaration docx4j writes on every XML part. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docx4j/core-ts",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "docx4j-core for TypeScript: Open Packaging (docx/pptx/xlsx zip and flat OPC), typed parts and relationships, style, numbering and font resolution over @docx4j/generated-objects-ts. Node, browsers, Word add-ins.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.mjs",
@@ -25,6 +25,14 @@
25
25
  "./model": {
26
26
  "types": "./dist/model/index.d.mts",
27
27
  "import": "./dist/model/index.mjs"
28
+ },
29
+ "./node": {
30
+ "types": "./dist/node/index.d.mts",
31
+ "import": "./dist/node/index.mjs"
32
+ },
33
+ "./office-js": {
34
+ "types": "./dist/office-js/index.d.mts",
35
+ "import": "./dist/office-js/index.mjs"
28
36
  }
29
37
  },
30
38
  "files": [
@@ -34,8 +42,12 @@
34
42
  "NOTICE"
35
43
  ],
36
44
  "scripts": {
45
+ "generate": "node scripts/generate-supported.mjs",
37
46
  "build": "tsc -p tsconfig.build.json",
38
- "typecheck": "tsc -p tsconfig.json",
47
+ "generate:fonts": "node scripts/generate-substitutions.mjs",
48
+ "typecheck": "tsc -p tsconfig.json && npm run typecheck:examples",
49
+ "typecheck:examples": "npm run build && tsc -p examples/office-addin/tsconfig.json",
50
+ "pretest": "node scripts/generate-supported.mjs",
39
51
  "test": "npm run build && tsc -p test/nodenext/tsconfig.json && node --test test/*.test.mjs",
40
52
  "prepublishOnly": "npm run typecheck && npm test"
41
53
  },
@@ -63,11 +75,20 @@
63
75
  },
64
76
  "license": "Apache-2.0",
65
77
  "dependencies": {
66
- "@docx4j/generated-objects-ts": "^0.1.1",
78
+ "@docx4j/generated-objects-ts": "^0.2.0",
67
79
  "fflate": "^0.8.2"
68
80
  },
69
81
  "devDependencies": {
70
- "typescript": "~5.6.3"
82
+ "typescript": "~5.6.3",
83
+ "xpath": "^0.0.34"
84
+ },
85
+ "peerDependencies": {
86
+ "xpath": "^0.0.34"
87
+ },
88
+ "peerDependenciesMeta": {
89
+ "xpath": {
90
+ "optional": true
91
+ }
71
92
  },
72
93
  "engines": {
73
94
  "node": ">=18"