@docx4j/core-ts 0.5.0 → 0.7.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 +92 -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 +507 -150
- package/dist/model/content/Comment.d.mts +23 -5
- package/dist/model/content/Comment.mjs +207 -26
- package/dist/model/content/ContentControl.d.mts +198 -19
- package/dist/model/content/ContentControl.mjs +672 -99
- package/dist/model/content/Font.d.mts +70 -17
- package/dist/model/content/Font.mjs +119 -36
- package/dist/model/content/InlinePicture.d.mts +11 -0
- package/dist/model/content/InlinePicture.mjs +21 -1
- package/dist/model/content/List.d.mts +6 -3
- package/dist/model/content/List.mjs +18 -8
- package/dist/model/content/Paragraph.d.mts +200 -14
- package/dist/model/content/Paragraph.mjs +898 -82
- 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 +135 -49
- package/dist/model/content/TrackedChange.d.mts +174 -15
- package/dist/model/content/TrackedChange.mjs +734 -170
- 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 +10 -3
- package/dist/model/content/index.mjs +10 -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/ooxml.mjs +12 -1
- package/dist/model/content/outline.d.mts +5 -0
- package/dist/model/content/outline.mjs +13 -0
- package/dist/model/content/paraIds.d.mts +5 -0
- package/dist/model/content/paraIds.mjs +54 -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 +74 -0
- package/dist/model/content/search.mjs +255 -9
- package/dist/model/content/spanEdits.d.mts +159 -0
- package/dist/model/content/spanEdits.mjs +728 -0
- package/dist/model/content/story.d.mts +47 -0
- package/dist/model/content/story.mjs +95 -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 +102 -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 +63 -6
- package/dist/model/content/tracking.mjs +242 -22
- package/dist/model/content/tree.d.mts +172 -24
- package/dist/model/content/tree.mjs +328 -54
- package/dist/model/content/wordRange.d.mts +48 -0
- package/dist/model/content/wordRange.mjs +97 -0
- package/dist/model/customxml/CustomXmlPartCollection.d.mts +30 -1
- package/dist/model/customxml/CustomXmlPartCollection.mjs +81 -12
- package/dist/model/customxml/XmlMapping.d.mts +32 -8
- package/dist/model/customxml/XmlMapping.mjs +64 -10
- package/dist/model/customxml/bindings.d.mts +33 -4
- package/dist/model/customxml/bindings.mjs +171 -45
- package/dist/model/customxml/index.d.mts +1 -0
- package/dist/model/customxml/index.mjs +1 -0
- package/dist/model/customxml/kinds.d.mts +8 -3
- package/dist/model/customxml/kinds.mjs +26 -5
- package/dist/model/customxml/opendope.d.mts +4 -1
- package/dist/model/customxml/opendope.mjs +9 -6
- 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 +22 -8
- package/dist/model/customxml/storeItems.d.mts +57 -0
- package/dist/model/customxml/storeItems.mjs +122 -0
- package/dist/model/customxml/xhtml.mjs +23 -22
- package/dist/model/dateZone.d.mts +25 -0
- package/dist/model/dateZone.mjs +57 -0
- package/dist/model/index.d.mts +3 -0
- package/dist/model/index.mjs +5 -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 +74 -2
- package/dist/model/properties/PropertyResolver.mjs +133 -5
- package/dist/model/properties/catalogue.d.mts +19 -5
- package/dist/model/properties/catalogue.mjs +41 -15
- package/dist/model/properties/index.d.mts +1 -1
- package/dist/model/properties/log.d.mts +1 -1
- package/dist/model/properties/log.mjs +5 -5
- package/dist/model/properties/styleUtil.d.mts +3 -1
- package/dist/model/properties/styleUtil.mjs +20 -24
- package/dist/model/properties/table.mjs +4 -2
- package/dist/model/text/CaseMapping.d.mts +38 -0
- package/dist/model/text/CaseMapping.mjs +86 -0
- package/dist/model/text/Extractor.d.mts +349 -0
- package/dist/model/text/Extractor.mjs +2406 -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 +542 -0
- package/dist/model/text/TextContext.d.mts +256 -0
- package/dist/model/text/TextContext.mjs +600 -0
- package/dist/model/text/TextOptions.d.mts +233 -0
- package/dist/model/text/TextOptions.mjs +419 -0
- package/dist/model/text/TextResult.d.mts +621 -0
- package/dist/model/text/TextResult.mjs +629 -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 +936 -0
- package/dist/model/text/caseMapping.generated.d.mts +7 -0
- package/dist/model/text/caseMapping.generated.mjs +214 -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 +8 -0
- package/dist/model/text/index.mjs +9 -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/model/wordIntegers.d.mts +29 -0
- package/dist/model/wordIntegers.mjs +78 -0
- package/dist/office-js/document.mjs +15 -1
- 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 +29 -12
- package/dist/opc/DirectoryPartStore.d.mts +6 -2
- package/dist/opc/DirectoryPartStore.mjs +11 -4
- package/dist/opc/FlatOpcPartStore.d.mts +4 -2
- package/dist/opc/FlatOpcPartStore.mjs +11 -8
- package/dist/opc/Load.d.mts +32 -0
- package/dist/opc/Load.mjs +115 -5
- package/dist/opc/PartStore.d.mts +34 -1
- package/dist/opc/PartStore.mjs +71 -8
- package/dist/opc/Save.d.mts +32 -0
- package/dist/opc/Save.mjs +110 -4
- package/dist/opc/ZipPartStore.d.mts +4 -2
- package/dist/opc/ZipPartStore.mjs +12 -7
- package/dist/opc/exceptions.d.mts +140 -0
- package/dist/opc/exceptions.mjs +108 -0
- package/dist/opc/index.d.mts +8 -5
- package/dist/opc/index.mjs +5 -3
- package/dist/opc/mce/preprocessor.d.mts +141 -5
- package/dist/opc/mce/preprocessor.mjs +119 -18
- package/dist/opc/mce/understood.d.mts +3 -11
- package/dist/opc/mce/understood.mjs +27 -23
- package/dist/opc/repair/breaks.d.mts +23 -0
- package/dist/opc/repair/breaks.mjs +288 -0
- package/dist/opc/repair/hosts.d.mts +12 -0
- package/dist/opc/repair/hosts.mjs +33 -0
- package/dist/opc/repair/mainRoot.d.mts +19 -0
- package/dist/opc/repair/mainRoot.mjs +168 -0
- package/dist/opc/repair/unknownElements.d.mts +8 -0
- package/dist/opc/repair/unknownElements.mjs +180 -0
- package/dist/opc/repair/wmlNames.generated.d.mts +2 -0
- package/dist/opc/repair/wmlNames.generated.mjs +80 -0
- package/dist/opc/skipped.d.mts +50 -0
- package/dist/opc/skipped.mjs +140 -0
- package/dist/packages/OpcPackage.d.mts +110 -4
- package/dist/packages/OpcPackage.mjs +123 -7
- package/dist/packages/WordprocessingMLPackage.d.mts +45 -8
- package/dist/packages/WordprocessingMLPackage.mjs +158 -21
- package/dist/packages/index.d.mts +1 -1
- package/dist/parts/DefaultXmlPart.mjs +2 -2
- package/dist/parts/Part.d.mts +14 -2
- package/dist/parts/RelationshipsPart.d.mts +15 -0
- package/dist/parts/RelationshipsPart.mjs +66 -1
- package/dist/parts/XmlPart.d.mts +63 -32
- package/dist/parts/XmlPart.mjs +240 -96
- package/dist/parts/wml/comments.mjs +30 -0
- package/dist/parts/wml/index.d.mts +12 -1
- package/dist/parts/wml/index.mjs +37 -1
- package/dist/xml/dom.d.mts +7 -0
- package/dist/xml/dom.mjs +18 -0
- package/package.json +2 -2
|
@@ -1,10 +1,15 @@
|
|
|
1
|
+
import { wallClockIn } from '../dateZone.mjs';
|
|
1
2
|
import { deepCopy } from '@docx4j/generated-objects-ts';
|
|
2
3
|
import * as el from '@docx4j/generated-objects-ts/el/org_docx4j_wml';
|
|
3
|
-
import { sdtProperty } from '@docx4j/generated-objects-ts/builders/wml';
|
|
4
|
+
import { sdtProperty, textOf } from '@docx4j/generated-objects-ts/builders/wml';
|
|
4
5
|
import { bindPicture } from './pictures.mjs';
|
|
5
|
-
|
|
6
|
+
import { isPropertiesStoreItem } from './storeItems.mjs';
|
|
7
|
+
/**
|
|
8
|
+
* The style Word gives placeholder text, and the text docx4j's placeholder.xml carries: Word 365's since docx4j's CR-063
|
|
9
|
+
* D5 (CR-002 section 63.22), where it was Word 2010's "Click here to enter text.".
|
|
10
|
+
*/
|
|
6
11
|
export const PLACEHOLDER_STYLE = 'PlaceholderText';
|
|
7
|
-
export const PLACEHOLDER_TEXT = 'Click here to enter text.';
|
|
12
|
+
export const PLACEHOLDER_TEXT = 'Click or tap here to enter text.';
|
|
8
13
|
/**
|
|
9
14
|
* Whether a node's value is a Flat OPC package: what Word writes into the node of a mapped rich
|
|
10
15
|
* text control when its content is edited, a whole `pkg:package` as escaped text (`test/README.md`
|
|
@@ -33,6 +38,16 @@ function isContainer(control) {
|
|
|
33
38
|
return true;
|
|
34
39
|
return control.form === 'Block' && control.tables.length > 0;
|
|
35
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* A control's text as its node takes it (CR-002 section 60 D4, F1, F2): `textOf`'s characters, as before CR-012 phase 4
|
|
43
|
+
* moved `ContentControl.text` to Office JS's, its paragraphs and breaks a line feed each, a non-breaking hyphen `-` as
|
|
44
|
+
* Word writes it (check 55b), an optional hyphen U+00AD, a note reference nothing. Office JS's U+000B and U+001E are no
|
|
45
|
+
* XML characters.
|
|
46
|
+
*/
|
|
47
|
+
export function boundValueOf(control) {
|
|
48
|
+
var _a;
|
|
49
|
+
return textOf(((_a = control.sdt.sdtContent) !== null && _a !== void 0 ? _a : {})).replace(/\u2011/g, '-');
|
|
50
|
+
}
|
|
36
51
|
/** docx4j ValueInserterPlainTextImpl: the runs for a value, with the w:sdtPr run properties. */
|
|
37
52
|
export function runsForValue(value, rPr, multiLine) {
|
|
38
53
|
if (value === '')
|
|
@@ -49,84 +64,184 @@ export function runsForValue(value, rPr, multiLine) {
|
|
|
49
64
|
});
|
|
50
65
|
return out;
|
|
51
66
|
}
|
|
52
|
-
/**
|
|
53
|
-
|
|
67
|
+
/**
|
|
68
|
+
* docx4j's placeholder.xml: a PlaceholderText-styled run over the control's own run properties, which goes with
|
|
69
|
+
* w:showingPlcHdr; its text docx4j's, or a glossary entry's (CR-002 section 63, D8).
|
|
70
|
+
*/
|
|
71
|
+
export function placeholderRun(rPr, text = PLACEHOLDER_TEXT) {
|
|
54
72
|
const properties = rPr ? deepCopy(rPr) : {};
|
|
55
73
|
properties.rStyle = { val: PLACEHOLDER_STYLE };
|
|
56
|
-
|
|
74
|
+
const t = { TYPE_NAME: 'org_docx4j_wml.Text', value: text };
|
|
75
|
+
if (text.startsWith(' ') || text.endsWith(' '))
|
|
76
|
+
t.space = 'preserve';
|
|
77
|
+
return el.r({ rPr: properties, content: [el.t(t)] });
|
|
57
78
|
}
|
|
58
79
|
/**
|
|
59
80
|
* A date in Word's `w:dateFormat` pattern (the .NET forms Word writes: `d MMMM yyyy`,
|
|
60
81
|
* `dddd, d MMMM yyyy`, `d/MM/yyyy`), in the control's `w:lid` locale. Month and day names come
|
|
61
82
|
* from `Intl`; text inside single or double quotes is literal. docx4j uses Java's
|
|
62
|
-
* `SimpleDateFormat` with `dddd` mapped to `EEEE`; this is the same vocabulary.
|
|
83
|
+
* `SimpleDateFormat` with `dddd` mapped to `EEEE`; this is the same vocabulary. `am/pm` and
|
|
84
|
+
* `AM/PM` (any mix of cases, as docx4j's `isAMPM`) are the locale's day-period names upper-cased,
|
|
85
|
+
* as Word shows both (CR-020 D5, docx4j CR-058's `wordAmPm`): `h:mm am/pm` at 15:05 is `3:05 PM`.
|
|
86
|
+
*
|
|
87
|
+
* The date's **UTC fields** are formatted: a bound date is its nominal date, the fields as written,
|
|
88
|
+
* which `w:fullDate` keeps with a `Z` and `DatePickerContentControl.fullDate` returns as a `Date` in
|
|
89
|
+
* UTC, so the day shown is the same whatever the machine's time zone (CR-002 section 56).
|
|
63
90
|
*/
|
|
64
91
|
export function formatDate(pattern, date, locale = 'en-US') {
|
|
65
92
|
const pad = (n, width) => String(n).padStart(width, '0');
|
|
66
93
|
const name = (options) => {
|
|
67
94
|
try {
|
|
68
|
-
return new Intl.DateTimeFormat(locale, options).format(date);
|
|
95
|
+
return new Intl.DateTimeFormat(locale, { ...options, timeZone: 'UTC' }).format(date);
|
|
69
96
|
}
|
|
70
97
|
catch {
|
|
71
|
-
return new Intl.DateTimeFormat('en-US', options).format(date);
|
|
98
|
+
return new Intl.DateTimeFormat('en-US', { ...options, timeZone: 'UTC' }).format(date);
|
|
72
99
|
}
|
|
73
100
|
};
|
|
74
|
-
const
|
|
75
|
-
|
|
101
|
+
const hours = date.getUTCHours();
|
|
102
|
+
const hours12 = hours % 12 === 0 ? 12 : hours % 12;
|
|
103
|
+
const dayPeriod = () => {
|
|
104
|
+
const of = (tag) => {
|
|
105
|
+
var _a;
|
|
106
|
+
return (_a = new Intl.DateTimeFormat(tag, { hour: 'numeric', hour12: true, timeZone: 'UTC' })
|
|
107
|
+
.formatToParts(date).find((part) => part.type === 'dayPeriod')) === null || _a === void 0 ? void 0 : _a.value;
|
|
108
|
+
};
|
|
109
|
+
let value;
|
|
110
|
+
try {
|
|
111
|
+
value = of(locale);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
value = of('en-US');
|
|
115
|
+
}
|
|
116
|
+
value !== null && value !== void 0 ? value : (value = hours < 12 ? 'AM' : 'PM');
|
|
117
|
+
try {
|
|
118
|
+
return value.toLocaleUpperCase(locale);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return value.toUpperCase();
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
return pattern.replace(/[aA][mM]\/[pP][mM]|d{1,4}|M{1,4}|y{2,4}|H{1,2}|h{1,2}|m{1,2}|s{1,2}|tt|'[^']*'|"[^"]*"/g, (token) => {
|
|
76
125
|
if (token.startsWith("'") || token.startsWith('"'))
|
|
77
126
|
return token.slice(1, -1);
|
|
127
|
+
if (token.length === 5 && token[2] === '/')
|
|
128
|
+
return dayPeriod();
|
|
78
129
|
switch (token) {
|
|
79
|
-
case 'd': return String(date.
|
|
80
|
-
case 'dd': return pad(date.
|
|
130
|
+
case 'd': return String(date.getUTCDate());
|
|
131
|
+
case 'dd': return pad(date.getUTCDate(), 2);
|
|
81
132
|
case 'ddd': return name({ weekday: 'short' });
|
|
82
133
|
case 'dddd': return name({ weekday: 'long' });
|
|
83
|
-
case 'M': return String(date.
|
|
84
|
-
case 'MM': return pad(date.
|
|
134
|
+
case 'M': return String(date.getUTCMonth() + 1);
|
|
135
|
+
case 'MM': return pad(date.getUTCMonth() + 1, 2);
|
|
85
136
|
case 'MMM': return name({ month: 'short' });
|
|
86
137
|
case 'MMMM': return name({ month: 'long' });
|
|
87
|
-
case 'yy': return pad(date.
|
|
138
|
+
case 'yy': return pad(date.getUTCFullYear() % 100, 2);
|
|
88
139
|
case 'yyy':
|
|
89
|
-
case 'yyyy': return String(date.
|
|
90
|
-
case 'H': return String(
|
|
91
|
-
case 'HH': return pad(
|
|
140
|
+
case 'yyyy': return String(date.getUTCFullYear());
|
|
141
|
+
case 'H': return String(hours);
|
|
142
|
+
case 'HH': return pad(hours, 2);
|
|
92
143
|
case 'h': return String(hours12);
|
|
93
144
|
case 'hh': return pad(hours12, 2);
|
|
94
|
-
case 'm': return String(date.
|
|
95
|
-
case 'mm': return pad(date.
|
|
96
|
-
case 's': return String(date.
|
|
97
|
-
case 'ss': return pad(date.
|
|
98
|
-
case 'tt': return
|
|
145
|
+
case 'm': return String(date.getUTCMinutes());
|
|
146
|
+
case 'mm': return pad(date.getUTCMinutes(), 2);
|
|
147
|
+
case 's': return String(date.getUTCSeconds());
|
|
148
|
+
case 'ss': return pad(date.getUTCSeconds(), 2);
|
|
149
|
+
case 'tt': return hours < 12 ? 'AM' : 'PM';
|
|
99
150
|
default: return token;
|
|
100
151
|
}
|
|
101
152
|
});
|
|
102
153
|
}
|
|
103
|
-
/** Word's stored date form, `2015-01-29T00:00:00
|
|
154
|
+
/** Word's stored date form, `2015-01-29T00:00:00`: a nominal date's fields, with no zone (CR-002 section 56). */
|
|
104
155
|
function isoOf(date) {
|
|
105
156
|
const pad = (n) => String(n).padStart(2, '0');
|
|
106
|
-
return `${date.
|
|
157
|
+
return `${date.getUTCFullYear()}-${pad(date.getUTCMonth() + 1)}-${pad(date.getUTCDate())}`
|
|
158
|
+
+ `T${pad(date.getUTCHours())}:${pad(date.getUTCMinutes())}:${pad(date.getUTCSeconds())}`;
|
|
107
159
|
}
|
|
108
|
-
/**
|
|
160
|
+
/**
|
|
161
|
+
* The date a bound value holds, when it is one (`2015-01-29`, `2015-01-29T00:00:00`, with seconds' fractions,
|
|
162
|
+
* a `Z` or an offset), as its nominal date: the fields as written, in UTC, the zone marker ignored, so that
|
|
163
|
+
* `2026-10-22T00:00:00Z` and `2026-10-22T00:00:00+05:00` are 22 October in any time zone (docx4j f62314d3b's
|
|
164
|
+
* rule, as Word shows them; CR-002 section 56). A date that doesn't exist (`2026-02-30`) is not one.
|
|
165
|
+
*/
|
|
109
166
|
function dateOf(value) {
|
|
110
|
-
|
|
167
|
+
var _a;
|
|
168
|
+
return (_a = parsedDateOf(value)) === null || _a === void 0 ? void 0 : _a.nominal;
|
|
169
|
+
}
|
|
170
|
+
const BOUND_DATE = /^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.\d+)?)?)?(Z|[+-]\d{2}:?\d{2})?$/;
|
|
171
|
+
/** A bound value's date as its nominal fields (UTC fields of `nominal`), and its zone marker's offset in minutes, where it has one. */
|
|
172
|
+
function parsedDateOf(value) {
|
|
173
|
+
const m = BOUND_DATE.exec(value);
|
|
174
|
+
if (!m)
|
|
175
|
+
return undefined;
|
|
176
|
+
const [year, month, day, hour, minute, second] = m.slice(1, 7).map((f) => Number(f !== null && f !== void 0 ? f : 0));
|
|
177
|
+
const date = new Date(Date.UTC(year, month - 1, day, hour, minute, second));
|
|
178
|
+
// Date.UTC rolls an impossible field over (30 February is 2 March): such a value is not a date
|
|
179
|
+
const exists = date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day
|
|
180
|
+
&& date.getUTCHours() === hour && date.getUTCMinutes() === minute && date.getUTCSeconds() === second;
|
|
181
|
+
if (!exists)
|
|
111
182
|
return undefined;
|
|
112
|
-
const
|
|
113
|
-
|
|
183
|
+
const marker = m[7];
|
|
184
|
+
const offset = marker === undefined ? undefined : marker === 'Z' ? 0
|
|
185
|
+
: (marker.startsWith('-') ? -1 : 1) * (Number(marker.slice(1, 3)) * 60 + Number(marker.slice(-2)));
|
|
186
|
+
return { nominal: date, offset };
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* A bound value's date as Word shows it to a reader in `zone` (`pkg.boundDatesConvertedAsWord`, CR-018): a value carrying
|
|
190
|
+
* a `Z` or an offset is the instant it names, shown on `zone`'s wall clock (Word reads the picker's `Z` as UTC and shows
|
|
191
|
+
* the machine's local time: on a machine at UTC+11, `2026-10-22T15:05:00Z` shows 2:05 AM the next day; docx4j CR-058 D6's
|
|
192
|
+
* probe); a value with no marker, or a date alone, is nominal, as `dateOf` reads it (unmeasured in Word, the date
|
|
193
|
+
* rule's point 4). The result is a nominal date in UTC fields, as every bound date here is, so `formatDate` and
|
|
194
|
+
* `w:fullDate` take it unchanged.
|
|
195
|
+
*/
|
|
196
|
+
function dateAsWordShows(value, zone) {
|
|
197
|
+
const parsed = parsedDateOf(value);
|
|
198
|
+
if (!parsed || parsed.offset === undefined)
|
|
199
|
+
return parsed === null || parsed === void 0 ? void 0 : parsed.nominal;
|
|
200
|
+
const instant = new Date(parsed.nominal.getTime() - parsed.offset * 60000);
|
|
201
|
+
const clock = wallClockIn(instant, zone);
|
|
202
|
+
return new Date(Date.UTC(clock.year, clock.month - 1, clock.day, clock.hour, clock.minute, clock.second));
|
|
114
203
|
}
|
|
115
204
|
/**
|
|
116
205
|
* Pushes the custom XML value into one control (docx4j BindingHandler's per-sdt work). Returns
|
|
117
206
|
* false when nothing was written: no binding, no part, an XPath that selects nothing, a kind
|
|
118
207
|
* this phase does not handle (explicit rich text), a node holding a Flat OPC package, or a
|
|
119
208
|
* picture control whose node holds no image (`notes` says which; CR-005 section 9).
|
|
209
|
+
*
|
|
210
|
+
* The part is the one the binding resolves to (CR-020): where its `w:storeItemID` names no part,
|
|
211
|
+
* the one its XPath fits, as Word repairs it on open; a control so bound gets that part's ID in
|
|
212
|
+
* its binding, as Word's save writes it (D2), and a note, as does a stale ID no part fits (D4).
|
|
120
213
|
*/
|
|
121
214
|
export function applyBindingTo(control, notes) {
|
|
122
|
-
var _a;
|
|
123
215
|
const mapping = control.xmlMapping;
|
|
124
|
-
|
|
216
|
+
const binding = mapping.dataBinding;
|
|
217
|
+
if (!binding)
|
|
125
218
|
return false;
|
|
126
|
-
const
|
|
219
|
+
const resolved = mapping.resolution;
|
|
220
|
+
const label = control.title || control.tag || `content control ${control.id}`;
|
|
221
|
+
if (!resolved) {
|
|
222
|
+
if (binding.storeItemID && !isPropertiesStoreItem(binding.storeItemID)) {
|
|
223
|
+
notes === null || notes === void 0 ? void 0 : notes.push(`${label}: store item ${binding.storeItemID} names no custom XML part, and none fits ${binding.xpath}; left as it is`);
|
|
224
|
+
}
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
const node = resolved.part.selectSingleNode(binding.xpath, binding.prefixMappings);
|
|
127
228
|
if (!node)
|
|
128
229
|
return false;
|
|
129
|
-
|
|
230
|
+
if (!bindValue(control, node.text.trim(), notes))
|
|
231
|
+
return false;
|
|
232
|
+
if (resolved.repaired) {
|
|
233
|
+
const stale = binding.storeItemID;
|
|
234
|
+
const id = resolved.part.id.toUpperCase();
|
|
235
|
+
mapping.repairStoreItemID(stale, id);
|
|
236
|
+
notes === null || notes === void 0 ? void 0 : notes.push(`${label}: store item ${stale} names no custom XML part; ${resolved.part.part.partName.name} ${id}`
|
|
237
|
+
+ (resolved.fitting > 1 ? `, the first of the ${resolved.fitting} that fit ${binding.xpath} to select a node,` : ` fits ${binding.xpath} and`)
|
|
238
|
+
+ ' is bound, its ID written into the control, as Word repairs it');
|
|
239
|
+
}
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
/** `applyBindingTo`'s write of a node's value into the control, by the control's kind. */
|
|
243
|
+
function bindValue(control, value, notes) {
|
|
244
|
+
var _a, _b, _c;
|
|
130
245
|
// A picture control's node holds base64 image data: the picture's a:blip is pointed at a new
|
|
131
246
|
// image part and the drawing kept, as docx4j's bind.xslt mode picture3 does (CR-005 section 9).
|
|
132
247
|
if (control.type === 'Picture') {
|
|
@@ -135,8 +250,9 @@ export function applyBindingTo(control, notes) {
|
|
|
135
250
|
notes === null || notes === void 0 ? void 0 : notes.push(outcome.note);
|
|
136
251
|
return outcome.done;
|
|
137
252
|
}
|
|
138
|
-
// Explicit rich text is bound from flat OPC or XHTML in docx4j; deferred, as it is there for this route.
|
|
139
|
-
|
|
253
|
+
// Explicit rich text is bound from flat OPC or XHTML in docx4j; deferred, as it is there for this route. A block
|
|
254
|
+
// control bound by w:dataBinding is plain text to Word, w:richText or not (CR-002 section 61 H4), and is bound as text.
|
|
255
|
+
if (sdtProperty(control.sdt.sdtPr, 'richText') !== undefined && control.type === 'RichText')
|
|
140
256
|
return false;
|
|
141
257
|
if (isContainer(control))
|
|
142
258
|
return false;
|
|
@@ -162,14 +278,24 @@ export function applyBindingTo(control, notes) {
|
|
|
162
278
|
}
|
|
163
279
|
else if (control.type === 'DatePicker') {
|
|
164
280
|
const date = control.datePickerContentControl;
|
|
165
|
-
const
|
|
281
|
+
const pkg = control.parentBody.package_;
|
|
282
|
+
const parsed = (pkg === null || pkg === void 0 ? void 0 : pkg.boundDatesConvertedAsWord) && pkg.effectiveDateTimeZone ? dateAsWordShows(value, pkg.effectiveDateTimeZone()) : dateOf(value);
|
|
166
283
|
if (date && parsed) {
|
|
167
284
|
date.fullDate = parsed;
|
|
168
|
-
// Word shows the date in w:dateFormat, not the stored form (docx4j formats it the same way)
|
|
285
|
+
// Word shows the date in w:dateFormat, not the stored form (docx4j formats it the same way), in w:lid's language,
|
|
286
|
+
// else the document's default language (CR-020 D5, docx4j CR-058 D2 revised), else en-US
|
|
287
|
+
const language = date.dateDisplayLocale || ((_c = (_b = pkg === null || pkg === void 0 ? void 0 : pkg.propertyResolverOrUndefined) === null || _b === void 0 ? void 0 : _b.getDocumentDefaultRPr().lang) === null || _c === void 0 ? void 0 : _c.val) || undefined;
|
|
169
288
|
if (date.dateFormat !== '')
|
|
170
|
-
display = formatDate(date.dateFormat, parsed,
|
|
289
|
+
display = formatDate(date.dateFormat, parsed, language);
|
|
171
290
|
}
|
|
172
291
|
}
|
|
292
|
+
// an empty value shows the control's placeholder in Word's form: the entry its w:placeholder names, else Word's default
|
|
293
|
+
// entry for a text control, written into the glossary on save (CR-002 section 63, D8; docx4j CR-063's D2 and D3).
|
|
294
|
+
// Another kind naming no entry, or one the glossary lacks, keeps docx4j's run.
|
|
295
|
+
if (display === '' && control.showsWordsFormPlaceholder) {
|
|
296
|
+
control.showPlaceholder();
|
|
297
|
+
return true;
|
|
298
|
+
}
|
|
173
299
|
control.setBoundContent(runsForValue(display, control.runProperties, control.isMultiLine), display === '');
|
|
174
300
|
return true;
|
|
175
301
|
}
|
|
@@ -178,7 +304,7 @@ export function applyBindingsTo(controls) {
|
|
|
178
304
|
const result = { bound: 0, updated: 0, skipped: 0 };
|
|
179
305
|
const notes = [];
|
|
180
306
|
for (const control of controls) {
|
|
181
|
-
if (!control.xmlMapping.
|
|
307
|
+
if (!control.xmlMapping.dataBinding)
|
|
182
308
|
continue;
|
|
183
309
|
result.bound++;
|
|
184
310
|
if (applyBindingTo(control, notes))
|
|
@@ -199,8 +325,7 @@ export function applyBindingsTo(controls) {
|
|
|
199
325
|
export function updateFromControl(control) {
|
|
200
326
|
var _a, _b;
|
|
201
327
|
const mapping = control.xmlMapping;
|
|
202
|
-
|
|
203
|
-
return false;
|
|
328
|
+
// the node in the part the binding resolves to, a stale ID's too, its ID left as it is (CR-020 D2, docx4j's UpdateXmlFromDocumentSurface)
|
|
204
329
|
const node = mapping.customXmlNode;
|
|
205
330
|
if (!node)
|
|
206
331
|
return false;
|
|
@@ -208,7 +333,8 @@ export function updateFromControl(control) {
|
|
|
208
333
|
// image's bytes go back to the node as base64, as Word 15 writes them (check 38).
|
|
209
334
|
if (control.type === 'Picture')
|
|
210
335
|
return false;
|
|
211
|
-
|
|
336
|
+
// a block control bound by w:dataBinding is plain text to Word, w:richText or not (H4); its text goes back as text
|
|
337
|
+
if (sdtProperty(control.sdt.sdtPr, 'richText') !== undefined && control.type === 'RichText')
|
|
212
338
|
return false;
|
|
213
339
|
if (isContainer(control))
|
|
214
340
|
return false;
|
|
@@ -218,7 +344,7 @@ export function updateFromControl(control) {
|
|
|
218
344
|
// The node holds a rich text control's content as Flat OPC: text is not written over it.
|
|
219
345
|
if (holdsFlatOpc(node.text))
|
|
220
346
|
return false;
|
|
221
|
-
let value = control
|
|
347
|
+
let value = boundValueOf(control);
|
|
222
348
|
if (control.type === 'CheckBox') {
|
|
223
349
|
const checkbox = control.checkboxContentControl;
|
|
224
350
|
if (!checkbox)
|
|
@@ -246,7 +372,7 @@ export function updateFromControl(control) {
|
|
|
246
372
|
export function updateFromControls(controls) {
|
|
247
373
|
const result = { bound: 0, updated: 0, skipped: 0 };
|
|
248
374
|
for (const control of controls) {
|
|
249
|
-
if (!control.xmlMapping.
|
|
375
|
+
if (!control.xmlMapping.dataBinding)
|
|
250
376
|
continue;
|
|
251
377
|
// counted by the picture pass, which reads the image part (CR-005 section 9)
|
|
252
378
|
if (control.type === 'Picture')
|
|
@@ -2,6 +2,7 @@ export { type XPathEngine, type XPathValue, type BooleanConversionMode, booleanV
|
|
|
2
2
|
export { CustomXmlPart, CustomXmlNode, CustomXmlPrefixMappingCollection, type CustomXmlNodeType, type CustomXmlPrefixMapping, type CustomXmlPartOwner } from './CustomXmlPart.mjs';
|
|
3
3
|
export { CustomXmlPartCollection, type CustomXmlHost } from './CustomXmlPartCollection.mjs';
|
|
4
4
|
export { XmlMapping, type CustomXmlPartLookup } from './XmlMapping.mjs';
|
|
5
|
+
export { StoreItemResolver, firstStep, isPropertiesStoreItem, normaliseStoreItemId, CORE_PROPERTIES_STOREITEMID, EXTENDED_PROPERTIES_STOREITEMID, type StoreItemCandidate, type StoreItemResolution } from './storeItems.mjs';
|
|
5
6
|
export { CheckboxContentControl, DatePickerContentControl, ListContentControl, ContentControlListItem, PictureContentControl, RepeatingSectionContentControl, GroupContentControl, checkboxRun, CHECKED_SYMBOL, UNCHECKED_SYMBOL, CHECKBOX_FONT, } from './kinds.mjs';
|
|
6
7
|
export { applyBindingsTo, applyBindingTo, updateFromControls, updateFromControl, runsForValue, formatDate, holdsFlatOpc, PLACEHOLDER_STYLE, PLACEHOLDER_TEXT, type BindingResult } from './bindings.mjs';
|
|
7
8
|
export { controlIdScope, sdtKindFor, isRunLevel } from './insert.mjs';
|
|
@@ -4,6 +4,7 @@ export { booleanValue, DefaultXPathEngine, parsePrefixMappings, formatPrefixMapp
|
|
|
4
4
|
export { CustomXmlPart, CustomXmlNode, CustomXmlPrefixMappingCollection } from './CustomXmlPart.mjs';
|
|
5
5
|
export { CustomXmlPartCollection } from './CustomXmlPartCollection.mjs';
|
|
6
6
|
export { XmlMapping } from './XmlMapping.mjs';
|
|
7
|
+
export { StoreItemResolver, firstStep, isPropertiesStoreItem, normaliseStoreItemId, CORE_PROPERTIES_STOREITEMID, EXTENDED_PROPERTIES_STOREITEMID } from './storeItems.mjs';
|
|
7
8
|
export { CheckboxContentControl, DatePickerContentControl, ListContentControl, ContentControlListItem, PictureContentControl, RepeatingSectionContentControl, GroupContentControl, checkboxRun, CHECKED_SYMBOL, UNCHECKED_SYMBOL, CHECKBOX_FONT, } from './kinds.mjs';
|
|
8
9
|
export { applyBindingsTo, applyBindingTo, updateFromControls, updateFromControl, runsForValue, formatDate, holdsFlatOpc, PLACEHOLDER_STYLE, PLACEHOLDER_TEXT } from './bindings.mjs';
|
|
9
10
|
export { controlIdScope, sdtKindFor, isRunLevel } from './insert.mjs';
|
|
@@ -27,7 +27,9 @@ export declare class CheckboxContentControl {
|
|
|
27
27
|
/** Office JS `Word.DatePickerContentControl` over `w:date`. */
|
|
28
28
|
export declare class DatePickerContentControl {
|
|
29
29
|
private readonly date;
|
|
30
|
-
|
|
30
|
+
private readonly guard;
|
|
31
|
+
/** `guard` refuses a write to a control in a branch of a kept `mc:AlternateContent` (CR-013 D4). */
|
|
32
|
+
constructor(date: wml.CTSdtDate, guard?: () => void);
|
|
31
33
|
/** `w:dateFormat`, Word's .NET date pattern ('d MMMM yyyy'). Office JS calls it dateDisplayFormat. */
|
|
32
34
|
get dateFormat(): string;
|
|
33
35
|
set dateFormat(format: string);
|
|
@@ -51,7 +53,8 @@ export declare class DatePickerContentControl {
|
|
|
51
53
|
export declare class ContentControlListItem {
|
|
52
54
|
private readonly items;
|
|
53
55
|
private readonly item;
|
|
54
|
-
|
|
56
|
+
private readonly guard;
|
|
57
|
+
constructor(items: wml.CTSdtListItem[], item: wml.CTSdtListItem, guard?: () => void);
|
|
55
58
|
get displayText(): string;
|
|
56
59
|
set displayText(text: string);
|
|
57
60
|
get value(): string;
|
|
@@ -62,7 +65,9 @@ export declare class ContentControlListItem {
|
|
|
62
65
|
/** Office JS `Word.DropDownListContentControl` / `Word.ComboBoxContentControl`: the same shape. */
|
|
63
66
|
export declare class ListContentControl {
|
|
64
67
|
private readonly list;
|
|
65
|
-
|
|
68
|
+
private readonly guard;
|
|
69
|
+
/** `guard` refuses a write to a control in a branch of a kept `mc:AlternateContent` (CR-013 D4). */
|
|
70
|
+
constructor(list: wml.CTSdtDropDownList | wml.CTSdtComboBox, guard?: () => void);
|
|
66
71
|
get listItems(): ContentControlListItem[];
|
|
67
72
|
/** Adds an entry; `value` defaults to the display text, `index` appends when omitted. */
|
|
68
73
|
addListItem(displayText: string, value?: string, index?: number): ContentControlListItem;
|
|
@@ -34,6 +34,7 @@ export class CheckboxContentControl {
|
|
|
34
34
|
set isChecked(value) {
|
|
35
35
|
var _a;
|
|
36
36
|
var _b;
|
|
37
|
+
this.control.assertWritable();
|
|
37
38
|
((_a = (_b = this.checkbox).checked) !== null && _a !== void 0 ? _a : (_b.checked = {})).val = value;
|
|
38
39
|
this.control.setCheckboxGlyph(value ? this.checkedSymbol : this.uncheckedSymbol);
|
|
39
40
|
}
|
|
@@ -44,6 +45,7 @@ export class CheckboxContentControl {
|
|
|
44
45
|
set checkedSymbol(symbol) {
|
|
45
46
|
var _a, _b;
|
|
46
47
|
var _c, _d;
|
|
48
|
+
this.control.assertWritable();
|
|
47
49
|
((_a = (_c = this.checkbox).checkedState) !== null && _a !== void 0 ? _a : (_c.checkedState = {})).val = codeOf(symbol);
|
|
48
50
|
(_b = (_d = this.checkbox.checkedState).font) !== null && _b !== void 0 ? _b : (_d.font = CHECKBOX_FONT);
|
|
49
51
|
}
|
|
@@ -53,6 +55,7 @@ export class CheckboxContentControl {
|
|
|
53
55
|
set uncheckedSymbol(symbol) {
|
|
54
56
|
var _a, _b;
|
|
55
57
|
var _c, _d;
|
|
58
|
+
this.control.assertWritable();
|
|
56
59
|
((_a = (_c = this.checkbox).uncheckedState) !== null && _a !== void 0 ? _a : (_c.uncheckedState = {})).val = codeOf(symbol);
|
|
57
60
|
(_b = (_d = this.checkbox.uncheckedState).font) !== null && _b !== void 0 ? _b : (_d.font = CHECKBOX_FONT);
|
|
58
61
|
}
|
|
@@ -64,8 +67,10 @@ export class CheckboxContentControl {
|
|
|
64
67
|
}
|
|
65
68
|
/** Office JS `Word.DatePickerContentControl` over `w:date`. */
|
|
66
69
|
export class DatePickerContentControl {
|
|
67
|
-
|
|
70
|
+
/** `guard` refuses a write to a control in a branch of a kept `mc:AlternateContent` (CR-013 D4). */
|
|
71
|
+
constructor(date, guard = () => { }) {
|
|
68
72
|
this.date = date;
|
|
73
|
+
this.guard = guard;
|
|
69
74
|
}
|
|
70
75
|
/** `w:dateFormat`, Word's .NET date pattern ('d MMMM yyyy'). Office JS calls it dateDisplayFormat. */
|
|
71
76
|
get dateFormat() {
|
|
@@ -73,6 +78,7 @@ export class DatePickerContentControl {
|
|
|
73
78
|
return (_b = (_a = this.date.dateFormat) === null || _a === void 0 ? void 0 : _a.val) !== null && _b !== void 0 ? _b : '';
|
|
74
79
|
}
|
|
75
80
|
set dateFormat(format) {
|
|
81
|
+
this.guard();
|
|
76
82
|
if (format === '') {
|
|
77
83
|
delete this.date.dateFormat;
|
|
78
84
|
return;
|
|
@@ -92,6 +98,7 @@ export class DatePickerContentControl {
|
|
|
92
98
|
return (_b = (_a = this.date.lid) === null || _a === void 0 ? void 0 : _a.val) !== null && _b !== void 0 ? _b : '';
|
|
93
99
|
}
|
|
94
100
|
set dateDisplayLocale(locale) {
|
|
101
|
+
this.guard();
|
|
95
102
|
if (locale === '') {
|
|
96
103
|
delete this.date.lid;
|
|
97
104
|
return;
|
|
@@ -104,6 +111,7 @@ export class DatePickerContentControl {
|
|
|
104
111
|
return (_b = (_a = this.date.calendar) === null || _a === void 0 ? void 0 : _a.val) !== null && _b !== void 0 ? _b : 'gregorian';
|
|
105
112
|
}
|
|
106
113
|
set dateCalendarType(calendar) {
|
|
114
|
+
this.guard();
|
|
107
115
|
this.date.calendar = { val: calendar };
|
|
108
116
|
}
|
|
109
117
|
/** `w:storeMappedDataAs`: how a bound date is written into the custom XML ('dateTime', 'date', 'text'). */
|
|
@@ -112,6 +120,7 @@ export class DatePickerContentControl {
|
|
|
112
120
|
return (_b = (_a = this.date.storeMappedDataAs) === null || _a === void 0 ? void 0 : _a.val) !== null && _b !== void 0 ? _b : 'text';
|
|
113
121
|
}
|
|
114
122
|
set dateStorageFormat(format) {
|
|
123
|
+
this.guard();
|
|
115
124
|
this.date.storeMappedDataAs = { val: format };
|
|
116
125
|
}
|
|
117
126
|
/** `w:fullDate`, the date itself when Word has one (extension). */
|
|
@@ -123,6 +132,7 @@ export class DatePickerContentControl {
|
|
|
123
132
|
return new Date(Date.UTC(c.year, ((_a = c.month) !== null && _a !== void 0 ? _a : 1) - 1, (_b = c.day) !== null && _b !== void 0 ? _b : 1, (_c = c.hour) !== null && _c !== void 0 ? _c : 0, (_d = c.minute) !== null && _d !== void 0 ? _d : 0, Math.floor((_e = c.second) !== null && _e !== void 0 ? _e : 0)));
|
|
124
133
|
}
|
|
125
134
|
set fullDate(value) {
|
|
135
|
+
this.guard();
|
|
126
136
|
if (!value) {
|
|
127
137
|
delete this.date.fullDate;
|
|
128
138
|
return;
|
|
@@ -135,15 +145,17 @@ export class DatePickerContentControl {
|
|
|
135
145
|
}
|
|
136
146
|
/** One entry of a drop-down list or combo box (Office JS `Word.ContentControlListItem`). */
|
|
137
147
|
export class ContentControlListItem {
|
|
138
|
-
constructor(items, item) {
|
|
148
|
+
constructor(items, item, guard = () => { }) {
|
|
139
149
|
this.items = items;
|
|
140
150
|
this.item = item;
|
|
151
|
+
this.guard = guard;
|
|
141
152
|
}
|
|
142
153
|
get displayText() {
|
|
143
154
|
var _a;
|
|
144
155
|
return (_a = this.item.displayText) !== null && _a !== void 0 ? _a : '';
|
|
145
156
|
}
|
|
146
157
|
set displayText(text) {
|
|
158
|
+
this.guard();
|
|
147
159
|
this.item.displayText = text;
|
|
148
160
|
}
|
|
149
161
|
get value() {
|
|
@@ -151,12 +163,14 @@ export class ContentControlListItem {
|
|
|
151
163
|
return (_a = this.item.value) !== null && _a !== void 0 ? _a : '';
|
|
152
164
|
}
|
|
153
165
|
set value(value) {
|
|
166
|
+
this.guard();
|
|
154
167
|
this.item.value = value;
|
|
155
168
|
}
|
|
156
169
|
get index() {
|
|
157
170
|
return this.items.indexOf(this.item);
|
|
158
171
|
}
|
|
159
172
|
delete() {
|
|
173
|
+
this.guard();
|
|
160
174
|
const at = this.index;
|
|
161
175
|
if (at >= 0)
|
|
162
176
|
this.items.splice(at, 1);
|
|
@@ -164,28 +178,32 @@ export class ContentControlListItem {
|
|
|
164
178
|
}
|
|
165
179
|
/** Office JS `Word.DropDownListContentControl` / `Word.ComboBoxContentControl`: the same shape. */
|
|
166
180
|
export class ListContentControl {
|
|
167
|
-
|
|
181
|
+
/** `guard` refuses a write to a control in a branch of a kept `mc:AlternateContent` (CR-013 D4). */
|
|
182
|
+
constructor(list, guard = () => { }) {
|
|
168
183
|
this.list = list;
|
|
184
|
+
this.guard = guard;
|
|
169
185
|
}
|
|
170
186
|
get listItems() {
|
|
171
187
|
var _a;
|
|
172
188
|
var _b;
|
|
173
189
|
const items = ((_a = (_b = this.list).listItem) !== null && _a !== void 0 ? _a : (_b.listItem = []));
|
|
174
|
-
return items.map((item) => new ContentControlListItem(items, item));
|
|
190
|
+
return items.map((item) => new ContentControlListItem(items, item, this.guard));
|
|
175
191
|
}
|
|
176
192
|
/** Adds an entry; `value` defaults to the display text, `index` appends when omitted. */
|
|
177
193
|
addListItem(displayText, value, index) {
|
|
178
194
|
var _a;
|
|
179
195
|
var _b;
|
|
196
|
+
this.guard();
|
|
180
197
|
const items = ((_a = (_b = this.list).listItem) !== null && _a !== void 0 ? _a : (_b.listItem = []));
|
|
181
198
|
const item = { TYPE_NAME: 'org_docx4j_wml.CTSdtListItem', displayText, value: value !== null && value !== void 0 ? value : displayText };
|
|
182
199
|
if (index === undefined || index >= items.length)
|
|
183
200
|
items.push(item);
|
|
184
201
|
else
|
|
185
202
|
items.splice(Math.max(0, index), 0, item);
|
|
186
|
-
return new ContentControlListItem(items, item);
|
|
203
|
+
return new ContentControlListItem(items, item, this.guard);
|
|
187
204
|
}
|
|
188
205
|
deleteAllListItems() {
|
|
206
|
+
this.guard();
|
|
189
207
|
this.list.listItem = [];
|
|
190
208
|
}
|
|
191
209
|
/** `w:lastValue`, what Word last showed (extension). */
|
|
@@ -194,6 +212,7 @@ export class ListContentControl {
|
|
|
194
212
|
return (_a = this.list.lastValue) !== null && _a !== void 0 ? _a : '';
|
|
195
213
|
}
|
|
196
214
|
set lastValue(value) {
|
|
215
|
+
this.guard();
|
|
197
216
|
this.list.lastValue = value;
|
|
198
217
|
}
|
|
199
218
|
}
|
|
@@ -227,6 +246,7 @@ export class RepeatingSectionContentControl {
|
|
|
227
246
|
return (_b = (_a = this.section.sectionTitle) === null || _a === void 0 ? void 0 : _a.val) !== null && _b !== void 0 ? _b : '';
|
|
228
247
|
}
|
|
229
248
|
set sectionTitle(title) {
|
|
249
|
+
this.control.assertWritable();
|
|
230
250
|
if (title === '') {
|
|
231
251
|
delete this.section.sectionTitle;
|
|
232
252
|
return;
|
|
@@ -239,6 +259,7 @@ export class RepeatingSectionContentControl {
|
|
|
239
259
|
return !(flag !== undefined && flag.val !== false);
|
|
240
260
|
}
|
|
241
261
|
set allowInsertDeleteSection(allow) {
|
|
262
|
+
this.control.assertWritable();
|
|
242
263
|
if (allow)
|
|
243
264
|
delete this.section.doNotAllowInsertDeleteSection;
|
|
244
265
|
else
|
|
@@ -22,11 +22,14 @@ export interface XPathsEntry {
|
|
|
22
22
|
export declare function xpathsEntriesOf(parts: CustomXmlPartLookup): Map<string, XPathsEntry>;
|
|
23
23
|
/**
|
|
24
24
|
* The node an `od:xpath` entry selects: the entry's XPath over the part its `storeItemID` names
|
|
25
|
-
* (the id compared without braces or case, as `getItem` does)
|
|
25
|
+
* (the id compared without braces or case, as `getItem` does), else, where it names none, the part
|
|
26
|
+
* its XPath fits, as a `w:dataBinding` is resolved (CR-020 D1, docx4j's `StoreItemResolver`; the
|
|
27
|
+
* entry is left as it is, and `repair` says which part was taken). What a tag-bound control's pass
|
|
26
28
|
* starts from; the note says why there is no node.
|
|
27
29
|
*/
|
|
28
30
|
export declare function selectEntryNode(entryId: string, parts: CustomXmlPartLookup): {
|
|
29
31
|
node: CustomXmlNode;
|
|
32
|
+
repair?: string;
|
|
30
33
|
} | {
|
|
31
34
|
note: string;
|
|
32
35
|
};
|
|
@@ -38,19 +38,22 @@ export function xpathsEntriesOf(parts) {
|
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
40
40
|
* The node an `od:xpath` entry selects: the entry's XPath over the part its `storeItemID` names
|
|
41
|
-
* (the id compared without braces or case, as `getItem` does)
|
|
41
|
+
* (the id compared without braces or case, as `getItem` does), else, where it names none, the part
|
|
42
|
+
* its XPath fits, as a `w:dataBinding` is resolved (CR-020 D1, docx4j's `StoreItemResolver`; the
|
|
43
|
+
* entry is left as it is, and `repair` says which part was taken). What a tag-bound control's pass
|
|
42
44
|
* starts from; the note says why there is no node.
|
|
43
45
|
*/
|
|
44
46
|
export function selectEntryNode(entryId, parts) {
|
|
45
|
-
var _a;
|
|
46
47
|
const entry = xpathsEntriesOf(parts).get(entryId);
|
|
47
48
|
if (!entry)
|
|
48
49
|
return { note: `od:xpath=${entryId}: no such entry in the XPaths part` };
|
|
49
|
-
const
|
|
50
|
-
if (!
|
|
50
|
+
const resolved = entry.storeItemID === '' ? undefined : parts.resolveStoreItem(entry.storeItemID, entry.xpath, entry.prefixMappings);
|
|
51
|
+
if (!resolved)
|
|
51
52
|
return { note: `od:xpath=${entryId}: no custom XML part ${entry.storeItemID}` };
|
|
52
|
-
const node = part.selectSingleNode(entry.xpath, entry.prefixMappings);
|
|
53
|
+
const node = resolved.part.selectSingleNode(entry.xpath, entry.prefixMappings);
|
|
53
54
|
if (!node)
|
|
54
55
|
return { note: `od:xpath=${entryId}: ${entry.xpath} selects nothing` };
|
|
55
|
-
|
|
56
|
+
if (!resolved.repaired)
|
|
57
|
+
return { node };
|
|
58
|
+
return { node, repair: `od:xpath=${entryId}: store item ${entry.storeItemID} names no custom XML part; ${resolved.part.part.partName.name} ${resolved.part.id} fits ${entry.xpath} and is used` };
|
|
56
59
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type * as wml from '@docx4j/generated-objects-ts/modules/org_docx4j_wml';
|
|
2
|
+
import type { Part } from '../../parts/Part.mjs';
|
|
3
|
+
import type { Element } from '../content/tree.mjs';
|
|
4
|
+
import type { ContentControl } from '../content/ContentControl.mjs';
|
|
5
|
+
/** docx4j's placeholder picture, a PNG, as base64. */
|
|
6
|
+
export declare const PICTURE_PLACEHOLDER_BASE64 = "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAIAAAAiOjnJAAAACXBIWXMAABYlAAAWJQFJUiTwAAACVklEQVR42u3cwU3jYBCGYRtx50gDNOUOckwDOaWBHNOBm6IAuEEBSByQIkv5B1njgGLP8xx3vasVeuVh82m3f/v46uDWHnwJEBbCQlggLISFsEBYCAthgbAQFsICYSEshAXCQlgU87jkF59Px+indvuDx9b+2PTH/y+sX/6gXdd9vr/O+U08ds+PnU/HdFtOIX+iT/8rncsbaxgGX8eNGcdx4TX0xsLfChEWwgJhISwq65f8pyAzP39jpZ6eX7yxcAoRFuTcYIQ26WyPSQenEGGBsBAWwgJhISxqMEITMkLjFCIsSDNC02CExilEWCAshIWwQFgIixqM0ISM0DiFCAvSjNA0GKFxChEWCAthISwQFsKiBiM0ISM0TiHCgjQjNA1GaJxChAXCQlgIC4SFsKjBCE3ICI1TiLAgzQhNgxEapxBhgbAQFsICYSEsajBCEzJC4xQiLEgzQtNghMYpRFggLISFsEBYCIsajNCEjNA4hQgL0ozQNBihcQoRFggLYSEsEBbCogYjNCEjNE4hwoI0IzQNRmicQoQFwkJYCAuEhbCowQhNyAiNU4iwIM0ITYMRGqcQYYGwEBbCAmEhLGowQhMyQuMUIixIM0LTYITGKURYICyEhbBAWAiLGozQhIzQOIUIC9KM0DQYoXEKERYIC2EhLBAWwqIGIzQhIzROIcKCNCM0DUZoNvfGuq57avoaaz7gsdU95o3Fmt9Yu/3h8m3WtZkfgXjsnh9Lf4PVLfyAFJxChIWwQFgIC2GBsBAWwgJhISyEBcJCWAgLhIWwEBb8+AbsaRgh6xNNrAAAAABJRU5ErkJggg==";
|
|
7
|
+
/** The drawing's extent, Word's: 1270000 EMU (100 points) square. */
|
|
8
|
+
export declare const PICTURE_PLACEHOLDER_EMU = 1270000;
|
|
9
|
+
/** The run holding the placeholder drawing in `source` (`scope` its drawing ids'), the image part added once per part. */
|
|
10
|
+
export declare function picturePlaceholderRun(source: Part, scope: object): Element<wml.R>;
|
|
11
|
+
/**
|
|
12
|
+
* Word's form for a picture control (`w:picture`): the flag, and its content one run holding the placeholder drawing, in
|
|
13
|
+
* a paragraph where the control is block-level. What a mapped control whose node is empty shows (CR-005 section 10, D1
|
|
14
|
+
* (a2)) and what `insertContentControl('Picture')` makes (D2), as Word's do. False, and nothing changed, where the
|
|
15
|
+
* control's body has no part to hold the image.
|
|
16
|
+
*/
|
|
17
|
+
export declare function showPicturePlaceholder(control: ContentControl): boolean;
|