@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
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
import * as el from '@docx4j/generated-objects-ts/el/org_docx4j_wml';
|
|
2
|
+
import * as wmlFactory from '@docx4j/generated-objects-ts/factory/org_docx4j_wml';
|
|
3
|
+
import * as w15Factory from '@docx4j/generated-objects-ts/factory/org_docx4j_w15';
|
|
4
|
+
import * as w16cidFactory from '@docx4j/generated-objects-ts/factory/org_docx4j_w16cid';
|
|
5
|
+
import { r as textRun, applyRunOptions, linkParents } from '@docx4j/generated-objects-ts/builders/wml';
|
|
6
|
+
import { Docx4JException } from '../../opc/exceptions.mjs';
|
|
7
|
+
import { Body } from './Body.mjs';
|
|
8
|
+
import { Paragraph } from './Paragraph.mjs';
|
|
9
|
+
import { Range } from './Range.mjs';
|
|
10
|
+
import { runOf, paragraphOf, typeNameOf } from './tree.mjs';
|
|
11
|
+
import { COMMENT_REFERENCE_STYLE, COMMENT_TEXT_STYLE, calendarToDate, commentExOf, commentIdsOf, commentPartsAccess, commentParaId, dateToCalendar, initialsOf, isDone, markersOf, markersOfParagraph, nextCommentId, paraIdTaken, randomHexId, removeMarkers, setCommentApi, } from './comments.mjs';
|
|
12
|
+
/**
|
|
13
|
+
* A subset of Office JS `Word.Comment` over a `w:comment` and the markers that anchor it. A view:
|
|
14
|
+
* the tree is the state, and a view may be created and discarded freely. Replies are `Comment`s
|
|
15
|
+
* too (Office JS has a separate `CommentReply`; see the CR's section 9), threaded through
|
|
16
|
+
* `w15:commentsEx`.
|
|
17
|
+
*/
|
|
18
|
+
export class Comment {
|
|
19
|
+
constructor(
|
|
20
|
+
/** The `w:comment` (extension; the model holds comments as values, not `{ name, value }` pairs). */
|
|
21
|
+
element,
|
|
22
|
+
/** The document's comment parts. */
|
|
23
|
+
parts,
|
|
24
|
+
/** The body the comment is anchored in. */
|
|
25
|
+
body) {
|
|
26
|
+
this.element = element;
|
|
27
|
+
this.parts = parts;
|
|
28
|
+
this.body = body;
|
|
29
|
+
this.replyList = [];
|
|
30
|
+
}
|
|
31
|
+
/** `w:id` (extension: Office JS's `id` is a string; this is the OOXML id docx4j users work with). */
|
|
32
|
+
get id() {
|
|
33
|
+
return this.element.id;
|
|
34
|
+
}
|
|
35
|
+
get authorName() {
|
|
36
|
+
var _a;
|
|
37
|
+
return (_a = this.element.author) !== null && _a !== void 0 ? _a : '';
|
|
38
|
+
}
|
|
39
|
+
/** `w:initials` (extension; Office JS has no initials). */
|
|
40
|
+
get initials() {
|
|
41
|
+
var _a;
|
|
42
|
+
return (_a = this.element.initials) !== null && _a !== void 0 ? _a : '';
|
|
43
|
+
}
|
|
44
|
+
/** The author's email from `w:people`, '' when the document records none. */
|
|
45
|
+
get authorEmail() {
|
|
46
|
+
var _a, _b, _c, _d;
|
|
47
|
+
const person = ((_b = (_a = this.parts.people) === null || _a === void 0 ? void 0 : _a.person) !== null && _b !== void 0 ? _b : []).find((p) => p.author === this.authorName);
|
|
48
|
+
const userId = (_d = (_c = person === null || person === void 0 ? void 0 : person.presenceInfo) === null || _c === void 0 ? void 0 : _c.userId) !== null && _d !== void 0 ? _d : '';
|
|
49
|
+
const ad = /^S::([^:]+)::/.exec(userId);
|
|
50
|
+
return ad ? ad[1] : userId;
|
|
51
|
+
}
|
|
52
|
+
/** `w:date`; undefined when the comment carries none. */
|
|
53
|
+
get creationDate() {
|
|
54
|
+
return calendarToDate(this.element.date);
|
|
55
|
+
}
|
|
56
|
+
/** The comment's paragraphs as a `Body` (extension: the same content API as the document's). */
|
|
57
|
+
get commentBody() {
|
|
58
|
+
var _a;
|
|
59
|
+
return ((_a = this.bodyView) !== null && _a !== void 0 ? _a : (this.bodyView = new Body(this.parts.commentsPart, this.element, `comment:${this.id}`, this.body.package_)));
|
|
60
|
+
}
|
|
61
|
+
/** The comment's paragraphs (extension). */
|
|
62
|
+
get paragraphs() {
|
|
63
|
+
return this.commentBody.paragraphs;
|
|
64
|
+
}
|
|
65
|
+
/** The comment's text, a paragraph per line; setting it replaces the paragraphs. */
|
|
66
|
+
get content() {
|
|
67
|
+
return this.commentBody.text;
|
|
68
|
+
}
|
|
69
|
+
set content(text) {
|
|
70
|
+
const paraId = commentParaId(this.element);
|
|
71
|
+
const paragraphs = text.split('\n').map((line, i) => commentParagraph(line, i === 0));
|
|
72
|
+
if (paraId)
|
|
73
|
+
paragraphs[0].value.paraId = paraId;
|
|
74
|
+
this.element.content = paragraphs;
|
|
75
|
+
linkParents(this.element.content, this.element);
|
|
76
|
+
this.bodyView = undefined;
|
|
77
|
+
}
|
|
78
|
+
/** `w15:done`: whether the thread is resolved. Setting it creates the w15 part when the document has none. */
|
|
79
|
+
get resolved() {
|
|
80
|
+
var _a;
|
|
81
|
+
return isDone((_a = commentExOf(this.parts, this.paraId)) === null || _a === void 0 ? void 0 : _a.done);
|
|
82
|
+
}
|
|
83
|
+
set resolved(value) {
|
|
84
|
+
var _a;
|
|
85
|
+
const extended = this.parts.ensureCommentsEx();
|
|
86
|
+
const paraId = this.ensureParaId();
|
|
87
|
+
const entries = ((_a = extended.commentEx) !== null && _a !== void 0 ? _a : (extended.commentEx = []));
|
|
88
|
+
let entry = entries.find((e) => e.paraId === paraId);
|
|
89
|
+
if (!entry) {
|
|
90
|
+
entry = w15Factory.createCTCommentEx({ paraId });
|
|
91
|
+
entries.push(entry);
|
|
92
|
+
linkParents(entry, extended);
|
|
93
|
+
}
|
|
94
|
+
entry.done = value ? '1' : '0';
|
|
95
|
+
}
|
|
96
|
+
/** The `w14:paraId` of the comment's first paragraph: the key of its w15 and w16cid entries (extension). */
|
|
97
|
+
get paraId() {
|
|
98
|
+
return commentParaId(this.element);
|
|
99
|
+
}
|
|
100
|
+
/** The replies to this comment, in document order; a reply's own replies nest further (Word shows one level). */
|
|
101
|
+
get replies() {
|
|
102
|
+
return this.replyList;
|
|
103
|
+
}
|
|
104
|
+
/** The comment this one replies to (extension). */
|
|
105
|
+
get parent() {
|
|
106
|
+
return this.parentComment;
|
|
107
|
+
}
|
|
108
|
+
/** A reply in the same thread, anchored to the same range, as Word writes them. */
|
|
109
|
+
async reply(text) {
|
|
110
|
+
const parts = await this.parts.ensureAll();
|
|
111
|
+
const id = nextCommentId(parts.comments, this.body.container);
|
|
112
|
+
placeAfter(this.body, this.id, id);
|
|
113
|
+
const reply = addComment(parts, this.body, id, text, this);
|
|
114
|
+
this.replyList.push(reply);
|
|
115
|
+
reply.parentComment = this;
|
|
116
|
+
return reply;
|
|
117
|
+
}
|
|
118
|
+
/** Removes the comment and its replies: the markers, the reference runs and every side-part entry. */
|
|
119
|
+
async delete() {
|
|
120
|
+
await this.parts.ensureAll();
|
|
121
|
+
for (const comment of this.thread())
|
|
122
|
+
comment.removeSelf();
|
|
123
|
+
if (this.parentComment) {
|
|
124
|
+
const i = this.parentComment.replyList.indexOf(this);
|
|
125
|
+
if (i >= 0)
|
|
126
|
+
this.parentComment.replyList.splice(i, 1);
|
|
127
|
+
this.parentComment = undefined;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* The commented range: a `Range` per paragraph the comment touches (extension; Office JS
|
|
132
|
+
* returns one `Range`). Empty when the comment has no markers in this body.
|
|
133
|
+
*/
|
|
134
|
+
getRange() {
|
|
135
|
+
var _a, _b, _c, _d;
|
|
136
|
+
const markers = markersOf(this.body.container).filter((m) => m.id === this.id && m.paragraph !== undefined);
|
|
137
|
+
if (markers.length === 0)
|
|
138
|
+
return [];
|
|
139
|
+
const paragraphs = this.body.paragraphs;
|
|
140
|
+
const indexOf = (marker) => paragraphs.findIndex((p) => p.element === marker.paragraph);
|
|
141
|
+
const start = markers.find((m) => m.kind === 'start');
|
|
142
|
+
const end = [...markers].reverse().find((m) => m.kind === 'end');
|
|
143
|
+
if (!start || !end) {
|
|
144
|
+
const marker = (_a = start !== null && start !== void 0 ? start : end) !== null && _a !== void 0 ? _a : markers.find((m) => m.kind === 'reference');
|
|
145
|
+
const i = indexOf(marker);
|
|
146
|
+
if (i < 0)
|
|
147
|
+
return [];
|
|
148
|
+
const p = paragraphs[i];
|
|
149
|
+
const at = (_b = marker.offset) !== null && _b !== void 0 ? _b : 0;
|
|
150
|
+
return [new Range(p, at, marker.kind === 'start' ? p.text.length : at)];
|
|
151
|
+
}
|
|
152
|
+
const from = indexOf(start);
|
|
153
|
+
const to = indexOf(end);
|
|
154
|
+
if (from < 0 || to < 0 || to < from)
|
|
155
|
+
return [];
|
|
156
|
+
const out = [];
|
|
157
|
+
for (let i = from; i <= to; i++) {
|
|
158
|
+
const p = paragraphs[i];
|
|
159
|
+
out.push(new Range(p, i === from ? (_c = start.offset) !== null && _c !== void 0 ? _c : 0 : 0, i === to ? (_d = end.offset) !== null && _d !== void 0 ? _d : p.text.length : p.text.length));
|
|
160
|
+
}
|
|
161
|
+
return out;
|
|
162
|
+
}
|
|
163
|
+
// --- internals ---
|
|
164
|
+
/** This comment and, depth first, its replies. */
|
|
165
|
+
thread() {
|
|
166
|
+
return [this, ...this.replyList.flatMap((r) => r.thread())];
|
|
167
|
+
}
|
|
168
|
+
removeSelf() {
|
|
169
|
+
var _a, _b, _c;
|
|
170
|
+
removeMarkers(this.body.container, this.id);
|
|
171
|
+
const comments = this.parts.comments.comment;
|
|
172
|
+
if (comments) {
|
|
173
|
+
const i = comments.indexOf(this.element);
|
|
174
|
+
if (i >= 0)
|
|
175
|
+
comments.splice(i, 1);
|
|
176
|
+
}
|
|
177
|
+
const paraId = this.paraId;
|
|
178
|
+
if (paraId === undefined)
|
|
179
|
+
return;
|
|
180
|
+
const extended = (_a = this.parts.commentsEx) === null || _a === void 0 ? void 0 : _a.commentEx;
|
|
181
|
+
if (extended) {
|
|
182
|
+
const i = extended.findIndex((e) => e.paraId === paraId);
|
|
183
|
+
if (i >= 0)
|
|
184
|
+
extended.splice(i, 1);
|
|
185
|
+
}
|
|
186
|
+
const ids = (_b = this.parts.commentsIds) === null || _b === void 0 ? void 0 : _b.commentId;
|
|
187
|
+
if (ids) {
|
|
188
|
+
const i = ids.findIndex((e) => e.paraId === paraId);
|
|
189
|
+
if (i >= 0) {
|
|
190
|
+
const durableId = ids[i].durableId;
|
|
191
|
+
ids.splice(i, 1);
|
|
192
|
+
if (durableId)
|
|
193
|
+
(_c = this.parts.extensible) === null || _c === void 0 ? void 0 : _c.remove(durableId);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/** The first paragraph's `w14:paraId`, assigned when the comment has none (Word always writes one). */
|
|
198
|
+
ensureParaId() {
|
|
199
|
+
var _a;
|
|
200
|
+
var _b;
|
|
201
|
+
const existing = this.paraId;
|
|
202
|
+
if (existing !== undefined)
|
|
203
|
+
return existing;
|
|
204
|
+
const content = ((_a = (_b = this.element).content) !== null && _a !== void 0 ? _a : (_b.content = []));
|
|
205
|
+
let first = content.find((e) => typeNameOf(e) === 'org_docx4j_wml.P');
|
|
206
|
+
if (!first) {
|
|
207
|
+
first = commentParagraph('', true);
|
|
208
|
+
content.unshift(first);
|
|
209
|
+
linkParents(first, this.element);
|
|
210
|
+
}
|
|
211
|
+
const paraId = randomHexId((id) => paraIdTaken(this.parts, this.body.container, id));
|
|
212
|
+
first.value.paraId = paraId;
|
|
213
|
+
return paraId;
|
|
214
|
+
}
|
|
215
|
+
/** Used by `commentsOf` while threading. */
|
|
216
|
+
addReply(reply) {
|
|
217
|
+
reply.parentComment = this;
|
|
218
|
+
this.replyList.push(reply);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/** The run Word puts first in a comment: the annotation reference in the `CommentReference` style. */
|
|
222
|
+
function annotationRefRun() {
|
|
223
|
+
return runOf([el.annotationRef(wmlFactory.createRAnnotationRef())], applyRunOptions({}, { style: COMMENT_REFERENCE_STYLE }));
|
|
224
|
+
}
|
|
225
|
+
/** The run that anchors a comment in the body: `w:commentReference` in the `CommentReference` style. */
|
|
226
|
+
function referenceRun(id) {
|
|
227
|
+
return runOf([el.commentReference(wmlFactory.createRCommentReference({ id }))], applyRunOptions({}, { style: COMMENT_REFERENCE_STYLE }));
|
|
228
|
+
}
|
|
229
|
+
/** A paragraph of a comment: the `CommentText` style, opened by the annotation reference run. */
|
|
230
|
+
function commentParagraph(text, first) {
|
|
231
|
+
const runs = [];
|
|
232
|
+
if (first)
|
|
233
|
+
runs.push(annotationRefRun());
|
|
234
|
+
if (text !== '')
|
|
235
|
+
runs.push(textRun(text));
|
|
236
|
+
return paragraphOf(runs, { TYPE_NAME: 'org_docx4j_wml.PPr', pStyle: { val: COMMENT_TEXT_STYLE } });
|
|
237
|
+
}
|
|
238
|
+
function insertAt(owner, index, items, parent) {
|
|
239
|
+
owner.splice(index, 0, ...items);
|
|
240
|
+
for (const item of items)
|
|
241
|
+
linkParents(item, parent);
|
|
242
|
+
}
|
|
243
|
+
function parentOf(element) {
|
|
244
|
+
return element.value.PARENT;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Where a marker for this segment's run goes: beside the run, but outside the `w:ins` or `w:del`
|
|
248
|
+
* the run sits in, so that a comment made while change tracking is on is a comment and not an
|
|
249
|
+
* insertion of its own (CR-002 section 13). Accepting or rejecting the revision then leaves the
|
|
250
|
+
* comment where it is; the cost is that a comment on part of an insertion widens to the whole of
|
|
251
|
+
* it, which is what Word shows anyway once the insertion is accepted.
|
|
252
|
+
*/
|
|
253
|
+
function markerSite(seg, fallback, after) {
|
|
254
|
+
var _a;
|
|
255
|
+
const item = seg.revision ? seg.revision.element : seg.runOwner[seg.runIndex];
|
|
256
|
+
const owner = seg.revision ? seg.revision.owner : seg.runOwner;
|
|
257
|
+
return { owner, index: owner.indexOf(item) + (after ? 1 : 0), parent: (_a = parentOf(item)) !== null && _a !== void 0 ? _a : fallback };
|
|
258
|
+
}
|
|
259
|
+
/** Writes the markers of a new comment around a range, splitting runs at its boundaries as `Range.font` does. */
|
|
260
|
+
function placeAround(range, id) {
|
|
261
|
+
var _a;
|
|
262
|
+
var _b;
|
|
263
|
+
const paragraph = range.paragraph;
|
|
264
|
+
paragraph.splitAt(range.start);
|
|
265
|
+
if (range.end > range.start)
|
|
266
|
+
paragraph.splitAt(range.end);
|
|
267
|
+
const covered = range.end > range.start ? paragraph.segments().filter((s) => s.end > range.start && s.start < range.end) : [];
|
|
268
|
+
const start = el.commentRangeStart(wmlFactory.createCommentRangeStart({ id }));
|
|
269
|
+
const end = el.commentRangeEnd(wmlFactory.createCommentRangeEnd({ id }));
|
|
270
|
+
const reference = referenceRun(id);
|
|
271
|
+
if (covered.length === 0) {
|
|
272
|
+
// an empty range or an empty paragraph: the reference run only, which is all Word requires
|
|
273
|
+
const segments = paragraph.segments();
|
|
274
|
+
const after = segments.find((s) => s.start >= range.start);
|
|
275
|
+
const before = [...segments].reverse().find((s) => s.end <= range.start);
|
|
276
|
+
const site = after ? markerSite(after, paragraph.p, false) : before ? markerSite(before, paragraph.p, true) : undefined;
|
|
277
|
+
if (site)
|
|
278
|
+
insertAt(site.owner, site.index, [reference], site.parent);
|
|
279
|
+
else
|
|
280
|
+
insertAt(((_a = (_b = paragraph.p).content) !== null && _a !== void 0 ? _a : (_b.content = [])), paragraph.p.content.length, [reference], paragraph.p);
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
const after = markerSite(covered[covered.length - 1], paragraph.p, true);
|
|
284
|
+
insertAt(after.owner, after.index, [end, reference], after.parent);
|
|
285
|
+
const before = markerSite(covered[0], paragraph.p, false);
|
|
286
|
+
insertAt(before.owner, before.index, [start], before.parent);
|
|
287
|
+
}
|
|
288
|
+
/** Writes the markers of a reply next to its parent's, as Word nests them. */
|
|
289
|
+
function placeAfter(body, parentId, id) {
|
|
290
|
+
const markers = markersOf(body.container).filter((m) => m.id === parentId);
|
|
291
|
+
const start = markers.find((m) => m.kind === 'start');
|
|
292
|
+
const end = [...markers].reverse().find((m) => m.kind === 'end');
|
|
293
|
+
const reference = [...markers].reverse().find((m) => m.kind === 'reference');
|
|
294
|
+
if (start)
|
|
295
|
+
insertAt(start.owner, start.owner.indexOf(start.item) + 1, [el.commentRangeStart(wmlFactory.createCommentRangeStart({ id }))], parentOf(start.item));
|
|
296
|
+
if (end)
|
|
297
|
+
insertAt(end.owner, end.owner.indexOf(end.item) + 1, [el.commentRangeEnd(wmlFactory.createCommentRangeEnd({ id }))], parentOf(end.item));
|
|
298
|
+
if ((reference === null || reference === void 0 ? void 0 : reference.run) && reference.runOwner) {
|
|
299
|
+
insertAt(reference.runOwner, reference.runOwner.indexOf(reference.run) + 1, [referenceRun(id)], parentOf(reference.run));
|
|
300
|
+
}
|
|
301
|
+
else if (end) {
|
|
302
|
+
insertAt(end.owner, end.owner.indexOf(end.item) + 1, [referenceRun(id)], parentOf(end.item));
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
throw new Docx4JException(`Comment ${parentId} has no markers in this body; cannot anchor a reply`);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
/** The `w:comment` and the side-part entries of a new comment; the markers are already written. */
|
|
309
|
+
function addComment(parts, body, id, text, parent) {
|
|
310
|
+
var _a, _b, _c, _d;
|
|
311
|
+
var _e, _f;
|
|
312
|
+
const author = parts.author;
|
|
313
|
+
const paragraphs = text.split('\n').map((line, i) => commentParagraph(line, i === 0));
|
|
314
|
+
const paraId = randomHexId((candidate) => paraIdTaken(parts, body.container, candidate));
|
|
315
|
+
paragraphs[0].value.paraId = paraId;
|
|
316
|
+
const comment = wmlFactory.createCommentsComment({
|
|
317
|
+
id, author: author.name, initials: initialsOf(author), date: dateToCalendar(new Date()),
|
|
318
|
+
content: paragraphs,
|
|
319
|
+
});
|
|
320
|
+
const comments = ((_a = (_e = parts.comments).comment) !== null && _a !== void 0 ? _a : (_e.comment = []));
|
|
321
|
+
comments.push(comment);
|
|
322
|
+
linkParents(comment, parts.comments);
|
|
323
|
+
const extended = parts.ensureCommentsEx();
|
|
324
|
+
const entry = w15Factory.createCTCommentEx({ paraId, done: '0' });
|
|
325
|
+
if (parent)
|
|
326
|
+
entry.paraIdParent = parent.ensureParaId();
|
|
327
|
+
((_b = extended.commentEx) !== null && _b !== void 0 ? _b : (extended.commentEx = [])).push(entry);
|
|
328
|
+
linkParents(entry, extended);
|
|
329
|
+
if (parts.commentsIds) {
|
|
330
|
+
const durableId = randomHexId((candidate) => { var _a; return ((_a = parts.commentsIds.commentId) !== null && _a !== void 0 ? _a : []).some((e) => e.durableId === candidate); });
|
|
331
|
+
const commentId = w16cidFactory.createCTCommentId({ paraId, durableId });
|
|
332
|
+
((_c = (_f = parts.commentsIds).commentId) !== null && _c !== void 0 ? _c : (_f.commentId = [])).push(commentId);
|
|
333
|
+
linkParents(commentId, parts.commentsIds);
|
|
334
|
+
(_d = parts.extensible) === null || _d === void 0 ? void 0 : _d.set(durableId, new Date());
|
|
335
|
+
}
|
|
336
|
+
addPerson(parts, author.name, author.email);
|
|
337
|
+
return new Comment(comment, parts, body);
|
|
338
|
+
}
|
|
339
|
+
/** Word records every comment author in `w:people`; the presence info carries the email. */
|
|
340
|
+
function addPerson(parts, name, email) {
|
|
341
|
+
var _a;
|
|
342
|
+
const people = parts.people;
|
|
343
|
+
if (!people)
|
|
344
|
+
return;
|
|
345
|
+
const list = ((_a = people.person) !== null && _a !== void 0 ? _a : (people.person = []));
|
|
346
|
+
if (list.some((p) => p.author === name))
|
|
347
|
+
return;
|
|
348
|
+
// w15:contact is declared required but Word omits it; the factory's init is partial, so it is
|
|
349
|
+
// simply left out (see the CR's section 9)
|
|
350
|
+
const person = w15Factory.createCTPerson({
|
|
351
|
+
author: name,
|
|
352
|
+
presenceInfo: w15Factory.createCTPresenceInfo({ providerId: 'None', userId: email !== null && email !== void 0 ? email : name }),
|
|
353
|
+
});
|
|
354
|
+
list.push(person);
|
|
355
|
+
linkParents(person, people);
|
|
356
|
+
}
|
|
357
|
+
/** `Range.insertComment` (CR-002 section 3.8): the markers, the comment and the side-part entries. */
|
|
358
|
+
export async function insertComment(range, text) {
|
|
359
|
+
const body = range.paragraph.parentBody;
|
|
360
|
+
const parts = await commentPartsAccess().create(body);
|
|
361
|
+
const id = nextCommentId(parts.comments, body.container);
|
|
362
|
+
placeAround(range, id);
|
|
363
|
+
return addComment(parts, body, id, text, undefined);
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* `getComments()` on a body, a paragraph or a range: the comments anchored there in document
|
|
367
|
+
* order, replies nested under their parent (a reply is in the array only when its parent is not).
|
|
368
|
+
*/
|
|
369
|
+
export async function commentsOf(scope) {
|
|
370
|
+
var _a, _b;
|
|
371
|
+
const paragraph = scope instanceof Range ? scope.paragraph : scope instanceof Paragraph ? scope : undefined;
|
|
372
|
+
const body = paragraph ? paragraph.parentBody : scope;
|
|
373
|
+
const parts = await commentPartsAccess().load(body);
|
|
374
|
+
if (!parts)
|
|
375
|
+
return [];
|
|
376
|
+
const views = new Map();
|
|
377
|
+
for (const comment of (_a = parts.comments.comment) !== null && _a !== void 0 ? _a : []) {
|
|
378
|
+
if (typeof comment.id === 'number' && !views.has(comment.id))
|
|
379
|
+
views.set(comment.id, new Comment(comment, parts, body));
|
|
380
|
+
}
|
|
381
|
+
const byParaId = new Map();
|
|
382
|
+
for (const view of views.values()) {
|
|
383
|
+
const paraId = view.paraId;
|
|
384
|
+
if (paraId !== undefined)
|
|
385
|
+
byParaId.set(paraId, view);
|
|
386
|
+
}
|
|
387
|
+
for (const view of views.values()) {
|
|
388
|
+
const parentParaId = (_b = commentExOf(parts, view.paraId)) === null || _b === void 0 ? void 0 : _b.paraIdParent;
|
|
389
|
+
const parent = parentParaId === undefined ? undefined : byParaId.get(parentParaId);
|
|
390
|
+
if (parent && parent !== view)
|
|
391
|
+
parent.addReply(view);
|
|
392
|
+
}
|
|
393
|
+
const ids = scope instanceof Range ? idsInRange(scope) : paragraph ? unique(markersOfParagraph(paragraph.element, paragraph.container).map((m) => m.id)) : commentIdsOf(body.container);
|
|
394
|
+
const inScope = new Set(ids);
|
|
395
|
+
const out = [];
|
|
396
|
+
for (const id of ids) {
|
|
397
|
+
const view = views.get(id);
|
|
398
|
+
if (!view)
|
|
399
|
+
continue;
|
|
400
|
+
if (view.parent && inScope.has(view.parent.id))
|
|
401
|
+
continue;
|
|
402
|
+
out.push(view);
|
|
403
|
+
}
|
|
404
|
+
return out;
|
|
405
|
+
}
|
|
406
|
+
/** The comments a range touches: a comment whose markers overlap [start, end]. */
|
|
407
|
+
function idsInRange(range) {
|
|
408
|
+
var _a;
|
|
409
|
+
const spans = new Map();
|
|
410
|
+
const order = [];
|
|
411
|
+
for (const marker of markersOfParagraph(range.paragraph.element, range.paragraph.container)) {
|
|
412
|
+
const at = (_a = marker.offset) !== null && _a !== void 0 ? _a : 0;
|
|
413
|
+
const span = spans.get(marker.id);
|
|
414
|
+
if (span) {
|
|
415
|
+
span.from = Math.min(span.from, at);
|
|
416
|
+
span.to = Math.max(span.to, at);
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
spans.set(marker.id, { from: at, to: at });
|
|
420
|
+
order.push(marker.id);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
return order.filter((id) => { const s = spans.get(id); return s.from <= range.end && s.to >= range.start; });
|
|
424
|
+
}
|
|
425
|
+
function unique(ids) {
|
|
426
|
+
const seen = new Set();
|
|
427
|
+
return ids.filter((id) => (seen.has(id) ? false : (seen.add(id), true)));
|
|
428
|
+
}
|
|
429
|
+
setCommentApi({ commentsOf, insertComment });
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import type * as wml from '@docx4j/generated-objects-ts/modules/org_docx4j_wml';
|
|
2
|
+
import { XmlMapping } from '../customxml/XmlMapping.mjs';
|
|
3
|
+
import { CheckboxContentControl, DatePickerContentControl, ListContentControl, PictureContentControl, RepeatingSectionContentControl, GroupContentControl } from '../customxml/kinds.mjs';
|
|
4
|
+
import { type SdtKind } from '@docx4j/generated-objects-ts/builders/wml';
|
|
5
|
+
import { type Element } from './tree.mjs';
|
|
6
|
+
import type { Body } from './Body.mjs';
|
|
7
|
+
import type { Paragraph } from './Paragraph.mjs';
|
|
8
|
+
import { Range } from './Range.mjs';
|
|
9
|
+
import { Table } from './Table.mjs';
|
|
10
|
+
import type { SearchOptions } from './search.mjs';
|
|
11
|
+
/**
|
|
12
|
+
* Office JS `Word.ContentControlType`, as Word reports it from w:sdtPr: the builders' `SdtKind`
|
|
13
|
+
* (objects CR-003 section 3.1) and Office JS's `Unknown`, which no `w:sdtPr` produces.
|
|
14
|
+
*/
|
|
15
|
+
export type ContentControlType = SdtKind | 'Unknown';
|
|
16
|
+
/** Which of the four w:sdt forms a control is. */
|
|
17
|
+
export type ContentControlForm = 'Block' | 'Run' | 'Row' | 'Cell';
|
|
18
|
+
/** Office JS `Word.ContentControlAppearance` (w15:appearance). */
|
|
19
|
+
export type ContentControlAppearance = 'BoundingBox' | 'Tags' | 'Hidden';
|
|
20
|
+
/** The namespaces of the Word 2010 and 2012 content-control properties. */
|
|
21
|
+
export declare const W14_NS = "http://schemas.microsoft.com/office/word/2010/wordml";
|
|
22
|
+
export declare const W15_NS = "http://schemas.microsoft.com/office/word/2012/wordml";
|
|
23
|
+
/** A subset of Office JS `Word.ContentControl` over a `w:sdt`. A view, as Paragraph is. */
|
|
24
|
+
export declare class ContentControl {
|
|
25
|
+
/** The `w:sdt` element pair (SdtBlock, SdtRun, CTSdtRow or CTSdtCell). */
|
|
26
|
+
readonly element: Element<wml.SdtBlock | wml.SdtRun | wml.CTSdtRow | wml.CTSdtCell>;
|
|
27
|
+
/** The array holding the element. */
|
|
28
|
+
readonly container: Element[];
|
|
29
|
+
/** The body the control is in (the part's). */
|
|
30
|
+
readonly parentBody: Body;
|
|
31
|
+
constructor(
|
|
32
|
+
/** The `w:sdt` element pair (SdtBlock, SdtRun, CTSdtRow or CTSdtCell). */
|
|
33
|
+
element: Element<wml.SdtBlock | wml.SdtRun | wml.CTSdtRow | wml.CTSdtCell>,
|
|
34
|
+
/** The array holding the element. */
|
|
35
|
+
container: Element[],
|
|
36
|
+
/** The body the control is in (the part's). */
|
|
37
|
+
parentBody: Body);
|
|
38
|
+
/** The sdt value. */
|
|
39
|
+
get sdt(): {
|
|
40
|
+
sdtPr?: wml.SdtPr;
|
|
41
|
+
sdtContent?: {
|
|
42
|
+
content?: Element[];
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
/** The control's content array (`w:sdtContent`); empty and detached when the control has none (reads never add one). */
|
|
46
|
+
get content(): Element[];
|
|
47
|
+
/** Which of the four forms this is: block, run, row or cell content. */
|
|
48
|
+
get form(): ContentControlForm;
|
|
49
|
+
/** The type Word reports (w:sdtPr's kind element); RichText when none is given, as Word does. */
|
|
50
|
+
get type(): ContentControlType;
|
|
51
|
+
/** w:tag. */
|
|
52
|
+
get tag(): string;
|
|
53
|
+
set tag(value: string);
|
|
54
|
+
/** w:alias, which is what Word's user interface calls the title. */
|
|
55
|
+
get title(): string;
|
|
56
|
+
set title(value: string);
|
|
57
|
+
/** w:id, the number Word gives a control; 0 when it has none. */
|
|
58
|
+
get id(): number;
|
|
59
|
+
/** The control's text, a line per paragraph (docx4j TextUtils). */
|
|
60
|
+
get text(): string;
|
|
61
|
+
/** Every paragraph in the control; for a run-level control, the paragraph it is in. */
|
|
62
|
+
get paragraphs(): Paragraph[];
|
|
63
|
+
/** The tables directly in the control; for a row or cell control, the table it is part of. */
|
|
64
|
+
get tables(): Table[];
|
|
65
|
+
/** The controls nested in this one, in document order. */
|
|
66
|
+
get contentControls(): ContentControl[];
|
|
67
|
+
/**
|
|
68
|
+
* Text at the start, the end, or replacing the control's text. On a **bound** control the value
|
|
69
|
+
* is written through to the custom XML node as well when the mapping resolves (CR-002 phase E):
|
|
70
|
+
* Word refreshes a bound control from the custom XML part when it opens the document, so an edit
|
|
71
|
+
* that only touched `w:sdtContent` would not show. When the XPath engine is not warm yet the
|
|
72
|
+
* write is left to `pkg.customXmlParts.updateFromContentControls()`.
|
|
73
|
+
*/
|
|
74
|
+
insertText(text: string, location: 'Start' | 'End' | 'Replace'): Range;
|
|
75
|
+
private insertTextInto;
|
|
76
|
+
/** A paragraph at the start or end of a block control; before or after the paragraph of a run control. */
|
|
77
|
+
insertParagraph(text: string, location: 'Start' | 'End' | 'Before' | 'After'): Paragraph;
|
|
78
|
+
/** Matches within the control. */
|
|
79
|
+
search(text: string, options?: SearchOptions): Range[];
|
|
80
|
+
/**
|
|
81
|
+
* The control's range. For a run-level control, exactly the text it holds; for the other forms,
|
|
82
|
+
* the first paragraph (departure: a Range here is within one paragraph, CR-002 section 7).
|
|
83
|
+
*/
|
|
84
|
+
getRange(location?: 'Whole' | 'Start' | 'End' | 'Content'): Range;
|
|
85
|
+
/** Removes the control; `keepContent` puts what it held in its place, as Office JS. */
|
|
86
|
+
delete(keepContent?: boolean): void;
|
|
87
|
+
/** The XML of the control (extension). */
|
|
88
|
+
getXml(): Promise<string>;
|
|
89
|
+
/** A Body view over the control's content, for the block form; the `w:sdtContent` is created if the control has none. */
|
|
90
|
+
private body;
|
|
91
|
+
private property;
|
|
92
|
+
private setProperty;
|
|
93
|
+
/** The paragraph a run-level control is in. */
|
|
94
|
+
private parentParagraph;
|
|
95
|
+
/** The offsets a run-level control covers in its paragraph. */
|
|
96
|
+
private runSpan;
|
|
97
|
+
/** The control's data binding (Office JS `xmlMapping`), backed by `w:dataBinding`. */
|
|
98
|
+
get xmlMapping(): XmlMapping;
|
|
99
|
+
/**
|
|
100
|
+
* The placeholder Word shows for an empty control: the control's own text while it is showing
|
|
101
|
+
* the placeholder (`w:showingPlcHdr`), else '' — Word keeps the text itself in a glossary
|
|
102
|
+
* document part, which this phase does not create (CR-002 section 12). Setting writes the text
|
|
103
|
+
* as the control's content and sets `w:showingPlcHdr`, which is refused when the control holds
|
|
104
|
+
* content of its own, so that a value is never lost.
|
|
105
|
+
*/
|
|
106
|
+
get placeholderText(): string;
|
|
107
|
+
set placeholderText(text: string);
|
|
108
|
+
/** Office JS `appearance`: how Word draws the control (`w15:appearance`). */
|
|
109
|
+
get appearance(): ContentControlAppearance;
|
|
110
|
+
set appearance(value: ContentControlAppearance);
|
|
111
|
+
/** Office JS `color`: the control's colour as '#RRGGBB' (`w15:color`). */
|
|
112
|
+
get color(): string;
|
|
113
|
+
set color(value: string);
|
|
114
|
+
/** Office JS `cannotDelete`: `w:lock` sdtLocked or sdtContentLocked. */
|
|
115
|
+
get cannotDelete(): boolean;
|
|
116
|
+
set cannotDelete(value: boolean);
|
|
117
|
+
/** Office JS `cannotEdit`: `w:lock` contentLocked or sdtContentLocked. */
|
|
118
|
+
get cannotEdit(): boolean;
|
|
119
|
+
set cannotEdit(value: boolean);
|
|
120
|
+
/** Office JS `removeWhenEdited`: `w:temporary`, the control Word drops once it is filled in. */
|
|
121
|
+
get removeWhenEdited(): boolean;
|
|
122
|
+
set removeWhenEdited(value: boolean);
|
|
123
|
+
/** The checkbox view, for a `w14:checkbox` control; undefined for every other kind, as Office JS. */
|
|
124
|
+
get checkboxContentControl(): CheckboxContentControl | undefined;
|
|
125
|
+
/** The date view, for a `w:date` control. */
|
|
126
|
+
get datePickerContentControl(): DatePickerContentControl | undefined;
|
|
127
|
+
/** The list view, for a `w:dropDownList` control. */
|
|
128
|
+
get dropDownListContentControl(): ListContentControl | undefined;
|
|
129
|
+
/** The list view, for a `w:comboBox` control. */
|
|
130
|
+
get comboBoxContentControl(): ListContentControl | undefined;
|
|
131
|
+
/** The picture view, for a `w:picture` control. */
|
|
132
|
+
get pictureContentControl(): PictureContentControl | undefined;
|
|
133
|
+
/** The repeating-section view, for a `w15:repeatingSection` control. */
|
|
134
|
+
get repeatingSectionContentControl(): RepeatingSectionContentControl | undefined;
|
|
135
|
+
/** The group view, for a `w:group` control (Office JS: an object with no members of its own). */
|
|
136
|
+
get groupContentControl(): GroupContentControl | undefined;
|
|
137
|
+
/** Adds or replaces a `w:sdtPr` child (extension). */
|
|
138
|
+
putProperty(element: Element): void;
|
|
139
|
+
/** Removes a `w:sdtPr` child (extension). */
|
|
140
|
+
removeProperty(localPart: string, namespaceURI?: string): void;
|
|
141
|
+
/** The run properties `w:sdtPr/w:rPr` a bound value is written with (docx4j does the same). */
|
|
142
|
+
get runProperties(): wml.RPr | undefined;
|
|
143
|
+
/** Whether a plain-text control accepts several lines (`w:text/@w:multiLine`). */
|
|
144
|
+
get isMultiLine(): boolean;
|
|
145
|
+
/** Whether the control is showing its placeholder rather than a value (`w:showingPlcHdr`). */
|
|
146
|
+
get isShowingPlaceholder(): boolean;
|
|
147
|
+
set isShowingPlaceholder(value: boolean);
|
|
148
|
+
/**
|
|
149
|
+
* Replaces what the control shows with these runs (docx4j BindingHandler's applyBoundContent):
|
|
150
|
+
* into the first paragraph of a block, row or cell control, keeping its `w:pPr`, and in place of
|
|
151
|
+
* the runs of a run-level one.
|
|
152
|
+
*/
|
|
153
|
+
setBoundContent(runs: Element[], showingPlaceholder?: boolean): void;
|
|
154
|
+
/** Shows a checkbox's glyph, as Word writes it: one run in the checkbox font (docx4j checkboxRun). */
|
|
155
|
+
setCheckboxGlyph(symbol: string): void;
|
|
156
|
+
/** A copy of this control right after it, as Word's repeating-section + button does (extension). */
|
|
157
|
+
insertCopyAfter(): ContentControl;
|
|
158
|
+
/**
|
|
159
|
+
* Writes the control's text into the node it is bound to, when there is one and the XPath engine
|
|
160
|
+
* is warm. Silent when it is not: reading a custom XML part is `pkg.customXmlParts.load()`'s job,
|
|
161
|
+
* and `updateFromContentControls()` is the explicit form of this write.
|
|
162
|
+
*/
|
|
163
|
+
private syncBoundNode;
|
|
164
|
+
private firstRunOfContent;
|
|
165
|
+
private lockValue;
|
|
166
|
+
private setLock;
|
|
167
|
+
/** The table a row-level or cell-level control belongs to. */
|
|
168
|
+
private ancestorTable;
|
|
169
|
+
}
|
|
170
|
+
/** Every content control under a list of block-level items, in document order, nested ones included. */
|
|
171
|
+
export declare function collectControls(items: Element[], body: Body, out: ContentControl[]): void;
|
|
172
|
+
/** The run-level controls in a paragraph (or any run holder), in order, nested ones included. */
|
|
173
|
+
export declare function collectRunControls(holder: object, body: Body, out: ContentControl[]): void;
|