@getodk/xforms-engine 0.2.0 → 0.4.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 (292) hide show
  1. package/dist/client/BaseNode.d.ts +69 -4
  2. package/dist/client/EngineConfig.d.ts +0 -1
  3. package/dist/client/GroupNode.d.ts +4 -3
  4. package/dist/client/ModelValueNode.d.ts +36 -0
  5. package/dist/client/NodeAppearances.d.ts +1 -2
  6. package/dist/client/NoteNode.d.ts +52 -0
  7. package/dist/client/RootNode.d.ts +4 -3
  8. package/dist/client/SelectNode.d.ts +6 -5
  9. package/dist/client/StringNode.d.ts +6 -5
  10. package/dist/client/SubtreeNode.d.ts +3 -2
  11. package/dist/client/TextRange.d.ts +85 -3
  12. package/dist/client/TriggerNode.d.ts +25 -0
  13. package/dist/client/constants.d.ts +8 -0
  14. package/dist/client/hierarchy.d.ts +19 -10
  15. package/dist/client/index.d.ts +0 -1
  16. package/dist/client/node-types.d.ts +3 -1
  17. package/dist/client/{RepeatRangeNode.d.ts → repeat/BaseRepeatRangeNode.d.ts} +18 -18
  18. package/dist/client/{RepeatInstanceNode.d.ts → repeat/RepeatInstanceNode.d.ts} +9 -9
  19. package/dist/client/repeat/RepeatRangeControlledNode.d.ts +18 -0
  20. package/dist/client/repeat/RepeatRangeUncontrolledNode.d.ts +19 -0
  21. package/dist/client/unsupported/RangeNode.d.ts +9 -0
  22. package/dist/client/unsupported/RankNode.d.ts +9 -0
  23. package/dist/client/unsupported/UnsupportedControlNode.d.ts +32 -0
  24. package/dist/client/unsupported/UploadNode.d.ts +9 -0
  25. package/dist/client/validation.d.ts +162 -0
  26. package/dist/index.d.ts +14 -6
  27. package/dist/index.js +39696 -36151
  28. package/dist/index.js.map +1 -1
  29. package/dist/instance/Group.d.ts +3 -2
  30. package/dist/instance/ModelValue.d.ts +39 -0
  31. package/dist/instance/Note.d.ts +41 -0
  32. package/dist/instance/Root.d.ts +5 -4
  33. package/dist/instance/SelectField.d.ts +11 -6
  34. package/dist/instance/StringField.d.ts +12 -7
  35. package/dist/instance/Subtree.d.ts +2 -1
  36. package/dist/instance/TriggerControl.d.ts +40 -0
  37. package/dist/instance/abstract/DescendantNode.d.ts +8 -10
  38. package/dist/instance/abstract/InstanceNode.d.ts +3 -2
  39. package/dist/instance/abstract/UnsupportedControl.d.ts +46 -0
  40. package/dist/instance/children.d.ts +0 -1
  41. package/dist/instance/hierarchy.d.ts +15 -6
  42. package/dist/instance/index.d.ts +0 -1
  43. package/dist/instance/internal-api/EvaluationContext.d.ts +0 -1
  44. package/dist/instance/internal-api/InstanceConfig.d.ts +0 -1
  45. package/dist/instance/internal-api/SubscribableDependency.d.ts +0 -1
  46. package/dist/instance/internal-api/TranslationContext.d.ts +0 -1
  47. package/dist/instance/internal-api/ValidationContext.d.ts +28 -0
  48. package/dist/instance/internal-api/ValueContext.d.ts +3 -4
  49. package/dist/instance/{RepeatRange.d.ts → repeat/BaseRepeatRange.d.ts} +46 -46
  50. package/dist/instance/{RepeatInstance.d.ts → repeat/RepeatInstance.d.ts} +13 -13
  51. package/dist/instance/repeat/RepeatRangeControlled.d.ts +15 -0
  52. package/dist/instance/repeat/RepeatRangeUncontrolled.d.ts +34 -0
  53. package/dist/instance/resource.d.ts +0 -1
  54. package/dist/instance/text/TextChunk.d.ts +0 -1
  55. package/dist/instance/text/TextRange.d.ts +4 -5
  56. package/dist/instance/unsupported/RangeControl.d.ts +4 -0
  57. package/dist/instance/unsupported/RankControl.d.ts +4 -0
  58. package/dist/instance/unsupported/UploadControl.d.ts +4 -0
  59. package/dist/lib/TokenListParser.d.ts +3 -3
  60. package/dist/lib/dom/query.d.ts +1 -2
  61. package/dist/lib/reactivity/createChildrenState.d.ts +0 -1
  62. package/dist/lib/reactivity/createComputedExpression.d.ts +7 -3
  63. package/dist/lib/reactivity/createNoteReadonlyThunk.d.ts +4 -0
  64. package/dist/lib/reactivity/createSelectItems.d.ts +0 -1
  65. package/dist/lib/reactivity/createValueState.d.ts +0 -1
  66. package/dist/lib/reactivity/materializeCurrentStateChildren.d.ts +0 -1
  67. package/dist/lib/reactivity/node-state/createClientState.d.ts +0 -1
  68. package/dist/lib/reactivity/node-state/createCurrentState.d.ts +0 -1
  69. package/dist/lib/reactivity/node-state/createEngineState.d.ts +0 -1
  70. package/dist/lib/reactivity/node-state/createSharedNodeState.d.ts +1 -2
  71. package/dist/lib/reactivity/node-state/createSpecifiedPropertyDescriptor.d.ts +0 -1
  72. package/dist/lib/reactivity/node-state/createSpecifiedState.d.ts +1 -2
  73. package/dist/lib/reactivity/node-state/representations.d.ts +0 -1
  74. package/dist/lib/reactivity/scope.d.ts +0 -1
  75. package/dist/lib/reactivity/text/createFieldHint.d.ts +3 -4
  76. package/dist/lib/reactivity/text/createNodeLabel.d.ts +3 -4
  77. package/dist/lib/reactivity/text/createNoteText.d.ts +24 -0
  78. package/dist/lib/reactivity/text/createTextRange.d.ts +5 -8
  79. package/dist/lib/reactivity/types.d.ts +0 -1
  80. package/dist/lib/reactivity/validation/createAggregatedViolations.d.ts +8 -0
  81. package/dist/lib/reactivity/validation/createValidation.d.ts +17 -0
  82. package/dist/{XFormDOM.d.ts → parse/XFormDOM.d.ts} +1 -2
  83. package/dist/{XFormDataType.d.ts → parse/XFormDataType.d.ts} +2 -4
  84. package/dist/{XFormDefinition.d.ts → parse/XFormDefinition.d.ts} +2 -3
  85. package/dist/{body → parse/body}/BodyDefinition.d.ts +15 -10
  86. package/dist/{body → parse/body}/BodyElementDefinition.d.ts +8 -7
  87. package/dist/{body → parse/body}/RepeatElementDefinition.d.ts +4 -5
  88. package/dist/{body → parse/body}/UnsupportedBodyElementDefinition.d.ts +0 -1
  89. package/dist/{body → parse/body}/appearance/inputAppearanceParser.d.ts +1 -2
  90. package/dist/{body → parse/body}/appearance/selectAppearanceParser.d.ts +1 -2
  91. package/dist/{body → parse/body}/appearance/structureElementAppearanceParser.d.ts +1 -2
  92. package/dist/parse/body/appearance/unknownAppearanceParser.d.ts +3 -0
  93. package/dist/{body → parse/body}/control/ControlDefinition.d.ts +3 -4
  94. package/dist/{body → parse/body}/control/InputDefinition.d.ts +1 -2
  95. package/dist/parse/body/control/RangeControlDefinition.d.ts +11 -0
  96. package/dist/parse/body/control/RankControlDefinition.d.ts +11 -0
  97. package/dist/parse/body/control/TriggerControlDefinition.d.ts +11 -0
  98. package/dist/parse/body/control/UploadControlDefinition.d.ts +11 -0
  99. package/dist/{body → parse/body}/control/select/ItemDefinition.d.ts +3 -4
  100. package/dist/{body → parse/body}/control/select/ItemsetDefinition.d.ts +7 -7
  101. package/dist/{body → parse/body}/control/select/ItemsetNodesetContext.d.ts +2 -3
  102. package/dist/{body → parse/body}/control/select/SelectDefinition.d.ts +3 -12
  103. package/dist/{body → parse/body}/group/BaseGroupDefinition.d.ts +3 -5
  104. package/dist/{body → parse/body}/group/LogicalGroupDefinition.d.ts +0 -1
  105. package/dist/{body → parse/body}/group/PresentationGroupDefinition.d.ts +1 -2
  106. package/dist/{body → parse/body}/group/StructuralGroupDefinition.d.ts +0 -1
  107. package/dist/{model/BindComputation.d.ts → parse/expression/BindComputationExpression.d.ts} +5 -6
  108. package/dist/{body/control/select → parse/expression}/ItemsetNodesetExpression.d.ts +2 -3
  109. package/dist/{body/control/select → parse/expression}/ItemsetValueExpression.d.ts +2 -3
  110. package/dist/parse/expression/RepeatCountControlExpression.d.ts +18 -0
  111. package/dist/parse/expression/TextLiteralExpression.d.ts +9 -0
  112. package/dist/parse/expression/TextOutputExpression.d.ts +7 -0
  113. package/dist/parse/expression/TextReferenceExpression.d.ts +7 -0
  114. package/dist/parse/expression/TextTranslationExpression.d.ts +8 -0
  115. package/dist/{expression → parse/expression/abstract}/DependencyContext.d.ts +0 -1
  116. package/dist/{expression → parse/expression/abstract}/DependentExpression.d.ts +13 -10
  117. package/dist/parse/expression/abstract/TextChunkExpression.d.ts +17 -0
  118. package/dist/parse/model/BindDefinition.d.ts +39 -0
  119. package/dist/{model → parse/model}/BindElement.d.ts +1 -0
  120. package/dist/{model → parse/model}/DescendentNodeDefinition.d.ts +0 -1
  121. package/dist/{model/ValueNodeDefinition.d.ts → parse/model/LeafNodeDefinition.d.ts} +3 -4
  122. package/dist/{model → parse/model}/ModelBindMap.d.ts +0 -1
  123. package/dist/{model → parse/model}/ModelDefinition.d.ts +1 -2
  124. package/dist/{model → parse/model}/NodeDefinition.d.ts +8 -9
  125. package/dist/parse/model/NoteNodeDefinition.d.ts +30 -0
  126. package/dist/{model → parse/model}/RepeatInstanceDefinition.d.ts +3 -4
  127. package/dist/{model → parse/model}/RepeatRangeDefinition.d.ts +14 -5
  128. package/dist/{model → parse/model}/RepeatTemplateDefinition.d.ts +2 -3
  129. package/dist/{model → parse/model}/RootDefinition.d.ts +2 -3
  130. package/dist/{model → parse/model}/SubtreeDefinition.d.ts +1 -2
  131. package/dist/parse/text/HintDefinition.d.ts +8 -0
  132. package/dist/parse/text/ItemLabelDefinition.d.ts +8 -0
  133. package/dist/parse/text/ItemsetLabelDefinition.d.ts +12 -0
  134. package/dist/parse/text/LabelDefinition.d.ts +14 -0
  135. package/dist/parse/text/MessageDefinition.d.ts +14 -0
  136. package/dist/parse/text/abstract/TextElementDefinition.d.ts +22 -0
  137. package/dist/parse/text/abstract/TextRangeDefinition.d.ts +34 -0
  138. package/dist/parse/xpath/dependency-analysis.d.ts +40 -0
  139. package/dist/parse/xpath/path-resolution.d.ts +69 -0
  140. package/dist/parse/xpath/predicate-analysis.d.ts +29 -0
  141. package/dist/parse/xpath/reference-parsing.d.ts +17 -0
  142. package/dist/parse/xpath/semantic-analysis.d.ts +97 -0
  143. package/dist/parse/xpath/syntax-traversal.d.ts +68 -0
  144. package/dist/solid.js +8745 -5186
  145. package/dist/solid.js.map +1 -1
  146. package/package.json +15 -16
  147. package/src/client/BaseNode.ts +74 -8
  148. package/src/client/GroupNode.ts +4 -2
  149. package/src/client/ModelValueNode.ts +40 -0
  150. package/src/client/NodeAppearances.ts +1 -1
  151. package/src/client/NoteNode.ts +74 -0
  152. package/src/client/README.md +1 -0
  153. package/src/client/RootNode.ts +4 -2
  154. package/src/client/SelectNode.ts +6 -4
  155. package/src/client/StringNode.ts +6 -4
  156. package/src/client/SubtreeNode.ts +3 -1
  157. package/src/client/TextRange.ts +98 -2
  158. package/src/client/TriggerNode.ts +29 -0
  159. package/src/client/constants.ts +10 -0
  160. package/src/client/hierarchy.ts +43 -15
  161. package/src/client/node-types.ts +17 -2
  162. package/src/client/{RepeatRangeNode.ts → repeat/BaseRepeatRangeNode.ts} +18 -19
  163. package/src/client/{RepeatInstanceNode.ts → repeat/RepeatInstanceNode.ts} +10 -8
  164. package/src/client/repeat/RepeatRangeControlledNode.ts +20 -0
  165. package/src/client/repeat/RepeatRangeUncontrolledNode.ts +21 -0
  166. package/src/client/unsupported/RangeNode.ts +14 -0
  167. package/src/client/unsupported/RankNode.ts +14 -0
  168. package/src/client/unsupported/UnsupportedControlNode.ts +40 -0
  169. package/src/client/unsupported/UploadNode.ts +14 -0
  170. package/src/client/validation.ts +199 -0
  171. package/src/index.ts +21 -9
  172. package/src/instance/Group.ts +10 -4
  173. package/src/instance/ModelValue.ts +104 -0
  174. package/src/instance/Note.ts +142 -0
  175. package/src/instance/Root.ts +16 -6
  176. package/src/instance/SelectField.ts +29 -7
  177. package/src/instance/StringField.ts +36 -10
  178. package/src/instance/Subtree.ts +9 -3
  179. package/src/instance/TriggerControl.ts +134 -0
  180. package/src/instance/abstract/DescendantNode.ts +9 -10
  181. package/src/instance/abstract/InstanceNode.ts +29 -7
  182. package/src/instance/abstract/UnsupportedControl.ts +151 -0
  183. package/src/instance/children.ts +113 -16
  184. package/src/instance/hierarchy.ts +42 -5
  185. package/src/instance/index.ts +1 -1
  186. package/src/instance/internal-api/EvaluationContext.ts +1 -1
  187. package/src/instance/internal-api/ValidationContext.ts +32 -0
  188. package/src/instance/internal-api/ValueContext.ts +3 -3
  189. package/src/instance/{RepeatRange.ts → repeat/BaseRepeatRange.ts} +114 -99
  190. package/src/instance/{RepeatInstance.ts → repeat/RepeatInstance.ts} +27 -22
  191. package/src/instance/repeat/RepeatRangeControlled.ts +82 -0
  192. package/src/instance/repeat/RepeatRangeUncontrolled.ts +67 -0
  193. package/src/instance/text/TextRange.ts +10 -4
  194. package/src/instance/unsupported/RangeControl.ts +5 -0
  195. package/src/instance/unsupported/RankControl.ts +5 -0
  196. package/src/instance/unsupported/UploadControl.ts +5 -0
  197. package/src/lib/TokenListParser.ts +11 -7
  198. package/src/lib/dom/query.ts +1 -1
  199. package/src/lib/reactivity/createComputedExpression.ts +25 -27
  200. package/src/lib/reactivity/createNoteReadonlyThunk.ts +33 -0
  201. package/src/lib/reactivity/createSelectItems.ts +23 -16
  202. package/src/lib/reactivity/createValueState.ts +3 -3
  203. package/src/lib/reactivity/node-state/createSharedNodeState.ts +1 -1
  204. package/src/lib/reactivity/node-state/createSpecifiedState.ts +1 -1
  205. package/src/lib/reactivity/text/createFieldHint.ts +9 -7
  206. package/src/lib/reactivity/text/createNodeLabel.ts +8 -6
  207. package/src/lib/reactivity/text/createNoteText.ts +72 -0
  208. package/src/lib/reactivity/text/createTextRange.ts +17 -90
  209. package/src/lib/reactivity/validation/createAggregatedViolations.ts +75 -0
  210. package/src/lib/reactivity/validation/createValidation.ts +196 -0
  211. package/src/{XFormDataType.ts → parse/XFormDataType.ts} +1 -3
  212. package/src/{XFormDefinition.ts → parse/XFormDefinition.ts} +2 -2
  213. package/src/{body → parse/body}/BodyDefinition.ts +44 -27
  214. package/src/{body → parse/body}/BodyElementDefinition.ts +13 -6
  215. package/src/{body → parse/body}/RepeatElementDefinition.ts +10 -20
  216. package/src/{body → parse/body}/appearance/inputAppearanceParser.ts +1 -1
  217. package/src/{body → parse/body}/appearance/selectAppearanceParser.ts +1 -1
  218. package/src/{body → parse/body}/appearance/structureElementAppearanceParser.ts +1 -1
  219. package/src/parse/body/appearance/unknownAppearanceParser.ts +5 -0
  220. package/src/{body → parse/body}/control/ControlDefinition.ts +5 -4
  221. package/src/parse/body/control/RangeControlDefinition.ts +26 -0
  222. package/src/parse/body/control/RankControlDefinition.ts +27 -0
  223. package/src/parse/body/control/TriggerControlDefinition.ts +26 -0
  224. package/src/parse/body/control/UploadControlDefinition.ts +26 -0
  225. package/src/{body → parse/body}/control/select/ItemDefinition.ts +4 -4
  226. package/src/parse/body/control/select/ItemsetDefinition.ts +53 -0
  227. package/src/{body → parse/body}/control/select/ItemsetNodesetContext.ts +2 -2
  228. package/src/{body → parse/body}/control/select/SelectDefinition.ts +3 -11
  229. package/src/{body → parse/body}/group/BaseGroupDefinition.ts +11 -21
  230. package/src/{body → parse/body}/group/PresentationGroupDefinition.ts +1 -1
  231. package/src/{model/BindComputation.ts → parse/expression/BindComputationExpression.ts} +8 -12
  232. package/src/parse/expression/ItemsetNodesetExpression.ts +8 -0
  233. package/src/{body/control/select → parse/expression}/ItemsetValueExpression.ts +2 -2
  234. package/src/parse/expression/RepeatCountControlExpression.ts +44 -0
  235. package/src/parse/expression/TextLiteralExpression.ts +19 -0
  236. package/src/parse/expression/TextOutputExpression.ts +25 -0
  237. package/src/parse/expression/TextReferenceExpression.ts +14 -0
  238. package/src/parse/expression/TextTranslationExpression.ts +38 -0
  239. package/src/{expression → parse/expression/abstract}/DependentExpression.ts +46 -28
  240. package/src/parse/expression/abstract/TextChunkExpression.ts +38 -0
  241. package/src/{model → parse/model}/BindDefinition.ts +30 -27
  242. package/src/{model → parse/model}/BindElement.ts +1 -0
  243. package/src/{model/ValueNodeDefinition.ts → parse/model/LeafNodeDefinition.ts} +4 -4
  244. package/src/{model → parse/model}/ModelBindMap.ts +4 -0
  245. package/src/{model → parse/model}/NodeDefinition.ts +12 -12
  246. package/src/parse/model/NoteNodeDefinition.ts +70 -0
  247. package/src/{model → parse/model}/RepeatInstanceDefinition.ts +2 -2
  248. package/src/parse/model/RepeatRangeDefinition.ts +94 -0
  249. package/src/{model → parse/model}/RootDefinition.ts +8 -4
  250. package/src/parse/text/HintDefinition.ts +25 -0
  251. package/src/parse/text/ItemLabelDefinition.ts +25 -0
  252. package/src/parse/text/ItemsetLabelDefinition.ts +44 -0
  253. package/src/parse/text/LabelDefinition.ts +61 -0
  254. package/src/parse/text/MessageDefinition.ts +49 -0
  255. package/src/parse/text/abstract/TextElementDefinition.ts +71 -0
  256. package/src/parse/text/abstract/TextRangeDefinition.ts +70 -0
  257. package/src/parse/xpath/dependency-analysis.ts +105 -0
  258. package/src/parse/xpath/path-resolution.ts +475 -0
  259. package/src/parse/xpath/predicate-analysis.ts +61 -0
  260. package/src/parse/xpath/reference-parsing.ts +90 -0
  261. package/src/parse/xpath/semantic-analysis.ts +466 -0
  262. package/src/parse/xpath/syntax-traversal.ts +129 -0
  263. package/dist/body/text/HintDefinition.d.ts +0 -11
  264. package/dist/body/text/LabelDefinition.d.ts +0 -22
  265. package/dist/body/text/TextElementDefinition.d.ts +0 -33
  266. package/dist/body/text/TextElementOutputPart.d.ts +0 -13
  267. package/dist/body/text/TextElementPart.d.ts +0 -13
  268. package/dist/body/text/TextElementReferencePart.d.ts +0 -7
  269. package/dist/body/text/TextElementStaticPart.d.ts +0 -7
  270. package/dist/lib/xpath/analysis.d.ts +0 -23
  271. package/dist/model/BindDefinition.d.ts +0 -32
  272. package/src/body/control/select/ItemsetDefinition.ts +0 -36
  273. package/src/body/control/select/ItemsetNodesetExpression.ts +0 -8
  274. package/src/body/text/HintDefinition.ts +0 -26
  275. package/src/body/text/LabelDefinition.ts +0 -68
  276. package/src/body/text/TextElementDefinition.ts +0 -97
  277. package/src/body/text/TextElementOutputPart.ts +0 -27
  278. package/src/body/text/TextElementPart.ts +0 -31
  279. package/src/body/text/TextElementReferencePart.ts +0 -21
  280. package/src/body/text/TextElementStaticPart.ts +0 -26
  281. package/src/lib/xpath/analysis.ts +0 -241
  282. package/src/model/RepeatRangeDefinition.ts +0 -53
  283. package/src/{XFormDOM.ts → parse/XFormDOM.ts} +0 -0
  284. package/src/{body → parse/body}/UnsupportedBodyElementDefinition.ts +0 -0
  285. package/src/{body → parse/body}/control/InputDefinition.ts +1 -1
  286. /package/src/{body → parse/body}/group/LogicalGroupDefinition.ts +0 -0
  287. /package/src/{body → parse/body}/group/StructuralGroupDefinition.ts +0 -0
  288. /package/src/{expression → parse/expression/abstract}/DependencyContext.ts +0 -0
  289. /package/src/{model → parse/model}/DescendentNodeDefinition.ts +0 -0
  290. /package/src/{model → parse/model}/ModelDefinition.ts +0 -0
  291. /package/src/{model → parse/model}/RepeatTemplateDefinition.ts +0 -0
  292. /package/src/{model → parse/model}/SubtreeDefinition.ts +0 -0
@@ -17,6 +17,10 @@ class ArtificialBindElement implements BindElement {
17
17
 
18
18
  return null;
19
19
  }
20
+
21
+ getAttributeNS() {
22
+ return null;
23
+ }
20
24
  }
21
25
 
22
26
  type TopologicalSortIndex = number;
@@ -1,12 +1,12 @@
1
1
  import type { AnyBodyElementDefinition } from '../body/BodyDefinition.ts';
2
2
  import type { RepeatElementDefinition } from '../body/RepeatElementDefinition.ts';
3
3
  import type { BindDefinition } from './BindDefinition.ts';
4
+ import type { LeafNodeDefinition } from './LeafNodeDefinition.ts';
4
5
  import type { RepeatInstanceDefinition } from './RepeatInstanceDefinition.ts';
5
- import type { RepeatRangeDefinition } from './RepeatRangeDefinition.ts';
6
+ import type { AnyRepeatRangeDefinition } from './RepeatRangeDefinition.ts';
6
7
  import type { RepeatTemplateDefinition } from './RepeatTemplateDefinition.ts';
7
8
  import type { RootDefinition } from './RootDefinition.ts';
8
9
  import type { SubtreeDefinition } from './SubtreeDefinition.ts';
9
- import type { ValueNodeDefinition } from './ValueNodeDefinition.ts';
10
10
 
11
11
  /**
12
12
  * Corresponds to the model/entry DOM root node, i.e.:
@@ -49,7 +49,7 @@ export type SubtreeNodeType = 'subtree';
49
49
  * - An element with no child elements
50
50
  * - Any attribute corresponding to a bind's `nodeset` expression
51
51
  */
52
- export type ValueNodeType = 'value-node';
52
+ export type LeafNodeType = 'leaf-node';
53
53
 
54
54
  // prettier-ignore
55
55
  export type NodeDefinitionType =
@@ -59,7 +59,7 @@ export type NodeDefinitionType =
59
59
  | RepeatTemplateType
60
60
  | RepeatInstanceType
61
61
  | SubtreeNodeType
62
- | ValueNodeType;
62
+ | LeafNodeType;
63
63
 
64
64
  // prettier-ignore
65
65
  export type ParentNodeDefinition =
@@ -71,9 +71,9 @@ export type ParentNodeDefinition =
71
71
 
72
72
  // prettier-ignore
73
73
  export type ChildNodeDefinition =
74
- | RepeatRangeDefinition
75
- | SubtreeDefinition
76
- | ValueNodeDefinition;
74
+ | AnyRepeatRangeDefinition
75
+ | LeafNodeDefinition
76
+ | SubtreeDefinition;
77
77
 
78
78
  // prettier-ignore
79
79
  export type ChildNodeInstanceDefinition =
@@ -81,7 +81,7 @@ export type ChildNodeInstanceDefinition =
81
81
  | RepeatTemplateDefinition
82
82
  | RepeatInstanceDefinition
83
83
  | SubtreeDefinition
84
- | ValueNodeDefinition;
84
+ | LeafNodeDefinition;
85
85
 
86
86
  // prettier-ignore
87
87
  export type NodeChildren<Type extends NodeDefinitionType> =
@@ -101,7 +101,7 @@ export type NodeParent<Type extends NodeDefinitionType> =
101
101
  ? ParentNodeDefinition
102
102
  : null;
103
103
 
104
- // TODO: value-node may be Attr
104
+ // TODO: leaf-node may be Attr
105
105
  // prettier-ignore
106
106
  export type ModelNode<Type extends NodeDefinitionType> =
107
107
  Type extends 'repeat-range'
@@ -110,7 +110,7 @@ export type ModelNode<Type extends NodeDefinitionType> =
110
110
 
111
111
  // prettier-ignore
112
112
  export type NodeDefaultValue<Type extends NodeDefinitionType> =
113
- Type extends 'value-node'
113
+ Type extends 'leaf-node'
114
114
  ? string
115
115
  : null;
116
116
 
@@ -137,10 +137,10 @@ export interface NodeDefinition<Type extends NodeDefinitionType> {
137
137
  export type AnyNodeDefinition =
138
138
  // eslint-disable-next-line @typescript-eslint/sort-type-constituents
139
139
  | RootDefinition
140
- | RepeatRangeDefinition
140
+ | AnyRepeatRangeDefinition
141
141
  | RepeatTemplateDefinition
142
142
  | RepeatInstanceDefinition
143
143
  | SubtreeDefinition
144
- | ValueNodeDefinition;
144
+ | LeafNodeDefinition;
145
145
 
146
146
  export type TypedNodeDefinition<Type> = Extract<AnyNodeDefinition, { readonly type: Type }>;
@@ -0,0 +1,70 @@
1
+ import type { NoteNode } from '../../client/NoteNode.ts';
2
+ import type { AnyBodyElementDefinition } from '../body/BodyDefinition.ts';
3
+ import type { InputDefinition } from '../body/control/InputDefinition.ts';
4
+ import { BindComputationExpression } from '../expression/BindComputationExpression.ts';
5
+ import type { ConstantTruthyDependentExpression } from '../expression/abstract/DependentExpression.ts';
6
+ import type { HintDefinition } from '../text/HintDefinition.ts';
7
+ import type { LabelDefinition } from '../text/LabelDefinition.ts';
8
+ import type { BindDefinition } from './BindDefinition.ts';
9
+ import { LeafNodeDefinition } from './LeafNodeDefinition.ts';
10
+ import type { ParentNodeDefinition } from './NodeDefinition.ts';
11
+
12
+ // prettier-ignore
13
+ export type NoteReadonlyDefinition =
14
+ & BindComputationExpression<'readonly'>
15
+ & ConstantTruthyDependentExpression;
16
+
17
+ export interface NoteBindDefinition extends BindDefinition {
18
+ readonly readonly: NoteReadonlyDefinition;
19
+ }
20
+
21
+ const isNoteBindDefinition = (bind: BindDefinition): bind is NoteBindDefinition => {
22
+ return bind.readonly.isConstantTruthyExpression();
23
+ };
24
+
25
+ // prettier-ignore
26
+ export type NoteTextDefinition =
27
+ // eslint-disable-next-line @typescript-eslint/sort-type-constituents
28
+ | LabelDefinition
29
+ | HintDefinition;
30
+
31
+ /**
32
+ * @package This class is used internally, both in static types and at runtime,
33
+ * to guard and guide the distinction between instance state nodes for 'note'
34
+ * and 'string' node types. It is intentionally package-private! The less
35
+ * specific {@link NoteNode.definition} type, if it has any client value at all,
36
+ * should be more than sufficient. Clients are otherwise expected to use other
37
+ * aspects of the node's interface (such as its {@link NoteNode.nodeType} and
38
+ * distinct {@link NoteNode.currentState} types) to handle note-specific logic.
39
+ */
40
+ export class NoteNodeDefinition extends LeafNodeDefinition {
41
+ static from(
42
+ parent: ParentNodeDefinition,
43
+ bind: BindDefinition,
44
+ bodyElement: AnyBodyElementDefinition | null,
45
+ node: Element
46
+ ): NoteNodeDefinition | null {
47
+ if (!isNoteBindDefinition(bind) || bodyElement?.type !== 'input') {
48
+ return null;
49
+ }
50
+
51
+ const { label, hint } = bodyElement;
52
+ const noteTextDefinition = label ?? hint;
53
+
54
+ if (noteTextDefinition == null) {
55
+ return null;
56
+ }
57
+
58
+ return new this(parent, bind, bodyElement, noteTextDefinition, node);
59
+ }
60
+
61
+ constructor(
62
+ parent: ParentNodeDefinition,
63
+ override readonly bind: NoteBindDefinition,
64
+ override readonly bodyElement: InputDefinition,
65
+ readonly noteTextDefinition: NoteTextDefinition,
66
+ node: Element
67
+ ) {
68
+ super(parent, bind, bodyElement, node);
69
+ }
70
+ }
@@ -1,7 +1,7 @@
1
1
  import { RepeatElementDefinition } from '../body/RepeatElementDefinition.ts';
2
2
  import { DescendentNodeDefinition } from './DescendentNodeDefinition.ts';
3
3
  import type { ChildNodeDefinition, NodeDefinition } from './NodeDefinition.ts';
4
- import type { RepeatRangeDefinition } from './RepeatRangeDefinition.ts';
4
+ import type { AnyRepeatRangeDefinition } from './RepeatRangeDefinition.ts';
5
5
 
6
6
  export class RepeatInstanceDefinition
7
7
  extends DescendentNodeDefinition<'repeat-instance', RepeatElementDefinition>
@@ -15,7 +15,7 @@ export class RepeatInstanceDefinition
15
15
  readonly defaultValue = null;
16
16
 
17
17
  constructor(
18
- range: RepeatRangeDefinition,
18
+ range: AnyRepeatRangeDefinition,
19
19
  readonly node: Element
20
20
  ) {
21
21
  const { bind, bodyElement, parent, root } = range;
@@ -0,0 +1,94 @@
1
+ import type { RepeatElementDefinition } from '../body/RepeatElementDefinition.ts';
2
+ import { RepeatCountControlExpression } from '../expression/RepeatCountControlExpression.ts';
3
+ import type { BindDefinition } from './BindDefinition.ts';
4
+ import { DescendentNodeDefinition } from './DescendentNodeDefinition.ts';
5
+ import type { NodeDefinition, ParentNodeDefinition } from './NodeDefinition.ts';
6
+ import { RepeatInstanceDefinition } from './RepeatInstanceDefinition.ts';
7
+ import { RepeatTemplateDefinition } from './RepeatTemplateDefinition.ts';
8
+
9
+ export interface ControlledRepeatRangeDefinition extends RepeatRangeDefinition {
10
+ readonly count: RepeatCountControlExpression;
11
+ }
12
+
13
+ export interface UncontrolledRepeatRangeDefinition extends RepeatRangeDefinition {
14
+ readonly count: null;
15
+ }
16
+
17
+ // prettier-ignore
18
+ export type AnyRepeatRangeDefinition =
19
+ | ControlledRepeatRangeDefinition
20
+ | UncontrolledRepeatRangeDefinition;
21
+
22
+ type AssertRepeatRangeDefinitionUnion = (
23
+ definition: RepeatRangeDefinition
24
+ ) => asserts definition is AnyRepeatRangeDefinition;
25
+
26
+ const assertRepeatRangeDefinitionUnion: AssertRepeatRangeDefinitionUnion = (_definition) => {
27
+ // Intentional no-op, used to guide the type checker. Implementation would
28
+ // check _definition.count == null || _definition.count != null, which is
29
+ // tautologically true!
30
+ };
31
+
32
+ export class RepeatRangeDefinition
33
+ extends DescendentNodeDefinition<'repeat-range', RepeatElementDefinition>
34
+ implements NodeDefinition<'repeat-range'>
35
+ {
36
+ static from(
37
+ parent: ParentNodeDefinition,
38
+ bind: BindDefinition,
39
+ bodyElement: RepeatElementDefinition,
40
+ modelNodes: readonly [Element, ...Element[]]
41
+ ): AnyRepeatRangeDefinition {
42
+ const definition = new this(parent, bind, bodyElement, modelNodes);
43
+
44
+ assertRepeatRangeDefinitionUnion(definition);
45
+
46
+ return definition;
47
+ }
48
+
49
+ readonly type = 'repeat-range';
50
+
51
+ readonly template: RepeatTemplateDefinition;
52
+ readonly children = null;
53
+ readonly instances: RepeatInstanceDefinition[];
54
+ readonly count: RepeatCountControlExpression | null;
55
+
56
+ readonly node = null;
57
+ readonly nodeName: string;
58
+ readonly defaultValue = null;
59
+
60
+ private constructor(
61
+ parent: ParentNodeDefinition,
62
+ bind: BindDefinition,
63
+ bodyElement: RepeatElementDefinition,
64
+ modelNodes: readonly [Element, ...Element[]]
65
+ ) {
66
+ super(parent, bind, bodyElement);
67
+
68
+ const { template, instanceNodes } = RepeatTemplateDefinition.parseModelNodes(this, modelNodes);
69
+
70
+ this.template = template;
71
+ this.nodeName = template.nodeName;
72
+ this.count = RepeatCountControlExpression.from(bodyElement, instanceNodes.length);
73
+
74
+ assertRepeatRangeDefinitionUnion(this);
75
+
76
+ this.instances = instanceNodes.map((element) => {
77
+ return new RepeatInstanceDefinition(this, element);
78
+ });
79
+ }
80
+
81
+ isControlled(): this is ControlledRepeatRangeDefinition {
82
+ return this.count != null;
83
+ }
84
+
85
+ isUncontrolled(): this is UncontrolledRepeatRangeDefinition {
86
+ return this.count == null;
87
+ }
88
+
89
+ toJSON() {
90
+ const { bind, bodyElement: groupDefinition, parent, root, ...rest } = this;
91
+
92
+ return rest;
93
+ }
94
+ }
@@ -1,15 +1,16 @@
1
- import type { XFormDefinition } from '../XFormDefinition.ts';
2
1
  import type { BodyClassList } from '../body/BodyDefinition.ts';
2
+ import type { XFormDefinition } from '../XFormDefinition.ts';
3
3
  import type { BindDefinition } from './BindDefinition.ts';
4
+ import { LeafNodeDefinition } from './LeafNodeDefinition.ts';
4
5
  import type { ModelDefinition } from './ModelDefinition.ts';
5
6
  import type {
6
7
  ChildNodeDefinition,
7
8
  NodeDefinition,
8
9
  ParentNodeDefinition,
9
10
  } from './NodeDefinition.ts';
11
+ import { NoteNodeDefinition } from './NoteNodeDefinition.ts';
10
12
  import { RepeatRangeDefinition } from './RepeatRangeDefinition.ts';
11
13
  import { SubtreeDefinition } from './SubtreeDefinition.ts';
12
- import { ValueNodeDefinition } from './ValueNodeDefinition.ts';
13
14
 
14
15
  export class RootDefinition implements NodeDefinition<'root'> {
15
16
  readonly type = 'root';
@@ -89,7 +90,7 @@ export class RootDefinition implements NodeDefinition<'root'> {
89
90
  const [firstChild, ...restChildren] = children;
90
91
 
91
92
  if (bodyElement?.type === 'repeat') {
92
- return new RepeatRangeDefinition(parent, bind, bodyElement, children);
93
+ return RepeatRangeDefinition.from(parent, bind, bodyElement, children);
93
94
  }
94
95
 
95
96
  if (restChildren.length) {
@@ -100,7 +101,10 @@ export class RootDefinition implements NodeDefinition<'root'> {
100
101
  const isLeafNode = element.childElementCount === 0;
101
102
 
102
103
  if (isLeafNode) {
103
- return new ValueNodeDefinition(parent, bind, bodyElement, element);
104
+ return (
105
+ NoteNodeDefinition.from(parent, bind, bodyElement, element) ??
106
+ new LeafNodeDefinition(parent, bind, bodyElement, element)
107
+ );
104
108
  }
105
109
 
106
110
  return new SubtreeDefinition(parent, bind, bodyElement, element);
@@ -0,0 +1,25 @@
1
+ import type { LocalNamedElement } from '@getodk/common/types/dom.ts';
2
+ import { getHintElement } from '../../lib/dom/query.ts';
3
+ import type { XFormDefinition } from '../../parse/XFormDefinition.ts';
4
+ import type { AnyControlDefinition } from '../body/control/ControlDefinition.ts';
5
+ import { TextElementDefinition } from './abstract/TextElementDefinition.ts';
6
+
7
+ interface HintElement extends LocalNamedElement<'hint'> {}
8
+
9
+ export class HintDefinition extends TextElementDefinition<'hint'> {
10
+ static forElement(form: XFormDefinition, owner: AnyControlDefinition): HintDefinition | null {
11
+ const hintElement = getHintElement(owner.element);
12
+
13
+ if (hintElement == null) {
14
+ return null;
15
+ }
16
+
17
+ return new this(form, owner, hintElement);
18
+ }
19
+
20
+ readonly role = 'hint';
21
+
22
+ private constructor(form: XFormDefinition, owner: AnyControlDefinition, element: HintElement) {
23
+ super(form, owner, element);
24
+ }
25
+ }
@@ -0,0 +1,25 @@
1
+ import type { LocalNamedElement } from '@getodk/common/types/dom.ts';
2
+ import { getLabelElement } from '../../lib/dom/query.ts';
3
+ import type { XFormDefinition } from '../../parse/XFormDefinition.ts';
4
+ import type { ItemDefinition } from '../body/control/select/ItemDefinition.ts';
5
+ import { TextElementDefinition } from './abstract/TextElementDefinition.ts';
6
+
7
+ interface LabelElement extends LocalNamedElement<'label'> {}
8
+
9
+ export class ItemLabelDefinition extends TextElementDefinition<'item-label'> {
10
+ static from(form: XFormDefinition, owner: ItemDefinition): ItemLabelDefinition | null {
11
+ const labelElement = getLabelElement(owner.element);
12
+
13
+ if (labelElement == null) {
14
+ return null;
15
+ }
16
+
17
+ return new this(form, owner, labelElement);
18
+ }
19
+
20
+ readonly role = 'item-label';
21
+
22
+ private constructor(form: XFormDefinition, owner: ItemDefinition, element: LabelElement) {
23
+ super(form, owner, element);
24
+ }
25
+ }
@@ -0,0 +1,44 @@
1
+ import type { LocalNamedElement } from '@getodk/common/types/dom.ts';
2
+ import { getLabelElement } from '../../lib/dom/query.ts';
3
+ import type { XFormDefinition } from '../../parse/XFormDefinition.ts';
4
+ import type { ItemDefinition } from '../body/control/select/ItemDefinition.ts';
5
+ import type { ItemsetDefinition } from '../body/control/select/ItemsetDefinition.ts';
6
+ import { TextReferenceExpression } from '../expression/TextReferenceExpression.ts';
7
+ import { TextTranslationExpression } from '../expression/TextTranslationExpression.ts';
8
+ import type { RefAttributeChunk } from './abstract/TextElementDefinition.ts';
9
+ import { TextRangeDefinition } from './abstract/TextRangeDefinition.ts';
10
+
11
+ export type ItemLabelOwner = ItemDefinition | ItemsetDefinition;
12
+
13
+ interface LabelElement extends LocalNamedElement<'label'> {}
14
+
15
+ export class ItemsetLabelDefinition extends TextRangeDefinition<'item-label'> {
16
+ static from(form: XFormDefinition, owner: ItemsetDefinition): ItemsetLabelDefinition | null {
17
+ const labelElement = getLabelElement(owner.element);
18
+
19
+ if (labelElement == null) {
20
+ return null;
21
+ }
22
+
23
+ return new this(form, owner, labelElement);
24
+ }
25
+
26
+ readonly role = 'item-label';
27
+ readonly chunks: readonly [RefAttributeChunk];
28
+
29
+ private constructor(form: XFormDefinition, owner: ItemsetDefinition, element: LabelElement) {
30
+ super(form, owner, element);
31
+
32
+ const refExpression = element.getAttribute('ref');
33
+
34
+ if (refExpression == null) {
35
+ throw new Error('<itemset><label> missing ref attribute');
36
+ }
37
+
38
+ const refChunk =
39
+ TextTranslationExpression.from(this, refExpression) ??
40
+ TextReferenceExpression.from(this, refExpression);
41
+
42
+ this.chunks = [refChunk];
43
+ }
44
+ }
@@ -0,0 +1,61 @@
1
+ import type { LocalNamedElement } from '@getodk/common/types/dom.ts';
2
+ import { getLabelElement, getRepeatGroupLabelElement } from '../../lib/dom/query.ts';
3
+ import type { XFormDefinition } from '../../parse/XFormDefinition.ts';
4
+ import type { AnyGroupElementDefinition } from '../../parse/body/BodyDefinition.ts';
5
+ import type { RepeatElementDefinition } from '../body/RepeatElementDefinition.ts';
6
+ import type { AnyControlDefinition } from '../body/control/ControlDefinition.ts';
7
+ import type { BaseGroupDefinition } from '../body/group/BaseGroupDefinition.ts';
8
+ import { TextElementDefinition } from './abstract/TextElementDefinition.ts';
9
+
10
+ // prettier-ignore
11
+ export type LabelOwner =
12
+ | AnyControlDefinition
13
+ | AnyGroupElementDefinition
14
+ | RepeatElementDefinition;
15
+
16
+ interface LabelElement extends LocalNamedElement<'label'> {}
17
+
18
+ export class LabelDefinition extends TextElementDefinition<'label'> {
19
+ static forControl(form: XFormDefinition, control: AnyControlDefinition): LabelDefinition | null {
20
+ const labelElement = getLabelElement(control.element);
21
+
22
+ if (labelElement == null) {
23
+ return null;
24
+ }
25
+
26
+ return new this(form, control, labelElement);
27
+ }
28
+
29
+ static forRepeatGroup(
30
+ form: XFormDefinition,
31
+ repeat: RepeatElementDefinition
32
+ ): LabelDefinition | null {
33
+ const repeatGroupLabel = getRepeatGroupLabelElement(repeat.element);
34
+
35
+ if (repeatGroupLabel == null) {
36
+ return null;
37
+ }
38
+
39
+ return new this(form, repeat, repeatGroupLabel);
40
+ }
41
+
42
+ static forGroup(
43
+ form: XFormDefinition,
44
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
+ group: BaseGroupDefinition<any>
46
+ ): LabelDefinition | null {
47
+ const labelElement = getLabelElement(group.element);
48
+
49
+ if (labelElement == null) {
50
+ return null;
51
+ }
52
+
53
+ return new this(form, group, labelElement);
54
+ }
55
+
56
+ readonly role = 'label';
57
+
58
+ private constructor(form: XFormDefinition, owner: LabelOwner, element: LabelElement) {
59
+ super(form, owner, element);
60
+ }
61
+ }
@@ -0,0 +1,49 @@
1
+ import { JAVAROSA_NAMESPACE_URI } from '@getodk/common/constants/xmlns.ts';
2
+ import { TextLiteralExpression } from '../expression/TextLiteralExpression.ts';
3
+ import { TextTranslationExpression } from '../expression/TextTranslationExpression.ts';
4
+ import type { BindDefinition } from '../model/BindDefinition.ts';
5
+ import type { TextBindAttributeLocalName, TextSourceNode } from './abstract/TextRangeDefinition.ts';
6
+ import { TextRangeDefinition } from './abstract/TextRangeDefinition.ts';
7
+
8
+ export type MessageSourceNode = TextSourceNode<TextBindAttributeLocalName>;
9
+
10
+ // prettier-ignore
11
+ type MessageChunk =
12
+ | TextLiteralExpression
13
+ | TextTranslationExpression;
14
+
15
+ export class MessageDefinition<
16
+ Type extends TextBindAttributeLocalName,
17
+ > extends TextRangeDefinition<Type> {
18
+ static from<Type extends TextBindAttributeLocalName>(
19
+ bind: BindDefinition,
20
+ type: Type
21
+ ): MessageDefinition<Type> | null {
22
+ const message = bind.bindElement.getAttributeNS(JAVAROSA_NAMESPACE_URI, type);
23
+
24
+ if (message == null) {
25
+ return null;
26
+ }
27
+
28
+ return new this(bind, type, message);
29
+ }
30
+
31
+ readonly chunks: readonly [MessageChunk];
32
+
33
+ private constructor(
34
+ bind: BindDefinition,
35
+ readonly role: Type,
36
+ message: string
37
+ ) {
38
+ super(bind.form, bind, null);
39
+
40
+ const chunk: MessageChunk =
41
+ TextTranslationExpression.fromMessage(this, message) ??
42
+ TextLiteralExpression.from(this, message);
43
+
44
+ this.chunks = [chunk];
45
+ }
46
+ }
47
+
48
+ // prettier-ignore
49
+ export type AnyMessageDefinition = MessageDefinition<TextBindAttributeLocalName>;
@@ -0,0 +1,71 @@
1
+ import { isElementNode, isTextNode } from '@getodk/common/lib/dom/predicates.ts';
2
+ import type { ElementTextRole } from '../../../client/TextRange.ts';
3
+ import type { XFormDefinition } from '../../../parse/XFormDefinition.ts';
4
+ import type { ItemDefinition } from '../../body/control/select/ItemDefinition.ts';
5
+ import { TextLiteralExpression } from '../../expression/TextLiteralExpression.ts';
6
+ import { TextOutputExpression } from '../../expression/TextOutputExpression.ts';
7
+ import { TextReferenceExpression } from '../../expression/TextReferenceExpression.ts';
8
+ import { TextTranslationExpression } from '../../expression/TextTranslationExpression.ts';
9
+ import { parseNodesetReference } from '../../xpath/reference-parsing.ts';
10
+ import type { HintDefinition } from '../HintDefinition.ts';
11
+ import type { ItemLabelDefinition } from '../ItemLabelDefinition.ts';
12
+ import type { ItemsetLabelDefinition } from '../ItemsetLabelDefinition.ts';
13
+ import type { LabelDefinition, LabelOwner } from '../LabelDefinition.ts';
14
+ import type { TextSourceNode } from './TextRangeDefinition.ts';
15
+ import { TextRangeDefinition } from './TextRangeDefinition.ts';
16
+
17
+ // prettier-ignore
18
+ export type RefAttributeChunk =
19
+ | TextReferenceExpression
20
+ | TextTranslationExpression;
21
+
22
+ // prettier-ignore
23
+ type TextElementChildChunk =
24
+ | TextOutputExpression
25
+ | TextLiteralExpression;
26
+
27
+ // prettier-ignore
28
+ type TextElementChunks =
29
+ | readonly [RefAttributeChunk]
30
+ | readonly TextElementChildChunk[];
31
+
32
+ type TextElementOwner = ItemDefinition | LabelOwner;
33
+
34
+ export abstract class TextElementDefinition<
35
+ Role extends ElementTextRole,
36
+ > extends TextRangeDefinition<Role> {
37
+ readonly chunks: TextElementChunks;
38
+
39
+ constructor(form: XFormDefinition, owner: TextElementOwner, sourceNode: TextSourceNode<Role>) {
40
+ super(form, owner, sourceNode);
41
+
42
+ const context = this as AnyTextElementDefinition;
43
+ const refExpression = parseNodesetReference(owner, sourceNode, 'ref');
44
+
45
+ if (refExpression == null) {
46
+ this.chunks = Array.from(sourceNode.childNodes).flatMap((childNode) => {
47
+ if (isElementNode(childNode)) {
48
+ return TextOutputExpression.from(context, childNode) ?? [];
49
+ }
50
+
51
+ if (isTextNode(childNode)) {
52
+ return TextLiteralExpression.from(context, childNode.data);
53
+ }
54
+
55
+ return [];
56
+ });
57
+ } else {
58
+ const refChunk =
59
+ TextTranslationExpression.from(context, refExpression) ??
60
+ TextReferenceExpression.from(context, refExpression);
61
+ this.chunks = [refChunk];
62
+ }
63
+ }
64
+ }
65
+
66
+ // prettier-ignore
67
+ export type AnyTextElementDefinition =
68
+ | HintDefinition
69
+ | ItemLabelDefinition
70
+ | ItemsetLabelDefinition
71
+ | LabelDefinition;
@@ -0,0 +1,70 @@
1
+ import type { LocalNamedElement } from '@getodk/common/types/dom.ts';
2
+ import type { TextRole } from '../../../client/TextRange.ts';
3
+ import type { XFormDefinition } from '../../../parse/XFormDefinition.ts';
4
+ import { DependencyContext } from '../../expression/abstract/DependencyContext.ts';
5
+ import type { AnyDependentExpression } from '../../expression/abstract/DependentExpression.ts';
6
+ import type { AnyTextChunkExpression } from '../../expression/abstract/TextChunkExpression.ts';
7
+ import type { AnyMessageDefinition } from '../MessageDefinition.ts';
8
+ import type { AnyTextElementDefinition } from './TextElementDefinition.ts';
9
+
10
+ export type TextBindAttributeLocalName = 'constraintMsg' | 'requiredMsg';
11
+ export type TextBodyElementLocalName = 'hint' | 'label';
12
+
13
+ interface TextSourceNodes {
14
+ readonly constraintMsg: null;
15
+ readonly hint: LocalNamedElement<'hint'>;
16
+ readonly label: LocalNamedElement<'label'>;
17
+ readonly 'item-label': LocalNamedElement<'label'>;
18
+ readonly requiredMsg: null;
19
+ }
20
+
21
+ export type TextSourceNode<Type extends TextRole> = TextSourceNodes[Type];
22
+
23
+ export abstract class TextRangeDefinition<Role extends TextRole> extends DependencyContext {
24
+ abstract readonly role: Role;
25
+ readonly parentReference: string | null;
26
+ readonly reference: string | null;
27
+
28
+ abstract readonly chunks: readonly AnyTextChunkExpression[];
29
+
30
+ override get isTranslated(): boolean {
31
+ return (
32
+ this.ownerContext.isTranslated || this.chunks.some((chunk) => chunk.source === 'translation')
33
+ );
34
+ }
35
+
36
+ override set isTranslated(value: true) {
37
+ if (this.ownerContext != null) {
38
+ this.ownerContext.isTranslated = value;
39
+ }
40
+
41
+ super.isTranslated = value;
42
+ }
43
+
44
+ protected constructor(
45
+ readonly form: XFormDefinition,
46
+ readonly ownerContext: DependencyContext,
47
+ readonly sourceNode: TextSourceNode<Role>
48
+ ) {
49
+ super();
50
+
51
+ this.reference = ownerContext.reference;
52
+ this.parentReference = ownerContext.parentReference;
53
+ }
54
+
55
+ override registerDependentExpression(expression: AnyDependentExpression): void {
56
+ this.ownerContext.registerDependentExpression(expression);
57
+ super.registerDependentExpression(expression);
58
+ }
59
+
60
+ toJSON(): object {
61
+ const { form, ownerContext, ...rest } = this;
62
+
63
+ return rest;
64
+ }
65
+ }
66
+
67
+ // prettier-ignore
68
+ export type AnyTextRangeDefinition =
69
+ | AnyMessageDefinition
70
+ | AnyTextElementDefinition;