@getodk/xforms-engine 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (425) hide show
  1. package/README.md +1 -1
  2. package/dist/client/BaseNode.d.ts +8 -4
  3. package/dist/client/BaseValueNode.d.ts +8 -4
  4. package/dist/client/GroupNode.d.ts +1 -0
  5. package/dist/client/InputNode.d.ts +32 -3
  6. package/dist/client/ModelValueNode.d.ts +1 -0
  7. package/dist/client/NoteNode.d.ts +24 -7
  8. package/dist/client/RangeNode.d.ts +36 -0
  9. package/dist/client/RankNode.d.ts +46 -0
  10. package/dist/client/RootNode.d.ts +21 -14
  11. package/dist/client/SelectNode.d.ts +47 -25
  12. package/dist/client/SubtreeNode.d.ts +1 -0
  13. package/dist/client/TriggerNode.d.ts +10 -6
  14. package/dist/client/constants.d.ts +11 -12
  15. package/dist/client/form/CreateFormInstance.d.ts +14 -0
  16. package/dist/client/form/EditFormInstance.d.ts +62 -0
  17. package/dist/client/form/FormInstance.d.ts +104 -0
  18. package/dist/client/form/FormInstanceConfig.d.ts +17 -0
  19. package/dist/client/form/FormResource.d.ts +1 -0
  20. package/dist/client/form/LoadForm.d.ts +79 -0
  21. package/dist/client/form/LoadFormResult.d.ts +67 -0
  22. package/dist/client/form/RestoreFormInstance.d.ts +8 -0
  23. package/dist/client/hierarchy.d.ts +5 -5
  24. package/dist/client/index.d.ts +37 -11
  25. package/dist/client/node-types.d.ts +2 -2
  26. package/dist/client/repeat/BaseRepeatRangeNode.d.ts +3 -4
  27. package/dist/client/repeat/RepeatInstanceNode.d.ts +4 -5
  28. package/dist/client/repeat/RepeatRangeControlledNode.d.ts +2 -2
  29. package/dist/client/repeat/RepeatRangeUncontrolledNode.d.ts +2 -2
  30. package/dist/client/resources.d.ts +1 -1
  31. package/dist/client/serialization/InstanceData.d.ts +12 -0
  32. package/dist/client/serialization/InstanceFile.d.ts +6 -0
  33. package/dist/client/serialization/InstancePayload.d.ts +93 -0
  34. package/dist/client/serialization/InstancePayloadOptions.d.ts +23 -0
  35. package/dist/client/serialization/InstanceState.d.ts +12 -0
  36. package/dist/client/submission/{SubmissionDefinition.d.ts → SubmissionMeta.d.ts} +1 -1
  37. package/dist/client/unsupported/UnsupportedControlNode.d.ts +1 -3
  38. package/dist/entrypoints/FormInstance.d.ts +20 -0
  39. package/dist/entrypoints/FormResult/BaseFormResult.d.ts +22 -0
  40. package/dist/entrypoints/FormResult/BaseInstantiableFormResult.d.ts +25 -0
  41. package/dist/entrypoints/FormResult/FormFailureResult.d.ts +17 -0
  42. package/dist/entrypoints/FormResult/FormSuccessResult.d.ts +15 -0
  43. package/dist/entrypoints/FormResult/FormWarningResult.d.ts +15 -0
  44. package/dist/entrypoints/createInstance.d.ts +9 -0
  45. package/dist/entrypoints/editInstance.d.ts +9 -0
  46. package/dist/entrypoints/index.d.ts +4 -0
  47. package/dist/entrypoints/loadForm.d.ts +4 -0
  48. package/dist/entrypoints/restoreInstance.d.ts +9 -0
  49. package/dist/error/LoadFormFailureError.d.ts +9 -0
  50. package/dist/error/MalformedInstanceDataError.d.ts +3 -0
  51. package/dist/error/RankMissingValueError.d.ts +3 -0
  52. package/dist/error/RankValueTypeError.d.ts +6 -0
  53. package/dist/error/SelectValueTypeError.d.ts +15 -0
  54. package/dist/error/TemplatedNodeAttributeSerializationError.d.ts +22 -0
  55. package/dist/error/XFormsSpecViolationError.d.ts +2 -0
  56. package/dist/index.d.ts +2 -34
  57. package/dist/index.js +7274 -5840
  58. package/dist/index.js.map +1 -1
  59. package/dist/instance/Group.d.ts +7 -5
  60. package/dist/instance/InputControl.d.ts +9 -6
  61. package/dist/instance/ModelValue.d.ts +7 -4
  62. package/dist/instance/Note.d.ts +14 -25
  63. package/dist/instance/PrimaryInstance.d.ts +36 -8
  64. package/dist/instance/RangeControl.d.ts +35 -0
  65. package/dist/instance/RankControl.d.ts +41 -0
  66. package/dist/instance/Root.d.ts +8 -9
  67. package/dist/instance/SelectControl.d.ts +67 -0
  68. package/dist/instance/Subtree.d.ts +7 -5
  69. package/dist/instance/TriggerControl.d.ts +10 -22
  70. package/dist/instance/abstract/DescendantNode.d.ts +11 -3
  71. package/dist/instance/abstract/InstanceNode.d.ts +10 -5
  72. package/dist/instance/abstract/ValueNode.d.ts +7 -6
  73. package/dist/instance/children/DescendantNodeInitOptions.d.ts +32 -0
  74. package/dist/instance/{children.d.ts → children/buildChildren.d.ts} +1 -1
  75. package/dist/instance/children/childrenInitOptions.d.ts +9 -0
  76. package/dist/instance/children/normalizeChildInitOptions.d.ts +2 -0
  77. package/dist/instance/hierarchy.d.ts +9 -9
  78. package/dist/instance/input/InitialInstanceState.d.ts +13 -0
  79. package/dist/instance/input/InstanceAttachmentMap.d.ts +19 -0
  80. package/dist/instance/internal-api/InstanceConfig.d.ts +2 -9
  81. package/dist/instance/internal-api/InstanceValueContext.d.ts +10 -1
  82. package/dist/instance/internal-api/serialization/ClientReactiveSerializableInstance.d.ts +14 -0
  83. package/dist/instance/internal-api/serialization/ClientReactiveSerializableLeafNode.d.ts +32 -0
  84. package/dist/instance/internal-api/serialization/ClientReactiveSerializableParentNode.d.ts +18 -0
  85. package/dist/instance/internal-api/serialization/ClientReactiveSerializableTemplatedNode.d.ts +13 -0
  86. package/dist/instance/internal-api/serialization/ClientReactiveSerializableValueNode.d.ts +21 -0
  87. package/dist/instance/repeat/BaseRepeatRange.d.ts +11 -8
  88. package/dist/instance/repeat/RepeatInstance.d.ts +11 -7
  89. package/dist/instance/repeat/RepeatRangeControlled.d.ts +27 -3
  90. package/dist/instance/repeat/RepeatRangeUncontrolled.d.ts +4 -3
  91. package/dist/instance/resource.d.ts +5 -1
  92. package/dist/instance/unsupported/UploadControl.d.ts +32 -4
  93. package/dist/integration/xpath/EngineXPathEvaluator.d.ts +2 -2
  94. package/dist/integration/xpath/adapter/kind.d.ts +4 -10
  95. package/dist/integration/xpath/adapter/names.d.ts +1 -11
  96. package/dist/integration/xpath/adapter/traversal.d.ts +10 -9
  97. package/dist/integration/xpath/static-dom/StaticAttribute.d.ts +10 -4
  98. package/dist/integration/xpath/static-dom/StaticDocument.d.ts +13 -11
  99. package/dist/integration/xpath/static-dom/StaticElement.d.ts +25 -18
  100. package/dist/integration/xpath/static-dom/StaticNode.d.ts +1 -1
  101. package/dist/integration/xpath/static-dom/StaticParentNode.d.ts +13 -0
  102. package/dist/integration/xpath/static-dom/staticNodeName.d.ts +3 -0
  103. package/dist/lib/client-reactivity/instance-state/createNodeRangeInstanceState.d.ts +4 -0
  104. package/dist/lib/client-reactivity/instance-state/createParentNodeInstanceState.d.ts +4 -0
  105. package/dist/lib/client-reactivity/instance-state/createPrimaryInstanceState.d.ts +3 -0
  106. package/dist/lib/client-reactivity/instance-state/createRootInstanceState.d.ts +3 -0
  107. package/dist/lib/client-reactivity/instance-state/createTemplatedNodeInstanceState.d.ts +6 -0
  108. package/dist/lib/client-reactivity/instance-state/createValueNodeInstanceState.d.ts +3 -0
  109. package/dist/lib/client-reactivity/instance-state/prepareInstancePayload.d.ts +8 -0
  110. package/dist/lib/codecs/Geopoint/Geopoint.d.ts +48 -0
  111. package/dist/lib/codecs/Geopoint/GeopointValueCodec.d.ts +5 -0
  112. package/dist/lib/codecs/NoteCodec.d.ts +8 -0
  113. package/dist/lib/codecs/RangeCodec.d.ts +8 -0
  114. package/dist/lib/codecs/TempUnsupportedControlCodec.d.ts +7 -0
  115. package/dist/lib/codecs/TriggerCodec.d.ts +7 -0
  116. package/dist/lib/codecs/ValueArrayCodec.d.ts +11 -0
  117. package/dist/lib/codecs/ValueCodec.d.ts +2 -2
  118. package/dist/lib/codecs/getNoteCodec.d.ts +3 -0
  119. package/dist/lib/codecs/getSelectCodec.d.ts +5 -0
  120. package/dist/lib/codecs/getSharedValueCodec.d.ts +3 -2
  121. package/dist/lib/codecs/items/BaseItemCodec.d.ts +9 -0
  122. package/dist/lib/codecs/items/MultipleValueItemCodec.d.ts +14 -0
  123. package/dist/lib/codecs/items/SingleValueItemCodec.d.ts +24 -0
  124. package/dist/lib/dom/query.d.ts +1 -2
  125. package/dist/lib/names/NamespaceDeclaration.d.ts +45 -0
  126. package/dist/lib/names/NamespaceDeclarationMap.d.ts +137 -0
  127. package/dist/lib/names/NamespaceURL.d.ts +30 -0
  128. package/dist/lib/names/QualifiedName.d.ts +113 -0
  129. package/dist/lib/names/UnprefixedXFormsName.d.ts +4 -0
  130. package/dist/lib/number-parsers.d.ts +2 -0
  131. package/dist/lib/reactivity/createInstanceValueState.d.ts +2 -27
  132. package/dist/lib/reactivity/createItemCollection.d.ts +21 -0
  133. package/dist/lib/xml-serialization.d.ts +11 -2
  134. package/dist/parse/XFormDOM.d.ts +1 -1
  135. package/dist/parse/body/BodyDefinition.d.ts +2 -2
  136. package/dist/parse/body/appearance/rangeAppearanceParser.d.ts +3 -0
  137. package/dist/parse/body/control/InputControlDefinition.d.ts +3 -0
  138. package/dist/parse/body/control/ItemDefinition.d.ts +14 -0
  139. package/dist/parse/body/control/ItemsetDefinition.d.ts +18 -0
  140. package/dist/parse/body/control/RangeControlDefinition.d.ts +31 -2
  141. package/dist/parse/body/control/RankControlDefinition.d.ts +7 -3
  142. package/dist/parse/body/control/{select/SelectDefinition.d.ts → SelectControlDefinition.d.ts} +9 -9
  143. package/dist/parse/expression/ItemsetNodesetExpression.d.ts +1 -1
  144. package/dist/parse/expression/ItemsetValueExpression.d.ts +1 -1
  145. package/dist/parse/model/BindDefinition.d.ts +3 -1
  146. package/dist/parse/model/BindPreloadDefinition.d.ts +42 -0
  147. package/dist/parse/model/DescendentNodeDefinition.d.ts +4 -13
  148. package/dist/parse/model/ItextTranslationsDefinition.d.ts +18 -0
  149. package/dist/parse/model/LeafNodeDefinition.d.ts +9 -7
  150. package/dist/parse/model/ModelDefinition.d.ts +9 -2
  151. package/dist/parse/model/NodeDefinition.d.ts +30 -45
  152. package/dist/parse/model/NoteNodeDefinition.d.ts +7 -5
  153. package/dist/parse/model/RangeNodeDefinition.d.ts +42 -0
  154. package/dist/parse/model/RepeatDefinition.d.ts +62 -0
  155. package/dist/parse/model/RootAttributeDefinition.d.ts +21 -0
  156. package/dist/parse/model/RootAttributeMap.d.ts +24 -0
  157. package/dist/parse/model/RootDefinition.d.ts +15 -14
  158. package/dist/parse/model/SecondaryInstance/SecondaryInstancesDefinition.d.ts +15 -2
  159. package/dist/parse/model/SecondaryInstance/assertSecondaryInstanceDefinition.d.ts +5 -0
  160. package/dist/parse/model/SecondaryInstance/defineSecondaryInstance.d.ts +5 -0
  161. package/dist/parse/model/SecondaryInstance/sources/BlankSecondaryInstanceSource.d.ts +1 -7
  162. package/dist/parse/model/SecondaryInstance/sources/CSVExternalSecondaryInstance.d.ts +1 -1
  163. package/dist/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.d.ts +1 -1
  164. package/dist/parse/model/SecondaryInstance/sources/InternalSecondaryInstanceSource.d.ts +1 -1
  165. package/dist/parse/model/SecondaryInstance/sources/SecondaryInstanceSource.d.ts +1 -1
  166. package/dist/parse/model/SecondaryInstance/sources/XMLExternalSecondaryInstanceSource.d.ts +1 -1
  167. package/dist/parse/model/{FormSubmissionDefinition.d.ts → SubmissionDefinition.d.ts} +2 -2
  168. package/dist/parse/model/SubtreeDefinition.d.ts +9 -7
  169. package/dist/parse/model/nodeDefinitionMap.d.ts +5 -0
  170. package/dist/parse/shared/parseInstanceXML.d.ts +21 -0
  171. package/dist/parse/shared/parseStaticDocumentFromDOMSubtree.d.ts +4 -22
  172. package/dist/parse/text/ItemLabelDefinition.d.ts +1 -1
  173. package/dist/parse/text/ItemsetLabelDefinition.d.ts +2 -2
  174. package/dist/parse/text/abstract/TextElementDefinition.d.ts +1 -1
  175. package/dist/parse/xpath/semantic-analysis.d.ts +1 -3
  176. package/dist/solid.js +7247 -5813
  177. package/dist/solid.js.map +1 -1
  178. package/package.json +15 -12
  179. package/src/client/BaseNode.ts +9 -4
  180. package/src/client/BaseValueNode.ts +8 -4
  181. package/src/client/GroupNode.ts +1 -0
  182. package/src/client/InputNode.ts +38 -2
  183. package/src/client/ModelValueNode.ts +1 -0
  184. package/src/client/NoteNode.ts +43 -7
  185. package/src/client/RangeNode.ts +51 -0
  186. package/src/client/RankNode.ts +54 -0
  187. package/src/client/RootNode.ts +30 -16
  188. package/src/client/SelectNode.ts +53 -26
  189. package/src/client/SubtreeNode.ts +1 -0
  190. package/src/client/TriggerNode.ts +12 -6
  191. package/src/client/constants.ts +12 -14
  192. package/src/client/form/CreateFormInstance.ts +19 -0
  193. package/src/client/form/EditFormInstance.ts +93 -0
  194. package/src/client/form/FormInstance.ts +114 -0
  195. package/src/client/form/FormInstanceConfig.ts +18 -0
  196. package/src/client/form/FormResource.ts +1 -0
  197. package/src/client/form/LoadForm.ts +92 -0
  198. package/src/client/form/LoadFormResult.ts +103 -0
  199. package/src/client/form/RestoreFormInstance.ts +14 -0
  200. package/src/client/hierarchy.ts +7 -8
  201. package/src/client/index.ts +47 -29
  202. package/src/client/node-types.ts +3 -5
  203. package/src/client/repeat/BaseRepeatRangeNode.ts +3 -4
  204. package/src/client/repeat/RepeatInstanceNode.ts +4 -8
  205. package/src/client/repeat/RepeatRangeControlledNode.ts +2 -2
  206. package/src/client/repeat/RepeatRangeUncontrolledNode.ts +2 -2
  207. package/src/client/resources.ts +2 -2
  208. package/src/client/serialization/InstanceData.ts +16 -0
  209. package/src/client/serialization/InstanceFile.ts +9 -0
  210. package/src/client/serialization/InstancePayload.ts +126 -0
  211. package/src/client/serialization/InstancePayloadOptions.ts +28 -0
  212. package/src/client/serialization/InstanceState.ts +14 -0
  213. package/src/client/submission/{SubmissionDefinition.ts → SubmissionMeta.ts} +1 -1
  214. package/src/client/unsupported/UnsupportedControlNode.ts +2 -6
  215. package/src/entrypoints/FormInstance.ts +55 -0
  216. package/src/entrypoints/FormResult/BaseFormResult.ts +40 -0
  217. package/src/entrypoints/FormResult/BaseInstantiableFormResult.ts +109 -0
  218. package/src/entrypoints/FormResult/FormFailureResult.ts +44 -0
  219. package/src/entrypoints/FormResult/FormSuccessResult.ts +25 -0
  220. package/src/entrypoints/FormResult/FormWarningResult.ts +25 -0
  221. package/src/entrypoints/createInstance.ts +23 -0
  222. package/src/entrypoints/editInstance.ts +24 -0
  223. package/src/entrypoints/index.ts +4 -0
  224. package/src/entrypoints/loadForm.ts +154 -0
  225. package/src/entrypoints/restoreInstance.ts +27 -0
  226. package/src/error/LoadFormFailureError.ts +114 -0
  227. package/src/error/MalformedInstanceDataError.ts +3 -0
  228. package/src/error/RankMissingValueError.ts +5 -0
  229. package/src/error/RankValueTypeError.ts +13 -0
  230. package/src/error/SelectValueTypeError.ts +22 -0
  231. package/src/error/TemplatedNodeAttributeSerializationError.ts +24 -0
  232. package/src/error/XFormsSpecViolationError.ts +1 -0
  233. package/src/index.ts +2 -56
  234. package/src/instance/Group.ts +17 -15
  235. package/src/instance/InputControl.ts +58 -12
  236. package/src/instance/ModelValue.ts +19 -11
  237. package/src/instance/Note.ts +40 -64
  238. package/src/instance/PrimaryInstance.ts +70 -31
  239. package/src/instance/RangeControl.ts +119 -0
  240. package/src/instance/RankControl.ts +208 -0
  241. package/src/instance/Root.ts +21 -31
  242. package/src/instance/SelectControl.ts +228 -0
  243. package/src/instance/Subtree.ts +17 -15
  244. package/src/instance/TriggerControl.ts +50 -80
  245. package/src/instance/abstract/DescendantNode.ts +13 -8
  246. package/src/instance/abstract/InstanceNode.ts +19 -7
  247. package/src/instance/abstract/ValueNode.ts +14 -15
  248. package/src/instance/children/DescendantNodeInitOptions.ts +35 -0
  249. package/src/instance/children/buildChildren.ts +206 -0
  250. package/src/instance/children/childrenInitOptions.ts +117 -0
  251. package/src/instance/children/normalizeChildInitOptions.ts +332 -0
  252. package/src/instance/hierarchy.ts +21 -16
  253. package/src/instance/input/InitialInstanceState.ts +108 -0
  254. package/src/instance/input/InstanceAttachmentMap.ts +142 -0
  255. package/src/instance/internal-api/InstanceConfig.ts +3 -10
  256. package/src/instance/internal-api/InstanceValueContext.ts +11 -1
  257. package/src/instance/internal-api/serialization/ClientReactiveSerializableInstance.ts +20 -0
  258. package/src/instance/internal-api/serialization/ClientReactiveSerializableLeafNode.ts +43 -0
  259. package/src/instance/internal-api/serialization/ClientReactiveSerializableParentNode.ts +26 -0
  260. package/src/instance/internal-api/serialization/ClientReactiveSerializableTemplatedNode.ts +24 -0
  261. package/src/instance/internal-api/serialization/ClientReactiveSerializableValueNode.ts +28 -0
  262. package/src/instance/repeat/BaseRepeatRange.ts +21 -24
  263. package/src/instance/repeat/RepeatInstance.ts +27 -19
  264. package/src/instance/repeat/RepeatRangeControlled.ts +90 -17
  265. package/src/instance/repeat/RepeatRangeUncontrolled.ts +10 -9
  266. package/src/instance/resource.ts +18 -2
  267. package/src/instance/unsupported/UploadControl.ts +116 -5
  268. package/src/integration/xpath/EngineXPathEvaluator.ts +2 -2
  269. package/src/integration/xpath/adapter/kind.ts +1 -28
  270. package/src/integration/xpath/adapter/names.ts +66 -17
  271. package/src/integration/xpath/adapter/traversal.ts +12 -11
  272. package/src/integration/xpath/static-dom/StaticAttribute.ts +16 -7
  273. package/src/integration/xpath/static-dom/StaticDocument.ts +17 -18
  274. package/src/integration/xpath/static-dom/StaticElement.ts +211 -52
  275. package/src/integration/xpath/static-dom/StaticNode.ts +1 -1
  276. package/src/integration/xpath/static-dom/StaticParentNode.ts +22 -0
  277. package/src/integration/xpath/static-dom/staticNodeName.ts +20 -0
  278. package/src/lib/client-reactivity/instance-state/createNodeRangeInstanceState.ts +17 -0
  279. package/src/lib/client-reactivity/instance-state/createParentNodeInstanceState.ts +22 -0
  280. package/src/lib/client-reactivity/instance-state/createPrimaryInstanceState.ts +12 -0
  281. package/src/lib/client-reactivity/instance-state/createRootInstanceState.ts +19 -0
  282. package/src/lib/client-reactivity/instance-state/createTemplatedNodeInstanceState.ts +31 -0
  283. package/src/lib/client-reactivity/instance-state/createValueNodeInstanceState.ts +21 -0
  284. package/src/lib/client-reactivity/instance-state/prepareInstancePayload.ts +173 -0
  285. package/src/lib/codecs/Geopoint/Geopoint.ts +150 -0
  286. package/src/lib/codecs/Geopoint/GeopointValueCodec.ts +20 -0
  287. package/src/lib/codecs/NoteCodec.ts +32 -0
  288. package/src/lib/codecs/RangeCodec.ts +65 -0
  289. package/src/lib/codecs/TempUnsupportedControlCodec.ts +32 -0
  290. package/src/lib/codecs/TriggerCodec.ts +64 -0
  291. package/src/lib/codecs/ValueArrayCodec.ts +42 -0
  292. package/src/lib/codecs/ValueCodec.ts +2 -2
  293. package/src/lib/codecs/getNoteCodec.ts +27 -0
  294. package/src/lib/codecs/getSelectCodec.ts +27 -0
  295. package/src/lib/codecs/getSharedValueCodec.ts +5 -3
  296. package/src/lib/codecs/items/BaseItemCodec.ts +20 -0
  297. package/src/lib/codecs/items/MultipleValueItemCodec.ts +28 -0
  298. package/src/lib/codecs/items/SingleValueItemCodec.ts +67 -0
  299. package/src/lib/dom/query.ts +1 -2
  300. package/src/lib/names/NamespaceDeclaration.ts +106 -0
  301. package/src/lib/names/NamespaceDeclarationMap.ts +228 -0
  302. package/src/lib/names/NamespaceURL.ts +44 -0
  303. package/src/lib/names/QualifiedName.ts +170 -0
  304. package/src/lib/names/UnprefixedXFormsName.ts +12 -0
  305. package/src/lib/number-parsers.ts +25 -0
  306. package/src/lib/reactivity/createInstanceValueState.ts +69 -43
  307. package/src/lib/reactivity/{createSelectItems.ts → createItemCollection.ts} +41 -36
  308. package/src/lib/xml-serialization.ts +76 -9
  309. package/src/parse/XFormDOM.ts +141 -21
  310. package/src/parse/XFormDefinition.ts +1 -4
  311. package/src/parse/body/BodyDefinition.ts +4 -4
  312. package/src/parse/body/appearance/rangeAppearanceParser.ts +11 -0
  313. package/src/parse/body/control/InputControlDefinition.ts +9 -0
  314. package/src/parse/body/control/{select/ItemDefinition.ts → ItemDefinition.ts} +8 -6
  315. package/src/parse/body/control/{select/ItemsetDefinition.ts → ItemsetDefinition.ts} +11 -9
  316. package/src/parse/body/control/RangeControlDefinition.ts +91 -6
  317. package/src/parse/body/control/RankControlDefinition.ts +25 -7
  318. package/src/parse/body/control/{select/SelectDefinition.ts → SelectControlDefinition.ts} +9 -9
  319. package/src/parse/expression/ItemsetNodesetExpression.ts +1 -1
  320. package/src/parse/expression/ItemsetValueExpression.ts +1 -1
  321. package/src/parse/model/BindDefinition.ts +4 -0
  322. package/src/parse/model/BindPreloadDefinition.ts +100 -0
  323. package/src/parse/model/DescendentNodeDefinition.ts +7 -25
  324. package/src/parse/model/ItextTranslationsDefinition.ts +79 -0
  325. package/src/parse/model/LeafNodeDefinition.ts +13 -8
  326. package/src/parse/model/ModelDefinition.ts +36 -3
  327. package/src/parse/model/NodeDefinition.ts +38 -85
  328. package/src/parse/model/NoteNodeDefinition.ts +12 -10
  329. package/src/parse/model/RangeNodeDefinition.ts +119 -0
  330. package/src/parse/model/RepeatDefinition.ts +382 -0
  331. package/src/parse/model/RootAttributeDefinition.ts +44 -0
  332. package/src/parse/model/RootAttributeMap.ts +49 -0
  333. package/src/parse/model/RootDefinition.ts +42 -43
  334. package/src/parse/model/SecondaryInstance/SecondaryInstancesDefinition.ts +23 -2
  335. package/src/parse/model/SecondaryInstance/assertSecondaryInstanceDefinition.ts +14 -0
  336. package/src/parse/model/SecondaryInstance/defineSecondaryInstance.ts +32 -0
  337. package/src/parse/model/SecondaryInstance/sources/BlankSecondaryInstanceSource.ts +3 -24
  338. package/src/parse/model/SecondaryInstance/sources/CSVExternalSecondaryInstance.ts +33 -86
  339. package/src/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.ts +64 -136
  340. package/src/parse/model/SecondaryInstance/sources/InternalSecondaryInstanceSource.ts +9 -7
  341. package/src/parse/model/SecondaryInstance/sources/SecondaryInstanceSource.ts +1 -1
  342. package/src/parse/model/SecondaryInstance/sources/XMLExternalSecondaryInstanceSource.ts +7 -7
  343. package/src/parse/model/{FormSubmissionDefinition.ts → SubmissionDefinition.ts} +2 -2
  344. package/src/parse/model/SubtreeDefinition.ts +15 -16
  345. package/src/parse/model/nodeDefinitionMap.ts +34 -0
  346. package/src/parse/shared/parseInstanceXML.ts +79 -0
  347. package/src/parse/shared/parseStaticDocumentFromDOMSubtree.ts +46 -131
  348. package/src/parse/text/ItemLabelDefinition.ts +1 -1
  349. package/src/parse/text/ItemsetLabelDefinition.ts +2 -2
  350. package/src/parse/text/abstract/TextElementDefinition.ts +1 -1
  351. package/src/parse/xpath/semantic-analysis.ts +4 -3
  352. package/dist/client/EngineConfig.d.ts +0 -79
  353. package/dist/client/submission/SubmissionData.d.ts +0 -7
  354. package/dist/client/submission/SubmissionInstanceFile.d.ts +0 -6
  355. package/dist/client/submission/SubmissionOptions.d.ts +0 -23
  356. package/dist/client/submission/SubmissionResult.d.ts +0 -91
  357. package/dist/client/submission/SubmissionState.d.ts +0 -12
  358. package/dist/client/unsupported/RangeNode.d.ts +0 -9
  359. package/dist/client/unsupported/RankNode.d.ts +0 -9
  360. package/dist/instance/SelectField.d.ts +0 -58
  361. package/dist/instance/abstract/UnsupportedControl.d.ts +0 -53
  362. package/dist/instance/index.d.ts +0 -8
  363. package/dist/instance/internal-api/ValueContext.d.ts +0 -23
  364. package/dist/instance/internal-api/submission/ClientReactiveSubmittableInstance.d.ts +0 -14
  365. package/dist/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.d.ts +0 -31
  366. package/dist/instance/internal-api/submission/ClientReactiveSubmittableParentNode.d.ts +0 -18
  367. package/dist/instance/internal-api/submission/ClientReactiveSubmittableValueNode.d.ts +0 -17
  368. package/dist/instance/unsupported/RangeControl.d.ts +0 -6
  369. package/dist/instance/unsupported/RankControl.d.ts +0 -6
  370. package/dist/integration/xpath/static-dom/StaticNamedNode.d.ts +0 -17
  371. package/dist/lib/client-reactivity/submission/createInstanceSubmissionState.d.ts +0 -3
  372. package/dist/lib/client-reactivity/submission/createLeafNodeSubmissionState.d.ts +0 -3
  373. package/dist/lib/client-reactivity/submission/createNodeRangeSubmissionState.d.ts +0 -4
  374. package/dist/lib/client-reactivity/submission/createParentNodeSubmissionState.d.ts +0 -4
  375. package/dist/lib/client-reactivity/submission/createValueNodeSubmissionState.d.ts +0 -3
  376. package/dist/lib/client-reactivity/submission/prepareSubmission.d.ts +0 -8
  377. package/dist/lib/reactivity/createSelectItems.d.ts +0 -16
  378. package/dist/lib/reactivity/createValueState.d.ts +0 -40
  379. package/dist/parse/body/control/select/ItemDefinition.d.ts +0 -13
  380. package/dist/parse/body/control/select/ItemsetDefinition.d.ts +0 -17
  381. package/dist/parse/body/control/select/ItemsetNodesetContext.d.ts +0 -9
  382. package/dist/parse/model/ItextTranslation/ItextTranslationDefinition.d.ts +0 -4
  383. package/dist/parse/model/ItextTranslation/ItextTranslationRootDefinition.d.ts +0 -8
  384. package/dist/parse/model/ItextTranslation/ItextTranslationsDefinition.d.ts +0 -8
  385. package/dist/parse/model/RepeatInstanceDefinition.d.ts +0 -14
  386. package/dist/parse/model/RepeatRangeDefinition.d.ts +0 -29
  387. package/dist/parse/model/RepeatTemplateDefinition.d.ts +0 -28
  388. package/dist/parse/model/SecondaryInstance/SecondaryInstanceDefinition.d.ts +0 -4
  389. package/dist/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.d.ts +0 -7
  390. package/src/client/EngineConfig.ts +0 -84
  391. package/src/client/submission/SubmissionData.ts +0 -12
  392. package/src/client/submission/SubmissionInstanceFile.ts +0 -9
  393. package/src/client/submission/SubmissionOptions.ts +0 -28
  394. package/src/client/submission/SubmissionResult.ts +0 -124
  395. package/src/client/submission/SubmissionState.ts +0 -14
  396. package/src/client/unsupported/RangeNode.ts +0 -14
  397. package/src/client/unsupported/RankNode.ts +0 -14
  398. package/src/instance/SelectField.ts +0 -263
  399. package/src/instance/abstract/UnsupportedControl.ts +0 -174
  400. package/src/instance/children.ts +0 -158
  401. package/src/instance/index.ts +0 -55
  402. package/src/instance/internal-api/ValueContext.ts +0 -28
  403. package/src/instance/internal-api/submission/ClientReactiveSubmittableInstance.ts +0 -20
  404. package/src/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.ts +0 -42
  405. package/src/instance/internal-api/submission/ClientReactiveSubmittableParentNode.ts +0 -25
  406. package/src/instance/internal-api/submission/ClientReactiveSubmittableValueNode.ts +0 -23
  407. package/src/instance/unsupported/RangeControl.ts +0 -9
  408. package/src/instance/unsupported/RankControl.ts +0 -9
  409. package/src/integration/xpath/static-dom/StaticNamedNode.ts +0 -45
  410. package/src/lib/client-reactivity/submission/createInstanceSubmissionState.ts +0 -12
  411. package/src/lib/client-reactivity/submission/createLeafNodeSubmissionState.ts +0 -20
  412. package/src/lib/client-reactivity/submission/createNodeRangeSubmissionState.ts +0 -17
  413. package/src/lib/client-reactivity/submission/createParentNodeSubmissionState.ts +0 -22
  414. package/src/lib/client-reactivity/submission/createValueNodeSubmissionState.ts +0 -21
  415. package/src/lib/client-reactivity/submission/prepareSubmission.ts +0 -172
  416. package/src/lib/reactivity/createValueState.ts +0 -200
  417. package/src/parse/body/control/select/ItemsetNodesetContext.ts +0 -21
  418. package/src/parse/model/ItextTranslation/ItextTranslationDefinition.ts +0 -4
  419. package/src/parse/model/ItextTranslation/ItextTranslationRootDefinition.ts +0 -41
  420. package/src/parse/model/ItextTranslation/ItextTranslationsDefinition.ts +0 -31
  421. package/src/parse/model/RepeatInstanceDefinition.ts +0 -34
  422. package/src/parse/model/RepeatRangeDefinition.ts +0 -94
  423. package/src/parse/model/RepeatTemplateDefinition.ts +0 -145
  424. package/src/parse/model/SecondaryInstance/SecondaryInstanceDefinition.ts +0 -4
  425. package/src/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.ts +0 -12
@@ -1,4 +1,9 @@
1
- import { XFORMS_NAMESPACE_URI, XMLNS_NAMESPACE_URI } from '@getodk/common/constants/xmlns.ts';
1
+ import {
2
+ JAVAROSA_NAMESPACE_URI,
3
+ OPENROSA_XFORMS_NAMESPACE_URI,
4
+ XFORMS_NAMESPACE_URI,
5
+ XMLNS_NAMESPACE_URI,
6
+ } from '@getodk/common/constants/xmlns.ts';
2
7
  import type {
3
8
  KnownAttributeLocalNamedElement,
4
9
  LocalNamedElement,
@@ -7,6 +12,118 @@ import { DefaultEvaluator } from '@getodk/xpath';
7
12
 
8
13
  interface DOMBindElement extends KnownAttributeLocalNamedElement<'bind', 'nodeset'> {}
9
14
 
15
+ const getMetaElement = (primaryInstanceRoot: Element): Element | null => {
16
+ for (const child of primaryInstanceRoot.children) {
17
+ const { localName, namespaceURI } = child;
18
+
19
+ if (
20
+ (namespaceURI === OPENROSA_XFORMS_NAMESPACE_URI || namespaceURI === XFORMS_NAMESPACE_URI) &&
21
+ localName === 'meta'
22
+ ) {
23
+ return child;
24
+ }
25
+ }
26
+
27
+ return null;
28
+ };
29
+
30
+ const getMetaChildElement = (meta: Element | null, localName: string): Element | null => {
31
+ if (meta == null) {
32
+ return null;
33
+ }
34
+
35
+ const { namespaceURI } = meta;
36
+
37
+ for (const child of meta.children) {
38
+ if (child.localName === localName && child.namespaceURI === namespaceURI) {
39
+ return child;
40
+ }
41
+ }
42
+
43
+ return null;
44
+ };
45
+
46
+ const getQualifiedName = (
47
+ contextNode: Node,
48
+ namespaceURI: string | null,
49
+ localName: string
50
+ ): string => {
51
+ const prefix = contextNode.lookupPrefix(namespaceURI);
52
+
53
+ if (prefix == null) {
54
+ return localName;
55
+ }
56
+
57
+ return `${prefix}:${localName}`;
58
+ };
59
+
60
+ const createNamespacedChildElement = (
61
+ parent: Element,
62
+ namespaceURI: string | null,
63
+ localName: string
64
+ ): Element => {
65
+ const qualifiedName = getQualifiedName(parent, namespaceURI, localName);
66
+ const child = parent.ownerDocument.createElementNS(namespaceURI, qualifiedName);
67
+
68
+ parent.append(child);
69
+
70
+ return child;
71
+ };
72
+
73
+ const setNamespacedAttributeValue = (
74
+ element: Element,
75
+ namespaceURI: string | null,
76
+ localName: string,
77
+ value: string
78
+ ) => {
79
+ const qualifiedName = getQualifiedName(element, namespaceURI, localName);
80
+
81
+ element.setAttributeNS(namespaceURI, qualifiedName, value);
82
+ };
83
+
84
+ const createDefaultInstanceIDBinding = (
85
+ model: Element,
86
+ primaryInstanceRoot: Element,
87
+ meta: Element,
88
+ instanceID: Element
89
+ ): DOMBindElement => {
90
+ const bind = createNamespacedChildElement(model, model.namespaceURI, 'bind');
91
+ const nodeset = `/${primaryInstanceRoot.nodeName}/${meta.nodeName}/${instanceID.nodeName}`;
92
+
93
+ bind.setAttribute('nodeset', nodeset);
94
+ setNamespacedAttributeValue(bind, JAVAROSA_NAMESPACE_URI, 'preload', 'uid');
95
+
96
+ return bind as DOMBindElement;
97
+ };
98
+
99
+ const normalizeDefaultMetaBindings = (
100
+ model: Element,
101
+ primaryInstanceRoot: Element,
102
+ binds: readonly DOMBindElement[]
103
+ ): readonly DOMBindElement[] => {
104
+ let meta = getMetaElement(primaryInstanceRoot);
105
+ let instanceID = getMetaChildElement(meta, 'instanceID');
106
+
107
+ if (meta == null) {
108
+ meta = createNamespacedChildElement(primaryInstanceRoot, OPENROSA_XFORMS_NAMESPACE_URI, 'meta');
109
+ }
110
+
111
+ if (instanceID == null) {
112
+ instanceID = createNamespacedChildElement(meta, meta.namespaceURI, 'instanceID');
113
+
114
+ const instanceIDBinding = createDefaultInstanceIDBinding(
115
+ model,
116
+ primaryInstanceRoot,
117
+ meta,
118
+ instanceID
119
+ );
120
+
121
+ return [...binds, instanceIDBinding];
122
+ }
123
+
124
+ return binds;
125
+ };
126
+
10
127
  export interface DOMItextTranslationElement
11
128
  extends KnownAttributeLocalNamedElement<'translation', 'lang'> {}
12
129
 
@@ -238,23 +355,6 @@ export class XFormDOM {
238
355
  const html = evaluator.evaluateNonNullElement('/h:html', {
239
356
  contextNode: xformDocument,
240
357
  });
241
-
242
- let body = evaluator.evaluateNonNullElement('./h:body', {
243
- contextNode: html,
244
- });
245
- let normalizedXML: string;
246
-
247
- if (options.isNormalized) {
248
- normalizedXML = sourceXML;
249
- } else {
250
- body = normalizeXFormBody(body);
251
-
252
- // TODO: if we keep doing normalization this way long term (or using the DOM
253
- // for parsing long term, for that matter!), we should measure this. And we
254
- // should measure against XMLSerializer while we're at it!
255
- normalizedXML = xformDocument.documentElement.outerHTML;
256
- }
257
-
258
358
  const head = evaluator.evaluateNonNullElement('./h:head', {
259
359
  contextNode: html,
260
360
  });
@@ -264,9 +364,12 @@ export class XFormDOM {
264
364
  const model = evaluator.evaluateNonNullElement('./xf:model', {
265
365
  contextNode: head,
266
366
  });
267
- const binds = evaluator.evaluateNodes<DOMBindElement>('./xf:bind[@nodeset]', {
268
- contextNode: model,
269
- });
367
+ let binds: readonly DOMBindElement[] = evaluator.evaluateNodes<DOMBindElement>(
368
+ './xf:bind[@nodeset]',
369
+ {
370
+ contextNode: model,
371
+ }
372
+ );
270
373
 
271
374
  const instances = evaluator.evaluateNodes<DOMInstanceElement>('./xf:instance', {
272
375
  contextNode: model,
@@ -292,6 +395,23 @@ export class XFormDOM {
292
395
  }
293
396
  );
294
397
 
398
+ let body = evaluator.evaluateNonNullElement('./h:body', {
399
+ contextNode: html,
400
+ });
401
+ let normalizedXML: string;
402
+
403
+ if (options.isNormalized) {
404
+ normalizedXML = sourceXML;
405
+ } else {
406
+ body = normalizeXFormBody(body);
407
+ binds = normalizeDefaultMetaBindings(model, primaryInstanceRoot, binds);
408
+
409
+ // TODO: if we keep doing normalization this way long term (or using the DOM
410
+ // for parsing long term, for that matter!), we should measure this. And we
411
+ // should measure against XMLSerializer while we're at it!
412
+ normalizedXML = xformDocument.documentElement.outerHTML;
413
+ }
414
+
295
415
  this.normalizedXML = normalizedXML;
296
416
  this.xformDocument = xformDocument;
297
417
  this.html = html;
@@ -24,10 +24,7 @@ export class XFormDefinition {
24
24
  this.xformDocument = xformDocument;
25
25
  this.id = id;
26
26
  this.title = title.textContent ?? '';
27
-
28
- // TODO: highly unlikely primary instance root will need a namespace prefix
29
- // but noting it just in case there is such weird usage...
30
- this.rootReference = `/${primaryInstanceRoot.localName}`;
27
+ this.rootReference = `/${primaryInstanceRoot.nodeName}`;
31
28
 
32
29
  this.body = new BodyDefinition(this);
33
30
  this.model = new ModelDefinition(this);
@@ -6,8 +6,8 @@ import { ControlDefinition } from './control/ControlDefinition.ts';
6
6
  import { InputControlDefinition } from './control/InputControlDefinition.ts';
7
7
  import { RangeControlDefinition } from './control/RangeControlDefinition.ts';
8
8
  import { RankControlDefinition } from './control/RankControlDefinition.ts';
9
- import type { AnySelectDefinition } from './control/select/SelectDefinition.ts';
10
- import { SelectDefinition } from './control/select/SelectDefinition.ts';
9
+ import type { AnySelectControlDefinition } from './control/SelectControlDefinition.ts';
10
+ import { SelectControlDefinition } from './control/SelectControlDefinition.ts';
11
11
  import { TriggerControlDefinition } from './control/TriggerControlDefinition.ts';
12
12
  import { UploadControlDefinition } from './control/UploadControlDefinition.ts';
13
13
  import { LogicalGroupDefinition } from './group/LogicalGroupDefinition.ts';
@@ -24,7 +24,7 @@ export interface BodyElementParentContext {
24
24
 
25
25
  // prettier-ignore
26
26
  export type ControlElementDefinition =
27
- | AnySelectDefinition
27
+ | AnySelectControlDefinition
28
28
  | InputControlDefinition
29
29
  | RangeControlDefinition
30
30
  | RankControlDefinition
@@ -48,7 +48,7 @@ const BodyElementDefinitionConstructors = [
48
48
  PresentationGroupDefinition,
49
49
  StructuralGroupDefinition,
50
50
  InputControlDefinition,
51
- SelectDefinition,
51
+ SelectControlDefinition,
52
52
  RangeControlDefinition,
53
53
  RankControlDefinition,
54
54
  TriggerControlDefinition,
@@ -0,0 +1,11 @@
1
+ import type { ParsedTokenList } from '../../../lib/TokenListParser.ts';
2
+ import { TokenListParser } from '../../../lib/TokenListParser.ts';
3
+
4
+ export const rangeAppearanceParser = new TokenListParser([
5
+ 'no-ticks',
6
+ 'picker',
7
+ 'rating',
8
+ 'vertical',
9
+ ]);
10
+
11
+ export type RangeAppearanceDefinition = ParsedTokenList<typeof rangeAppearanceParser>;
@@ -2,6 +2,7 @@ import type { XFormDefinition } from '../../XFormDefinition.ts';
2
2
  import type { InputAppearanceDefinition } from '../appearance/inputAppearanceParser.ts';
3
3
  import { inputAppearanceParser } from '../appearance/inputAppearanceParser.ts';
4
4
  import type { BodyElementParentContext } from '../BodyDefinition.ts';
5
+ import { parseToFloat, parseToInteger } from '../../../lib/number-parsers.ts';
5
6
  import { ControlDefinition } from './ControlDefinition.ts';
6
7
 
7
8
  export class InputControlDefinition extends ControlDefinition<'input'> {
@@ -11,10 +12,18 @@ export class InputControlDefinition extends ControlDefinition<'input'> {
11
12
 
12
13
  readonly type = 'input';
13
14
  readonly appearances: InputAppearanceDefinition;
15
+ readonly rows: number | null;
16
+ readonly accuracyThreshold: number | null;
17
+ readonly unacceptableAccuracyThreshold: number | null;
14
18
 
15
19
  constructor(form: XFormDefinition, parent: BodyElementParentContext, element: Element) {
16
20
  super(form, parent, element);
17
21
 
18
22
  this.appearances = inputAppearanceParser.parseFrom(element, 'appearance');
23
+ this.rows = parseToInteger(element.getAttribute('rows'));
24
+ this.accuracyThreshold = parseToFloat(element.getAttribute('accuracyThreshold'));
25
+ this.unacceptableAccuracyThreshold = parseToFloat(
26
+ element.getAttribute('unacceptableAccuracyThreshold')
27
+ );
19
28
  }
20
29
  }
@@ -1,8 +1,10 @@
1
- import { getValueElement, type ItemElement } from '../../../../lib/dom/query.ts';
2
- import { ItemLabelDefinition } from '../../../text/ItemLabelDefinition.ts';
3
- import type { XFormDefinition } from '../../../XFormDefinition.ts';
4
- import { BodyElementDefinition } from '../../BodyElementDefinition.ts';
5
- import type { AnySelectDefinition } from './SelectDefinition.ts';
1
+ import type { ItemElement } from '../../../lib/dom/query.ts';
2
+ import { getValueElement } from '../../../lib/dom/query.ts';
3
+ import { ItemLabelDefinition } from '../../text/ItemLabelDefinition.ts';
4
+ import type { XFormDefinition } from '../../XFormDefinition.ts';
5
+ import { BodyElementDefinition } from '../BodyElementDefinition.ts';
6
+ import type { AnySelectControlDefinition } from './SelectControlDefinition.ts';
7
+ import { RankControlDefinition } from './RankControlDefinition.ts';
6
8
 
7
9
  export class ItemDefinition extends BodyElementDefinition<'item'> {
8
10
  override readonly category = 'support';
@@ -13,7 +15,7 @@ export class ItemDefinition extends BodyElementDefinition<'item'> {
13
15
 
14
16
  constructor(
15
17
  form: XFormDefinition,
16
- override readonly parent: AnySelectDefinition,
18
+ override readonly parent: AnySelectControlDefinition | RankControlDefinition,
17
19
  element: ItemElement
18
20
  ) {
19
21
  const valueElement = getValueElement(element);
@@ -1,11 +1,13 @@
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';
1
+ import type { ItemsetElement } from '../../../lib/dom/query.ts';
2
+ import { getValueElement } from '../../../lib/dom/query.ts';
3
+ import { ItemsetNodesetExpression } from '../../expression/ItemsetNodesetExpression.ts';
4
+ import { ItemsetValueExpression } from '../../expression/ItemsetValueExpression.ts';
5
+ import { ItemsetLabelDefinition } from '../../text/ItemsetLabelDefinition.ts';
6
+ import type { XFormDefinition } from '../../XFormDefinition.ts';
7
+ import { parseNodesetReference } from '../../xpath/reference-parsing.ts';
8
+ import { BodyElementDefinition } from '../BodyElementDefinition.ts';
9
+ import type { AnySelectControlDefinition } from './SelectControlDefinition.ts';
10
+ import { RankControlDefinition } from './RankControlDefinition.ts';
9
11
 
10
12
  export class ItemsetDefinition extends BodyElementDefinition<'itemset'> {
11
13
  override readonly category = 'support';
@@ -19,7 +21,7 @@ export class ItemsetDefinition extends BodyElementDefinition<'itemset'> {
19
21
 
20
22
  constructor(
21
23
  form: XFormDefinition,
22
- override readonly parent: AnySelectDefinition,
24
+ override readonly parent: AnySelectControlDefinition | RankControlDefinition,
23
25
  element: ItemsetElement
24
26
  ) {
25
27
  super(form, parent, element);
@@ -1,23 +1,108 @@
1
+ import { ErrorProductionDesignPendingError } from '../../../error/ErrorProductionDesignPendingError.ts';
1
2
  import type { XFormDefinition } from '../../XFormDefinition.ts';
2
- import {
3
- unknownAppearanceParser,
4
- type UnknownAppearanceDefinition,
5
- } from '../appearance/unknownAppearanceParser.ts';
3
+ import type { RangeAppearanceDefinition } from '../appearance/rangeAppearanceParser.ts';
4
+ import { rangeAppearanceParser } from '../appearance/rangeAppearanceParser.ts';
6
5
  import type { BodyElementParentContext } from '../BodyDefinition.ts';
7
6
  import { ControlDefinition } from './ControlDefinition.ts';
8
7
 
8
+ type NumericString = `${number}`;
9
+
10
+ /**
11
+ * @todo this should likely become a basis for generalizing how we parse number
12
+ * values from strings. Note for when we take that on: number semantics vary
13
+ * between:
14
+ *
15
+ * - {@link https://www.w3.org/TR/1999/REC-xpath-19991116/#numbers | XPath}:
16
+ * XPath "64-bit [...] IEEE 754" number values are almost totally consistent
17
+ * with JavaScript numbers; the main difference is that JavaScript's
18
+ * {@link Number} factory is more flexible in casting from string than the
19
+ * casting semantics specified by XPath
20
+ *
21
+ * - {@link https://getodk.github.io/xforms-spec/#data-types | [ODK] XForms}:
22
+ * specifies both `int` and `decimal` types. Decimals are **NOT** expected to
23
+ * have the same precision tradeoffs as IEEE 754 numbers, and we'll want to
24
+ * take special care that parsing does not introduce precision errors.
25
+ */
26
+ const NUMERIC_STRING_PATTERN = /^-?\d+(\.\d+)?$/;
27
+
28
+ const isNumericString = (value: string): value is NumericString => {
29
+ return NUMERIC_STRING_PATTERN.test(value);
30
+ };
31
+
32
+ type AssertNumericStringAttribute = (
33
+ localName: string,
34
+ value: string | null
35
+ ) => asserts value is NumericString;
36
+
37
+ const assertNumericStringAttribute: AssertNumericStringAttribute = (localName, value) => {
38
+ if (value == null) {
39
+ throw new ErrorProductionDesignPendingError(`Expected attribute ${localName} is not defined`);
40
+ }
41
+
42
+ if (!isNumericString(value)) {
43
+ throw new ErrorProductionDesignPendingError(
44
+ `Expected attribute ${localName} to be defined with numeric string, got: ${JSON.stringify(value)}`
45
+ );
46
+ }
47
+ };
48
+
49
+ const parseNumericStringAttribute = (element: Element, localName: string): NumericString => {
50
+ const value = element.getAttribute(localName);
51
+
52
+ assertNumericStringAttribute(localName, value);
53
+
54
+ return value;
55
+ };
56
+
57
+ /**
58
+ * Per
59
+ * {@link https://getodk.github.io/xforms-spec/#body-elements | ODK XForms spec},
60
+ * the following attributes are required:
61
+ *
62
+ * - `start`
63
+ * - `end`
64
+ * - `step`
65
+ *
66
+ * While we also know that a `<range>` control is expected to have a bind type
67
+ * of either `decimal` or `int`, at this parsing stage we do not yet know which
68
+ * type is associated with the control. So we parse the attributes as strings,
69
+ * checking only that they appear to be numeric values. We also preserve the
70
+ * attributes' names here, for consistency with the spec.
71
+ *
72
+ * Downstream, we parse these to their appropriate numeric runtime types, and
73
+ * alias them to their more conventional names (i.e. "start" -> "min", "end" ->
74
+ * "max").
75
+ */
76
+ export class RangeControlBoundsDefinition {
77
+ static from(element: Element) {
78
+ const start = parseNumericStringAttribute(element, 'start');
79
+ const end = parseNumericStringAttribute(element, 'end');
80
+ const step = parseNumericStringAttribute(element, 'step');
81
+
82
+ return new this(start, end, step);
83
+ }
84
+
85
+ constructor(
86
+ readonly start: NumericString,
87
+ readonly end: NumericString,
88
+ readonly step: NumericString
89
+ ) {}
90
+ }
91
+
9
92
  export class RangeControlDefinition extends ControlDefinition<'range'> {
10
93
  static override isCompatible(localName: string): boolean {
11
94
  return localName === 'range';
12
95
  }
13
96
 
14
97
  readonly type = 'range';
15
- readonly appearances: UnknownAppearanceDefinition;
98
+ readonly appearances: RangeAppearanceDefinition;
99
+ readonly bounds: RangeControlBoundsDefinition;
16
100
 
17
101
  constructor(form: XFormDefinition, parent: BodyElementParentContext, element: Element) {
18
102
  super(form, parent, element);
19
103
 
20
- this.appearances = unknownAppearanceParser.parseFrom(element, 'appearance');
104
+ this.appearances = rangeAppearanceParser.parseFrom(element, 'appearance');
105
+ this.bounds = RangeControlBoundsDefinition.from(element);
21
106
  }
22
107
 
23
108
  override toJSON(): object {
@@ -1,27 +1,45 @@
1
- import { ODK_NAMESPACE_URI } from '@getodk/common/constants/xmlns.ts';
1
+ import { getItemElements, getItemsetElement } from '../../../lib/dom/query.ts';
2
2
  import type { XFormDefinition } from '../../XFormDefinition.ts';
3
+ import type { BodyElementParentContext } from '../BodyDefinition.ts';
4
+ import { ControlDefinition } from './ControlDefinition.ts';
5
+ import { ItemsetDefinition } from './ItemsetDefinition.ts';
6
+ import { ItemDefinition } from './ItemDefinition.ts';
3
7
  import {
4
- unknownAppearanceParser,
5
8
  type UnknownAppearanceDefinition,
9
+ unknownAppearanceParser,
6
10
  } from '../appearance/unknownAppearanceParser.ts';
7
- import type { BodyElementParentContext } from '../BodyDefinition.ts';
8
- import { ControlDefinition } from './ControlDefinition.ts';
9
11
 
10
12
  export class RankControlDefinition extends ControlDefinition<'rank'> {
11
- static override isCompatible(localName: string, element: Element): boolean {
12
- return localName === 'rank' && element.namespaceURI === ODK_NAMESPACE_URI;
13
+ static override isCompatible(localName: string): boolean {
14
+ return localName === 'rank';
13
15
  }
14
16
 
15
17
  readonly type = 'rank';
16
18
  readonly appearances: UnknownAppearanceDefinition;
19
+ readonly itemset: ItemsetDefinition | null;
20
+ readonly items: readonly ItemDefinition[];
17
21
 
18
22
  constructor(form: XFormDefinition, parent: BodyElementParentContext, element: Element) {
19
23
  super(form, parent, element);
20
24
 
21
25
  this.appearances = unknownAppearanceParser.parseFrom(element, 'appearance');
26
+ const itemsetElement = getItemsetElement(element);
27
+ const itemElements = getItemElements(element);
28
+
29
+ if (itemsetElement === null || itemElements === undefined) {
30
+ this.itemset = null;
31
+ this.items = itemElements.map((itemElement) => new ItemDefinition(form, this, itemElement));
32
+ } else {
33
+ if (itemElements.length > 0) {
34
+ throw new Error(`<${element.nodeName}> has both <itemset> and <item> children`);
35
+ }
36
+
37
+ this.items = [];
38
+ this.itemset = new ItemsetDefinition(form, this, itemsetElement);
39
+ }
22
40
  }
23
41
 
24
- override toJSON(): object {
42
+ override toJSON() {
25
43
  return {};
26
44
  }
27
45
  }
@@ -1,11 +1,11 @@
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';
4
- import type { XFormDefinition } from '../../../XFormDefinition.ts';
5
- import type { SelectAppearanceDefinition } from '../../appearance/selectAppearanceParser.ts';
6
- import { selectAppearanceParser } from '../../appearance/selectAppearanceParser.ts';
7
- import type { AnyBodyElementDefinition, BodyElementParentContext } from '../../BodyDefinition.ts';
8
- import { ControlDefinition } from '../ControlDefinition.ts';
3
+ import { getItemElements, getItemsetElement } from '../../../lib/dom/query.ts';
4
+ import type { XFormDefinition } from '../../XFormDefinition.ts';
5
+ import type { SelectAppearanceDefinition } from '../appearance/selectAppearanceParser.ts';
6
+ import { selectAppearanceParser } from '../appearance/selectAppearanceParser.ts';
7
+ import type { AnyBodyElementDefinition, BodyElementParentContext } from '../BodyDefinition.ts';
8
+ import { ControlDefinition } from './ControlDefinition.ts';
9
9
  import { ItemDefinition } from './ItemDefinition.ts';
10
10
  import { ItemsetDefinition } from './ItemsetDefinition.ts';
11
11
 
@@ -22,12 +22,12 @@ const isSelectElement = (
22
22
  return selectLocalNames.has(localName as SelectType);
23
23
  };
24
24
 
25
- export class SelectDefinition<Type extends SelectType> extends ControlDefinition<Type> {
25
+ export class SelectControlDefinition<Type extends SelectType> extends ControlDefinition<Type> {
26
26
  static override isCompatible(localName: string, element: Element): boolean {
27
27
  return isSelectElement(element, localName);
28
28
  }
29
29
 
30
- static isSelect(element: AnyBodyElementDefinition): element is AnySelectDefinition {
30
+ static isSelect(element: AnyBodyElementDefinition): element is AnySelectControlDefinition {
31
31
  return selectLocalNames.has(element.type as SelectType);
32
32
  }
33
33
 
@@ -72,4 +72,4 @@ export class SelectDefinition<Type extends SelectType> extends ControlDefinition
72
72
  }
73
73
  }
74
74
 
75
- export type AnySelectDefinition = SelectDefinition<SelectType>;
75
+ export type AnySelectControlDefinition = SelectControlDefinition<SelectType>;
@@ -1,4 +1,4 @@
1
- import type { ItemsetDefinition } from '../body/control/select/ItemsetDefinition.ts';
1
+ import type { ItemsetDefinition } from '../body/control/ItemsetDefinition.ts';
2
2
  import { DependentExpression } from './abstract/DependentExpression.ts';
3
3
 
4
4
  export class ItemsetNodesetExpression extends DependentExpression<'nodes'> {
@@ -1,4 +1,4 @@
1
- import type { ItemsetDefinition } from '../body/control/select/ItemsetDefinition.ts';
1
+ import type { ItemsetDefinition } from '../body/control/ItemsetDefinition.ts';
2
2
  import { DependentExpression } from './abstract/DependentExpression.ts';
3
3
 
4
4
  export class ItemsetValueExpression extends DependentExpression<'string'> {
@@ -4,6 +4,7 @@ import { BindComputationExpression } from '../expression/BindComputationExpressi
4
4
  import { MessageDefinition } from '../text/MessageDefinition.ts';
5
5
  import type { XFormDefinition } from '../XFormDefinition.ts';
6
6
  import type { BindElement } from './BindElement.ts';
7
+ import { BindPreloadDefinition, type AnyBindPreloadDefinition } from './BindPreloadDefinition.ts';
7
8
  import type { BindType } from './BindTypeDefinition.ts';
8
9
  import { BindTypeDefinition } from './BindTypeDefinition.ts';
9
10
  import type { ModelDefinition } from './ModelDefinition.ts';
@@ -12,6 +13,8 @@ export class BindDefinition<T extends BindType = BindType> extends DependencyCon
12
13
  readonly type: BindTypeDefinition<T>;
13
14
  readonly parentNodeset: string | null;
14
15
 
16
+ readonly preload: AnyBindPreloadDefinition | null;
17
+
15
18
  readonly calculate: BindComputationExpression<'calculate'> | null;
16
19
  readonly readonly: BindComputationExpression<'readonly'>;
17
20
  readonly relevant: BindComputationExpression<'relevant'>;
@@ -82,6 +85,7 @@ export class BindDefinition<T extends BindType = BindType> extends DependencyCon
82
85
  const parentNodeset = nodeset.replace(/\/[^/]+$/, '');
83
86
 
84
87
  this.parentNodeset = parentNodeset.length > 1 ? parentNodeset : null;
88
+ this.preload = BindPreloadDefinition.from(bindElement);
85
89
  this.calculate = BindComputationExpression.forComputation(this, 'calculate');
86
90
  this.readonly = BindComputationExpression.forComputation(this, 'readonly');
87
91
  this.relevant = BindComputationExpression.forComputation(this, 'relevant');