@docx4j/core-ts 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/dist/html/convert.mjs +38 -14
- package/dist/model/content/Body.d.mts +13 -1
- package/dist/model/content/Body.mjs +90 -19
- package/dist/model/content/Comment.mjs +7 -0
- package/dist/model/content/InlinePicture.d.mts +71 -7
- package/dist/model/content/InlinePicture.mjs +201 -28
- package/dist/model/content/List.mjs +10 -1
- package/dist/model/content/Paragraph.d.mts +28 -5
- package/dist/model/content/Paragraph.mjs +77 -37
- package/dist/model/content/Range.d.mts +18 -2
- package/dist/model/content/Range.mjs +194 -64
- package/dist/model/content/TrackedChange.d.mts +129 -3
- package/dist/model/content/TrackedChange.mjs +577 -12
- package/dist/model/content/binder.d.mts +2 -1
- package/dist/model/content/binder.mjs +48 -1
- package/dist/model/content/index.d.mts +2 -2
- package/dist/model/content/index.mjs +1 -1
- package/dist/model/content/relationships.d.mts +30 -0
- package/dist/model/content/relationships.mjs +133 -0
- package/dist/model/content/tree.d.mts +52 -2
- package/dist/model/content/tree.mjs +48 -3
- package/dist/model/customxml/pictures.d.mts +5 -2
- package/dist/model/customxml/pictures.mjs +13 -7
- package/dist/model/fonts/families.generated.mjs +2 -2
- package/dist/model/fonts/registry.mjs +7 -1
- package/dist/model/fonts/substitutions.generated.mjs +2 -2
- package/dist/model/fonts/themes.generated.mjs +1 -1
- package/dist/model/listnumbering/definitions.mjs +18 -0
- package/dist/model/properties/PropertyResolver.d.mts +27 -6
- package/dist/model/properties/PropertyResolver.mjs +83 -16
- package/dist/model/properties/catalogue.d.mts +15 -1
- package/dist/model/properties/catalogue.mjs +80 -27
- package/dist/model/properties/table.d.mts +16 -2
- package/dist/model/properties/table.mjs +13 -3
- package/dist/opc/Load.d.mts +9 -2
- package/dist/opc/index.d.mts +2 -2
- package/dist/opc/index.mjs +2 -2
- package/dist/opc/mce/preprocessor.d.mts +62 -6
- package/dist/opc/mce/preprocessor.mjs +142 -35
- package/dist/opc/mce/understood.d.mts +10 -0
- package/dist/opc/mce/understood.mjs +25 -3
- package/dist/packages/OpcPackage.d.mts +7 -0
- package/dist/packages/OpcPackage.mjs +15 -3
- package/dist/packages/WordprocessingMLPackage.d.mts +35 -2
- package/dist/packages/WordprocessingMLPackage.mjs +98 -2
- package/dist/parts/XmlPart.d.mts +26 -5
- package/dist/parts/XmlPart.mjs +67 -18
- package/package.json +2 -2
package/dist/parts/XmlPart.mjs
CHANGED
|
@@ -25,11 +25,19 @@ const warnedPrefixes = new Set();
|
|
|
25
25
|
* element, so the location is everything before the position or the colon - and `w:sz` must not be
|
|
26
26
|
* cut at its own prefix separator, which a naive split on `:` does.
|
|
27
27
|
*/
|
|
28
|
+
/** The runtime's located message: `w:sz/@w:val (line 12): reason`, the position optional. */
|
|
29
|
+
const LOCATION_PREFIX = /^(.+?)(?: \(line \d+(?:, column \d+)?\))?: /;
|
|
28
30
|
function locationOf(message, located) {
|
|
29
31
|
var _a;
|
|
30
32
|
if (!located)
|
|
31
33
|
return undefined;
|
|
32
|
-
return (_a =
|
|
34
|
+
return (_a = LOCATION_PREFIX.exec(message)) === null || _a === void 0 ? void 0 : _a[1];
|
|
35
|
+
}
|
|
36
|
+
/** ` (line 12, column 9)`, or as much of it as is known. */
|
|
37
|
+
function positionOf(line, column) {
|
|
38
|
+
if (line === undefined)
|
|
39
|
+
return '';
|
|
40
|
+
return column === undefined ? ` (line ${line})` : ` (line ${line}, column ${column})`;
|
|
33
41
|
}
|
|
34
42
|
/** The objects package's prefix table as XPath wants it, prefix to URI; built once. */
|
|
35
43
|
const NAMESPACE_PREFIXES_BY_PREFIX = (() => {
|
|
@@ -48,6 +56,7 @@ const NAMESPACE_PREFIXES_BY_PREFIX = (() => {
|
|
|
48
56
|
export class XmlPart extends Part {
|
|
49
57
|
constructor(partName, contentType, relationshipType, rootName) {
|
|
50
58
|
super(partName, contentType, relationshipType);
|
|
59
|
+
this.parseWarnings = [];
|
|
51
60
|
this.rootName = rootName;
|
|
52
61
|
}
|
|
53
62
|
/** True once contents were unmarshalled or set; the part is then re-marshalled on save. */
|
|
@@ -65,6 +74,14 @@ export class XmlPart extends Part {
|
|
|
65
74
|
get isUntouched() {
|
|
66
75
|
return this.element === undefined && this.bytes === undefined;
|
|
67
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* What the preprocessor reported the last time this part was parsed (CR-010 phase 1): an
|
|
79
|
+
* mc:AlternateContent whose branches' text differs (`mce.branches_differ`). Empty until the part
|
|
80
|
+
* is parsed, by `getContents()` or a private read, and again once its contents are set.
|
|
81
|
+
*/
|
|
82
|
+
get warnings() {
|
|
83
|
+
return this.parseWarnings;
|
|
84
|
+
}
|
|
68
85
|
/** The unmarshalled contents (docx4j getJaxbElement()); throws when not yet unmarshalled. */
|
|
69
86
|
get contents() {
|
|
70
87
|
if (this.element === undefined)
|
|
@@ -77,16 +94,16 @@ export class XmlPart extends Part {
|
|
|
77
94
|
}
|
|
78
95
|
/** Unmarshals on first call (docx4j getContents()). */
|
|
79
96
|
async getContents() {
|
|
80
|
-
var _a, _b
|
|
97
|
+
var _a, _b;
|
|
81
98
|
if (this.element === undefined) {
|
|
82
99
|
const bytes = (_a = this.bytes) !== null && _a !== void 0 ? _a : (await this.loadSourceBytes());
|
|
83
100
|
if (bytes === undefined)
|
|
84
101
|
throw new Docx4JException(`Part ${this.partName} has no content: set contents or load it from a container`);
|
|
85
|
-
const doc =
|
|
102
|
+
const doc = this.parse(bytes);
|
|
86
103
|
this.recordDeclarations(doc);
|
|
87
|
-
|
|
104
|
+
this.preprocess(doc);
|
|
88
105
|
this.element = await this.unmarshal(doc);
|
|
89
|
-
(
|
|
106
|
+
(_b = this.rootName) !== null && _b !== void 0 ? _b : (this.rootName = { namespaceURI: this.element.name.namespaceURI, localPart: this.element.name.localPart });
|
|
90
107
|
this.bytes = undefined;
|
|
91
108
|
}
|
|
92
109
|
return this.element.value;
|
|
@@ -101,17 +118,22 @@ export class XmlPart extends Part {
|
|
|
101
118
|
* reads the styles and numbering parts of a document nobody has otherwise touched.
|
|
102
119
|
*/
|
|
103
120
|
async readContents() {
|
|
104
|
-
var _a
|
|
121
|
+
var _a;
|
|
105
122
|
if (this.element !== undefined)
|
|
106
123
|
return this.element.value;
|
|
107
124
|
const bytes = (_a = this.bytes) !== null && _a !== void 0 ? _a : (await this.loadSourceBytes());
|
|
108
125
|
if (bytes === undefined)
|
|
109
126
|
throw new Docx4JException(`Part ${this.partName} has no content: set contents or load it from a container`);
|
|
110
|
-
const doc =
|
|
127
|
+
const doc = this.parse(bytes);
|
|
111
128
|
this.recordDeclarations(doc);
|
|
112
|
-
|
|
129
|
+
this.preprocess(doc);
|
|
113
130
|
return (await this.unmarshal(doc)).value;
|
|
114
131
|
}
|
|
132
|
+
preprocess(doc) {
|
|
133
|
+
var _a;
|
|
134
|
+
const warnings = (_a = this.preprocessor) === null || _a === void 0 ? void 0 : _a.call(this, doc, this);
|
|
135
|
+
this.parseWarnings = warnings ? [...warnings] : [];
|
|
136
|
+
}
|
|
115
137
|
/** Replaces the contents (docx4j setJaxbElement / setContents). The root name defaults to the part's. */
|
|
116
138
|
setContents(value, rootName) {
|
|
117
139
|
var _a, _b;
|
|
@@ -120,6 +142,7 @@ export class XmlPart extends Part {
|
|
|
120
142
|
throw new Docx4JException(`Part ${this.partName}: no root element name; pass one`);
|
|
121
143
|
this.element = { name: { namespaceURI: name.namespaceURI, localPart: name.localPart }, value };
|
|
122
144
|
this.bytes = undefined;
|
|
145
|
+
this.parseWarnings = [];
|
|
123
146
|
}
|
|
124
147
|
/** Replaces the contents with raw XML bytes; they are unmarshalled on the next getContents(). */
|
|
125
148
|
setBytes(bytes) {
|
|
@@ -183,28 +206,54 @@ export class XmlPart extends Part {
|
|
|
183
206
|
this.declareIgnorablePrefixes(root);
|
|
184
207
|
return root;
|
|
185
208
|
}
|
|
209
|
+
/**
|
|
210
|
+
* Parses the part's bytes, and names the part when the XML is not well-formed. xmldom's error
|
|
211
|
+
* (Node) carries the line and column of the fault; a browser's says them in its text, which
|
|
212
|
+
* `parseXml` passes on.
|
|
213
|
+
*/
|
|
214
|
+
parse(bytes) {
|
|
215
|
+
try {
|
|
216
|
+
return parseXml(decodeXmlText(bytes));
|
|
217
|
+
}
|
|
218
|
+
catch (cause) {
|
|
219
|
+
const at = cause === null || cause === void 0 ? void 0 : cause.locator;
|
|
220
|
+
const line = typeof (at === null || at === void 0 ? void 0 : at.lineNumber) === 'number' ? at.lineNumber : undefined;
|
|
221
|
+
const column = typeof (at === null || at === void 0 ? void 0 : at.columnNumber) === 'number' ? at.columnNumber : undefined;
|
|
222
|
+
const reason = (cause instanceof Error ? cause.message : String(cause)).replace(/^Malformed XML: /, '');
|
|
223
|
+
throw new PartUnmarshalException(`${this.partName}: Malformed XML${positionOf(line, column)}: ${reason}`, this.partName.name, { cause, line, column });
|
|
224
|
+
}
|
|
225
|
+
}
|
|
186
226
|
/**
|
|
187
227
|
* Unmarshals, and names the part when the runtime refuses. The runtime's own message says what is
|
|
188
228
|
* wrong and, since `@docx4j/jsonix` 3.4.0, where - `w:sz/@w:val (line 12): Argument [NaN] must be
|
|
189
229
|
* an integer` - but not which part it was reading, which is the first thing a person editing a
|
|
190
|
-
* part's XML needs (CR-002 section 27)
|
|
191
|
-
*
|
|
192
|
-
*
|
|
230
|
+
* part's XML needs (CR-002 section 27), nor the value it refused. The message names the part, and
|
|
231
|
+
* for an attribute gives the value as written and the column too:
|
|
232
|
+
* `/word/styles.xml: w:sz/@w:val="big" (line 12, column 9): Argument [NaN] must be an integer, ...`.
|
|
233
|
+
* The location it found is lifted onto the exception so a caller does not parse the message; `line`
|
|
234
|
+
* is undefined where the parser supplies no position, which is every browser (only xmldom carries a
|
|
235
|
+
* locator).
|
|
193
236
|
*/
|
|
194
237
|
async unmarshal(doc) {
|
|
195
|
-
var _a, _b;
|
|
238
|
+
var _a, _b, _c, _d, _e, _f;
|
|
196
239
|
try {
|
|
197
240
|
return await unmarshalNode(doc);
|
|
198
241
|
}
|
|
199
242
|
catch (cause) {
|
|
200
243
|
const located = cause;
|
|
201
244
|
const message = typeof (located === null || located === void 0 ? void 0 : located.message) === 'string' ? located.message : String(cause);
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
245
|
+
const location = locationOf(message, (located === null || located === void 0 ? void 0 : located.jsonixLocated) === true);
|
|
246
|
+
const line = typeof ((_a = located === null || located === void 0 ? void 0 : located.node) === null || _a === void 0 ? void 0 : _a.lineNumber) === 'number' ? located.node.lineNumber : undefined;
|
|
247
|
+
const column = typeof ((_b = located === null || located === void 0 ? void 0 : located.node) === null || _b === void 0 ? void 0 : _b.columnNumber) === 'number' ? located.node.columnNumber : undefined;
|
|
248
|
+
let detail = message;
|
|
249
|
+
if (location !== undefined) {
|
|
250
|
+
const reason = message.slice((_d = (_c = LOCATION_PREFIX.exec(message)) === null || _c === void 0 ? void 0 : _c[0].length) !== null && _d !== void 0 ? _d : 0);
|
|
251
|
+
const name = located === null || located === void 0 ? void 0 : located.attributeName;
|
|
252
|
+
const value = (name === null || name === void 0 ? void 0 : name.localPart) ? (_f = (_e = located === null || located === void 0 ? void 0 : located.node) === null || _e === void 0 ? void 0 : _e.getAttributeNS) === null || _f === void 0 ? void 0 : _f.call(_e, name.namespaceURI || null, name.localPart) : undefined;
|
|
253
|
+
const shown = typeof value === 'string' ? `=${JSON.stringify(value.length > 80 ? `${value.slice(0, 80)}...` : value)}` : '';
|
|
254
|
+
detail = `${location}${shown}${positionOf(line, column)}: ${reason}`;
|
|
255
|
+
}
|
|
256
|
+
throw new PartUnmarshalException(`${this.partName}: ${detail}`, this.partName.name, { cause, location, line, column });
|
|
208
257
|
}
|
|
209
258
|
}
|
|
210
259
|
/** The source root element's namespace declarations, prefix to URI (`xmlns=` is the empty prefix). */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docx4j/core-ts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
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",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
},
|
|
84
84
|
"license": "Apache-2.0",
|
|
85
85
|
"dependencies": {
|
|
86
|
-
"@docx4j/generated-objects-ts": "^0.
|
|
86
|
+
"@docx4j/generated-objects-ts": "^0.4.2",
|
|
87
87
|
"fflate": "^0.8.2"
|
|
88
88
|
},
|
|
89
89
|
"devDependencies": {
|