@docx4j/core-ts 0.5.0 → 0.6.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/NOTICE +4 -0
- package/README.md +32 -4
- package/dist/html/convert.mjs +2 -1
- package/dist/html/elements.mjs +2 -1
- package/dist/model/color/ColorMath.d.mts +29 -0
- package/dist/model/color/ColorMath.mjs +146 -0
- package/dist/model/color/ColorTables.d.mts +6 -0
- package/dist/model/color/ColorTables.mjs +83 -0
- package/dist/model/color/DrawingMLColors.d.mts +52 -0
- package/dist/model/color/DrawingMLColors.mjs +374 -0
- package/dist/model/color/ResolvedColor.d.mts +36 -0
- package/dist/model/color/ResolvedColor.mjs +65 -0
- package/dist/model/color/SpreadsheetColors.d.mts +36 -0
- package/dist/model/color/SpreadsheetColors.mjs +84 -0
- package/dist/model/color/StyleFill.d.mts +28 -0
- package/dist/model/color/StyleFill.mjs +21 -0
- package/dist/model/color/ThemeColors.d.mts +86 -0
- package/dist/model/color/ThemeColors.mjs +304 -0
- package/dist/model/color/WordColors.d.mts +71 -0
- package/dist/model/color/WordColors.mjs +121 -0
- package/dist/model/color/index.d.mts +6 -0
- package/dist/model/color/index.mjs +30 -0
- package/dist/model/content/Body.d.mts +145 -23
- package/dist/model/content/Body.mjs +509 -141
- package/dist/model/content/Comment.d.mts +21 -3
- package/dist/model/content/Comment.mjs +195 -19
- package/dist/model/content/ContentControl.d.mts +197 -18
- package/dist/model/content/ContentControl.mjs +664 -95
- package/dist/model/content/Font.d.mts +67 -17
- package/dist/model/content/Font.mjs +114 -35
- package/dist/model/content/InlinePicture.d.mts +11 -0
- package/dist/model/content/InlinePicture.mjs +21 -1
- package/dist/model/content/List.mjs +3 -0
- package/dist/model/content/Paragraph.d.mts +189 -13
- package/dist/model/content/Paragraph.mjs +870 -74
- package/dist/model/content/Range.d.mts +227 -12
- package/dist/model/content/Range.mjs +785 -59
- package/dist/model/content/ResolvedView.d.mts +104 -0
- package/dist/model/content/ResolvedView.mjs +596 -0
- package/dist/model/content/Table.d.mts +29 -3
- package/dist/model/content/Table.mjs +109 -33
- package/dist/model/content/TrackedChange.d.mts +172 -13
- package/dist/model/content/TrackedChange.mjs +728 -167
- package/dist/model/content/comments.d.mts +20 -6
- package/dist/model/content/comments.mjs +67 -57
- package/dist/model/content/generalException.d.mts +18 -0
- package/dist/model/content/generalException.mjs +24 -0
- package/dist/model/content/index.d.mts +8 -3
- package/dist/model/content/index.mjs +7 -2
- package/dist/model/content/mathText.d.mts +21 -0
- package/dist/model/content/mathText.mjs +267 -0
- package/dist/model/content/officeText.d.mts +27 -0
- package/dist/model/content/officeText.mjs +74 -0
- package/dist/model/content/outline.d.mts +5 -0
- package/dist/model/content/outline.mjs +13 -0
- package/dist/model/content/placeholders.d.mts +110 -0
- package/dist/model/content/placeholders.mjs +253 -0
- package/dist/model/content/search.d.mts +72 -0
- package/dist/model/content/search.mjs +204 -2
- package/dist/model/content/spanEdits.d.mts +159 -0
- package/dist/model/content/spanEdits.mjs +728 -0
- package/dist/model/content/story.d.mts +44 -0
- package/dist/model/content/story.mjs +92 -0
- package/dist/model/content/tableColumns.d.mts +1 -1
- package/dist/model/content/tableColumns.mjs +108 -80
- package/dist/model/content/tableRevisions.d.mts +11 -3
- package/dist/model/content/tableRevisions.mjs +72 -42
- package/dist/model/content/tableRules.d.mts +30 -0
- package/dist/model/content/tableRules.mjs +100 -0
- package/dist/model/content/textBoxes.d.mts +18 -0
- package/dist/model/content/textBoxes.mjs +105 -0
- package/dist/model/content/trackedChangeFilter.d.mts +39 -0
- package/dist/model/content/trackedChangeFilter.mjs +81 -0
- package/dist/model/content/tracking.d.mts +28 -0
- package/dist/model/content/tracking.mjs +149 -10
- package/dist/model/content/tree.d.mts +171 -22
- package/dist/model/content/tree.mjs +329 -53
- package/dist/model/customxml/CustomXmlPartCollection.d.mts +8 -0
- package/dist/model/customxml/CustomXmlPartCollection.mjs +34 -11
- package/dist/model/customxml/XmlMapping.d.mts +1 -1
- package/dist/model/customxml/XmlMapping.mjs +11 -0
- package/dist/model/customxml/bindings.d.mts +21 -2
- package/dist/model/customxml/bindings.mjs +76 -32
- package/dist/model/customxml/kinds.d.mts +8 -3
- package/dist/model/customxml/kinds.mjs +26 -5
- package/dist/model/customxml/picturePlaceholder.d.mts +17 -0
- package/dist/model/customxml/picturePlaceholder.mjs +32 -0
- package/dist/model/customxml/pictures.d.mts +4 -3
- package/dist/model/customxml/pictures.mjs +18 -6
- package/dist/model/customxml/xhtml.mjs +8 -2
- package/dist/model/index.d.mts +2 -0
- package/dist/model/index.mjs +4 -0
- package/dist/model/listnumbering/Emulator.d.mts +37 -5
- package/dist/model/listnumbering/Emulator.mjs +63 -9
- package/dist/model/properties/PropertyResolver.d.mts +60 -1
- package/dist/model/properties/PropertyResolver.mjs +115 -2
- package/dist/model/properties/catalogue.d.mts +19 -5
- package/dist/model/properties/catalogue.mjs +41 -15
- package/dist/model/properties/log.d.mts +1 -1
- package/dist/model/properties/log.mjs +5 -5
- package/dist/model/properties/table.mjs +4 -2
- package/dist/model/text/Extractor.d.mts +289 -0
- package/dist/model/text/Extractor.mjs +2162 -0
- package/dist/model/text/LinkTargets.d.mts +45 -0
- package/dist/model/text/LinkTargets.mjs +170 -0
- package/dist/model/text/MarkdownExporter.d.mts +140 -0
- package/dist/model/text/MarkdownExporter.mjs +255 -0
- package/dist/model/text/PlainText.d.mts +29 -0
- package/dist/model/text/PlainText.mjs +539 -0
- package/dist/model/text/TextContext.d.mts +161 -0
- package/dist/model/text/TextContext.mjs +425 -0
- package/dist/model/text/TextOptions.d.mts +150 -0
- package/dist/model/text/TextOptions.mjs +278 -0
- package/dist/model/text/TextResult.d.mts +504 -0
- package/dist/model/text/TextResult.mjs +526 -0
- package/dist/model/text/Texts.d.mts +99 -0
- package/dist/model/text/Texts.mjs +187 -0
- package/dist/model/text/WmlToMarkdown.d.mts +120 -0
- package/dist/model/text/WmlToMarkdown.mjs +911 -0
- package/dist/model/text/commonmark.d.mts +121 -0
- package/dist/model/text/commonmark.mjs +655 -0
- package/dist/model/text/index.d.mts +7 -0
- package/dist/model/text/index.mjs +8 -0
- package/dist/model/text/normalize.d.mts +8 -0
- package/dist/model/text/normalize.mjs +13 -0
- package/dist/model/text/outline.d.mts +4 -0
- package/dist/model/text/outline.mjs +71 -0
- package/dist/office-js/fragment.d.mts +7 -5
- package/dist/office-js/fragment.mjs +63 -14
- package/dist/office-js/proxy.d.mts +8 -0
- package/dist/office-js/proxy.mjs +29 -0
- package/dist/office-js/run.mjs +2 -0
- package/dist/office-js/supported.generated.mjs +16 -0
- package/dist/office-js/toApiScript.mjs +21 -5
- package/dist/opc/Save.d.mts +17 -0
- package/dist/opc/Save.mjs +12 -2
- package/dist/opc/index.d.mts +3 -3
- package/dist/opc/index.mjs +1 -1
- package/dist/opc/mce/preprocessor.d.mts +28 -3
- package/dist/opc/mce/preprocessor.mjs +4 -4
- package/dist/opc/mce/understood.d.mts +30 -6
- package/dist/opc/mce/understood.mjs +37 -7
- package/dist/packages/OpcPackage.d.mts +13 -0
- package/dist/packages/OpcPackage.mjs +1 -0
- package/dist/packages/WordprocessingMLPackage.d.mts +45 -8
- package/dist/packages/WordprocessingMLPackage.mjs +155 -20
- package/dist/parts/DefaultXmlPart.mjs +2 -2
- package/dist/parts/Part.d.mts +10 -2
- package/dist/parts/XmlPart.d.mts +12 -30
- package/dist/parts/XmlPart.mjs +44 -93
- package/dist/parts/wml/comments.mjs +30 -0
- package/dist/parts/wml/index.mjs +12 -0
- package/dist/xml/dom.d.mts +7 -0
- package/dist/xml/dom.mjs +18 -0
- package/package.json +2 -2
|
@@ -64,10 +64,27 @@ export declare class Comment {
|
|
|
64
64
|
/** Removes the comment and its replies: the markers, the reference runs and every side-part entry. */
|
|
65
65
|
delete(): Promise<void>;
|
|
66
66
|
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
67
|
+
* @internal `delete()` once the side parts it touches are loaded: public so that a resolution's
|
|
68
|
+
* removals (`flushPendingRemovals`), which load only the parts the document has, take a comment away
|
|
69
|
+
* without creating any (CR-002 section 54).
|
|
69
70
|
*/
|
|
70
|
-
|
|
71
|
+
removeThread(): void;
|
|
72
|
+
/**
|
|
73
|
+
* The commented range: one `Range` from the comment's start to its end, across paragraphs where the comment
|
|
74
|
+
* spans them, as Office JS's `Comment.getRange()` (CR-014 phase 1, D2; check 52: a comment from one paragraph
|
|
75
|
+
* into the next reads `BODY1B\rLIST1A`). A start marker between blocks (Word writes one before a control's
|
|
76
|
+
* first paragraph) starts the range at the next paragraph, and an end marker between blocks ends it at the
|
|
77
|
+
* previous one's end. Undefined when the comment has no markers in this body. `getRanges()` gives the range a
|
|
78
|
+
* paragraph at a time, as this method did before.
|
|
79
|
+
*/
|
|
80
|
+
getRange(): Range | undefined;
|
|
81
|
+
/** Where a range marker stands: its paragraph and offset, a block-level one's the next or the previous paragraph's edge. */
|
|
82
|
+
private anchor;
|
|
83
|
+
/**
|
|
84
|
+
* The commented range a paragraph at a time: a `Range` per paragraph the comment touches (extension; what
|
|
85
|
+
* `getRange()` returned until CR-014 phase 1). Empty when the comment has no markers in this body.
|
|
86
|
+
*/
|
|
87
|
+
getRanges(): Range[];
|
|
71
88
|
/** This comment and, depth first, its replies. */
|
|
72
89
|
private thread;
|
|
73
90
|
private removeSelf;
|
|
@@ -108,6 +125,7 @@ export declare function commentsOf(scope: Body | Paragraph | Range): Promise<Com
|
|
|
108
125
|
* Comments whose anchored text went with a rejected insertion or an accepted deletion (check 32;
|
|
109
126
|
* `TrackedChange`'s `removeRevision`) had their markers removed then; their entries go here, with
|
|
110
127
|
* their replies, when the comments are next read or the package is saved (`WordprocessingMLPackage.saveTo`).
|
|
128
|
+
* With the last comment, the comment parts go too (`flushPendingRemovals`).
|
|
111
129
|
*/
|
|
112
130
|
export declare function flushPendingCommentRemovals(body: Body): Promise<void>;
|
|
113
131
|
export type { CommentParts, Author } from './comments.mjs';
|
|
@@ -2,12 +2,14 @@ import * as el from '@docx4j/generated-objects-ts/el/org_docx4j_wml';
|
|
|
2
2
|
import * as wmlFactory from '@docx4j/generated-objects-ts/factory/org_docx4j_wml';
|
|
3
3
|
import * as w15Factory from '@docx4j/generated-objects-ts/factory/org_docx4j_w15';
|
|
4
4
|
import * as w16cidFactory from '@docx4j/generated-objects-ts/factory/org_docx4j_w16cid';
|
|
5
|
-
import {
|
|
5
|
+
import { applyRunOptions, linkParents } from '@docx4j/generated-objects-ts/builders/wml';
|
|
6
|
+
import { oneParagraphRun } from './officeText.mjs';
|
|
6
7
|
import { Docx4JException } from '../../opc/exceptions.mjs';
|
|
7
8
|
import { Body } from './Body.mjs';
|
|
8
9
|
import { Paragraph } from './Paragraph.mjs';
|
|
9
10
|
import { Range } from './Range.mjs';
|
|
10
|
-
import { runOf, paragraphOf, typeNameOf } from './tree.mjs';
|
|
11
|
+
import { runOf, paragraphOf, typeNameOf, selectedBranchOf, BRANCH_TYPES } from './tree.mjs';
|
|
12
|
+
import { storyLayout } from './story.mjs';
|
|
11
13
|
import { revisionDateOf, wordCalendarOf, copyRPr } from './tracking.mjs';
|
|
12
14
|
import { relationshipIdsIn, queueRelationshipRemovals } from './relationships.mjs';
|
|
13
15
|
import { COMMENT_REFERENCE_STYLE, COMMENT_TEXT_STYLE, commentExOf, commentIdsOf, commentPartsAccess, commentParaId, initialsOf, isDone, markersOf, markersOfParagraph, nextCommentId, paraIdTaken, randomHexId, removeMarkers, setCommentApi, } from './comments.mjs';
|
|
@@ -78,11 +80,13 @@ export class Comment {
|
|
|
78
80
|
}
|
|
79
81
|
/** The comment's text, a paragraph per line; setting it replaces the paragraphs. */
|
|
80
82
|
get content() {
|
|
83
|
+
// Office JS's comment.content: its body's text, the paragraphs a mark \r apart (check 51)
|
|
81
84
|
return this.commentBody.text;
|
|
82
85
|
}
|
|
83
86
|
set content(text) {
|
|
84
87
|
const paraId = commentParaId(this.element);
|
|
85
|
-
|
|
88
|
+
// a paragraph per line, \r (as the getter gives it) or \n
|
|
89
|
+
const paragraphs = text.split(/\r\n|\r|\n/).map((line, i) => commentParagraph(line, i === 0));
|
|
86
90
|
if (paraId)
|
|
87
91
|
paragraphs[0].value.paraId = paraId;
|
|
88
92
|
this.element.content = paragraphs;
|
|
@@ -136,6 +140,14 @@ export class Comment {
|
|
|
136
140
|
/** Removes the comment and its replies: the markers, the reference runs and every side-part entry. */
|
|
137
141
|
async delete() {
|
|
138
142
|
await this.parts.ensureAll();
|
|
143
|
+
this.removeThread();
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* @internal `delete()` once the side parts it touches are loaded: public so that a resolution's
|
|
147
|
+
* removals (`flushPendingRemovals`), which load only the parts the document has, take a comment away
|
|
148
|
+
* without creating any (CR-002 section 54).
|
|
149
|
+
*/
|
|
150
|
+
removeThread() {
|
|
139
151
|
for (const comment of this.thread())
|
|
140
152
|
comment.removeSelf();
|
|
141
153
|
if (this.parentComment) {
|
|
@@ -146,12 +158,57 @@ export class Comment {
|
|
|
146
158
|
}
|
|
147
159
|
}
|
|
148
160
|
/**
|
|
149
|
-
* The commented range:
|
|
150
|
-
*
|
|
161
|
+
* The commented range: one `Range` from the comment's start to its end, across paragraphs where the comment
|
|
162
|
+
* spans them, as Office JS's `Comment.getRange()` (CR-014 phase 1, D2; check 52: a comment from one paragraph
|
|
163
|
+
* into the next reads `BODY1B\rLIST1A`). A start marker between blocks (Word writes one before a control's
|
|
164
|
+
* first paragraph) starts the range at the next paragraph, and an end marker between blocks ends it at the
|
|
165
|
+
* previous one's end. Undefined when the comment has no markers in this body. `getRanges()` gives the range a
|
|
166
|
+
* paragraph at a time, as this method did before.
|
|
151
167
|
*/
|
|
152
168
|
getRange() {
|
|
169
|
+
const markers = markersOf(this.body.container, (p) => this.body.hiddenRuns(p)).filter((m) => m.id === this.id);
|
|
170
|
+
const start = markers.find((m) => m.kind === 'start');
|
|
171
|
+
const end = [...markers].reverse().find((m) => m.kind === 'end');
|
|
172
|
+
const from = start && this.anchor(start, 'start');
|
|
173
|
+
const to = end && this.anchor(end, 'end');
|
|
174
|
+
if (!from || !to)
|
|
175
|
+
return this.getRanges()[0];
|
|
176
|
+
const paragraphs = this.body.paragraphs;
|
|
177
|
+
const a = paragraphs.findIndex((p) => p.element === from.paragraph.element);
|
|
178
|
+
const b = paragraphs.findIndex((p) => p.element === to.paragraph.element);
|
|
179
|
+
if (a < 0 || b < 0 || b < a || (a === b && to.offset < from.offset))
|
|
180
|
+
return this.getRanges()[0];
|
|
181
|
+
return a === b ? new Range(from.paragraph, from.offset, to.offset)
|
|
182
|
+
: new Range(from.paragraph, from.offset, to.offset, false, false, to.paragraph);
|
|
183
|
+
}
|
|
184
|
+
/** Where a range marker stands: its paragraph and offset, a block-level one's the next or the previous paragraph's edge. */
|
|
185
|
+
anchor(marker, side) {
|
|
186
|
+
var _a;
|
|
187
|
+
if (marker.paragraph && marker.paragraphContainer) {
|
|
188
|
+
const paragraph = new Paragraph(marker.paragraph, marker.paragraphContainer, this.body);
|
|
189
|
+
return { paragraph, offset: (_a = marker.offset) !== null && _a !== void 0 ? _a : (side === 'start' ? 0 : paragraph.text.length) };
|
|
190
|
+
}
|
|
191
|
+
const at = marker.owner.indexOf(marker.item);
|
|
192
|
+
if (at < 0)
|
|
193
|
+
return undefined;
|
|
194
|
+
const blocks = side === 'start' ? marker.owner.slice(at + 1) : marker.owner.slice(0, at).reverse();
|
|
195
|
+
for (const block of blocks) {
|
|
196
|
+
const found = storyLayout([block], () => '').paragraphs;
|
|
197
|
+
const sp = side === 'start' ? found[0] : found[found.length - 1];
|
|
198
|
+
if (!sp)
|
|
199
|
+
continue;
|
|
200
|
+
const paragraph = new Paragraph(sp.element, sp.container, this.body);
|
|
201
|
+
return { paragraph, offset: side === 'start' ? 0 : paragraph.text.length };
|
|
202
|
+
}
|
|
203
|
+
return undefined;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* The commented range a paragraph at a time: a `Range` per paragraph the comment touches (extension; what
|
|
207
|
+
* `getRange()` returned until CR-014 phase 1). Empty when the comment has no markers in this body.
|
|
208
|
+
*/
|
|
209
|
+
getRanges() {
|
|
153
210
|
var _a, _b, _c, _d;
|
|
154
|
-
const markers = markersOf(this.body.container).filter((m) => m.id === this.id && m.paragraph !== undefined);
|
|
211
|
+
const markers = markersOf(this.body.container, (p) => this.body.hiddenRuns(p)).filter((m) => m.id === this.id && m.paragraph !== undefined);
|
|
155
212
|
if (markers.length === 0)
|
|
156
213
|
return [];
|
|
157
214
|
const paragraphs = this.body.paragraphs;
|
|
@@ -292,11 +349,14 @@ function nestedIndex(owner, index) {
|
|
|
292
349
|
}
|
|
293
350
|
/** A paragraph of a comment: the `CommentText` style, opened by the annotation reference run. */
|
|
294
351
|
function commentParagraph(text, first) {
|
|
352
|
+
var _a;
|
|
295
353
|
const runs = [];
|
|
296
354
|
if (first)
|
|
297
355
|
runs.push(annotationRefRun());
|
|
298
|
-
|
|
299
|
-
|
|
356
|
+
// its line's characters as they read (CR-002 section 60 D1, E3); a line break is a paragraph of its own (D5)
|
|
357
|
+
const run = oneParagraphRun(text);
|
|
358
|
+
if ((_a = run.value.content) === null || _a === void 0 ? void 0 : _a.length)
|
|
359
|
+
runs.push(run);
|
|
300
360
|
return paragraphOf(runs, { TYPE_NAME: 'org_docx4j_wml.PPr', pStyle: { val: COMMENT_TEXT_STYLE } });
|
|
301
361
|
}
|
|
302
362
|
function insertAt(owner, index, items, parent) {
|
|
@@ -307,6 +367,18 @@ function insertAt(owner, index, items, parent) {
|
|
|
307
367
|
function parentOf(element) {
|
|
308
368
|
return element.value.PARENT;
|
|
309
369
|
}
|
|
370
|
+
/** The innermost branch of a kept `mc:AlternateContent` no reader takes that holds a value, or undefined. */
|
|
371
|
+
function unreadBranchOf(value) {
|
|
372
|
+
for (let o = value.PARENT, guard = 0; o && guard < 256; o = o.PARENT, guard++) {
|
|
373
|
+
const tn = o.TYPE_NAME;
|
|
374
|
+
if (tn === undefined || !BRANCH_TYPES.has(tn))
|
|
375
|
+
continue;
|
|
376
|
+
const ac = o.PARENT;
|
|
377
|
+
if (ac && selectedBranchOf(ac) !== o.any)
|
|
378
|
+
return o;
|
|
379
|
+
}
|
|
380
|
+
return undefined;
|
|
381
|
+
}
|
|
310
382
|
/**
|
|
311
383
|
* Where a marker for this segment's run goes when it is not put inside the revision the run sits
|
|
312
384
|
* in (`placeAround`): beside the run, but outside the `w:ins` or `w:del`, so that a comment made
|
|
@@ -323,10 +395,17 @@ function markerSite(seg, fallback, after) {
|
|
|
323
395
|
function placeAround(range, id) {
|
|
324
396
|
var _a;
|
|
325
397
|
var _b;
|
|
398
|
+
if (range.spansParagraphs) {
|
|
399
|
+
placeAcross(range, id);
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
326
402
|
const paragraph = range.paragraph;
|
|
327
|
-
|
|
403
|
+
// a run holding the span holds nothing else, a tab or a break beside it moved out too, as `font` splits (until
|
|
404
|
+
// CR-014 phase 3 only the w:t were split, and a marker went beside the whole run, widening the anchor)
|
|
328
405
|
if (range.end > range.start)
|
|
329
|
-
paragraph.
|
|
406
|
+
paragraph.splitRunsAround(range.start, range.end);
|
|
407
|
+
else
|
|
408
|
+
paragraph.splitAt(range.start);
|
|
330
409
|
const covered = range.end > range.start ? paragraph.segments().filter((s) => s.end > range.start && s.start < range.end) : [];
|
|
331
410
|
const start = el.commentRangeStart(wmlFactory.createCommentRangeStart({ id }));
|
|
332
411
|
const end = el.commentRangeEnd(wmlFactory.createCommentRangeEnd({ id }));
|
|
@@ -369,16 +448,90 @@ function placeAround(range, id) {
|
|
|
369
448
|
insertAt(before.owner, before.index, [start], before.parent);
|
|
370
449
|
}
|
|
371
450
|
}
|
|
451
|
+
/**
|
|
452
|
+
* The markers of a comment over a range across paragraphs, as Word writes them (check 52, cases 79 to 85; CR-014
|
|
453
|
+
* phase 3): the start before the range's first character, in its first paragraph, and the end and the reference
|
|
454
|
+
* run after its last character, in its last paragraph, before a mark the range holds. A table between, or a cell
|
|
455
|
+
* either end is in, stays as it is: the markers stand in the paragraphs. On a block control's content range Word
|
|
456
|
+
* put the start before the control's first paragraph, in `w:sdtContent` (case 82); here it is inside that
|
|
457
|
+
* paragraph, which reads the same (CR-014 section 9.2). An insertion at either end is treated as `placeAround`
|
|
458
|
+
* treats one: the start inside it, before the first commented run; the end after the last, the rest of the
|
|
459
|
+
* insertion split off.
|
|
460
|
+
*/
|
|
461
|
+
function placeAcross(range, id) {
|
|
462
|
+
var _a, _b, _c, _d, _e;
|
|
463
|
+
var _f, _g;
|
|
464
|
+
const first = range.paragraph;
|
|
465
|
+
const last = range.endParagraph;
|
|
466
|
+
const start = el.commentRangeStart(wmlFactory.createCommentRangeStart({ id }));
|
|
467
|
+
const end = el.commentRangeEnd(wmlFactory.createCommentRangeEnd({ id }));
|
|
468
|
+
const reference = referenceRun(id);
|
|
469
|
+
// the end first; the two are in different paragraphs, so neither's offsets move with the other's markers. The
|
|
470
|
+
// runs are split as `font` splits them, so a marker never goes beside a run holding text outside the range
|
|
471
|
+
if (range.end > 0)
|
|
472
|
+
last.splitRunsAround(0, range.end);
|
|
473
|
+
const before = last.segments().filter((s) => s.start < range.end);
|
|
474
|
+
const lastSeg = before[before.length - 1];
|
|
475
|
+
if (((_a = lastSeg === null || lastSeg === void 0 ? void 0 : lastSeg.revision) === null || _a === void 0 ? void 0 : _a.kind) === 'ins') {
|
|
476
|
+
last.splitHolderAround(lastSeg.revision, lastSeg.runIndex + 1, [end, reference], () => last.nextAnnotationId());
|
|
477
|
+
}
|
|
478
|
+
else if (lastSeg) {
|
|
479
|
+
const site = markerSite(lastSeg, last.p, true);
|
|
480
|
+
insertAt(site.owner, site.index, [end, reference], site.parent);
|
|
481
|
+
}
|
|
482
|
+
else {
|
|
483
|
+
// nothing of the last paragraph in the range: the end at its start
|
|
484
|
+
const next = last.segments()[0];
|
|
485
|
+
const site = next ? markerSite(next, last.p, false) : { owner: ((_b = (_f = last.p).content) !== null && _b !== void 0 ? _b : (_f.content = [])), index: 0, parent: last.p };
|
|
486
|
+
insertAt(site.owner, site.index, [end, reference], site.parent);
|
|
487
|
+
}
|
|
488
|
+
if (range.start < first.text.length)
|
|
489
|
+
first.splitRunsAround(range.start, first.text.length);
|
|
490
|
+
const segments = first.segments();
|
|
491
|
+
const firstSeg = segments.find((s) => s.end > range.start);
|
|
492
|
+
if (((_c = firstSeg === null || firstSeg === void 0 ? void 0 : firstSeg.revision) === null || _c === void 0 ? void 0 : _c.kind) === 'ins')
|
|
493
|
+
insertAt(firstSeg.runOwner, firstSeg.runIndex, [start], firstSeg.revision.value);
|
|
494
|
+
else if (firstSeg) {
|
|
495
|
+
const site = markerSite(firstSeg, first.p, false);
|
|
496
|
+
insertAt(site.owner, site.index, [start], site.parent);
|
|
497
|
+
}
|
|
498
|
+
else {
|
|
499
|
+
// nothing of the first paragraph in the range: the start at its end
|
|
500
|
+
const previous = segments[segments.length - 1];
|
|
501
|
+
const site = previous ? markerSite(previous, first.p, true) : { owner: ((_d = (_g = first.p).content) !== null && _d !== void 0 ? _d : (_g.content = [])), index: ((_e = first.p.content) !== null && _e !== void 0 ? _e : []).length, parent: first.p };
|
|
502
|
+
insertAt(site.owner, site.index, [start], site.parent);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
372
505
|
/** Writes the markers of a reply next to its parent's, as Word nests them. */
|
|
373
506
|
function placeAfter(body, parentId, id) {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
const
|
|
378
|
-
|
|
507
|
+
var _a;
|
|
508
|
+
// the parent's markers in every branch of a kept mc:AlternateContent, each branch no reader takes
|
|
509
|
+
// apart, so that the reply is anchored in each as its parent is (CR-013 phase 3)
|
|
510
|
+
const groups = new Map();
|
|
511
|
+
for (const marker of markersOf(body.container, undefined, 'every')) {
|
|
512
|
+
if (marker.id !== parentId)
|
|
513
|
+
continue;
|
|
514
|
+
const key = unreadBranchOf(marker.item.value);
|
|
515
|
+
let group = groups.get(key);
|
|
516
|
+
if (!group)
|
|
517
|
+
groups.set(key, group = []);
|
|
518
|
+
group.push(marker);
|
|
519
|
+
}
|
|
520
|
+
const read = (_a = groups.get(undefined)) !== null && _a !== void 0 ? _a : [];
|
|
521
|
+
if (!read.some((m) => (m.kind === 'reference' && m.run && m.runOwner) || m.kind === 'end')) {
|
|
379
522
|
// refused before anything is written, so that no marker is left naming a comment never made
|
|
380
523
|
throw new Docx4JException(`Comment ${parentId} has no markers in this body; cannot anchor a reply`);
|
|
381
524
|
}
|
|
525
|
+
for (const markers of groups.values())
|
|
526
|
+
placeAfterIn(markers, id);
|
|
527
|
+
}
|
|
528
|
+
/** A reply's markers after its parent's, in one branch's markers (or those outside any no reader takes). */
|
|
529
|
+
function placeAfterIn(markers, id) {
|
|
530
|
+
const start = markers.find((m) => m.kind === 'start');
|
|
531
|
+
const end = [...markers].reverse().find((m) => m.kind === 'end');
|
|
532
|
+
const reference = [...markers].reverse().find((m) => m.kind === 'reference');
|
|
533
|
+
if (!((reference === null || reference === void 0 ? void 0 : reference.run) && reference.runOwner) && !end)
|
|
534
|
+
return;
|
|
382
535
|
if (start)
|
|
383
536
|
insertAt(start.owner, start.owner.indexOf(start.item) + 1, [el.commentRangeStart(wmlFactory.createCommentRangeStart({ id }))], parentOf(start.item));
|
|
384
537
|
if (end)
|
|
@@ -513,8 +666,9 @@ function commentId(parts, body, options) {
|
|
|
513
666
|
}
|
|
514
667
|
/** The paragraphs of a comment's content: a string splits on newlines, elements are taken as they are. */
|
|
515
668
|
function paragraphsOfContent(content) {
|
|
669
|
+
// a paragraph per line, at \r, \n or \r\n, as Word's comments take them (CR-002 section 60 D5, check 55)
|
|
516
670
|
if (typeof content === 'string')
|
|
517
|
-
return content.split(
|
|
671
|
+
return content.split(/\r\n|\r|\n/).map((line, i) => commentParagraph(line, i === 0));
|
|
518
672
|
const paragraphs = [...content];
|
|
519
673
|
if (paragraphs.length === 0)
|
|
520
674
|
throw new Docx4JException('A comment needs at least one paragraph');
|
|
@@ -549,6 +703,7 @@ export async function commentsOf(scope) {
|
|
|
549
703
|
* Comments whose anchored text went with a rejected insertion or an accepted deletion (check 32;
|
|
550
704
|
* `TrackedChange`'s `removeRevision`) had their markers removed then; their entries go here, with
|
|
551
705
|
* their replies, when the comments are next read or the package is saved (`WordprocessingMLPackage.saveTo`).
|
|
706
|
+
* With the last comment, the comment parts go too (`flushPendingRemovals`).
|
|
552
707
|
*/
|
|
553
708
|
export async function flushPendingCommentRemovals(body) {
|
|
554
709
|
var _a;
|
|
@@ -562,18 +717,39 @@ export async function flushPendingCommentRemovals(body) {
|
|
|
562
717
|
}
|
|
563
718
|
await flushPendingRemovals(body, parts);
|
|
564
719
|
}
|
|
720
|
+
/**
|
|
721
|
+
* The entries of the comments a resolution took away, replies included. The side parts the document
|
|
722
|
+
* has are loaded for it and none is created: before section 54 a removal created the commentsExtended,
|
|
723
|
+
* commentsIds and people parts a document lacked, as `delete()` does.
|
|
724
|
+
*
|
|
725
|
+
* With the last comment a resolution takes away, the comment parts go, as Word 365 removed them
|
|
726
|
+
* (docx4j CR-043 section 15; docx4j-python's artefact 8 rejected, docx4j's U22, core-ts check 32): the
|
|
727
|
+
* comments part and its commentsExtended, commentsIds and commentsExtensible parts, with their
|
|
728
|
+
* relationships; and the people part where no tracked change is left to name an author (U22: Word kept
|
|
729
|
+
* it while a deletion was still tracked). docx4j decides when its resolution ends; this, when the
|
|
730
|
+
* entries go, so tracked changes made or resolved in between count.
|
|
731
|
+
*/
|
|
565
732
|
async function flushPendingRemovals(body, parts) {
|
|
733
|
+
var _a;
|
|
566
734
|
const pkg = body.package_;
|
|
567
735
|
const pending = pkg === null || pkg === void 0 ? void 0 : pkg.pendingCommentRemovals;
|
|
568
736
|
if (!(pending === null || pending === void 0 ? void 0 : pending.size))
|
|
569
737
|
return;
|
|
738
|
+
await parts.loadExisting();
|
|
570
739
|
const views = viewsOf(parts, body);
|
|
740
|
+
let removed = false;
|
|
571
741
|
for (const id of [...pending]) {
|
|
572
742
|
const view = views.get(id);
|
|
573
|
-
if (view)
|
|
574
|
-
|
|
743
|
+
if (view) {
|
|
744
|
+
view.removeThread();
|
|
745
|
+
removed = true;
|
|
746
|
+
}
|
|
575
747
|
pending.delete(id);
|
|
576
748
|
}
|
|
749
|
+
if (!removed || ((_a = parts.comments.comment) !== null && _a !== void 0 ? _a : []).length > 0)
|
|
750
|
+
return;
|
|
751
|
+
const people = parts.people !== undefined && (pkg === null || pkg === void 0 ? void 0 : pkg.getAllTrackedChanges) !== undefined && (await pkg.getAllTrackedChanges()).length === 0;
|
|
752
|
+
parts.drop(people);
|
|
577
753
|
}
|
|
578
754
|
/** A `Comment` view per entry in the parts, replies linked to their parents. */
|
|
579
755
|
function viewsOf(parts, body) {
|
|
@@ -602,7 +778,7 @@ function idsInRange(range) {
|
|
|
602
778
|
var _a;
|
|
603
779
|
const spans = new Map();
|
|
604
780
|
const order = [];
|
|
605
|
-
for (const marker of markersOfParagraph(range.paragraph.element, range.paragraph.container)) {
|
|
781
|
+
for (const marker of markersOfParagraph(range.paragraph.element, range.paragraph.container, range.paragraph.hiddenRuns())) {
|
|
606
782
|
const at = (_a = marker.offset) !== null && _a !== void 0 ? _a : 0;
|
|
607
783
|
const span = spans.get(marker.id);
|
|
608
784
|
if (span) {
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type * as wml from '@docx4j/generated-objects-ts/modules/org_docx4j_wml';
|
|
2
2
|
import { XmlMapping } from '../customxml/XmlMapping.mjs';
|
|
3
3
|
import { CheckboxContentControl, DatePickerContentControl, ListContentControl, PictureContentControl, RepeatingSectionContentControl, GroupContentControl } from '../customxml/kinds.mjs';
|
|
4
|
+
import { type LineBreaks } from './officeText.mjs';
|
|
5
|
+
import { type DefaultEntry } from './placeholders.mjs';
|
|
4
6
|
import { type SdtKind } from '@docx4j/generated-objects-ts/builders/wml';
|
|
5
|
-
import { type Element } from './tree.mjs';
|
|
7
|
+
import { type Element, type BranchMode } from './tree.mjs';
|
|
6
8
|
import type { Body } from './Body.mjs';
|
|
7
9
|
import type { Paragraph } from './Paragraph.mjs';
|
|
8
10
|
import { Range } from './Range.mjs';
|
|
@@ -56,7 +58,11 @@ export declare class ContentControl {
|
|
|
56
58
|
set title(value: string);
|
|
57
59
|
/** w:id, the number Word gives a control; 0 when it has none. */
|
|
58
60
|
get id(): number;
|
|
59
|
-
/**
|
|
61
|
+
/**
|
|
62
|
+
* The control's text as Office JS gives it (CR-012 phase 4): a run-level control's span of
|
|
63
|
+
* `Paragraph.text`; a block-level one's content as `Body.text` reads it, its paragraphs a mark `\r` apart
|
|
64
|
+
* (check 51); a row control's cells a `\t` apart and a cell control's paragraphs `\r` apart (check 53).
|
|
65
|
+
*/
|
|
60
66
|
get text(): string;
|
|
61
67
|
/** Every paragraph in the control; for a run-level control, the paragraph it is in. */
|
|
62
68
|
get paragraphs(): Paragraph[];
|
|
@@ -64,6 +70,12 @@ export declare class ContentControl {
|
|
|
64
70
|
get tables(): Table[];
|
|
65
71
|
/** The controls nested in this one, in document order. */
|
|
66
72
|
get contentControls(): ContentControl[];
|
|
73
|
+
/**
|
|
74
|
+
* Office JS `getContentControls` (WordApi 1.5): the content controls `contentControls` lists, those of `options.types`
|
|
75
|
+
* where given. Word's `contentControls` lists rich-text controls only; this package's lists every kind, a recorded
|
|
76
|
+
* departure (CR-002 section 60 G1, check 55b), so this is how add-in code that asks for plain-text controls finds them.
|
|
77
|
+
*/
|
|
78
|
+
getContentControls(options?: ContentControlOptions): ContentControl[];
|
|
67
79
|
/**
|
|
68
80
|
* Text at the start, the end, or replacing the control's text. On a **bound** control the value
|
|
69
81
|
* is written through to the custom XML node as well when the mapping resolves (CR-002 phase E):
|
|
@@ -72,17 +84,112 @@ export declare class ContentControl {
|
|
|
72
84
|
* write is left to `pkg.customXmlParts.updateFromContentControls()`.
|
|
73
85
|
*/
|
|
74
86
|
insertText(text: string, location: 'Start' | 'End' | 'Replace'): Range;
|
|
87
|
+
/**
|
|
88
|
+
* The glossary entry the control's `w:placeholder` names, which makes it Word's form; undefined where it names none,
|
|
89
|
+
* the bare form, which has no entry to show once emptied, nor for `placeholderText` to read (CR-002 section 63; an
|
|
90
|
+
* extension). Writes are the same in both forms (check 63's run 2).
|
|
91
|
+
*/
|
|
92
|
+
get placeholderEntry(): string | undefined;
|
|
93
|
+
/** @internal True for a block or run-level control showing its placeholder, which a text write replaces (section 63). */
|
|
94
|
+
get showsPlaceholderContent(): boolean;
|
|
95
|
+
/** The package's glossary entries, where the control is in a package. */
|
|
96
|
+
private get glossary();
|
|
97
|
+
/**
|
|
98
|
+
* @internal Text written into the content of this control while it shows its placeholder, by any route: its own
|
|
99
|
+
* `insertText`, its 'Content' range's, a block control's paragraph's (CR-002 section 63, D1, D2 (b), D5, D11). The
|
|
100
|
+
* placeholder is no content, in either form (checks 64 and 67, check 63's run 2): its runs go, untracked, the text takes
|
|
101
|
+
* their place in one paragraph, and the flag is cleared; under tracking only the insertion is recorded. The text takes
|
|
102
|
+
* the control's own run properties (`w:sdtPr/w:rPr`) and nothing of the placeholder's (check 68, cases 1 to 20).
|
|
103
|
+
*/
|
|
104
|
+
writePlaceholder(text: string, options?: {
|
|
105
|
+
lineBreaks?: LineBreaks;
|
|
106
|
+
}): Range;
|
|
107
|
+
/** The control's first paragraph, made where its content has none. */
|
|
108
|
+
private firstParagraph;
|
|
109
|
+
/**
|
|
110
|
+
* Takes the placeholder's runs out of the content: a run-level control's, or a block control's paragraphs', the first
|
|
111
|
+
* paragraph kept, emptied, and any other going. What held them.
|
|
112
|
+
*/
|
|
113
|
+
private takePlaceholderRuns;
|
|
114
|
+
/**
|
|
115
|
+
* Shows Word's filler for a control emptied in the bare form, where no glossary entry gives it a placeholder: the flag
|
|
116
|
+
* on over a run of five spaces, in the control's own run properties (CR-002 section 63, D10; check 63's run 2, cases 6,
|
|
117
|
+
* 17, 32 and 43, and check 52's case 13). Nothing is marked under tracking. The spaces read as no text while the flag is
|
|
118
|
+
* on (CR-012 section 18).
|
|
119
|
+
*/
|
|
120
|
+
private showFiller;
|
|
121
|
+
/**
|
|
122
|
+
* @internal A write through the control's 'Content' or 'Whole' range that the control takes (D3, D4): text into a
|
|
123
|
+
* control showing its placeholder, or into an empty run-level control, goes inside it; a 'Whole' range's Replace over
|
|
124
|
+
* a run-level control showing its placeholder takes the control, the text in its place. Undefined where the range's
|
|
125
|
+
* own write applies.
|
|
126
|
+
*/
|
|
127
|
+
writeThrough(part: 'Content' | 'Whole', text: string, location: string): Range | undefined;
|
|
128
|
+
/**
|
|
129
|
+
* @internal A delete through the control's 'Content' or 'Whole' range that the control takes; false where the range's
|
|
130
|
+
* own delete applies. A 'Content' delete of a control showing its placeholder keeps the control and the flag: in the
|
|
131
|
+
* bare form over Word's filler, five spaces (D10; check 63's run 2, cases 6, 17, 32 and 43, nothing marked under
|
|
132
|
+
* tracking); in Word's form nothing changes, the placeholder being no content. A 'Whole' delete takes a run-level
|
|
133
|
+
* control showing its placeholder (D3).
|
|
134
|
+
*/
|
|
135
|
+
deleteThrough(part: 'Content' | 'Whole'): boolean;
|
|
136
|
+
/**
|
|
137
|
+
* @internal After a 'Content' delete, untracked, that left the control holding no text: in Word's form it shows its
|
|
138
|
+
* entry again (check 66 case 3); in the bare form Word's filler (D10; check 52's case 13), as for a control of a kind
|
|
139
|
+
* Word gives no default entry, naming an entry the glossary lacks.
|
|
140
|
+
*/
|
|
141
|
+
showEmptied(): void;
|
|
142
|
+
/**
|
|
143
|
+
* @internal Word's default placeholder entry for this control's kind (CR-002 section 63.22; docx4j CR-063's D8): the
|
|
144
|
+
* text kinds', the date picker's, the lists', a building block gallery's, a repeating section item's. Undefined for a
|
|
145
|
+
* kind Word gives none.
|
|
146
|
+
*/
|
|
147
|
+
get defaultPlaceholderEntry(): DefaultEntry | undefined;
|
|
148
|
+
/**
|
|
149
|
+
* @internal Whether an empty control shows a placeholder in Word's form (D8; docx4j CR-063's D3 and D8): a kind Word
|
|
150
|
+
* gives a default entry, or one naming an entry the glossary holds.
|
|
151
|
+
*/
|
|
152
|
+
get showsWordsFormPlaceholder(): boolean;
|
|
153
|
+
/**
|
|
154
|
+
* @internal Takes the control whole (D3): a Replace or delete over a control showing its placeholder, as Word takes one
|
|
155
|
+
* (check 63 cases 12, 18 to 20, 26, 38, 44 to 46 and 52). Untracked it goes, a block control leaving its paragraph,
|
|
156
|
+
* emptied, in its place; tracked it is marked deleted in Word's form (`markHolderDeleted`: `w:customXmlDelRange`
|
|
157
|
+
* markers around it and inside its content), its placeholder gone unmarked and the flag cleared (check 63's run 2,
|
|
158
|
+
* cases 38, 44 to 46 and 52). `text` goes where a run-level control stood, before it under tracking, as Word puts a
|
|
159
|
+
* Replace's insertion first.
|
|
160
|
+
*/
|
|
161
|
+
takeWhole(text?: string): Range;
|
|
162
|
+
/** The control marked deleted with Word's markers, its placeholder gone, unmarked, and the flag cleared (`takeWhole`). */
|
|
163
|
+
private markWholeDeleted;
|
|
164
|
+
/**
|
|
165
|
+
* Shows the control's placeholder (CR-002 section 63, D8; section 63.18): a copy of the content of the entry its
|
|
166
|
+
* `w:placeholder` names, as the glossary holds it, the control's own run properties not over it, as Word shows it
|
|
167
|
+
* (check 68, section 63.21), with `w:showingPlcHdr`. A control naming no entry, or one the glossary lacks, is made to
|
|
168
|
+
* name Word's default entry for its kind (section 63.22: a date picker's is "Click or tap to enter a date.", a list's
|
|
169
|
+
* "Choose an item."), which is written into the glossary on save where it lacks it (D9), as docx4j's CR-063 has it:
|
|
170
|
+
* Word's save drops a reference no entry holds (check 65). A kind Word gives no default entry (a picture, a check box)
|
|
171
|
+
* keeps the name it has, and naming none shows docx4j's run, with no reference; any control keeps its name until the
|
|
172
|
+
* glossary is read (`getBody`, `Word.run`), showing its kind's default text. An extension.
|
|
173
|
+
*/
|
|
174
|
+
showPlaceholder(): void;
|
|
75
175
|
private insertTextInto;
|
|
76
176
|
/** A paragraph at the start or end of a block control; before or after the paragraph of a run control. */
|
|
77
177
|
insertParagraph(text: string, location: 'Start' | 'End' | 'Before' | 'After'): Paragraph;
|
|
78
178
|
/** Matches within the control. */
|
|
79
179
|
search(text: string, options?: SearchOptions): Range[];
|
|
80
180
|
/**
|
|
81
|
-
* The control's range. For a run-level control, exactly the text it holds; for the other forms,
|
|
82
|
-
* the first
|
|
181
|
+
* The control's range. For a run-level control, exactly the text it holds; for the other forms, its
|
|
182
|
+
* paragraphs: one `Range` from the first one's start to the last one's end (CR-014 phase 1), its 'Whole'
|
|
183
|
+
* ending with the last one's mark, as Office JS's does (check 51: `CCP1\rCCP2\rCCP3\r`, its 'Content'
|
|
184
|
+
* without the last `\r`).
|
|
83
185
|
*/
|
|
84
186
|
getRange(location?: 'Whole' | 'Start' | 'End' | 'Content'): Range;
|
|
85
|
-
|
|
187
|
+
private rangeOf;
|
|
188
|
+
/**
|
|
189
|
+
* Removes the control; `keepContent` puts what it held in its place, as Office JS. Where the control held the
|
|
190
|
+
* paragraph a table cell ends with, that paragraph stays in its place, emptied, its properties kept, outside
|
|
191
|
+
* any control, as Word keeps a cell's last paragraph (check 52, case 95; CR-002 section 55.6).
|
|
192
|
+
*/
|
|
86
193
|
delete(keepContent?: boolean): void;
|
|
87
194
|
/** The XML of the control (extension). */
|
|
88
195
|
getXml(): Promise<string>;
|
|
@@ -103,14 +210,21 @@ export declare class ContentControl {
|
|
|
103
210
|
/** The control's data binding (Office JS `xmlMapping`), backed by `w:dataBinding`. */
|
|
104
211
|
get xmlMapping(): XmlMapping;
|
|
105
212
|
/**
|
|
106
|
-
* The placeholder Word shows for an empty control: the
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
213
|
+
* The placeholder Word shows for an empty control: the text of the glossary entry the control's `w:placeholder` names,
|
|
214
|
+
* as Office JS reads it (CR-002 section 63, D8; check 65), `null` where the control names none (the bare form) or the
|
|
215
|
+
* glossary lacks the entry. The glossary is read when the body is (`getBody`, `Word.run`). Setting it names Word's
|
|
216
|
+
* default entry for Word's default text, else a new entry holding the text, named as Word names one (32 hex digits),
|
|
217
|
+
* which is written into the glossary on save, the entry named before left there; a control showing its placeholder,
|
|
218
|
+
* or holding nothing, shows the new text. A control's content is left alone. Until section 63 the text was written as
|
|
219
|
+
* the control's content in the bare form, and a control holding content refused it.
|
|
111
220
|
*/
|
|
112
|
-
get placeholderText(): string;
|
|
221
|
+
get placeholderText(): string | null;
|
|
113
222
|
set placeholderText(text: string);
|
|
223
|
+
/**
|
|
224
|
+
* Blocks taken out of the control's content: the relationships only they used (a picture's image) and the comments
|
|
225
|
+
* whose references they held go when the package is saved, as a deletion's do.
|
|
226
|
+
*/
|
|
227
|
+
private removeBlocks;
|
|
114
228
|
/** Office JS `appearance`: how Word draws the control (`w15:appearance`). */
|
|
115
229
|
get appearance(): ContentControlAppearance;
|
|
116
230
|
set appearance(value: ContentControlAppearance);
|
|
@@ -152,6 +266,8 @@ export declare class ContentControl {
|
|
|
152
266
|
get runProperties(): wml.RPr | undefined;
|
|
153
267
|
/** Whether a plain-text control accepts several lines (`w:text/@w:multiLine`). */
|
|
154
268
|
get isMultiLine(): boolean;
|
|
269
|
+
/** Office JS's name for `isShowingPlaceholder` (`showingPlaceholderText`, WordApiDesktop 1.3, read-only there). */
|
|
270
|
+
get showingPlaceholderText(): boolean;
|
|
155
271
|
/** Whether the control is showing its placeholder rather than a value (`w:showingPlcHdr`). */
|
|
156
272
|
get isShowingPlaceholder(): boolean;
|
|
157
273
|
set isShowingPlaceholder(value: boolean);
|
|
@@ -166,18 +282,81 @@ export declare class ContentControl {
|
|
|
166
282
|
/** A copy of this control right after it, as Word's repeating-section + button does (extension). */
|
|
167
283
|
insertCopyAfter(): ContentControl;
|
|
168
284
|
/**
|
|
169
|
-
* Writes the control's text into the node it is bound to, when there is one and the XPath engine
|
|
170
|
-
* is warm. Silent when it is not: reading a custom XML part is `pkg.customXmlParts.load()`'s job,
|
|
285
|
+
* @internal Writes the control's text into the node it is bound to, when there is one and the XPath engine
|
|
286
|
+
* is warm (CR-002 section 63, D7: every text write into a bound control). Silent when it is not: reading a custom XML part is `pkg.customXmlParts.load()`'s job,
|
|
171
287
|
* and `updateFromContentControls()` is the explicit form of this write.
|
|
172
288
|
*/
|
|
173
|
-
|
|
174
|
-
private firstRunOfContent;
|
|
289
|
+
syncBoundNode(): void;
|
|
175
290
|
private lockValue;
|
|
176
291
|
private setLock;
|
|
292
|
+
/**
|
|
293
|
+
* True for a control in the selected branch of a kept `mc:AlternateContent`, at any level, which the
|
|
294
|
+
* collectors list as Word reads it (CR-013 phase 2). Such a view is read-only (D4).
|
|
295
|
+
*/
|
|
296
|
+
get inBranch(): boolean;
|
|
297
|
+
/** Refuses a write to a control in a branch (CR-013 D4). Internal: the control's mutators, and its kinds', call it first. */
|
|
298
|
+
assertWritable(): void;
|
|
177
299
|
/** The table a row-level or cell-level control belongs to. */
|
|
178
300
|
private ancestorTable;
|
|
179
301
|
}
|
|
180
|
-
/**
|
|
181
|
-
|
|
302
|
+
/**
|
|
303
|
+
* Every content control under a list of block-level items, in document order, nested ones included. In a
|
|
304
|
+
* kept `mc:AlternateContent` a reader's (`'read'`, the default) takes the selected branch's controls (CR-013
|
|
305
|
+
* phase 2), the binding passes (`'every'`) every branch's, each other branch's where the element stands
|
|
306
|
+
* (phase 3).
|
|
307
|
+
*/
|
|
308
|
+
export declare function collectControls(items: Element[], body: Body, out: ContentControl[], mode?: BranchMode): void;
|
|
182
309
|
/** The run-level controls in a paragraph (or any run holder), in order, nested ones included. */
|
|
183
|
-
export declare function collectRunControls(holder: object, body: Body, out: ContentControl[]): void;
|
|
310
|
+
export declare function collectRunControls(holder: object, body: Body, out: ContentControl[], mode?: BranchMode): void;
|
|
311
|
+
/**
|
|
312
|
+
* A view of the content control whose `w:sdt` value this is, found in its owner's list (a paragraph's runs, a body's
|
|
313
|
+
* blocks, a holder's items).
|
|
314
|
+
*/
|
|
315
|
+
export declare function controlViewOf(sdt: object, body: Body): ContentControl;
|
|
316
|
+
/**
|
|
317
|
+
* A block-level control bound by `w:dataBinding`, untyped, `w:text` or `w:richText`, whose node doesn't hold flat OPC
|
|
318
|
+
* (CR-002 section 61 H1): Word holds its content to one paragraph, and can't open a file where it holds more (check 56,
|
|
319
|
+
* docx4j-python's file 3). A node not resolved (the custom XML parts not loaded) counts as not flat OPC. `w15:dataBinding`
|
|
320
|
+
* is Word's rich-text binding, and isn't this.
|
|
321
|
+
*/
|
|
322
|
+
export declare function isBoundBlockControl(control: ContentControl): boolean;
|
|
323
|
+
/**
|
|
324
|
+
* How a control holds lines, as Word reads it: `multi` or `single` for a plain-text control (`w:text` and its
|
|
325
|
+
* `w:multiLine`), `single` for a bound block control Word reads as plain text (section 61 H4); undefined for any other.
|
|
326
|
+
*/
|
|
327
|
+
export declare function plainTextLinesOf(control: ContentControl): 'multi' | 'single' | undefined;
|
|
328
|
+
/**
|
|
329
|
+
* Text for a run-level control: a line feed or carriage return there is refused before anything changes (CR-002
|
|
330
|
+
* section 60 F4: Word, given one, moved a bound plain-text control to block level), and a plain-text control's breaks
|
|
331
|
+
* go as its kind takes them (F3: dropped in a single-line one).
|
|
332
|
+
*/
|
|
333
|
+
export declare function textForRunControl(control: ContentControl, text: string): string;
|
|
334
|
+
/** Word's error for a block write into a bound block control, where measured (CR-002 section 61 H3; check 56). */
|
|
335
|
+
export type BlockRefusal = 'InvalidArgument' | 'GeneralException';
|
|
336
|
+
/**
|
|
337
|
+
* Refuses, before anything changes, putting blocks into a block-level control bound by `w:dataBinding` (untyped,
|
|
338
|
+
* `w:text` or `w:richText`, its node not flat OPC) that would leave it holding anything but one paragraph: Word can't
|
|
339
|
+
* open such a file, and its repair loses the extra blocks (CR-002 section 61, check 56). Word's own error where
|
|
340
|
+
* measured (`insertTable` `InvalidArgument`, `insertOoxml` `GeneralException`), else `NotSupportedError` (H3).
|
|
341
|
+
*/
|
|
342
|
+
export declare function assertControlHolds(body: Body, holder: object, container: Element[], elements: readonly Element[], refusal?: BlockRefusal, member?: [string, string]): void;
|
|
343
|
+
/** Office JS `Word.ContentControlOptions`: the types `getContentControls` lists. */
|
|
344
|
+
export interface ContentControlOptions {
|
|
345
|
+
/** `ContentControlType` values; Office JS takes the enum's strings. */
|
|
346
|
+
types?: readonly string[];
|
|
347
|
+
}
|
|
348
|
+
/** The controls of `options.types`, or all of them. */
|
|
349
|
+
export declare function controlsOfTypes(controls: ContentControl[], options?: ContentControlOptions): ContentControl[];
|
|
350
|
+
/**
|
|
351
|
+
* Whether a control of this kind made on an empty range shows its default placeholder, as Word's does (CR-002 section
|
|
352
|
+
* 63, D8; check 64; Jason's `placeholders.docx`, section 63.22): a text control, a date picker, a drop-down list or a
|
|
353
|
+
* combo box. The building block and repeating section kinds are made as before.
|
|
354
|
+
*/
|
|
355
|
+
export declare function showsPlaceholderWhenMade(kind: ContentControlType | undefined): boolean;
|
|
356
|
+
/** A stand-in for a block-level control about to be made, for `assertControlHolds` before `sdtOf` takes its content. */
|
|
357
|
+
export declare const BLOCK_CONTROL: Element;
|
|
358
|
+
/**
|
|
359
|
+
* Whether a block-level control holds one paragraph and nothing else at block level, or nothing yet: what a bound
|
|
360
|
+
* block control may hold (CR-002 section 61).
|
|
361
|
+
*/
|
|
362
|
+
export declare function holdsOneParagraph(control: ContentControl): boolean;
|