@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.
Files changed (207) hide show
  1. package/NOTICE +4 -0
  2. package/README.md +92 -4
  3. package/dist/html/convert.mjs +2 -1
  4. package/dist/html/elements.mjs +2 -1
  5. package/dist/model/color/ColorMath.d.mts +29 -0
  6. package/dist/model/color/ColorMath.mjs +146 -0
  7. package/dist/model/color/ColorTables.d.mts +6 -0
  8. package/dist/model/color/ColorTables.mjs +83 -0
  9. package/dist/model/color/DrawingMLColors.d.mts +52 -0
  10. package/dist/model/color/DrawingMLColors.mjs +374 -0
  11. package/dist/model/color/ResolvedColor.d.mts +36 -0
  12. package/dist/model/color/ResolvedColor.mjs +65 -0
  13. package/dist/model/color/SpreadsheetColors.d.mts +36 -0
  14. package/dist/model/color/SpreadsheetColors.mjs +84 -0
  15. package/dist/model/color/StyleFill.d.mts +28 -0
  16. package/dist/model/color/StyleFill.mjs +21 -0
  17. package/dist/model/color/ThemeColors.d.mts +86 -0
  18. package/dist/model/color/ThemeColors.mjs +304 -0
  19. package/dist/model/color/WordColors.d.mts +71 -0
  20. package/dist/model/color/WordColors.mjs +121 -0
  21. package/dist/model/color/index.d.mts +6 -0
  22. package/dist/model/color/index.mjs +30 -0
  23. package/dist/model/content/Body.d.mts +145 -23
  24. package/dist/model/content/Body.mjs +507 -150
  25. package/dist/model/content/Comment.d.mts +23 -5
  26. package/dist/model/content/Comment.mjs +207 -26
  27. package/dist/model/content/ContentControl.d.mts +198 -19
  28. package/dist/model/content/ContentControl.mjs +672 -99
  29. package/dist/model/content/Font.d.mts +70 -17
  30. package/dist/model/content/Font.mjs +119 -36
  31. package/dist/model/content/InlinePicture.d.mts +11 -0
  32. package/dist/model/content/InlinePicture.mjs +21 -1
  33. package/dist/model/content/List.d.mts +6 -3
  34. package/dist/model/content/List.mjs +18 -8
  35. package/dist/model/content/Paragraph.d.mts +200 -14
  36. package/dist/model/content/Paragraph.mjs +898 -82
  37. package/dist/model/content/Range.d.mts +227 -12
  38. package/dist/model/content/Range.mjs +785 -59
  39. package/dist/model/content/ResolvedView.d.mts +104 -0
  40. package/dist/model/content/ResolvedView.mjs +596 -0
  41. package/dist/model/content/Table.d.mts +29 -3
  42. package/dist/model/content/Table.mjs +135 -49
  43. package/dist/model/content/TrackedChange.d.mts +174 -15
  44. package/dist/model/content/TrackedChange.mjs +734 -170
  45. package/dist/model/content/comments.d.mts +20 -6
  46. package/dist/model/content/comments.mjs +67 -57
  47. package/dist/model/content/generalException.d.mts +18 -0
  48. package/dist/model/content/generalException.mjs +24 -0
  49. package/dist/model/content/index.d.mts +10 -3
  50. package/dist/model/content/index.mjs +10 -2
  51. package/dist/model/content/mathText.d.mts +21 -0
  52. package/dist/model/content/mathText.mjs +267 -0
  53. package/dist/model/content/officeText.d.mts +27 -0
  54. package/dist/model/content/officeText.mjs +74 -0
  55. package/dist/model/content/ooxml.mjs +12 -1
  56. package/dist/model/content/outline.d.mts +5 -0
  57. package/dist/model/content/outline.mjs +13 -0
  58. package/dist/model/content/paraIds.d.mts +5 -0
  59. package/dist/model/content/paraIds.mjs +54 -0
  60. package/dist/model/content/placeholders.d.mts +110 -0
  61. package/dist/model/content/placeholders.mjs +253 -0
  62. package/dist/model/content/search.d.mts +74 -0
  63. package/dist/model/content/search.mjs +255 -9
  64. package/dist/model/content/spanEdits.d.mts +159 -0
  65. package/dist/model/content/spanEdits.mjs +728 -0
  66. package/dist/model/content/story.d.mts +47 -0
  67. package/dist/model/content/story.mjs +95 -0
  68. package/dist/model/content/tableColumns.d.mts +1 -1
  69. package/dist/model/content/tableColumns.mjs +108 -80
  70. package/dist/model/content/tableRevisions.d.mts +11 -3
  71. package/dist/model/content/tableRevisions.mjs +72 -42
  72. package/dist/model/content/tableRules.d.mts +30 -0
  73. package/dist/model/content/tableRules.mjs +102 -0
  74. package/dist/model/content/textBoxes.d.mts +18 -0
  75. package/dist/model/content/textBoxes.mjs +105 -0
  76. package/dist/model/content/trackedChangeFilter.d.mts +39 -0
  77. package/dist/model/content/trackedChangeFilter.mjs +81 -0
  78. package/dist/model/content/tracking.d.mts +63 -6
  79. package/dist/model/content/tracking.mjs +242 -22
  80. package/dist/model/content/tree.d.mts +172 -24
  81. package/dist/model/content/tree.mjs +328 -54
  82. package/dist/model/content/wordRange.d.mts +48 -0
  83. package/dist/model/content/wordRange.mjs +97 -0
  84. package/dist/model/customxml/CustomXmlPartCollection.d.mts +30 -1
  85. package/dist/model/customxml/CustomXmlPartCollection.mjs +81 -12
  86. package/dist/model/customxml/XmlMapping.d.mts +32 -8
  87. package/dist/model/customxml/XmlMapping.mjs +64 -10
  88. package/dist/model/customxml/bindings.d.mts +33 -4
  89. package/dist/model/customxml/bindings.mjs +171 -45
  90. package/dist/model/customxml/index.d.mts +1 -0
  91. package/dist/model/customxml/index.mjs +1 -0
  92. package/dist/model/customxml/kinds.d.mts +8 -3
  93. package/dist/model/customxml/kinds.mjs +26 -5
  94. package/dist/model/customxml/opendope.d.mts +4 -1
  95. package/dist/model/customxml/opendope.mjs +9 -6
  96. package/dist/model/customxml/picturePlaceholder.d.mts +17 -0
  97. package/dist/model/customxml/picturePlaceholder.mjs +32 -0
  98. package/dist/model/customxml/pictures.d.mts +4 -3
  99. package/dist/model/customxml/pictures.mjs +22 -8
  100. package/dist/model/customxml/storeItems.d.mts +57 -0
  101. package/dist/model/customxml/storeItems.mjs +122 -0
  102. package/dist/model/customxml/xhtml.mjs +23 -22
  103. package/dist/model/dateZone.d.mts +25 -0
  104. package/dist/model/dateZone.mjs +57 -0
  105. package/dist/model/index.d.mts +3 -0
  106. package/dist/model/index.mjs +5 -0
  107. package/dist/model/listnumbering/Emulator.d.mts +37 -5
  108. package/dist/model/listnumbering/Emulator.mjs +63 -9
  109. package/dist/model/properties/PropertyResolver.d.mts +74 -2
  110. package/dist/model/properties/PropertyResolver.mjs +133 -5
  111. package/dist/model/properties/catalogue.d.mts +19 -5
  112. package/dist/model/properties/catalogue.mjs +41 -15
  113. package/dist/model/properties/index.d.mts +1 -1
  114. package/dist/model/properties/log.d.mts +1 -1
  115. package/dist/model/properties/log.mjs +5 -5
  116. package/dist/model/properties/styleUtil.d.mts +3 -1
  117. package/dist/model/properties/styleUtil.mjs +20 -24
  118. package/dist/model/properties/table.mjs +4 -2
  119. package/dist/model/text/CaseMapping.d.mts +38 -0
  120. package/dist/model/text/CaseMapping.mjs +86 -0
  121. package/dist/model/text/Extractor.d.mts +349 -0
  122. package/dist/model/text/Extractor.mjs +2406 -0
  123. package/dist/model/text/LinkTargets.d.mts +45 -0
  124. package/dist/model/text/LinkTargets.mjs +170 -0
  125. package/dist/model/text/MarkdownExporter.d.mts +140 -0
  126. package/dist/model/text/MarkdownExporter.mjs +255 -0
  127. package/dist/model/text/PlainText.d.mts +29 -0
  128. package/dist/model/text/PlainText.mjs +542 -0
  129. package/dist/model/text/TextContext.d.mts +256 -0
  130. package/dist/model/text/TextContext.mjs +600 -0
  131. package/dist/model/text/TextOptions.d.mts +233 -0
  132. package/dist/model/text/TextOptions.mjs +419 -0
  133. package/dist/model/text/TextResult.d.mts +621 -0
  134. package/dist/model/text/TextResult.mjs +629 -0
  135. package/dist/model/text/Texts.d.mts +99 -0
  136. package/dist/model/text/Texts.mjs +187 -0
  137. package/dist/model/text/WmlToMarkdown.d.mts +120 -0
  138. package/dist/model/text/WmlToMarkdown.mjs +936 -0
  139. package/dist/model/text/caseMapping.generated.d.mts +7 -0
  140. package/dist/model/text/caseMapping.generated.mjs +214 -0
  141. package/dist/model/text/commonmark.d.mts +121 -0
  142. package/dist/model/text/commonmark.mjs +655 -0
  143. package/dist/model/text/index.d.mts +8 -0
  144. package/dist/model/text/index.mjs +9 -0
  145. package/dist/model/text/normalize.d.mts +8 -0
  146. package/dist/model/text/normalize.mjs +13 -0
  147. package/dist/model/text/outline.d.mts +4 -0
  148. package/dist/model/text/outline.mjs +71 -0
  149. package/dist/model/wordIntegers.d.mts +29 -0
  150. package/dist/model/wordIntegers.mjs +78 -0
  151. package/dist/office-js/document.mjs +15 -1
  152. package/dist/office-js/fragment.d.mts +7 -5
  153. package/dist/office-js/fragment.mjs +63 -14
  154. package/dist/office-js/proxy.d.mts +8 -0
  155. package/dist/office-js/proxy.mjs +29 -0
  156. package/dist/office-js/run.mjs +2 -0
  157. package/dist/office-js/supported.generated.mjs +16 -0
  158. package/dist/office-js/toApiScript.mjs +29 -12
  159. package/dist/opc/DirectoryPartStore.d.mts +6 -2
  160. package/dist/opc/DirectoryPartStore.mjs +11 -4
  161. package/dist/opc/FlatOpcPartStore.d.mts +4 -2
  162. package/dist/opc/FlatOpcPartStore.mjs +11 -8
  163. package/dist/opc/Load.d.mts +32 -0
  164. package/dist/opc/Load.mjs +115 -5
  165. package/dist/opc/PartStore.d.mts +34 -1
  166. package/dist/opc/PartStore.mjs +71 -8
  167. package/dist/opc/Save.d.mts +32 -0
  168. package/dist/opc/Save.mjs +110 -4
  169. package/dist/opc/ZipPartStore.d.mts +4 -2
  170. package/dist/opc/ZipPartStore.mjs +12 -7
  171. package/dist/opc/exceptions.d.mts +140 -0
  172. package/dist/opc/exceptions.mjs +108 -0
  173. package/dist/opc/index.d.mts +8 -5
  174. package/dist/opc/index.mjs +5 -3
  175. package/dist/opc/mce/preprocessor.d.mts +141 -5
  176. package/dist/opc/mce/preprocessor.mjs +119 -18
  177. package/dist/opc/mce/understood.d.mts +3 -11
  178. package/dist/opc/mce/understood.mjs +27 -23
  179. package/dist/opc/repair/breaks.d.mts +23 -0
  180. package/dist/opc/repair/breaks.mjs +288 -0
  181. package/dist/opc/repair/hosts.d.mts +12 -0
  182. package/dist/opc/repair/hosts.mjs +33 -0
  183. package/dist/opc/repair/mainRoot.d.mts +19 -0
  184. package/dist/opc/repair/mainRoot.mjs +168 -0
  185. package/dist/opc/repair/unknownElements.d.mts +8 -0
  186. package/dist/opc/repair/unknownElements.mjs +180 -0
  187. package/dist/opc/repair/wmlNames.generated.d.mts +2 -0
  188. package/dist/opc/repair/wmlNames.generated.mjs +80 -0
  189. package/dist/opc/skipped.d.mts +50 -0
  190. package/dist/opc/skipped.mjs +140 -0
  191. package/dist/packages/OpcPackage.d.mts +110 -4
  192. package/dist/packages/OpcPackage.mjs +123 -7
  193. package/dist/packages/WordprocessingMLPackage.d.mts +45 -8
  194. package/dist/packages/WordprocessingMLPackage.mjs +158 -21
  195. package/dist/packages/index.d.mts +1 -1
  196. package/dist/parts/DefaultXmlPart.mjs +2 -2
  197. package/dist/parts/Part.d.mts +14 -2
  198. package/dist/parts/RelationshipsPart.d.mts +15 -0
  199. package/dist/parts/RelationshipsPart.mjs +66 -1
  200. package/dist/parts/XmlPart.d.mts +63 -32
  201. package/dist/parts/XmlPart.mjs +240 -96
  202. package/dist/parts/wml/comments.mjs +30 -0
  203. package/dist/parts/wml/index.d.mts +12 -1
  204. package/dist/parts/wml/index.mjs +37 -1
  205. package/dist/xml/dom.d.mts +7 -0
  206. package/dist/xml/dom.mjs +18 -0
  207. 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
- /** The style Word gives placeholder text, and the text docx4j's placeholder.xml carries. */
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
- /** docx4j's placeholder.xml: a PlaceholderText-styled run, which goes with w:showingPlcHdr. */
53
- function placeholderRun(rPr) {
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
- return el.r({ rPr: properties, content: [el.t({ value: PLACEHOLDER_TEXT })] });
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 hours12 = date.getHours() % 12 === 0 ? 12 : date.getHours() % 12;
75
- return pattern.replace(/d{1,4}|M{1,4}|y{2,4}|H{1,2}|h{1,2}|m{1,2}|s{1,2}|tt|'[^']*'|"[^"]*"/g, (token) => {
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.getDate());
80
- case 'dd': return pad(date.getDate(), 2);
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.getMonth() + 1);
84
- case 'MM': return pad(date.getMonth() + 1, 2);
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.getFullYear() % 100, 2);
138
+ case 'yy': return pad(date.getUTCFullYear() % 100, 2);
88
139
  case 'yyy':
89
- case 'yyyy': return String(date.getFullYear());
90
- case 'H': return String(date.getHours());
91
- case 'HH': return pad(date.getHours(), 2);
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.getMinutes());
95
- case 'mm': return pad(date.getMinutes(), 2);
96
- case 's': return String(date.getSeconds());
97
- case 'ss': return pad(date.getSeconds(), 2);
98
- case 'tt': return date.getHours() < 12 ? 'AM' : 'PM';
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` (local, as `w:fullDate` without a zone). */
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.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
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
- /** The date a bound value holds, when it is one (`2015-01-29T00:00:00`, `2015-01-29`, or with a Z). */
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
- if (!/^\d{4}-\d{2}-\d{2}([T ]\d{2}:\d{2}(:\d{2})?)?/.test(value))
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 parsed = new Date(value.replace(/Z$/, '').replace(' ', 'T'));
113
- return Number.isNaN(parsed.getTime()) ? undefined : parsed;
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
- if (!mapping.isMapped)
216
+ const binding = mapping.dataBinding;
217
+ if (!binding)
125
218
  return false;
126
- const node = mapping.customXmlNode;
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
- const value = node.text.trim();
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
- if (sdtProperty(control.sdt.sdtPr, 'richText') !== undefined)
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 parsed = dateOf(value);
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, date.dateDisplayLocale || undefined);
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.isMapped)
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
- if (!mapping.isMapped)
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
- if (sdtProperty(control.sdt.sdtPr, 'richText') !== undefined)
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.text;
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.isMapped)
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
- constructor(date: wml.CTSdtDate);
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
- constructor(items: wml.CTSdtListItem[], item: wml.CTSdtListItem);
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
- constructor(list: wml.CTSdtDropDownList | wml.CTSdtComboBox);
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
- constructor(date) {
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
- constructor(list) {
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). What a tag-bound control's pass
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). What a tag-bound control's pass
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 part = (_a = parts.getItem(entry.storeItemID)) !== null && _a !== void 0 ? _a : parts.items.find((p) => p.id.replace(/[{}]/g, '').toLowerCase() === entry.storeItemID.replace(/[{}]/g, '').toLowerCase());
50
- if (!part)
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
- return { node };
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;