@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.
- package/README.md +410 -10
- package/dist/model/content/Body.d.mts +109 -4
- package/dist/model/content/Body.mjs +300 -29
- package/dist/model/content/Comment.d.mts +78 -0
- package/dist/model/content/Comment.mjs +429 -0
- package/dist/model/content/ContentControl.d.mts +173 -0
- package/dist/model/content/ContentControl.mjs +638 -0
- package/dist/model/content/Font.d.mts +48 -8
- package/dist/model/content/Font.mjs +55 -13
- package/dist/model/content/InlinePicture.d.mts +103 -0
- package/dist/model/content/InlinePicture.mjs +361 -0
- package/dist/model/content/List.d.mts +253 -0
- package/dist/model/content/List.mjs +778 -0
- package/dist/model/content/Paragraph.d.mts +213 -16
- package/dist/model/content/Paragraph.mjs +611 -57
- package/dist/model/content/Range.d.mts +48 -4
- package/dist/model/content/Range.mjs +161 -4
- package/dist/model/content/Table.d.mts +130 -0
- package/dist/model/content/Table.mjs +429 -0
- package/dist/model/content/TrackedChange.d.mts +96 -0
- package/dist/model/content/TrackedChange.mjs +352 -0
- package/dist/model/content/comments.d.mts +122 -0
- package/dist/model/content/comments.mjs +248 -0
- package/dist/model/content/index.d.mts +13 -3
- package/dist/model/content/index.mjs +15 -3
- package/dist/model/content/ooxml.d.mts +17 -0
- package/dist/model/content/ooxml.mjs +214 -0
- package/dist/model/content/styles.d.mts +21 -0
- package/dist/model/content/styles.mjs +86 -0
- package/dist/model/content/tracking.d.mts +104 -0
- package/dist/model/content/tracking.mjs +313 -0
- package/dist/model/content/tree.d.mts +56 -9
- package/dist/model/content/tree.mjs +104 -31
- package/dist/model/customxml/CustomXmlPart.d.mts +158 -0
- package/dist/model/customxml/CustomXmlPart.mjs +415 -0
- package/dist/model/customxml/CustomXmlPartCollection.d.mts +68 -0
- package/dist/model/customxml/CustomXmlPartCollection.mjs +183 -0
- package/dist/model/customxml/XmlMapping.d.mts +46 -0
- package/dist/model/customxml/XmlMapping.mjs +98 -0
- package/dist/model/customxml/bindings.d.mts +41 -0
- package/dist/model/customxml/bindings.mjs +230 -0
- package/dist/model/customxml/index.d.mts +7 -0
- package/dist/model/customxml/index.mjs +9 -0
- package/dist/model/customxml/insert.d.mts +20 -0
- package/dist/model/customxml/insert.mjs +22 -0
- package/dist/model/customxml/kinds.d.mts +103 -0
- package/dist/model/customxml/kinds.mjs +267 -0
- package/dist/model/customxml/xpath.d.mts +52 -0
- package/dist/model/customxml/xpath.mjs +205 -0
- package/dist/model/fonts/CJKToEnglish.d.mts +2 -0
- package/dist/model/fonts/CJKToEnglish.mjs +16 -0
- package/dist/model/fonts/FontFallback.d.mts +58 -0
- package/dist/model/fonts/FontFallback.mjs +219 -0
- package/dist/model/fonts/IdentityPlusMapper.d.mts +7 -0
- package/dist/model/fonts/IdentityPlusMapper.mjs +19 -0
- package/dist/model/fonts/LanguageTagToScriptMapping.d.mts +7 -0
- package/dist/model/fonts/LanguageTagToScriptMapping.mjs +67 -0
- package/dist/model/fonts/Mapper.d.mts +190 -0
- package/dist/model/fonts/Mapper.mjs +481 -0
- package/dist/model/fonts/PhysicalFont.d.mts +34 -0
- package/dist/model/fonts/PhysicalFont.mjs +62 -0
- package/dist/model/fonts/RunFontSelector.d.mts +194 -0
- package/dist/model/fonts/RunFontSelector.mjs +441 -0
- package/dist/model/fonts/ThemeFonts.d.mts +17 -0
- package/dist/model/fonts/ThemeFonts.mjs +76 -0
- package/dist/model/fonts/defaultTheme.d.mts +37 -0
- package/dist/model/fonts/defaultTheme.mjs +57 -0
- package/dist/model/fonts/families.generated.d.mts +11 -0
- package/dist/model/fonts/families.generated.mjs +17 -0
- package/dist/model/fonts/fontsInUse.d.mts +39 -0
- package/dist/model/fonts/fontsInUse.mjs +183 -0
- package/dist/model/fonts/index.d.mts +14 -0
- package/dist/model/fonts/index.mjs +29 -0
- package/dist/model/fonts/lookup.d.mts +5 -0
- package/dist/model/fonts/lookup.mjs +12 -0
- package/dist/model/fonts/registry.d.mts +31 -0
- package/dist/model/fonts/registry.mjs +103 -0
- package/dist/model/fonts/scripts.d.mts +2 -0
- package/dist/model/fonts/scripts.mjs +78 -0
- package/dist/model/fonts/substitutions.generated.d.mts +30 -0
- package/dist/model/fonts/substitutions.generated.mjs +12 -0
- package/dist/model/fonts/themes.generated.d.mts +6 -0
- package/dist/model/fonts/themes.generated.mjs +11 -0
- package/dist/model/index.d.mts +5 -0
- package/dist/model/index.mjs +13 -1
- package/dist/model/listnumbering/Emulator.d.mts +187 -0
- package/dist/model/listnumbering/Emulator.mjs +332 -0
- package/dist/model/listnumbering/definitions.d.mts +251 -0
- package/dist/model/listnumbering/definitions.mjs +571 -0
- package/dist/model/listnumbering/formats.d.mts +25 -0
- package/dist/model/listnumbering/formats.mjs +320 -0
- package/dist/model/listnumbering/index.d.mts +4 -0
- package/dist/model/listnumbering/index.mjs +15 -0
- package/dist/model/listnumbering/state.d.mts +97 -0
- package/dist/model/listnumbering/state.mjs +179 -0
- package/dist/model/properties/PropertyResolver.d.mts +216 -0
- package/dist/model/properties/PropertyResolver.mjs +524 -0
- package/dist/model/properties/catalogue.d.mts +179 -0
- package/dist/model/properties/catalogue.mjs +860 -0
- package/dist/model/properties/index.d.mts +4 -0
- package/dist/model/properties/index.mjs +9 -0
- package/dist/model/properties/log.d.mts +7 -0
- package/dist/model/properties/log.mjs +25 -0
- package/dist/model/properties/styleUtil.d.mts +112 -0
- package/dist/model/properties/styleUtil.mjs +359 -0
- package/dist/node/index.d.mts +1 -0
- package/dist/node/index.mjs +12 -0
- package/dist/office-js/document.d.mts +111 -0
- package/dist/office-js/document.mjs +267 -0
- package/dist/office-js/enums.d.mts +187 -0
- package/dist/office-js/enums.mjs +176 -0
- package/dist/office-js/errors.d.mts +29 -0
- package/dist/office-js/errors.mjs +39 -0
- package/dist/office-js/extras.d.mts +5 -0
- package/dist/office-js/extras.mjs +29 -0
- package/dist/office-js/fragment.d.mts +10 -0
- package/dist/office-js/fragment.mjs +23 -0
- package/dist/office-js/index.d.mts +183 -0
- package/dist/office-js/index.mjs +54 -0
- package/dist/office-js/proxy.d.mts +72 -0
- package/dist/office-js/proxy.mjs +279 -0
- package/dist/office-js/run.d.mts +32 -0
- package/dist/office-js/run.mjs +66 -0
- package/dist/office-js/supported.d.mts +7 -0
- package/dist/office-js/supported.generated.d.mts +1 -0
- package/dist/office-js/supported.generated.mjs +235 -0
- package/dist/office-js/supported.mjs +53 -0
- package/dist/office-js/toApiScript.d.mts +25 -0
- package/dist/office-js/toApiScript.mjs +394 -0
- package/dist/opc/ContentTypes.d.mts +1 -0
- package/dist/opc/ContentTypes.mjs +1 -0
- package/dist/opc/DirectoryPartStore.d.mts +47 -0
- package/dist/opc/DirectoryPartStore.mjs +123 -0
- package/dist/opc/exceptions.d.mts +30 -0
- package/dist/opc/exceptions.mjs +38 -0
- package/dist/opc/index.d.mts +1 -1
- package/dist/opc/index.mjs +1 -1
- package/dist/packages/OpcPackage.d.mts +19 -1
- package/dist/packages/OpcPackage.mjs +29 -0
- package/dist/packages/PresentationMLPackage.d.mts +71 -1
- package/dist/packages/PresentationMLPackage.mjs +179 -0
- package/dist/packages/SpreadsheetMLPackage.d.mts +30 -1
- package/dist/packages/SpreadsheetMLPackage.mjs +78 -0
- package/dist/packages/WordprocessingMLPackage.d.mts +124 -2
- package/dist/packages/WordprocessingMLPackage.mjs +309 -2
- package/dist/packages/index.d.mts +1 -1
- package/dist/packages/index.mjs +1 -1
- package/dist/parts/DefaultXmlPart.d.mts +18 -0
- package/dist/parts/DefaultXmlPart.mjs +34 -5
- package/dist/parts/PartRegistry.mjs +1 -0
- package/dist/parts/XmlPart.d.mts +33 -0
- package/dist/parts/XmlPart.mjs +105 -2
- package/dist/parts/pml/defaults.d.mts +6 -0
- package/dist/parts/pml/defaults.mjs +53 -0
- package/dist/parts/pml/index.d.mts +66 -3
- package/dist/parts/pml/index.mjs +206 -7
- package/dist/parts/pml/placeholders.d.mts +71 -0
- package/dist/parts/pml/placeholders.mjs +141 -0
- package/dist/parts/sml/index.d.mts +19 -1
- package/dist/parts/sml/index.mjs +60 -1
- package/dist/parts/wml/comments.d.mts +1 -0
- package/dist/parts/wml/comments.mjs +179 -0
- package/dist/parts/wml/defaultNumbering.d.mts +1 -0
- package/dist/parts/wml/defaultNumbering.mjs +216 -0
- package/dist/parts/wml/index.d.mts +121 -0
- package/dist/parts/wml/index.mjs +291 -0
- package/dist/xml/dom.mjs +1 -2
- package/package.json +25 -4
|
@@ -1,8 +1,18 @@
|
|
|
1
|
-
import { Docx4JException } from '../../opc/exceptions.mjs';
|
|
2
|
-
import { typeNameOf, childrenOf, linkParents, BLOCK_LEVEL_TYPES, textOf } from './tree.mjs';
|
|
3
|
-
import {
|
|
1
|
+
import { Docx4JException, PropertyResolverNotCreatedException } from '../../opc/exceptions.mjs';
|
|
2
|
+
import { typeNameOf, childrenOf, linkParents, BLOCK_LEVEL_TYPES, textOf, textOfView, rowsOf, cellsOf } from './tree.mjs';
|
|
3
|
+
import { r as textRun, br as breakItem, tbl as tableOf } from '@docx4j/generated-objects-ts/builders/wml';
|
|
4
4
|
import { runOf, paragraphOf } from './tree.mjs';
|
|
5
5
|
import { Paragraph } from './Paragraph.mjs';
|
|
6
|
+
import { Table } from './Table.mjs';
|
|
7
|
+
import { ContentControl, collectControls } from './ContentControl.mjs';
|
|
8
|
+
import { sdt as sdtOf, nextSdtId } from '@docx4j/generated-objects-ts/builders/wml';
|
|
9
|
+
import { controlIdScope, sdtKindFor } from '../customxml/insert.mjs';
|
|
10
|
+
import { InlinePicture, addImage, writableWidthEmu } from './InlinePicture.mjs';
|
|
11
|
+
import { contentOf } from './ooxml.mjs';
|
|
12
|
+
import { commentApi } from './comments.mjs';
|
|
13
|
+
import { trackerOf, trackInsertedParagraph, trackInsertedTable } from './tracking.mjs';
|
|
14
|
+
import { trackedChangesOfRow } from './TrackedChange.mjs';
|
|
15
|
+
import { listsOf, listLabelsOf } from './List.mjs';
|
|
6
16
|
/**
|
|
7
17
|
* A subset of Office JS `Word.Body` over any container with block-level content: the main
|
|
8
18
|
* document's body, a header, a footer, a footnote, a cell or a content control. A view: the
|
|
@@ -21,6 +31,20 @@ export class Body {
|
|
|
21
31
|
this.prefix = prefix;
|
|
22
32
|
this.package_ = package_;
|
|
23
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* The package's `PropertyResolver`, which every effective-formatting read goes through
|
|
36
|
+
* (CR-001 Phase B step 2). Throws `PropertyResolverNotCreatedException` when this body has
|
|
37
|
+
* no package, or the package has not built one yet: building it unmarshals the styles part,
|
|
38
|
+
* which cannot be done synchronously, so `await pkg.getPropertyResolver()` (or `getBody()`,
|
|
39
|
+
* which does it) first - or read direct formatting with `{ direct: true }`.
|
|
40
|
+
*/
|
|
41
|
+
get propertyResolver() {
|
|
42
|
+
const pkg = this.package_;
|
|
43
|
+
const resolver = pkg === null || pkg === void 0 ? void 0 : pkg.propertyResolverOrUndefined;
|
|
44
|
+
if (!resolver)
|
|
45
|
+
throw new PropertyResolverNotCreatedException();
|
|
46
|
+
return resolver;
|
|
47
|
+
}
|
|
24
48
|
/** The live content array (docx4j getContent()); block-level elements only, sectPr excluded. */
|
|
25
49
|
get content() {
|
|
26
50
|
var _a;
|
|
@@ -31,7 +55,7 @@ export class Body {
|
|
|
31
55
|
get paragraphs() {
|
|
32
56
|
const out = [];
|
|
33
57
|
const visit = (items) => {
|
|
34
|
-
var _a
|
|
58
|
+
var _a;
|
|
35
59
|
for (const el of items) {
|
|
36
60
|
const tn = typeNameOf(el);
|
|
37
61
|
if (tn === 'org_docx4j_wml.P')
|
|
@@ -41,9 +65,9 @@ export class Body {
|
|
|
41
65
|
if (typeof v !== 'object' || v === null)
|
|
42
66
|
continue;
|
|
43
67
|
if (tn === 'org_docx4j_wml.Tbl') {
|
|
44
|
-
for (const row of (
|
|
45
|
-
for (const cell of (
|
|
46
|
-
visit((
|
|
68
|
+
for (const row of rowsOf(v))
|
|
69
|
+
for (const cell of cellsOf(row.element.value))
|
|
70
|
+
visit((_a = childrenOf(cell.element.value)) !== null && _a !== void 0 ? _a : []);
|
|
47
71
|
}
|
|
48
72
|
else {
|
|
49
73
|
const children = childrenOf(v);
|
|
@@ -56,14 +80,70 @@ export class Body {
|
|
|
56
80
|
visit(this.content);
|
|
57
81
|
return out;
|
|
58
82
|
}
|
|
59
|
-
/** The tables directly in this body
|
|
83
|
+
/** The tables directly in this body, as Office JS reports them (nested tables are a cell's). */
|
|
60
84
|
get tables() {
|
|
61
|
-
return this.content.filter((el) => typeNameOf(el) === 'org_docx4j_wml.Tbl').map((element) => (
|
|
85
|
+
return this.content.filter((el) => typeNameOf(el) === 'org_docx4j_wml.Tbl').map((element) => new Table(element, this.content, this));
|
|
86
|
+
}
|
|
87
|
+
/** Every content control in this body, in document order, nested ones included. */
|
|
88
|
+
get contentControls() {
|
|
89
|
+
const out = [];
|
|
90
|
+
collectControls(this.content, this, out);
|
|
91
|
+
return out;
|
|
92
|
+
}
|
|
93
|
+
/** Every inline picture in this body, in document order (Office JS Body.inlinePictures). */
|
|
94
|
+
get inlinePictures() {
|
|
95
|
+
return this.paragraphs.flatMap((p) => p.inlinePictures);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Office JS `body.lists`: every `w:num` a paragraph of this body names, in the order they are
|
|
99
|
+
* first used (CR-002 phase H). Empty where the document has no numbering part, or where
|
|
100
|
+
* nothing has read it yet (`await pkg.getBody()` builds the resolver, which does).
|
|
101
|
+
*/
|
|
102
|
+
get lists() {
|
|
103
|
+
return listsOf(this);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Every numbered paragraph of this body's **story** with its label, level, list and sibling
|
|
107
|
+
* index, in one walk (extension). `listItem.listString` walks the story per read, which is
|
|
108
|
+
* what Word's counting needs; this is the way to ask for all of them at once.
|
|
109
|
+
*
|
|
110
|
+
* Keyed by the `w:p` itself: `labels.get(paragraph.p)?.listString`.
|
|
111
|
+
*/
|
|
112
|
+
listLabels() {
|
|
113
|
+
return listLabelsOf(this);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* A view over a container nested in this body (a cell, a content control), sharing this body's
|
|
117
|
+
* part and package. The address prefix is the container's own address, so that the addresses a
|
|
118
|
+
* nested body reports carry on from this one.
|
|
119
|
+
*/
|
|
120
|
+
sub(container, prefix = this.prefix) {
|
|
121
|
+
return new Body(this.part, container, prefix, this.package_);
|
|
122
|
+
}
|
|
123
|
+
/** The view of a `w:p` somewhere in this body's tree; its container comes from PARENT. */
|
|
124
|
+
paragraphFor(p) {
|
|
125
|
+
var _a;
|
|
126
|
+
const container = childrenOf(((_a = p.PARENT) !== null && _a !== void 0 ? _a : {}));
|
|
127
|
+
const element = container === null || container === void 0 ? void 0 : container.find((e) => e.value === p);
|
|
128
|
+
return element && container ? new Paragraph(element, container, this) : undefined;
|
|
62
129
|
}
|
|
63
130
|
/** The text, a paragraph per line. */
|
|
64
131
|
get text() {
|
|
65
132
|
return this.paragraphs.map((p) => p.text).join('\n');
|
|
66
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* The text in one of the two views (extension; `text` is the accepted one).
|
|
136
|
+
* `{ view: 'original' }` reads the document as it was before the tracked changes.
|
|
137
|
+
*/
|
|
138
|
+
getText(options) {
|
|
139
|
+
if ((options === null || options === void 0 ? void 0 : options.view) !== 'original')
|
|
140
|
+
return this.text;
|
|
141
|
+
return this.paragraphs.map((p) => textOfView(p.p, options)).join('\n');
|
|
142
|
+
}
|
|
143
|
+
/** The package's change tracker while `changeTrackingMode` is on; undefined when it is off (CR-002 phase F). */
|
|
144
|
+
get changeTracker() {
|
|
145
|
+
return trackerOf(this.package_);
|
|
146
|
+
}
|
|
67
147
|
insertParagraph(text, location) {
|
|
68
148
|
const el = paragraphOf(text === '' ? [] : [textRun(text)]);
|
|
69
149
|
return this.insertElement(el, location);
|
|
@@ -80,10 +160,40 @@ export class Body {
|
|
|
80
160
|
return paragraphs[0].insertText(text, 'Start');
|
|
81
161
|
return paragraphs[paragraphs.length - 1].insertText(text, 'End');
|
|
82
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* A table of `rowCount` by `columnCount` cells at the start or end (Office JS insertTable);
|
|
165
|
+
* `values` fills it row by row. The columns are equal over the section's text width.
|
|
166
|
+
*/
|
|
167
|
+
insertTable(rowCount, columnCount, location, values) {
|
|
168
|
+
if (rowCount < 1 || columnCount < 1)
|
|
169
|
+
throw new Docx4JException(`A table needs at least one row and one column; got ${rowCount} by ${columnCount}`);
|
|
170
|
+
const rows = Array.from({ length: rowCount }, (_, r) => Array.from({ length: columnCount }, (_, c) => { var _a, _b; return (_b = (_a = values === null || values === void 0 ? void 0 : values[r]) === null || _a === void 0 ? void 0 : _a[c]) !== null && _b !== void 0 ? _b : ''; }));
|
|
171
|
+
const width = writableWidthTwips(this.container);
|
|
172
|
+
const element = tableOf(rows, width ? { width } : {});
|
|
173
|
+
this.insertElement(element, location);
|
|
174
|
+
return new Table(element, this.content, this);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Adds the image as a part of this body's part, with a relationship, and shows it in a new
|
|
178
|
+
* paragraph at the start or the end (Office JS insertInlinePictureFromBase64). An image wider
|
|
179
|
+
* than the text area is scaled down, as docx4j's CxCy.scale does.
|
|
180
|
+
*/
|
|
181
|
+
insertInlinePictureFromBase64(base64, location, options) {
|
|
182
|
+
if (!this.part)
|
|
183
|
+
throw new Docx4JException('This body has no part, so an image cannot be related to it');
|
|
184
|
+
const { run, drawing } = addImage(this.part, base64, this.container, writableWidthEmu(this.container), options);
|
|
185
|
+
const paragraph = this.insertParagraph('', location);
|
|
186
|
+
paragraph.p.content.push(run);
|
|
187
|
+
linkParents(run, paragraph.p);
|
|
188
|
+
return new InlinePicture(drawing, run, paragraph);
|
|
189
|
+
}
|
|
83
190
|
insertBreak(type, location) {
|
|
84
191
|
const p = this.insertParagraph('', location);
|
|
85
|
-
|
|
86
|
-
|
|
192
|
+
const run = runOf([breakItem(type === 'Page' ? 'page' : undefined)]);
|
|
193
|
+
const tracker = this.changeTracker;
|
|
194
|
+
const item = tracker ? tracker.ins([run]) : run;
|
|
195
|
+
p.p.content.push(item);
|
|
196
|
+
linkParents(item, p.p);
|
|
87
197
|
}
|
|
88
198
|
/**
|
|
89
199
|
* Inserts block-level elements (docx4j addObject): at the start or end of this body, or
|
|
@@ -113,19 +223,48 @@ export class Body {
|
|
|
113
223
|
}
|
|
114
224
|
container.splice(index, 0, ...elements);
|
|
115
225
|
const owner = this.ownerOf(container);
|
|
226
|
+
const tracker = this.changeTracker;
|
|
116
227
|
for (const el of elements) {
|
|
117
228
|
linkParents(el, owner);
|
|
118
|
-
|
|
229
|
+
const tn = typeNameOf(el);
|
|
230
|
+
if (tn === 'org_docx4j_wml.P') {
|
|
119
231
|
this.assignParaId(el.value);
|
|
232
|
+
if (tracker)
|
|
233
|
+
trackInsertedParagraph(tracker, el.value);
|
|
234
|
+
}
|
|
235
|
+
else if (tn === 'org_docx4j_wml.Tbl' && tracker) {
|
|
236
|
+
trackInsertedTable(tracker, el.value);
|
|
237
|
+
}
|
|
120
238
|
}
|
|
121
239
|
const first = elements[0];
|
|
122
240
|
return typeNameOf(first) === 'org_docx4j_wml.P' ? new Paragraph(first, container, this) : { element: first, container };
|
|
123
241
|
}
|
|
124
242
|
/** Inserts a WML fragment (one or more w:p / w:tbl / ... as inside document.xml); the standard prefixes are declared for it. */
|
|
125
243
|
async insertXml(xml, location, target) {
|
|
244
|
+
return this.insertContent(await contentOf(xml, { preprocess: this.preprocessor() }), location, target);
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Word's `insertOoxml`: a flat OPC `pkg:package` string, whose body content is inserted with
|
|
248
|
+
* the parts it references (images, embedded objects) copied into this package under fresh
|
|
249
|
+
* names and relationship ids; styles and numbering are not merged (CR-002 open question 5).
|
|
250
|
+
* A bare `w:p` / `w:tbl` fragment is accepted too, as `insertXml` takes. Returns the views of
|
|
251
|
+
* what was inserted, as `insertXml` does, since a package may bring several blocks.
|
|
252
|
+
*/
|
|
253
|
+
async insertOoxml(ooxml, location, target) {
|
|
254
|
+
const elements = await contentOf(ooxml, { preprocess: this.preprocessor(), target: this.part });
|
|
255
|
+
if (location === 'Replace') {
|
|
256
|
+
this.clear();
|
|
257
|
+
return this.insertContent(elements, 'End');
|
|
258
|
+
}
|
|
259
|
+
return this.insertContent(elements, location, target);
|
|
260
|
+
}
|
|
261
|
+
/** The package's DOM preprocessor (the MCE one), for fragments and incoming packages. */
|
|
262
|
+
preprocessor() {
|
|
126
263
|
var _a;
|
|
127
264
|
const preprocess = (_a = this.package_) === null || _a === void 0 ? void 0 : _a.loadOptions.preprocessor;
|
|
128
|
-
|
|
265
|
+
return preprocess ? (doc) => preprocess(doc) : undefined;
|
|
266
|
+
}
|
|
267
|
+
insertContent(elements, location, target) {
|
|
129
268
|
if (elements.length === 0)
|
|
130
269
|
return [];
|
|
131
270
|
this.insertElement(elements, location, target);
|
|
@@ -137,9 +276,109 @@ export class Body {
|
|
|
137
276
|
search(text, options) {
|
|
138
277
|
return this.paragraphs.flatMap((p) => p.search(text, options));
|
|
139
278
|
}
|
|
140
|
-
/**
|
|
279
|
+
/**
|
|
280
|
+
* Replaces every match of `find` with `replace`, last match first so that the offsets of the
|
|
281
|
+
* ones still to do stay valid (CR-002 section 3.7). Returns the number replaced; tracked when
|
|
282
|
+
* the package's `changeTrackingMode` is on.
|
|
283
|
+
*/
|
|
284
|
+
replaceText(find, replace, options) {
|
|
285
|
+
const matches = this.search(find, options);
|
|
286
|
+
for (let i = matches.length - 1; i >= 0; i--)
|
|
287
|
+
matches[i].insertText(replace, 'Replace');
|
|
288
|
+
return matches.length;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Removes everything (section properties stay). While the package tracks changes, every
|
|
292
|
+
* paragraph is marked deleted and every row's `w:trPr` takes a `w:del` instead.
|
|
293
|
+
*/
|
|
141
294
|
clear() {
|
|
142
|
-
|
|
295
|
+
const tracker = this.changeTracker;
|
|
296
|
+
if (!tracker) {
|
|
297
|
+
this.content.length = 0;
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
for (const row of this.rowElements())
|
|
301
|
+
tracker.markRowDeleted(row.value);
|
|
302
|
+
for (const p of this.paragraphs)
|
|
303
|
+
p.delete();
|
|
304
|
+
}
|
|
305
|
+
// --- change tracking (CR-002 phase F) ---------------------------------------------------
|
|
306
|
+
/** Every tracked change in this body, in document order. */
|
|
307
|
+
getTrackedChanges() {
|
|
308
|
+
const out = [];
|
|
309
|
+
const visit = (items, into) => {
|
|
310
|
+
var _a;
|
|
311
|
+
for (const el of items) {
|
|
312
|
+
const tn = typeNameOf(el);
|
|
313
|
+
if (tn === 'org_docx4j_wml.P') {
|
|
314
|
+
into.push(...new Paragraph(el, items, this).getTrackedChanges());
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
const v = el.value;
|
|
318
|
+
if (typeof v !== 'object' || v === null)
|
|
319
|
+
continue;
|
|
320
|
+
if (tn === 'org_docx4j_wml.Tbl') {
|
|
321
|
+
for (const row of rowsOf(v)) {
|
|
322
|
+
// A row that is itself a revision reports as one change, as Office JS does: the
|
|
323
|
+
// markup its cells carry (Word marks every run and mark of a deleted or inserted row)
|
|
324
|
+
// belongs to that change, which accepts or rejects it along with the row.
|
|
325
|
+
const inner = [];
|
|
326
|
+
for (const cell of cellsOf(row.element.value))
|
|
327
|
+
visit((_a = childrenOf(cell.element.value)) !== null && _a !== void 0 ? _a : [], inner);
|
|
328
|
+
const rowChanges = trackedChangesOfRow(row.element, row.container, inner);
|
|
329
|
+
into.push(...(rowChanges.length > 0 ? rowChanges : inner));
|
|
330
|
+
}
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
const children = childrenOf(v);
|
|
334
|
+
if (children)
|
|
335
|
+
visit(children, into);
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
visit(this.content, out);
|
|
339
|
+
return out;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Accepts every tracked change, last first so that a paragraph join never disturbs one still
|
|
343
|
+
* to do (docx4j `AcceptTrackedChanges` is the reference). Returns how many were accepted.
|
|
344
|
+
*/
|
|
345
|
+
acceptAll() {
|
|
346
|
+
const changes = this.getTrackedChanges();
|
|
347
|
+
for (let i = changes.length - 1; i >= 0; i--)
|
|
348
|
+
changes[i].accept();
|
|
349
|
+
return changes.length;
|
|
350
|
+
}
|
|
351
|
+
/** Rejects every tracked change, last first. Returns how many were rejected. */
|
|
352
|
+
rejectAll() {
|
|
353
|
+
const changes = this.getTrackedChanges();
|
|
354
|
+
for (let i = changes.length - 1; i >= 0; i--)
|
|
355
|
+
changes[i].reject();
|
|
356
|
+
return changes.length;
|
|
357
|
+
}
|
|
358
|
+
/** Every `w:tr` in this body's tables, in document order (rows of nested tables included). */
|
|
359
|
+
rowElements() {
|
|
360
|
+
const out = [];
|
|
361
|
+
const visit = (items) => {
|
|
362
|
+
var _a;
|
|
363
|
+
for (const el of items) {
|
|
364
|
+
const v = el.value;
|
|
365
|
+
if (typeof v !== 'object' || v === null)
|
|
366
|
+
continue;
|
|
367
|
+
if (typeNameOf(el) === 'org_docx4j_wml.Tbl') {
|
|
368
|
+
for (const row of rowsOf(v)) {
|
|
369
|
+
out.push(row.element);
|
|
370
|
+
for (const cell of cellsOf(row.element.value))
|
|
371
|
+
visit((_a = childrenOf(cell.element.value)) !== null && _a !== void 0 ? _a : []);
|
|
372
|
+
}
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
const children = childrenOf(v);
|
|
376
|
+
if (children)
|
|
377
|
+
visit(children);
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
visit(this.content);
|
|
381
|
+
return out;
|
|
143
382
|
}
|
|
144
383
|
/** The part's XML (extension; Office JS getOoxml wraps it in a package). */
|
|
145
384
|
async getXml() {
|
|
@@ -158,14 +397,16 @@ export class Body {
|
|
|
158
397
|
: this.paragraphs.find((q) => q.text.includes(address.contains));
|
|
159
398
|
return p ? { element: p.element, container: p.container } : undefined;
|
|
160
399
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
400
|
+
// The prefix may itself hold slashes: a cell's body is addressed 'body/4/0/1'.
|
|
401
|
+
if (!address.startsWith(this.prefix))
|
|
402
|
+
return undefined;
|
|
403
|
+
const tail = address.substring(this.prefix.length);
|
|
404
|
+
if (tail !== '' && !tail.startsWith('/'))
|
|
164
405
|
return undefined;
|
|
165
406
|
let current = this.container;
|
|
166
407
|
let container;
|
|
167
408
|
let element;
|
|
168
|
-
for (const seg of
|
|
409
|
+
for (const seg of tail === '' ? [] : tail.substring(1).split('/')) {
|
|
169
410
|
container = childrenOf(current);
|
|
170
411
|
const i = Number(seg);
|
|
171
412
|
if (!container || !Number.isInteger(i) || i < 0 || i >= container.length)
|
|
@@ -257,7 +498,6 @@ export class Body {
|
|
|
257
498
|
return this.container;
|
|
258
499
|
let owner = this.container;
|
|
259
500
|
const seek = (value) => {
|
|
260
|
-
var _a, _b;
|
|
261
501
|
const children = childrenOf(value);
|
|
262
502
|
if (!children)
|
|
263
503
|
return false;
|
|
@@ -270,9 +510,9 @@ export class Body {
|
|
|
270
510
|
if (typeof v !== 'object' || v === null)
|
|
271
511
|
continue;
|
|
272
512
|
if (typeNameOf(el) === 'org_docx4j_wml.Tbl') {
|
|
273
|
-
for (const row of (
|
|
274
|
-
for (const cell of (
|
|
275
|
-
if (seek(cell.value))
|
|
513
|
+
for (const row of rowsOf(v))
|
|
514
|
+
for (const cell of cellsOf(row.element.value))
|
|
515
|
+
if (seek(cell.element.value))
|
|
276
516
|
return true;
|
|
277
517
|
}
|
|
278
518
|
else if (seek(v))
|
|
@@ -288,7 +528,6 @@ export class Body {
|
|
|
288
528
|
containerOf(element) {
|
|
289
529
|
let found = this.content;
|
|
290
530
|
const seek = (value) => {
|
|
291
|
-
var _a, _b;
|
|
292
531
|
const children = childrenOf(value);
|
|
293
532
|
if (!children)
|
|
294
533
|
return false;
|
|
@@ -301,9 +540,9 @@ export class Body {
|
|
|
301
540
|
if (typeof v !== 'object' || v === null)
|
|
302
541
|
continue;
|
|
303
542
|
if (typeNameOf(el) === 'org_docx4j_wml.Tbl') {
|
|
304
|
-
for (const row of (
|
|
305
|
-
for (const cell of (
|
|
306
|
-
if (seek(cell.value))
|
|
543
|
+
for (const row of rowsOf(v))
|
|
544
|
+
for (const cell of cellsOf(row.element.value))
|
|
545
|
+
if (seek(cell.element.value))
|
|
307
546
|
return true;
|
|
308
547
|
}
|
|
309
548
|
else if (seek(v))
|
|
@@ -322,8 +561,8 @@ export class Body {
|
|
|
322
561
|
let parent = child.PARENT;
|
|
323
562
|
if (!parent)
|
|
324
563
|
return undefined;
|
|
325
|
-
// sdtContent is not a level of its own
|
|
326
|
-
if ((_a = parent.TYPE_NAME)
|
|
564
|
+
// sdtContent is not a level of its own, at block, row, cell or run level
|
|
565
|
+
if (/SdtContent(Block|Row|Cell|Run)$/.test((_a = parent.TYPE_NAME) !== null && _a !== void 0 ? _a : ''))
|
|
327
566
|
parent = parent.PARENT;
|
|
328
567
|
if (!parent)
|
|
329
568
|
return undefined;
|
|
@@ -355,6 +594,38 @@ export class Body {
|
|
|
355
594
|
usesParaIds() {
|
|
356
595
|
return this.paragraphs.some((q) => q.paraId !== undefined);
|
|
357
596
|
}
|
|
597
|
+
// --- comments (CR-002 phase G) ---
|
|
598
|
+
/**
|
|
599
|
+
* The comments anchored in this body, in document order, with replies nested under their
|
|
600
|
+
* parent (only top-level comments are in the array). Asynchronous because it unmarshals the
|
|
601
|
+
* comment parts.
|
|
602
|
+
*/
|
|
603
|
+
async getComments() {
|
|
604
|
+
return commentApi().commentsOf(this);
|
|
605
|
+
}
|
|
606
|
+
// --- content controls (CR-002 phase E) ---
|
|
607
|
+
/**
|
|
608
|
+
* Wraps everything this body holds in a new content control (Office JS
|
|
609
|
+
* `Body.insertContentControl`), typed for the kind when one is given; the `w:id` is free in this
|
|
610
|
+
* body. Returns the control.
|
|
611
|
+
*/
|
|
612
|
+
insertContentControl(kind) {
|
|
613
|
+
const content = [...this.content];
|
|
614
|
+
const sdt = sdtOf(content, { kind: sdtKindFor(kind), id: nextSdtId(controlIdScope(this)), form: 'block' });
|
|
615
|
+
this.content.length = 0;
|
|
616
|
+
this.content.push(sdt);
|
|
617
|
+
linkParents(sdt, this.container);
|
|
618
|
+
return new ContentControl(sdt, this.content, this);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
/** The width of the text area in twips (page width less the margins), for a new table. */
|
|
622
|
+
function writableWidthTwips(container) {
|
|
623
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
624
|
+
const pgSz = (_a = container.sectPr) === null || _a === void 0 ? void 0 : _a.pgSz;
|
|
625
|
+
if (!(pgSz === null || pgSz === void 0 ? void 0 : pgSz.w))
|
|
626
|
+
return undefined;
|
|
627
|
+
const width = pgSz.w - ((_d = (_c = (_b = container.sectPr) === null || _b === void 0 ? void 0 : _b.pgMar) === null || _c === void 0 ? void 0 : _c.left) !== null && _d !== void 0 ? _d : 0) - ((_g = (_f = (_e = container.sectPr) === null || _e === void 0 ? void 0 : _e.pgMar) === null || _f === void 0 ? void 0 : _f.right) !== null && _g !== void 0 ? _g : 0);
|
|
628
|
+
return width > 0 ? width : undefined;
|
|
358
629
|
}
|
|
359
630
|
function describe(el) {
|
|
360
631
|
var _a, _b;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type * as wml from '@docx4j/generated-objects-ts/modules/org_docx4j_wml';
|
|
2
|
+
import { Body } from './Body.mjs';
|
|
3
|
+
import { Paragraph } from './Paragraph.mjs';
|
|
4
|
+
import { Range } from './Range.mjs';
|
|
5
|
+
import { type CommentParts } from './comments.mjs';
|
|
6
|
+
/**
|
|
7
|
+
* A subset of Office JS `Word.Comment` over a `w:comment` and the markers that anchor it. A view:
|
|
8
|
+
* the tree is the state, and a view may be created and discarded freely. Replies are `Comment`s
|
|
9
|
+
* too (Office JS has a separate `CommentReply`; see the CR's section 9), threaded through
|
|
10
|
+
* `w15:commentsEx`.
|
|
11
|
+
*/
|
|
12
|
+
export declare class Comment {
|
|
13
|
+
/** The `w:comment` (extension; the model holds comments as values, not `{ name, value }` pairs). */
|
|
14
|
+
readonly element: wml.Comments.Comment;
|
|
15
|
+
/** The document's comment parts. */
|
|
16
|
+
readonly parts: CommentParts;
|
|
17
|
+
/** The body the comment is anchored in. */
|
|
18
|
+
readonly body: Body;
|
|
19
|
+
private parentComment;
|
|
20
|
+
private readonly replyList;
|
|
21
|
+
private bodyView;
|
|
22
|
+
constructor(
|
|
23
|
+
/** The `w:comment` (extension; the model holds comments as values, not `{ name, value }` pairs). */
|
|
24
|
+
element: wml.Comments.Comment,
|
|
25
|
+
/** The document's comment parts. */
|
|
26
|
+
parts: CommentParts,
|
|
27
|
+
/** The body the comment is anchored in. */
|
|
28
|
+
body: Body);
|
|
29
|
+
/** `w:id` (extension: Office JS's `id` is a string; this is the OOXML id docx4j users work with). */
|
|
30
|
+
get id(): number;
|
|
31
|
+
get authorName(): string;
|
|
32
|
+
/** `w:initials` (extension; Office JS has no initials). */
|
|
33
|
+
get initials(): string;
|
|
34
|
+
/** The author's email from `w:people`, '' when the document records none. */
|
|
35
|
+
get authorEmail(): string;
|
|
36
|
+
/** `w:date`; undefined when the comment carries none. */
|
|
37
|
+
get creationDate(): Date | undefined;
|
|
38
|
+
/** The comment's paragraphs as a `Body` (extension: the same content API as the document's). */
|
|
39
|
+
get commentBody(): Body;
|
|
40
|
+
/** The comment's paragraphs (extension). */
|
|
41
|
+
get paragraphs(): Paragraph[];
|
|
42
|
+
/** The comment's text, a paragraph per line; setting it replaces the paragraphs. */
|
|
43
|
+
get content(): string;
|
|
44
|
+
set content(text: string);
|
|
45
|
+
/** `w15:done`: whether the thread is resolved. Setting it creates the w15 part when the document has none. */
|
|
46
|
+
get resolved(): boolean;
|
|
47
|
+
set resolved(value: boolean);
|
|
48
|
+
/** The `w14:paraId` of the comment's first paragraph: the key of its w15 and w16cid entries (extension). */
|
|
49
|
+
get paraId(): string | undefined;
|
|
50
|
+
/** The replies to this comment, in document order; a reply's own replies nest further (Word shows one level). */
|
|
51
|
+
get replies(): Comment[];
|
|
52
|
+
/** The comment this one replies to (extension). */
|
|
53
|
+
get parent(): Comment | undefined;
|
|
54
|
+
/** A reply in the same thread, anchored to the same range, as Word writes them. */
|
|
55
|
+
reply(text: string): Promise<Comment>;
|
|
56
|
+
/** Removes the comment and its replies: the markers, the reference runs and every side-part entry. */
|
|
57
|
+
delete(): Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* The commented range: a `Range` per paragraph the comment touches (extension; Office JS
|
|
60
|
+
* returns one `Range`). Empty when the comment has no markers in this body.
|
|
61
|
+
*/
|
|
62
|
+
getRange(): Range[];
|
|
63
|
+
/** This comment and, depth first, its replies. */
|
|
64
|
+
private thread;
|
|
65
|
+
private removeSelf;
|
|
66
|
+
/** The first paragraph's `w14:paraId`, assigned when the comment has none (Word always writes one). */
|
|
67
|
+
ensureParaId(): string;
|
|
68
|
+
/** Used by `commentsOf` while threading. */
|
|
69
|
+
addReply(reply: Comment): void;
|
|
70
|
+
}
|
|
71
|
+
/** `Range.insertComment` (CR-002 section 3.8): the markers, the comment and the side-part entries. */
|
|
72
|
+
export declare function insertComment(range: Range, text: string): Promise<Comment>;
|
|
73
|
+
/**
|
|
74
|
+
* `getComments()` on a body, a paragraph or a range: the comments anchored there in document
|
|
75
|
+
* order, replies nested under their parent (a reply is in the array only when its parent is not).
|
|
76
|
+
*/
|
|
77
|
+
export declare function commentsOf(scope: Body | Paragraph | Range): Promise<Comment[]>;
|
|
78
|
+
export type { CommentParts, Author } from './comments.mjs';
|