@docx4j/core-ts 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) 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 +1 -0
  131. package/dist/opc/ContentTypes.mjs +1 -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/PartRegistry.mjs +1 -0
  151. package/dist/parts/XmlPart.d.mts +33 -0
  152. package/dist/parts/XmlPart.mjs +105 -2
  153. package/dist/parts/pml/defaults.d.mts +6 -0
  154. package/dist/parts/pml/defaults.mjs +53 -0
  155. package/dist/parts/pml/index.d.mts +66 -3
  156. package/dist/parts/pml/index.mjs +206 -7
  157. package/dist/parts/pml/placeholders.d.mts +71 -0
  158. package/dist/parts/pml/placeholders.mjs +141 -0
  159. package/dist/parts/sml/index.d.mts +19 -1
  160. package/dist/parts/sml/index.mjs +60 -1
  161. package/dist/parts/wml/comments.d.mts +1 -0
  162. package/dist/parts/wml/comments.mjs +179 -0
  163. package/dist/parts/wml/defaultNumbering.d.mts +1 -0
  164. package/dist/parts/wml/defaultNumbering.mjs +216 -0
  165. package/dist/parts/wml/index.d.mts +121 -0
  166. package/dist/parts/wml/index.mjs +291 -0
  167. package/dist/xml/dom.mjs +1 -2
  168. package/package.json +25 -4
@@ -0,0 +1,352 @@
1
+ import { textOf } from '@docx4j/generated-objects-ts/builders/wml';
2
+ import { Docx4JException } from '../../opc/exceptions.mjs';
3
+ import { typeNameOf, runItemsOf, revisionKindOf, linkParents, segmentsOf, textOfView, cellsOf, childrenOf } from './tree.mjs';
4
+ import { Range } from './Range.mjs';
5
+ import { rPrFromElements } from '@docx4j/generated-objects-ts/builders/wml';
6
+ import { dateOf, toRestoredText, restoreRPr, restorePPr, pruneParagraphProperties } from './tracking.mjs';
7
+ /**
8
+ * A subset of Office JS `Word.TrackedChange`: `type`, `author`, `date`, `text`, `accept()`,
9
+ * `reject()` and `getRange()`, plus `element`, `id` and `target` as extensions. A view, like
10
+ * `Paragraph` and `Range`: it holds the markup it is over, nothing is cached.
11
+ */
12
+ export class TrackedChange {
13
+ constructor(target,
14
+ /** The paragraph the change is in; undefined for a row revision. */
15
+ paragraph) {
16
+ this.target = target;
17
+ this.paragraph = paragraph;
18
+ }
19
+ /** Office JS `Word.ChangeTrackingState`. */
20
+ get type() {
21
+ const t = this.target;
22
+ switch (t.kind) {
23
+ case 'run': return t.revision === 'ins' || t.revision === 'moveTo' ? 'Added' : 'Deleted';
24
+ case 'mark': return t.mark === 'ins' ? 'Added' : 'Deleted';
25
+ case 'row': return t.row === 'ins' ? 'Added' : 'Deleted';
26
+ default: return 'Formatted';
27
+ }
28
+ }
29
+ get author() {
30
+ return this.target.value.author;
31
+ }
32
+ /** `w:date`, when the markup carries one. */
33
+ get date() {
34
+ return dateOf(this.target.value.date);
35
+ }
36
+ /** The annotation id (`w:id`; an extension). */
37
+ get id() {
38
+ return this.target.value.id;
39
+ }
40
+ /** The markup this change is over (an extension): the `w:ins` element, the `w:rPrChange`, ... */
41
+ get element() {
42
+ return this.target.kind === 'run' ? this.target.element : this.target.kind === 'row' ? this.target.tr : this.target.value;
43
+ }
44
+ /** The text the change covers; '' for a paragraph mark, whose range is the paragraph. */
45
+ get text() {
46
+ var _a, _b;
47
+ const t = this.target;
48
+ switch (t.kind) {
49
+ case 'run': return segmentsOf(t.element.value, { view: t.revision === 'ins' || t.revision === 'moveTo' ? 'accepted' : 'original' }).map((s) => s.text).join('');
50
+ case 'runProperties': return textOf(t.run);
51
+ case 'paragraphProperties': return (_b = (_a = this.paragraph) === null || _a === void 0 ? void 0 : _a.text) !== null && _b !== void 0 ? _b : '';
52
+ // a deleted row's content is `w:delText` inside `w:del`, which the accepted view skips:
53
+ // its text is what the row said before, as for a run deletion
54
+ case 'row': return rowText(t.tr.value, t.row === 'del' ? 'original' : 'accepted');
55
+ default: return '';
56
+ }
57
+ }
58
+ /** The range the change covers; a deletion is a collapsed range where it sits in the accepted text. */
59
+ getRange() {
60
+ const p = this.paragraph;
61
+ if (!p)
62
+ return undefined;
63
+ const t = this.target;
64
+ if (t.kind === 'run') {
65
+ const [start, end] = spanOf(p, t.element);
66
+ return new Range(p, start, end);
67
+ }
68
+ if (t.kind === 'runProperties') {
69
+ const segs = p.segments().filter((s) => s.run === t.run);
70
+ if (segs.length === 0)
71
+ return p.getRange('Start');
72
+ return new Range(p, segs[0].start, segs[segs.length - 1].end);
73
+ }
74
+ return p.getRange('Whole');
75
+ }
76
+ /** Keeps the change: a `w:ins` is unwrapped, a `w:del` removed, a deleted mark joins the paragraphs. */
77
+ accept() {
78
+ var _a, _b, _c;
79
+ const t = this.target;
80
+ switch (t.kind) {
81
+ case 'run':
82
+ if (t.revision === 'ins' || t.revision === 'moveTo')
83
+ unwrap(t);
84
+ else
85
+ remove(t.owner, t.element);
86
+ return;
87
+ case 'mark':
88
+ if (t.mark === 'ins')
89
+ dropMark(this.paragraph, 'ins');
90
+ else
91
+ joinWithNext(this.requireParagraph());
92
+ return;
93
+ case 'runProperties':
94
+ (_a = t.run.rPr) === null || _a === void 0 ? true : delete _a.rPrChange;
95
+ return;
96
+ case 'paragraphProperties': {
97
+ const p = this.requireParagraph().p;
98
+ (_b = p.pPr) === null || _b === void 0 ? true : delete _b.pPrChange;
99
+ pruneParagraphProperties(p);
100
+ return;
101
+ }
102
+ case 'row':
103
+ // an accepted insertion keeps the row, so its content's own w:ins must go with the
104
+ // w:trPr/w:ins; an accepted deletion takes the row and everything in it away
105
+ if (t.row === 'ins') {
106
+ (_c = t.tr.value.trPr) === null || _c === void 0 ? true : delete _c.ins;
107
+ applyInner(t.inner, 'accept');
108
+ }
109
+ else
110
+ remove(t.owner, t.tr);
111
+ return;
112
+ }
113
+ }
114
+ /** Puts back what was there: a `w:ins` is removed, a `w:del` restored, a `w:rPrChange` re-applied. */
115
+ reject() {
116
+ var _a;
117
+ const t = this.target;
118
+ switch (t.kind) {
119
+ case 'run':
120
+ if (t.revision === 'ins' || t.revision === 'moveTo')
121
+ remove(t.owner, t.element);
122
+ else
123
+ restoreDeleted(t);
124
+ return;
125
+ case 'mark':
126
+ if (t.mark === 'del')
127
+ dropMark(this.paragraph, 'del');
128
+ else
129
+ joinWithNext(this.requireParagraph(), true);
130
+ return;
131
+ case 'runProperties':
132
+ restoreRPr(t.run, rPrFromElements(t.value.rPr));
133
+ return;
134
+ case 'paragraphProperties': {
135
+ const p = this.requireParagraph().p;
136
+ restorePPr(p, t.value.pPr);
137
+ return;
138
+ }
139
+ case 'row':
140
+ // a rejected deletion keeps the row, so its content comes back too (w:delText to w:t,
141
+ // the w:del unwrapped, the deleted marks dropped); a rejected insertion takes it away
142
+ if (t.row === 'del') {
143
+ (_a = t.tr.value.trPr) === null || _a === void 0 ? true : delete _a.del;
144
+ applyInner(t.inner, 'reject');
145
+ }
146
+ else
147
+ remove(t.owner, t.tr);
148
+ return;
149
+ }
150
+ }
151
+ requireParagraph() {
152
+ if (!this.paragraph)
153
+ throw new Docx4JException('This tracked change has no paragraph');
154
+ return this.paragraph;
155
+ }
156
+ }
157
+ // --- the operations ------------------------------------------------------------------------
158
+ /**
159
+ * The text of a table row in one of the two views, a line per paragraph (docx4j TextUtils, which
160
+ * the builders' `textOf` is - but that reads the accepted view only, and a deleted row's content
161
+ * is all `w:delText`).
162
+ */
163
+ function rowText(tr, view) {
164
+ const lines = [];
165
+ const visit = (items) => {
166
+ for (const el of items !== null && items !== void 0 ? items : []) {
167
+ if (typeNameOf(el) === 'org_docx4j_wml.P') {
168
+ lines.push(textOfView(el.value, { view }));
169
+ continue;
170
+ }
171
+ const v = el.value;
172
+ if (typeof v === 'object' && v !== null)
173
+ visit(childrenOf(v));
174
+ }
175
+ };
176
+ for (const cell of cellsOf(tr))
177
+ visit(childrenOf(cell.element.value));
178
+ return lines.join('\n');
179
+ }
180
+ /** The changes inside a row, last first, so that a paragraph join never disturbs one still to do. */
181
+ function applyInner(inner, what) {
182
+ for (let i = inner.length - 1; i >= 0; i--)
183
+ inner[i][what]();
184
+ }
185
+ function remove(owner, element) {
186
+ const i = owner.indexOf(element);
187
+ if (i >= 0)
188
+ owner.splice(i, 1);
189
+ }
190
+ /** A `w:ins` or `w:moveTo` accepted: its runs take its place. */
191
+ function unwrap(t) {
192
+ var _a;
193
+ const i = t.owner.indexOf(t.element);
194
+ if (i < 0)
195
+ return;
196
+ const items = (_a = runItemsOf(t.element.value)) !== null && _a !== void 0 ? _a : [];
197
+ t.owner.splice(i, 1, ...items);
198
+ const parent = t.value.PARENT;
199
+ for (const item of items)
200
+ linkParents(item, parent);
201
+ }
202
+ /** A `w:del` or `w:moveFrom` rejected: its runs come back, with `w:delText` turned into `w:t`. */
203
+ function restoreDeleted(t) {
204
+ var _a;
205
+ for (const item of (_a = runItemsOf(t.element.value)) !== null && _a !== void 0 ? _a : []) {
206
+ if (typeNameOf(item) === 'org_docx4j_wml.R')
207
+ toRestoredText(item.value);
208
+ }
209
+ unwrap(t);
210
+ }
211
+ function dropMark(paragraph, which) {
212
+ var _a;
213
+ if (!paragraph)
214
+ return;
215
+ const rPr = (_a = paragraph.p.pPr) === null || _a === void 0 ? void 0 : _a.rPr;
216
+ if (rPr)
217
+ delete rPr[which];
218
+ pruneParagraphProperties(paragraph.p);
219
+ }
220
+ /**
221
+ * docx4j AcceptTrackedChanges: the paragraph takes the next one's content and properties, so the
222
+ * mark that survives is the next one's. Called when a deleted mark is accepted and when an
223
+ * inserted one is rejected.
224
+ *
225
+ * `fallbackToPrevious` is for the second case at the end of a container, where this package's
226
+ * inserted paragraph carries its own mark (section 13) and there is nothing after it to join
227
+ * with: the paragraph then goes, its content joining the one before. With neither neighbour the
228
+ * mark is simply dropped.
229
+ */
230
+ export function joinWithNext(paragraph, fallbackToPrevious = false) {
231
+ var _a, _b, _c, _d, _e;
232
+ const container = paragraph.container;
233
+ const i = container.indexOf(paragraph.element);
234
+ const next = i >= 0 ? container[i + 1] : undefined;
235
+ const p = paragraph.p;
236
+ if (!next || typeNameOf(next) !== 'org_docx4j_wml.P') {
237
+ const previous = fallbackToPrevious && i > 0 ? container[i - 1] : undefined;
238
+ if (previous && typeNameOf(previous) === 'org_docx4j_wml.P') {
239
+ const into = previous.value;
240
+ const items = ((_a = into.content) !== null && _a !== void 0 ? _a : (into.content = []));
241
+ for (const item of (_b = p.content) !== null && _b !== void 0 ? _b : [])
242
+ items.push(item);
243
+ linkParents(items, into);
244
+ container.splice(i, 1);
245
+ return;
246
+ }
247
+ const rPr = (_c = p.pPr) === null || _c === void 0 ? void 0 : _c.rPr;
248
+ if (rPr) {
249
+ delete rPr.ins;
250
+ delete rPr.del;
251
+ }
252
+ pruneParagraphProperties(p);
253
+ return;
254
+ }
255
+ const nextP = next.value;
256
+ const content = ((_d = p.content) !== null && _d !== void 0 ? _d : (p.content = []));
257
+ for (const item of (_e = nextP.content) !== null && _e !== void 0 ? _e : [])
258
+ content.push(item);
259
+ linkParents(content, p);
260
+ p.pPr = nextP.pPr;
261
+ if (p.pPr)
262
+ linkParents(p.pPr, p);
263
+ container.splice(i + 1, 1);
264
+ }
265
+ /** The span of a run-level revision in the paragraph's accepted text; collapsed for a deletion. */
266
+ function spanOf(paragraph, element) {
267
+ const segs = paragraph.segments();
268
+ const inside = segs.filter((s) => { var _a; return ((_a = s.revision) === null || _a === void 0 ? void 0 : _a.element) === element; });
269
+ if (inside.length > 0)
270
+ return [inside[0].start, inside[inside.length - 1].end];
271
+ const at = acceptedOffsetOf(paragraph.p, element);
272
+ return [at, at];
273
+ }
274
+ /** How much accepted text comes before `target` in the paragraph. */
275
+ function acceptedOffsetOf(p, target) {
276
+ let pos = 0;
277
+ let found = -1;
278
+ const visit = (items) => {
279
+ if (!items || found >= 0)
280
+ return;
281
+ for (const el of items) {
282
+ if (found >= 0)
283
+ return;
284
+ if (el === target) {
285
+ found = pos;
286
+ return;
287
+ }
288
+ if (typeNameOf(el) === 'org_docx4j_wml.R') {
289
+ pos += segmentsOf({ content: [el] }).map((s) => s.text).join('').length;
290
+ continue;
291
+ }
292
+ const kind = revisionKindOf(el);
293
+ if (kind === 'del' || kind === 'moveFrom')
294
+ continue;
295
+ visit(runItemsOf(el.value));
296
+ }
297
+ };
298
+ visit(runItemsOf(p));
299
+ return found >= 0 ? found : pos;
300
+ }
301
+ // --- collecting ----------------------------------------------------------------------------
302
+ /** The tracked changes of one paragraph, in document order. */
303
+ export function trackedChangesOfParagraph(paragraph) {
304
+ var _a, _b, _c;
305
+ const out = [];
306
+ const p = paragraph.p;
307
+ const pPrChange = (_a = p.pPr) === null || _a === void 0 ? void 0 : _a.pPrChange;
308
+ if (pPrChange)
309
+ out.push(new TrackedChange({ kind: 'paragraphProperties', value: pPrChange }, paragraph));
310
+ const rPr = (_b = p.pPr) === null || _b === void 0 ? void 0 : _b.rPr;
311
+ if (rPr === null || rPr === void 0 ? void 0 : rPr.ins)
312
+ out.push(new TrackedChange({ kind: 'mark', mark: 'ins', value: rPr.ins }, paragraph));
313
+ if (rPr === null || rPr === void 0 ? void 0 : rPr.del)
314
+ out.push(new TrackedChange({ kind: 'mark', mark: 'del', value: rPr.del }, paragraph));
315
+ collectRunLevel(paragraph, ((_c = p.content) !== null && _c !== void 0 ? _c : []), out);
316
+ return out;
317
+ }
318
+ function collectRunLevel(paragraph, items, out) {
319
+ var _a;
320
+ for (const el of items) {
321
+ const kind = revisionKindOf(el);
322
+ if (kind !== undefined) {
323
+ out.push(new TrackedChange({ kind: 'run', revision: kind, element: el, owner: items, value: el.value }, paragraph));
324
+ const nested = runItemsOf(el.value);
325
+ if (nested)
326
+ collectRunLevel(paragraph, nested, out);
327
+ continue;
328
+ }
329
+ if (typeNameOf(el) === 'org_docx4j_wml.R') {
330
+ const run = el.value;
331
+ if ((_a = run.rPr) === null || _a === void 0 ? void 0 : _a.rPrChange)
332
+ out.push(new TrackedChange({ kind: 'runProperties', run, value: run.rPr.rPrChange }, paragraph));
333
+ continue;
334
+ }
335
+ const nested = runItemsOf(el.value);
336
+ if (nested)
337
+ collectRunLevel(paragraph, nested, out);
338
+ }
339
+ }
340
+ /**
341
+ * The `w:trPr/w:ins` and `w:trPr/w:del` revisions of a table row. `inner` is the revision markup
342
+ * of the row's own cells, which the row's change owns rather than reporting separately.
343
+ */
344
+ export function trackedChangesOfRow(tr, owner, inner = []) {
345
+ const trPr = tr.value.trPr;
346
+ const out = [];
347
+ if (trPr === null || trPr === void 0 ? void 0 : trPr.ins)
348
+ out.push(new TrackedChange({ kind: 'row', row: 'ins', tr, owner, value: trPr.ins, inner }, undefined));
349
+ if (trPr === null || trPr === void 0 ? void 0 : trPr.del)
350
+ out.push(new TrackedChange({ kind: 'row', row: 'del', tr, owner, value: trPr.del, inner }, undefined));
351
+ return out;
352
+ }
@@ -0,0 +1,122 @@
1
+ import type * as wml from '@docx4j/generated-objects-ts/modules/org_docx4j_wml';
2
+ import type * as w15 from '@docx4j/generated-objects-ts/modules/org_docx4j_w15';
3
+ import type * as w16cid from '@docx4j/generated-objects-ts/modules/org_docx4j_w16cid';
4
+ import type { XmlCalendar } from '@docx4j/generated-objects-ts';
5
+ import type { XmlPart } from '../../parts/XmlPart.mjs';
6
+ import { type Element } from './tree.mjs';
7
+ import type { Body } from './Body.mjs';
8
+ import type { Paragraph } from './Paragraph.mjs';
9
+ import type { Range } from './Range.mjs';
10
+ import type { Comment } from './Comment.mjs';
11
+ /** The style Word gives a comment's paragraphs. */
12
+ export declare const COMMENT_TEXT_STYLE = "CommentText";
13
+ /** The character style of the annotation reference run, in the comment and in the body. */
14
+ export declare const COMMENT_REFERENCE_STYLE = "CommentReference";
15
+ /**
16
+ * Who a comment (and, with phase F, a tracked change) is by. `WordprocessingMLPackage.author`;
17
+ * there is no signed-in user here, so the package carries the identity.
18
+ */
19
+ export interface Author {
20
+ name: string;
21
+ /** Word's `w:initials`; derived from the name when not given. */
22
+ initials?: string;
23
+ /** Written to `w:people` as the author's presence info; Office JS `Comment.authorEmail`. */
24
+ email?: string;
25
+ }
26
+ /** The initials Word would show: the first letter of each word of the name, at most three. */
27
+ export declare function initialsOf(author: Author): string;
28
+ /**
29
+ * The `w16cex` part (`w16cex:commentsExtensible`, a UTC date per comment), typed since objects
30
+ * 0.1.3 (`CommentsExtensiblePart`). Only kept in step when the document already has the part;
31
+ * none is created.
32
+ */
33
+ export interface CommentsExtensible {
34
+ /** Adds or updates the entry of a durable id. */
35
+ set(durableId: string, dateUtc: Date): void;
36
+ remove(durableId: string): void;
37
+ }
38
+ /** The four (five with w16cex) comment parts of a document, unmarshalled. */
39
+ export interface CommentParts {
40
+ /** The comments part, for the `Body` view over a comment's paragraphs. */
41
+ readonly commentsPart: XmlPart<unknown>;
42
+ /** `w:comments` (docx4j CommentsPart contents). */
43
+ readonly comments: wml.Comments;
44
+ /** `w15:commentsEx`: the thread links and the done flags. */
45
+ commentsEx: w15.CTCommentsEx | undefined;
46
+ /** `w15:people`. */
47
+ people: w15.CTPeople | undefined;
48
+ /** `w16cid:commentsIds`: the durable ids; loaded by `ensureAll` only, since no view reads it. */
49
+ commentsIds: w16cid.CTCommentsIds | undefined;
50
+ /** `w16cex:commentsExtensible`, when the document has one. */
51
+ extensible: CommentsExtensible | undefined;
52
+ /** The package's author identity. */
53
+ readonly author: Author;
54
+ /** The w15 extended part, created (with its relationship and content type) when absent. */
55
+ ensureCommentsEx(): w15.CTCommentsEx;
56
+ /** Loads and creates the side parts the bookkeeping needs (w15, w16cid; w16cex only if present). */
57
+ ensureAll(): Promise<CommentParts>;
58
+ }
59
+ /** How the content API reaches the comment parts; implemented and registered by `src/parts/wml/comments.mts`. */
60
+ export interface CommentPartsAccess {
61
+ /** The document's comment parts, or undefined when it has none. Only what a view reads is unmarshalled. */
62
+ load(body: Body): Promise<CommentParts | undefined>;
63
+ /** As `load`, creating every absent part and the two comment styles. */
64
+ create(body: Body): Promise<CommentParts>;
65
+ }
66
+ /** Registered by `src/parts/wml/comments.mts` (imported for that by `WordprocessingMLPackage`). */
67
+ export declare function setCommentPartsAccess(access: CommentPartsAccess): void;
68
+ export declare function commentPartsAccess(): CommentPartsAccess;
69
+ /** How `Body`, `Paragraph` and `Range` reach the `Comment` views; registered by `Comment.mts`. */
70
+ export interface CommentApi {
71
+ commentsOf(scope: Body | Paragraph | Range): Promise<Comment[]>;
72
+ insertComment(range: Range, text: string): Promise<Comment>;
73
+ }
74
+ export declare function setCommentApi(implementation: CommentApi): void;
75
+ export declare function commentApi(): CommentApi;
76
+ export type CommentMarkerKind = 'start' | 'end' | 'reference';
77
+ /** One comment marker in a body, with everything an edit needs: what holds it, and where it is. */
78
+ export interface CommentMarker {
79
+ id: number;
80
+ kind: CommentMarkerKind;
81
+ /** The `{ name, value }` pair: w:commentRangeStart, w:commentRangeEnd or w:commentReference. */
82
+ item: Element;
83
+ /** The array holding the item (a paragraph's content, a run's content, a body's content). */
84
+ owner: Element[];
85
+ /** For a reference: the run holding it and the array holding that run. */
86
+ run?: Element<wml.R>;
87
+ runOwner?: Element[];
88
+ /** The paragraph the marker is in, and the block-level array holding that paragraph. */
89
+ paragraph?: Element<wml.P>;
90
+ paragraphContainer?: Element[];
91
+ /** The marker's offset in the paragraph's text; undefined for a block-level marker. */
92
+ offset?: number;
93
+ }
94
+ /**
95
+ * Every comment marker under a container (a body, a cell, a paragraph), in document order.
96
+ * Deleted content (`w:del`) is not entered, as the text model does not enter it either.
97
+ */
98
+ export declare function markersOf(container: object): CommentMarker[];
99
+ /** The markers of one paragraph, with their offsets in its text. */
100
+ export declare function markersOfParagraph(element: Element<wml.P>, container: Element[]): CommentMarker[];
101
+ /** The comment ids under a container, in document order, first occurrence first. */
102
+ export declare function commentIdsOf(container: object): number[];
103
+ /** Removes every marker of a comment from a body, and the reference run when nothing is left in it. */
104
+ export declare function removeMarkers(container: object, id: number): void;
105
+ /** The next free `w:id` for a comment: above every comment and every marker in the body. */
106
+ export declare function nextCommentId(comments: wml.Comments, container: object): number;
107
+ /** An 8 hex digit id, as Word writes `w14:paraId` and `w16cid:durableId` (never 0, high bit clear). */
108
+ export declare function randomHexId(taken: (id: string) => boolean): string;
109
+ /** The `w14:paraId` of a comment's first paragraph: the key of its w15 and w16cid entries. */
110
+ export declare function commentParaId(comment: wml.Comments.Comment): string | undefined;
111
+ /** True when a paragraph id is already used by a comment or by a paragraph of the document. */
112
+ export declare function paraIdTaken(parts: CommentParts, container: object, id: string): boolean;
113
+ /** The `w15:commentEx` entry keyed by a comment's first paragraph id. */
114
+ export declare function commentExOf(parts: CommentParts, paraId: string | undefined): w15.CTCommentEx | undefined;
115
+ /** Word writes `w15:done="0"` and `"1"`; `w:ST_OnOff` also allows true/false/on/off. */
116
+ export declare function isDone(value: string | undefined): boolean;
117
+ /** A Jsonix calendar (what `w:date` unmarshals to) as a Date; undefined when there is none. */
118
+ export declare function calendarToDate(calendar: XmlCalendar | undefined): Date | undefined;
119
+ /** A Date as the UTC calendar Word writes (`2026-09-15T09:00:00Z`). */
120
+ export declare function dateToCalendar(date: Date): XmlCalendar;
121
+ /** `2026-09-15T09:00:00Z`, the form Word writes in w16cex. */
122
+ export declare function toUtcString(date: Date): string;