@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
@@ -0,0 +1,53 @@
1
+ import { getValueElement, type ItemsetElement } from '../../../../lib/dom/query.ts';
2
+ import { ItemsetNodesetExpression } from '../../../expression/ItemsetNodesetExpression.ts';
3
+ import { ItemsetValueExpression } from '../../../expression/ItemsetValueExpression.ts';
4
+ import { ItemsetLabelDefinition } from '../../../text/ItemsetLabelDefinition.ts';
5
+ import type { XFormDefinition } from '../../../XFormDefinition.ts';
6
+ import { parseNodesetReference } from '../../../xpath/reference-parsing.ts';
7
+ import { BodyElementDefinition } from '../../BodyElementDefinition.ts';
8
+ import type { AnySelectDefinition } from './SelectDefinition.ts';
9
+
10
+ export class ItemsetDefinition extends BodyElementDefinition<'itemset'> {
11
+ override readonly category = 'support';
12
+ readonly type = 'itemset';
13
+
14
+ override readonly reference: string;
15
+ override readonly label: ItemsetLabelDefinition | null;
16
+
17
+ readonly nodes: ItemsetNodesetExpression;
18
+ readonly value: ItemsetValueExpression;
19
+
20
+ constructor(
21
+ form: XFormDefinition,
22
+ override readonly parent: AnySelectDefinition,
23
+ element: ItemsetElement
24
+ ) {
25
+ super(form, parent, element);
26
+
27
+ const nodesetExpression = parseNodesetReference(parent, element, 'nodeset');
28
+
29
+ this.nodes = new ItemsetNodesetExpression(this, nodesetExpression);
30
+ this.reference = nodesetExpression;
31
+
32
+ const valueElement = getValueElement(element);
33
+
34
+ if (valueElement == null) {
35
+ throw new Error('<itemset> has no <value>');
36
+ }
37
+
38
+ const valueExpression = parseNodesetReference(
39
+ {
40
+ reference: null,
41
+ },
42
+ valueElement,
43
+ 'ref'
44
+ );
45
+
46
+ if (valueExpression == null) {
47
+ throw new Error(`<itemset> has no <value>`);
48
+ }
49
+
50
+ this.value = new ItemsetValueExpression(this, valueExpression);
51
+ this.label = ItemsetLabelDefinition.from(form, this);
52
+ }
53
+ }
@@ -1,5 +1,5 @@
1
- import { DependencyContext } from '../../../expression/DependencyContext.ts';
2
- import type { AnyDependentExpression } from '../../../expression/DependentExpression.ts';
1
+ import { DependencyContext } from '../../../expression/abstract/DependencyContext.ts';
2
+ import type { AnyDependentExpression } from '../../../expression/abstract/DependentExpression.ts';
3
3
  import type { ItemsetDefinition } from './ItemsetDefinition.ts';
4
4
 
5
5
  export class ItemsetNodesetContext extends DependencyContext {
@@ -1,23 +1,15 @@
1
1
  import type { CollectionValues } from '@getodk/common/types/collections/CollectionValues.ts';
2
2
  import type { LocalNamedElement } from '@getodk/common/types/dom.ts';
3
+ import { getItemElements, getItemsetElement } from '../../../../lib/dom/query.ts';
3
4
  import type { XFormDefinition } from '../../../XFormDefinition.ts';
4
- import { getItemElements, getItemsetElement } from '../../../lib/dom/query.ts';
5
- import type { AnyBodyElementDefinition, BodyElementParentContext } from '../../BodyDefinition.ts';
6
5
  import type { SelectAppearanceDefinition } from '../../appearance/selectAppearanceParser.ts';
7
6
  import { selectAppearanceParser } from '../../appearance/selectAppearanceParser.ts';
7
+ import type { AnyBodyElementDefinition, BodyElementParentContext } from '../../BodyDefinition.ts';
8
8
  import { ControlDefinition } from '../ControlDefinition.ts';
9
9
  import { ItemDefinition } from './ItemDefinition.ts';
10
10
  import { ItemsetDefinition } from './ItemsetDefinition.ts';
11
11
 
12
- /**
13
- * @todo We were previously a bit overzealous about introducing `<rank>` support
14
- * here. It'll likely still fit, but we should approach it with more intention.
15
- *
16
- * @todo `<trigger>` is *almost* reasonable to support here too. The main
17
- * hesitation is that its single, implicit "item" does not have a distinct
18
- * <label>, and presumably has different UX **and translation** considerations.
19
- */
20
- const selectLocalNames = new Set([/* 'rank', */ 'select', 'select1'] as const);
12
+ const selectLocalNames = new Set(['select', 'select1'] as const);
21
13
 
22
14
  export type SelectType = CollectionValues<typeof selectLocalNames>;
23
15
 
@@ -1,15 +1,15 @@
1
1
  import { UpsertableMap } from '@getodk/common/lib/collections/UpsertableMap.ts';
2
+ import { getLabelElement } from '../../../lib/dom/query.ts';
3
+ import { LabelDefinition } from '../../text/LabelDefinition.ts';
2
4
  import type { XFormDefinition } from '../../XFormDefinition.ts';
3
- import { getLabelElement } from '../../lib/dom/query.ts';
5
+ import { parseNodesetReference } from '../../xpath/reference-parsing.ts';
6
+ import type { StructureElementAppearanceDefinition } from '../appearance/structureElementAppearanceParser.ts';
7
+ import { structureElementAppearanceParser } from '../appearance/structureElementAppearanceParser.ts';
4
8
  import {
5
- BodyDefinition,
6
9
  type BodyElementDefinitionArray,
7
10
  type BodyElementParentContext,
8
11
  } from '../BodyDefinition.ts';
9
12
  import { BodyElementDefinition } from '../BodyElementDefinition.ts';
10
- import type { StructureElementAppearanceDefinition } from '../appearance/structureElementAppearanceParser.ts';
11
- import { structureElementAppearanceParser } from '../appearance/structureElementAppearanceParser.ts';
12
- import { LabelDefinition } from '../text/LabelDefinition.ts';
13
13
 
14
14
  /**
15
15
  * These type names are derived from **and expand upon** the language used in
@@ -72,28 +72,18 @@ export abstract class BaseGroupDefinition<
72
72
  readonly appearances: StructureElementAppearanceDefinition;
73
73
  override readonly label: LabelDefinition | null;
74
74
 
75
- constructor(
76
- form: XFormDefinition,
77
- parent: BodyElementParentContext,
78
- element: Element,
79
- children?: BodyElementDefinitionArray
80
- ) {
75
+ constructor(form: XFormDefinition, parent: BodyElementParentContext, element: Element) {
81
76
  super(form, parent, element);
82
77
 
83
- this.children = children ?? this.getChildren(element);
84
- this.reference = element.getAttribute('ref');
85
- this.appearances = structureElementAppearanceParser.parseFrom(element, 'appearance');
86
- this.label = LabelDefinition.forGroup(form, this);
87
- }
88
-
89
- getChildren(element: Element): BodyElementDefinitionArray {
90
- const { form } = this;
91
- const children = Array.from(element.children).filter((child) => {
78
+ const childElements = Array.from(element.children).filter((child) => {
92
79
  const childName = child.localName;
93
80
 
94
81
  return childName !== 'label';
95
82
  });
96
83
 
97
- return BodyDefinition.getChildElementDefinitions(form, this, element, children);
84
+ this.children = this.body.getChildElementDefinitions(form, this, element, childElements);
85
+ this.reference = parseNodesetReference(parent, element, 'ref');
86
+ this.appearances = structureElementAppearanceParser.parseFrom(element, 'appearance');
87
+ this.label = LabelDefinition.forGroup(form, this);
98
88
  }
99
89
  }
@@ -1,6 +1,6 @@
1
+ import { LabelDefinition } from '../../text/LabelDefinition.ts';
1
2
  import type { XFormDefinition } from '../../XFormDefinition.ts';
2
3
  import type { BodyElementParentContext } from '../BodyDefinition.ts';
3
- import { LabelDefinition } from '../text/LabelDefinition.ts';
4
4
  import { BaseGroupDefinition } from './BaseGroupDefinition.ts';
5
5
 
6
6
  export class PresentationGroupDefinition extends BaseGroupDefinition<'presentation-group'> {
@@ -1,5 +1,5 @@
1
- import { DependentExpression } from '../expression/DependentExpression.ts';
2
- import type { BindDefinition } from './BindDefinition.ts';
1
+ import type { BindDefinition } from '../model/BindDefinition.ts';
2
+ import { DependentExpression } from './abstract/DependentExpression.ts';
3
3
 
4
4
  const defaultBindComputationExpressions = {
5
5
  calculate: null,
@@ -16,8 +16,8 @@ export type BindComputationType = keyof DefaultBindComputationExpressions;
16
16
 
17
17
  type BindComputationFactoryResult<Type extends BindComputationType> =
18
18
  DefaultBindComputationExpressions[Type] extends null
19
- ? BindComputation<Type> | null
20
- : BindComputation<Type>;
19
+ ? BindComputationExpression<Type> | null
20
+ : BindComputationExpression<Type>;
21
21
 
22
22
  const bindComputationResultTypes = {
23
23
  calculate: 'string',
@@ -33,10 +33,10 @@ type BindComputationResultTypes = typeof bindComputationResultTypes;
33
33
  export type BindComputationResultType<Computation extends BindComputationType> =
34
34
  BindComputationResultTypes[Computation];
35
35
 
36
- export class BindComputation<Computation extends BindComputationType> extends DependentExpression<
37
- BindComputationResultType<Computation>
38
- > {
39
- static forExpression<Type extends BindComputationType>(
36
+ export class BindComputationExpression<
37
+ Computation extends BindComputationType,
38
+ > extends DependentExpression<BindComputationResultType<Computation>> {
39
+ static forComputation<Type extends BindComputationType>(
40
40
  bind: BindDefinition,
41
41
  computation: Type
42
42
  ): BindComputationFactoryResult<Type> {
@@ -57,7 +57,6 @@ export class BindComputation<Computation extends BindComputationType> extends De
57
57
  readonly computation: Computation,
58
58
  expression: string | null
59
59
  ) {
60
- const isInherited = computation === 'readonly' || computation === 'relevant';
61
60
  const ignoreContextReference = computation === 'constraint';
62
61
 
63
62
  let isDefaultExpression: boolean;
@@ -78,9 +77,6 @@ export class BindComputation<Computation extends BindComputationType> extends De
78
77
 
79
78
  super(bind, bindComputationResultTypes[computation], resolvedExpression, {
80
79
  ignoreContextReference,
81
- semanticDependencies: {
82
- parentContext: isInherited,
83
- },
84
80
  });
85
81
 
86
82
  this.isDefaultExpression = isDefaultExpression;
@@ -0,0 +1,8 @@
1
+ import type { ItemsetDefinition } from '../body/control/select/ItemsetDefinition.ts';
2
+ import { DependentExpression } from './abstract/DependentExpression.ts';
3
+
4
+ export class ItemsetNodesetExpression extends DependentExpression<'nodes'> {
5
+ constructor(itemset: ItemsetDefinition, nodesetExpression: string) {
6
+ super(itemset.parent, 'nodes', nodesetExpression);
7
+ }
8
+ }
@@ -1,5 +1,5 @@
1
- import { DependentExpression } from '../../../expression/DependentExpression.ts';
2
- import type { ItemsetDefinition } from './ItemsetDefinition.ts';
1
+ import type { ItemsetDefinition } from '../body/control/select/ItemsetDefinition.ts';
2
+ import { DependentExpression } from './abstract/DependentExpression.ts';
3
3
 
4
4
  export class ItemsetValueExpression extends DependentExpression<'string'> {
5
5
  constructor(
@@ -0,0 +1,44 @@
1
+ import type { RepeatRangeControlledNode } from '../../client/repeat/RepeatRangeControlledNode.ts';
2
+ import { RepeatElementDefinition } from '../body/RepeatElementDefinition.ts';
3
+ import { isConstantTruthyExpression } from '../xpath/semantic-analysis.ts';
4
+ import { DependentExpression } from './abstract/DependentExpression.ts';
5
+
6
+ /**
7
+ * Represents either of these
8
+ * {@link https://getodk.github.io/xforms-spec/#body-attributes | body attributes}:
9
+ *
10
+ * - `jr:count`
11
+ * - `jr:noAddRemove`
12
+ *
13
+ * In both cases, the downstream effect is that the engine is responsible for
14
+ * controlling the count of a repeat range's instances. Representing both cases
15
+ * should simplify client usage, as well as implementation of the internal
16
+ * representation of {@link RepeatRangeControlledNode}.
17
+ */
18
+ export class RepeatCountControlExpression extends DependentExpression<'number'> {
19
+ static from(
20
+ bodyElement: RepeatElementDefinition,
21
+ initialCount: number
22
+ ): RepeatCountControlExpression | null {
23
+ const { countExpression, noAddRemoveExpression } = bodyElement;
24
+
25
+ if (countExpression != null) {
26
+ return new this(bodyElement, countExpression);
27
+ }
28
+
29
+ if (noAddRemoveExpression != null && isConstantTruthyExpression(noAddRemoveExpression)) {
30
+ // Assumption: `noAddRemove` with no form-defined repeat instances has no
31
+ // purpose. Infer intent as a single repeat instance, as defined by the
32
+ // repeat's template.
33
+ const fixedCountExpression = String(Math.max(initialCount, 1));
34
+
35
+ return new this(bodyElement, fixedCountExpression);
36
+ }
37
+
38
+ return null;
39
+ }
40
+
41
+ private constructor(context: RepeatElementDefinition, expression: string) {
42
+ super(context, 'number', expression);
43
+ }
44
+ }
@@ -0,0 +1,19 @@
1
+ import type { AnyTextRangeDefinition } from '../text/abstract/TextRangeDefinition.ts';
2
+ import { TextChunkExpression } from './abstract/TextChunkExpression.ts';
3
+
4
+ export type TextLiteralSourceNode = Attr | Text;
5
+
6
+ export class TextLiteralExpression extends TextChunkExpression<'literal'> {
7
+ static from(context: AnyTextRangeDefinition, stringValue: string): TextLiteralExpression {
8
+ return new this(context, stringValue);
9
+ }
10
+
11
+ readonly source = 'literal';
12
+
13
+ private constructor(
14
+ context: AnyTextRangeDefinition,
15
+ override readonly stringValue: string
16
+ ) {
17
+ super(context, 'null');
18
+ }
19
+ }
@@ -0,0 +1,25 @@
1
+ import type { KnownAttributeLocalNamedElement } from '@getodk/common/types/dom.ts';
2
+ import type { AnyTextRangeDefinition } from '../text/abstract/TextRangeDefinition.ts';
3
+ import { TextChunkExpression } from './abstract/TextChunkExpression.ts';
4
+
5
+ interface OutputElement extends KnownAttributeLocalNamedElement<'output', 'value'> {}
6
+
7
+ const isOutputElement = (element: Element): element is OutputElement => {
8
+ return element.localName === 'output' && element.hasAttribute('value');
9
+ };
10
+
11
+ export class TextOutputExpression extends TextChunkExpression<'output'> {
12
+ static from(context: AnyTextRangeDefinition, element: Element): TextOutputExpression | null {
13
+ if (isOutputElement(element)) {
14
+ return new this(context, element);
15
+ }
16
+
17
+ return null;
18
+ }
19
+
20
+ readonly source = 'output';
21
+
22
+ private constructor(context: AnyTextRangeDefinition, element: OutputElement) {
23
+ super(context, element.getAttribute('value'));
24
+ }
25
+ }
@@ -0,0 +1,14 @@
1
+ import type { AnyTextRangeDefinition } from '../text/abstract/TextRangeDefinition.ts';
2
+ import { TextChunkExpression } from './abstract/TextChunkExpression.ts';
3
+
4
+ export class TextReferenceExpression extends TextChunkExpression<'reference'> {
5
+ static from(context: AnyTextRangeDefinition, refExpression: string): TextReferenceExpression {
6
+ return new this(context, refExpression);
7
+ }
8
+
9
+ readonly source = 'reference';
10
+
11
+ private constructor(context: AnyTextRangeDefinition, refExpression: string) {
12
+ super(context, refExpression);
13
+ }
14
+ }
@@ -0,0 +1,38 @@
1
+ import { expressionParser } from '@getodk/xpath/expressionParser.js';
2
+ import type { AnyTextRangeDefinition } from '../text/abstract/TextRangeDefinition.ts';
3
+ import type { TranslationExpression } from '../xpath/semantic-analysis.ts';
4
+ import { isTranslationExpression } from '../xpath/semantic-analysis.ts';
5
+ import { TextChunkExpression } from './abstract/TextChunkExpression.ts';
6
+
7
+ export class TextTranslationExpression extends TextChunkExpression<'translation'> {
8
+ static fromMessage(
9
+ context: AnyTextRangeDefinition,
10
+ maybeExpression: string
11
+ ): TextTranslationExpression | null {
12
+ try {
13
+ expressionParser.parse(maybeExpression);
14
+ } catch {
15
+ return null;
16
+ }
17
+
18
+ if (isTranslationExpression(maybeExpression)) {
19
+ return new this(context, maybeExpression);
20
+ }
21
+
22
+ return null;
23
+ }
24
+
25
+ static from(context: AnyTextRangeDefinition, maybeExpression: string) {
26
+ if (isTranslationExpression(maybeExpression)) {
27
+ return new this(context, maybeExpression);
28
+ }
29
+
30
+ return null;
31
+ }
32
+
33
+ readonly source = 'translation';
34
+
35
+ private constructor(context: AnyTextRangeDefinition, expression: TranslationExpression) {
36
+ super(context, expression, { isTranslated: true });
37
+ }
38
+ }
@@ -1,10 +1,20 @@
1
1
  import type { XFormsXPathEvaluator } from '@getodk/xpath';
2
- import { getNodesetDependencies, isItextFunctionCalled } from '../lib/xpath/analysis.ts';
2
+ import { resolveDependencyNodesets } from '../../xpath/dependency-analysis.ts';
3
+ import type {
4
+ ConstantExpression,
5
+ ConstantTruthyExpression,
6
+ } from '../../xpath/semantic-analysis.ts';
7
+ import {
8
+ isConstantExpression,
9
+ isConstantTruthyExpression,
10
+ isTranslationExpression,
11
+ } from '../../xpath/semantic-analysis.ts';
3
12
  import type { DependencyContext } from './DependencyContext.ts';
4
13
 
5
14
  const evaluatorMethodsByResultType = {
6
15
  boolean: 'evaluateBoolean',
7
16
  nodes: 'evaluateNodes',
17
+ number: 'evaluateNumber',
8
18
  string: 'evaluateString',
9
19
  } as const;
10
20
 
@@ -20,11 +30,6 @@ export type DependentExpressionResult<Type extends DependentExpressionResultType
20
30
  >;
21
31
 
22
32
  interface SemanticDependencyOptions {
23
- /**
24
- * @default false
25
- */
26
- readonly parentContext?: boolean | undefined;
27
-
28
33
  /**
29
34
  * @default false
30
35
  */
@@ -37,18 +42,24 @@ interface DependentExpressionOptions {
37
42
  */
38
43
  readonly ignoreContextReference?: boolean;
39
44
 
40
- /**
41
- * @default true
42
- */
43
- readonly ignoreNullExpressions?: boolean;
44
-
45
45
  readonly semanticDependencies?: SemanticDependencyOptions;
46
46
  }
47
47
 
48
- export class DependentExpression<Type extends DependentExpressionResultType> {
48
+ export interface ConstantDependentExpression<Type extends DependentExpressionResultType>
49
+ extends DependentExpression<Type> {
50
+ readonly expression: ConstantExpression;
51
+ }
52
+
53
+ export interface ConstantTruthyDependentExpression extends ConstantDependentExpression<'boolean'> {
54
+ readonly expression: ConstantTruthyExpression;
55
+ }
56
+
57
+ export abstract class DependentExpression<Type extends DependentExpressionResultType> {
49
58
  readonly dependencyReferences: ReadonlySet<string> = new Set();
50
59
  readonly isTranslated: boolean = false;
51
60
  readonly evaluatorMethod: DependentExpressionEvaluatorMethod<Type>;
61
+ readonly constantExpression: ConstantExpression | null;
62
+ readonly constantTruthyExpression: ConstantTruthyExpression | null;
52
63
 
53
64
  constructor(
54
65
  context: DependencyContext,
@@ -56,34 +67,33 @@ export class DependentExpression<Type extends DependentExpressionResultType> {
56
67
  readonly expression: string,
57
68
  options: DependentExpressionOptions = {}
58
69
  ) {
70
+ if (resultType === 'boolean' && isConstantTruthyExpression(expression)) {
71
+ this.constantTruthyExpression = expression;
72
+ this.constantExpression = expression;
73
+ } else if (isConstantExpression(expression)) {
74
+ this.constantTruthyExpression = null;
75
+ this.constantExpression = expression;
76
+ } else {
77
+ this.constantTruthyExpression = null;
78
+ this.constantExpression = null;
79
+ }
80
+
59
81
  this.evaluatorMethod = evaluatorMethodsByResultType[resultType];
60
82
 
61
83
  const {
62
84
  ignoreContextReference = false,
63
- ignoreNullExpressions = true,
64
85
  semanticDependencies = {
65
- parentContext: false,
66
86
  translations: false,
67
87
  },
68
88
  } = options;
69
89
 
70
- const dependencyReferences = new Set<string>(
71
- getNodesetDependencies(expression, {
72
- contextReference: context.reference,
73
- ignoreContextReference,
74
- ignoreNullExpressions,
90
+ this.dependencyReferences = new Set(
91
+ resolveDependencyNodesets(context.reference, expression, {
92
+ ignoreReferenceToContextPath: ignoreContextReference,
75
93
  })
76
94
  );
77
95
 
78
- const parentDependency = semanticDependencies.parentContext ? context.parentReference : null;
79
-
80
- if (parentDependency != null) {
81
- dependencyReferences.add(parentDependency);
82
- }
83
-
84
- this.dependencyReferences = dependencyReferences;
85
-
86
- const isTranslated = semanticDependencies.translations && isItextFunctionCalled(expression);
96
+ const isTranslated = semanticDependencies.translations && isTranslationExpression(expression);
87
97
 
88
98
  if (isTranslated) {
89
99
  this.isTranslated = true;
@@ -93,6 +103,14 @@ export class DependentExpression<Type extends DependentExpressionResultType> {
93
103
  context.registerDependentExpression(this);
94
104
  }
95
105
 
106
+ isConstantExpression(): this is ConstantDependentExpression<Type> {
107
+ return this.constantExpression != null;
108
+ }
109
+
110
+ isConstantTruthyExpression(): this is ConstantTruthyDependentExpression {
111
+ return this.resultType === 'boolean' && this.constantTruthyExpression != null;
112
+ }
113
+
96
114
  toString(): string | null {
97
115
  return this.expression;
98
116
  }
@@ -0,0 +1,38 @@
1
+ import type { TextChunkSource } from '../../../client/TextRange.ts';
2
+ import type { AnyTextRangeDefinition } from '../../text/abstract/TextRangeDefinition.ts';
3
+ import type { TextLiteralExpression } from '../TextLiteralExpression.ts';
4
+ import type { TextOutputExpression } from '../TextOutputExpression.ts';
5
+ import type { TextReferenceExpression } from '../TextReferenceExpression.ts';
6
+ import type { TextTranslationExpression } from '../TextTranslationExpression.ts';
7
+ import { DependentExpression } from './DependentExpression.ts';
8
+
9
+ interface TextChunkExpressionOptions {
10
+ readonly isTranslated?: true;
11
+ }
12
+
13
+ export abstract class TextChunkExpression<
14
+ Source extends TextChunkSource,
15
+ > extends DependentExpression<'string'> {
16
+ abstract readonly source: Source;
17
+ readonly stringValue?: string;
18
+
19
+ constructor(
20
+ context: AnyTextRangeDefinition,
21
+ expression: string,
22
+ options: TextChunkExpressionOptions = {}
23
+ ) {
24
+ super(context, 'string', expression, {
25
+ semanticDependencies: {
26
+ translations: options.isTranslated,
27
+ },
28
+ ignoreContextReference: true,
29
+ });
30
+ }
31
+ }
32
+
33
+ // prettier-ignore
34
+ export type AnyTextChunkExpression =
35
+ | TextLiteralExpression
36
+ | TextOutputExpression
37
+ | TextReferenceExpression
38
+ | TextTranslationExpression;
@@ -1,9 +1,10 @@
1
+ import { DependencyContext } from '../expression/abstract/DependencyContext.ts';
2
+ import type { DependentExpression } from '../expression/abstract/DependentExpression.ts';
3
+ import { BindComputationExpression } from '../expression/BindComputationExpression.ts';
4
+ import { MessageDefinition } from '../text/MessageDefinition.ts';
1
5
  import type { XFormDataType } from '../XFormDataType.ts';
2
6
  import { bindDataType } from '../XFormDataType.ts';
3
7
  import type { XFormDefinition } from '../XFormDefinition.ts';
4
- import { DependencyContext } from '../expression/DependencyContext.ts';
5
- import type { DependentExpression } from '../expression/DependentExpression.ts';
6
- import { BindComputation } from './BindComputation.ts';
7
8
  import type { BindElement } from './BindElement.ts';
8
9
  import type { ModelDefinition } from './ModelDefinition.ts';
9
10
 
@@ -12,28 +13,30 @@ export class BindDefinition extends DependencyContext {
12
13
  readonly dataType: XFormDataType;
13
14
  readonly parentNodeset: string | null;
14
15
 
15
- readonly calculate: BindComputation<'calculate'> | null;
16
- readonly readonly: BindComputation<'readonly'>;
17
- readonly relevant: BindComputation<'relevant'>;
18
- readonly required: BindComputation<'required'>;
16
+ readonly calculate: BindComputationExpression<'calculate'> | null;
17
+ readonly readonly: BindComputationExpression<'readonly'>;
18
+ readonly relevant: BindComputationExpression<'relevant'>;
19
+ readonly required: BindComputationExpression<'required'>;
19
20
 
20
- // According to
21
- //
22
- // this is not stored in the DAG. In contrast, we do compute constraint
23
- // dependencies, but self-references are ignored (handled by `BindComputation`
24
- // and its `DependentExpression` parent class).
25
21
  /**
26
- * Diverges from {@link https://github.com/getodk/javarosa/blob/059321160e6f8dbb3e81d9add61d68dd35b13cc8/dag.md | JavaRosa's}, which excludes `constraint` expressions. We compute `constraint` dependencies like the other <bind> computation expressions, but explicitly ignore self-references (this is currently handled by {@link BindComputation}, via its {@link DependentExpression} parent class).
22
+ * Diverges from
23
+ * {@link https://github.com/getodk/javarosa/blob/059321160e6f8dbb3e81d9add61d68dd35b13cc8/dag.md | JavaRosa's},
24
+ * which excludes `constraint` expressions. We compute `constraint`
25
+ * dependencies like the other <bind> computation expressions, but explicitly
26
+ * ignore self-references (this is currently handled by
27
+ * {@link BindComputationExpression}, via its {@link DependentExpression}
28
+ * super class).
27
29
  */
28
- readonly constraint: BindComputation<'constraint'> & DependentExpression<'boolean'>;
30
+ readonly constraint: BindComputationExpression<'constraint'>;
31
+
32
+ readonly constraintMsg: MessageDefinition<'constraintMsg'> | null;
33
+ readonly requiredMsg: MessageDefinition<'requiredMsg'> | null;
29
34
 
30
35
  // TODO: it is unclear whether this will need to be supported.
31
36
  // https://github.com/getodk/collect/issues/3758 mentions deprecation.
32
- readonly saveIncomplete: BindComputation<'saveIncomplete'>;
37
+ readonly saveIncomplete: BindComputationExpression<'saveIncomplete'>;
33
38
 
34
- // TODO: these are deferred just to put off sharing namespace stuff
35
- // readonly requiredMsg: string | null;
36
- // readonly constraintMsg: string | null;
39
+ // TODO: these are deferred until prioritized
37
40
  // readonly preload: string | null;
38
41
  // readonly preloadParams: string | null;
39
42
  // readonly 'max-pixels': string | null;
@@ -82,15 +85,15 @@ export class BindDefinition extends DependencyContext {
82
85
  const parentNodeset = nodeset.replace(/\/[^/]+$/, '');
83
86
 
84
87
  this.parentNodeset = parentNodeset.length > 1 ? parentNodeset : null;
85
- this.calculate = BindComputation.forExpression(this, 'calculate');
86
- this.readonly = BindComputation.forExpression(this, 'readonly');
87
- this.relevant = BindComputation.forExpression(this, 'relevant');
88
- this.required = BindComputation.forExpression(this, 'required');
89
- this.constraint = BindComputation.forExpression(this, 'constraint');
90
- this.saveIncomplete = BindComputation.forExpression(this, 'saveIncomplete');
91
-
92
- // this.requiredMsg = BindComputation.forExpression(this, 'requiredMsg');
93
- // this.constraintMsg = BindComputation.forExpression(this, 'constraintMsg');
88
+ this.calculate = BindComputationExpression.forComputation(this, 'calculate');
89
+ this.readonly = BindComputationExpression.forComputation(this, 'readonly');
90
+ this.relevant = BindComputationExpression.forComputation(this, 'relevant');
91
+ this.required = BindComputationExpression.forComputation(this, 'required');
92
+ this.constraint = BindComputationExpression.forComputation(this, 'constraint');
93
+ this.saveIncomplete = BindComputationExpression.forComputation(this, 'saveIncomplete');
94
+ this.constraintMsg = MessageDefinition.from(this, 'constraintMsg');
95
+ this.requiredMsg = MessageDefinition.from(this, 'requiredMsg');
96
+
94
97
  // this.preload = BindComputation.forExpression(this, 'preload');
95
98
  // this.preloadParams = BindComputation.forExpression(this, 'preloadParams');
96
99
  // this['max-pixels'] = BindComputation.forExpression(this, 'max-pixels');
@@ -5,4 +5,5 @@ export interface BindElement {
5
5
 
6
6
  getAttribute(name: 'nodeset'): BindNodeset;
7
7
  getAttribute(name: string): string | null;
8
+ getAttributeNS(namespaceURI: string | null, localName: string): string | null;
8
9
  }
@@ -3,11 +3,11 @@ import type { BindDefinition } from './BindDefinition.ts';
3
3
  import { DescendentNodeDefinition } from './DescendentNodeDefinition.ts';
4
4
  import type { NodeDefinition, ParentNodeDefinition } from './NodeDefinition.ts';
5
5
 
6
- export class ValueNodeDefinition
7
- extends DescendentNodeDefinition<'value-node', ControlElementDefinition | null>
8
- implements NodeDefinition<'value-node'>
6
+ export class LeafNodeDefinition
7
+ extends DescendentNodeDefinition<'leaf-node', ControlElementDefinition | null>
8
+ implements NodeDefinition<'leaf-node'>
9
9
  {
10
- readonly type = 'value-node';
10
+ readonly type = 'leaf-node';
11
11
 
12
12
  readonly nodeName: string;
13
13
  readonly children = null;