@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.
- package/README.md +1 -1
- package/dist/client/BaseNode.d.ts +8 -4
- package/dist/client/BaseValueNode.d.ts +8 -4
- package/dist/client/GroupNode.d.ts +1 -0
- package/dist/client/InputNode.d.ts +32 -3
- package/dist/client/ModelValueNode.d.ts +1 -0
- package/dist/client/NoteNode.d.ts +24 -7
- package/dist/client/RangeNode.d.ts +36 -0
- package/dist/client/RankNode.d.ts +46 -0
- package/dist/client/RootNode.d.ts +21 -14
- package/dist/client/SelectNode.d.ts +47 -25
- package/dist/client/SubtreeNode.d.ts +1 -0
- package/dist/client/TriggerNode.d.ts +10 -6
- package/dist/client/constants.d.ts +11 -12
- package/dist/client/form/CreateFormInstance.d.ts +14 -0
- package/dist/client/form/EditFormInstance.d.ts +62 -0
- package/dist/client/form/FormInstance.d.ts +104 -0
- package/dist/client/form/FormInstanceConfig.d.ts +17 -0
- package/dist/client/form/FormResource.d.ts +1 -0
- package/dist/client/form/LoadForm.d.ts +79 -0
- package/dist/client/form/LoadFormResult.d.ts +67 -0
- package/dist/client/form/RestoreFormInstance.d.ts +8 -0
- package/dist/client/hierarchy.d.ts +5 -5
- package/dist/client/index.d.ts +37 -11
- package/dist/client/node-types.d.ts +2 -2
- package/dist/client/repeat/BaseRepeatRangeNode.d.ts +3 -4
- package/dist/client/repeat/RepeatInstanceNode.d.ts +4 -5
- package/dist/client/repeat/RepeatRangeControlledNode.d.ts +2 -2
- package/dist/client/repeat/RepeatRangeUncontrolledNode.d.ts +2 -2
- package/dist/client/resources.d.ts +1 -1
- package/dist/client/serialization/InstanceData.d.ts +12 -0
- package/dist/client/serialization/InstanceFile.d.ts +6 -0
- package/dist/client/serialization/InstancePayload.d.ts +93 -0
- package/dist/client/serialization/InstancePayloadOptions.d.ts +23 -0
- package/dist/client/serialization/InstanceState.d.ts +12 -0
- package/dist/client/submission/{SubmissionDefinition.d.ts → SubmissionMeta.d.ts} +1 -1
- package/dist/client/unsupported/UnsupportedControlNode.d.ts +1 -3
- package/dist/entrypoints/FormInstance.d.ts +20 -0
- package/dist/entrypoints/FormResult/BaseFormResult.d.ts +22 -0
- package/dist/entrypoints/FormResult/BaseInstantiableFormResult.d.ts +25 -0
- package/dist/entrypoints/FormResult/FormFailureResult.d.ts +17 -0
- package/dist/entrypoints/FormResult/FormSuccessResult.d.ts +15 -0
- package/dist/entrypoints/FormResult/FormWarningResult.d.ts +15 -0
- package/dist/entrypoints/createInstance.d.ts +9 -0
- package/dist/entrypoints/editInstance.d.ts +9 -0
- package/dist/entrypoints/index.d.ts +4 -0
- package/dist/entrypoints/loadForm.d.ts +4 -0
- package/dist/entrypoints/restoreInstance.d.ts +9 -0
- package/dist/error/LoadFormFailureError.d.ts +9 -0
- package/dist/error/MalformedInstanceDataError.d.ts +3 -0
- package/dist/error/RankMissingValueError.d.ts +3 -0
- package/dist/error/RankValueTypeError.d.ts +6 -0
- package/dist/error/SelectValueTypeError.d.ts +15 -0
- package/dist/error/TemplatedNodeAttributeSerializationError.d.ts +22 -0
- package/dist/error/XFormsSpecViolationError.d.ts +2 -0
- package/dist/index.d.ts +2 -34
- package/dist/index.js +7274 -5840
- package/dist/index.js.map +1 -1
- package/dist/instance/Group.d.ts +7 -5
- package/dist/instance/InputControl.d.ts +9 -6
- package/dist/instance/ModelValue.d.ts +7 -4
- package/dist/instance/Note.d.ts +14 -25
- package/dist/instance/PrimaryInstance.d.ts +36 -8
- package/dist/instance/RangeControl.d.ts +35 -0
- package/dist/instance/RankControl.d.ts +41 -0
- package/dist/instance/Root.d.ts +8 -9
- package/dist/instance/SelectControl.d.ts +67 -0
- package/dist/instance/Subtree.d.ts +7 -5
- package/dist/instance/TriggerControl.d.ts +10 -22
- package/dist/instance/abstract/DescendantNode.d.ts +11 -3
- package/dist/instance/abstract/InstanceNode.d.ts +10 -5
- package/dist/instance/abstract/ValueNode.d.ts +7 -6
- package/dist/instance/children/DescendantNodeInitOptions.d.ts +32 -0
- package/dist/instance/{children.d.ts → children/buildChildren.d.ts} +1 -1
- package/dist/instance/children/childrenInitOptions.d.ts +9 -0
- package/dist/instance/children/normalizeChildInitOptions.d.ts +2 -0
- package/dist/instance/hierarchy.d.ts +9 -9
- package/dist/instance/input/InitialInstanceState.d.ts +13 -0
- package/dist/instance/input/InstanceAttachmentMap.d.ts +19 -0
- package/dist/instance/internal-api/InstanceConfig.d.ts +2 -9
- package/dist/instance/internal-api/InstanceValueContext.d.ts +10 -1
- package/dist/instance/internal-api/serialization/ClientReactiveSerializableInstance.d.ts +14 -0
- package/dist/instance/internal-api/serialization/ClientReactiveSerializableLeafNode.d.ts +32 -0
- package/dist/instance/internal-api/serialization/ClientReactiveSerializableParentNode.d.ts +18 -0
- package/dist/instance/internal-api/serialization/ClientReactiveSerializableTemplatedNode.d.ts +13 -0
- package/dist/instance/internal-api/serialization/ClientReactiveSerializableValueNode.d.ts +21 -0
- package/dist/instance/repeat/BaseRepeatRange.d.ts +11 -8
- package/dist/instance/repeat/RepeatInstance.d.ts +11 -7
- package/dist/instance/repeat/RepeatRangeControlled.d.ts +27 -3
- package/dist/instance/repeat/RepeatRangeUncontrolled.d.ts +4 -3
- package/dist/instance/resource.d.ts +5 -1
- package/dist/instance/unsupported/UploadControl.d.ts +32 -4
- package/dist/integration/xpath/EngineXPathEvaluator.d.ts +2 -2
- package/dist/integration/xpath/adapter/kind.d.ts +4 -10
- package/dist/integration/xpath/adapter/names.d.ts +1 -11
- package/dist/integration/xpath/adapter/traversal.d.ts +10 -9
- package/dist/integration/xpath/static-dom/StaticAttribute.d.ts +10 -4
- package/dist/integration/xpath/static-dom/StaticDocument.d.ts +13 -11
- package/dist/integration/xpath/static-dom/StaticElement.d.ts +25 -18
- package/dist/integration/xpath/static-dom/StaticNode.d.ts +1 -1
- package/dist/integration/xpath/static-dom/StaticParentNode.d.ts +13 -0
- package/dist/integration/xpath/static-dom/staticNodeName.d.ts +3 -0
- package/dist/lib/client-reactivity/instance-state/createNodeRangeInstanceState.d.ts +4 -0
- package/dist/lib/client-reactivity/instance-state/createParentNodeInstanceState.d.ts +4 -0
- package/dist/lib/client-reactivity/instance-state/createPrimaryInstanceState.d.ts +3 -0
- package/dist/lib/client-reactivity/instance-state/createRootInstanceState.d.ts +3 -0
- package/dist/lib/client-reactivity/instance-state/createTemplatedNodeInstanceState.d.ts +6 -0
- package/dist/lib/client-reactivity/instance-state/createValueNodeInstanceState.d.ts +3 -0
- package/dist/lib/client-reactivity/instance-state/prepareInstancePayload.d.ts +8 -0
- package/dist/lib/codecs/Geopoint/Geopoint.d.ts +48 -0
- package/dist/lib/codecs/Geopoint/GeopointValueCodec.d.ts +5 -0
- package/dist/lib/codecs/NoteCodec.d.ts +8 -0
- package/dist/lib/codecs/RangeCodec.d.ts +8 -0
- package/dist/lib/codecs/TempUnsupportedControlCodec.d.ts +7 -0
- package/dist/lib/codecs/TriggerCodec.d.ts +7 -0
- package/dist/lib/codecs/ValueArrayCodec.d.ts +11 -0
- package/dist/lib/codecs/ValueCodec.d.ts +2 -2
- package/dist/lib/codecs/getNoteCodec.d.ts +3 -0
- package/dist/lib/codecs/getSelectCodec.d.ts +5 -0
- package/dist/lib/codecs/getSharedValueCodec.d.ts +3 -2
- package/dist/lib/codecs/items/BaseItemCodec.d.ts +9 -0
- package/dist/lib/codecs/items/MultipleValueItemCodec.d.ts +14 -0
- package/dist/lib/codecs/items/SingleValueItemCodec.d.ts +24 -0
- package/dist/lib/dom/query.d.ts +1 -2
- package/dist/lib/names/NamespaceDeclaration.d.ts +45 -0
- package/dist/lib/names/NamespaceDeclarationMap.d.ts +137 -0
- package/dist/lib/names/NamespaceURL.d.ts +30 -0
- package/dist/lib/names/QualifiedName.d.ts +113 -0
- package/dist/lib/names/UnprefixedXFormsName.d.ts +4 -0
- package/dist/lib/number-parsers.d.ts +2 -0
- package/dist/lib/reactivity/createInstanceValueState.d.ts +2 -27
- package/dist/lib/reactivity/createItemCollection.d.ts +21 -0
- package/dist/lib/xml-serialization.d.ts +11 -2
- package/dist/parse/XFormDOM.d.ts +1 -1
- package/dist/parse/body/BodyDefinition.d.ts +2 -2
- package/dist/parse/body/appearance/rangeAppearanceParser.d.ts +3 -0
- package/dist/parse/body/control/InputControlDefinition.d.ts +3 -0
- package/dist/parse/body/control/ItemDefinition.d.ts +14 -0
- package/dist/parse/body/control/ItemsetDefinition.d.ts +18 -0
- package/dist/parse/body/control/RangeControlDefinition.d.ts +31 -2
- package/dist/parse/body/control/RankControlDefinition.d.ts +7 -3
- package/dist/parse/body/control/{select/SelectDefinition.d.ts → SelectControlDefinition.d.ts} +9 -9
- package/dist/parse/expression/ItemsetNodesetExpression.d.ts +1 -1
- package/dist/parse/expression/ItemsetValueExpression.d.ts +1 -1
- package/dist/parse/model/BindDefinition.d.ts +3 -1
- package/dist/parse/model/BindPreloadDefinition.d.ts +42 -0
- package/dist/parse/model/DescendentNodeDefinition.d.ts +4 -13
- package/dist/parse/model/ItextTranslationsDefinition.d.ts +18 -0
- package/dist/parse/model/LeafNodeDefinition.d.ts +9 -7
- package/dist/parse/model/ModelDefinition.d.ts +9 -2
- package/dist/parse/model/NodeDefinition.d.ts +30 -45
- package/dist/parse/model/NoteNodeDefinition.d.ts +7 -5
- package/dist/parse/model/RangeNodeDefinition.d.ts +42 -0
- package/dist/parse/model/RepeatDefinition.d.ts +62 -0
- package/dist/parse/model/RootAttributeDefinition.d.ts +21 -0
- package/dist/parse/model/RootAttributeMap.d.ts +24 -0
- package/dist/parse/model/RootDefinition.d.ts +15 -14
- package/dist/parse/model/SecondaryInstance/SecondaryInstancesDefinition.d.ts +15 -2
- package/dist/parse/model/SecondaryInstance/assertSecondaryInstanceDefinition.d.ts +5 -0
- package/dist/parse/model/SecondaryInstance/defineSecondaryInstance.d.ts +5 -0
- package/dist/parse/model/SecondaryInstance/sources/BlankSecondaryInstanceSource.d.ts +1 -7
- package/dist/parse/model/SecondaryInstance/sources/CSVExternalSecondaryInstance.d.ts +1 -1
- package/dist/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.d.ts +1 -1
- package/dist/parse/model/SecondaryInstance/sources/InternalSecondaryInstanceSource.d.ts +1 -1
- package/dist/parse/model/SecondaryInstance/sources/SecondaryInstanceSource.d.ts +1 -1
- package/dist/parse/model/SecondaryInstance/sources/XMLExternalSecondaryInstanceSource.d.ts +1 -1
- package/dist/parse/model/{FormSubmissionDefinition.d.ts → SubmissionDefinition.d.ts} +2 -2
- package/dist/parse/model/SubtreeDefinition.d.ts +9 -7
- package/dist/parse/model/nodeDefinitionMap.d.ts +5 -0
- package/dist/parse/shared/parseInstanceXML.d.ts +21 -0
- package/dist/parse/shared/parseStaticDocumentFromDOMSubtree.d.ts +4 -22
- package/dist/parse/text/ItemLabelDefinition.d.ts +1 -1
- package/dist/parse/text/ItemsetLabelDefinition.d.ts +2 -2
- package/dist/parse/text/abstract/TextElementDefinition.d.ts +1 -1
- package/dist/parse/xpath/semantic-analysis.d.ts +1 -3
- package/dist/solid.js +7247 -5813
- package/dist/solid.js.map +1 -1
- package/package.json +15 -12
- package/src/client/BaseNode.ts +9 -4
- package/src/client/BaseValueNode.ts +8 -4
- package/src/client/GroupNode.ts +1 -0
- package/src/client/InputNode.ts +38 -2
- package/src/client/ModelValueNode.ts +1 -0
- package/src/client/NoteNode.ts +43 -7
- package/src/client/RangeNode.ts +51 -0
- package/src/client/RankNode.ts +54 -0
- package/src/client/RootNode.ts +30 -16
- package/src/client/SelectNode.ts +53 -26
- package/src/client/SubtreeNode.ts +1 -0
- package/src/client/TriggerNode.ts +12 -6
- package/src/client/constants.ts +12 -14
- package/src/client/form/CreateFormInstance.ts +19 -0
- package/src/client/form/EditFormInstance.ts +93 -0
- package/src/client/form/FormInstance.ts +114 -0
- package/src/client/form/FormInstanceConfig.ts +18 -0
- package/src/client/form/FormResource.ts +1 -0
- package/src/client/form/LoadForm.ts +92 -0
- package/src/client/form/LoadFormResult.ts +103 -0
- package/src/client/form/RestoreFormInstance.ts +14 -0
- package/src/client/hierarchy.ts +7 -8
- package/src/client/index.ts +47 -29
- package/src/client/node-types.ts +3 -5
- package/src/client/repeat/BaseRepeatRangeNode.ts +3 -4
- package/src/client/repeat/RepeatInstanceNode.ts +4 -8
- package/src/client/repeat/RepeatRangeControlledNode.ts +2 -2
- package/src/client/repeat/RepeatRangeUncontrolledNode.ts +2 -2
- package/src/client/resources.ts +2 -2
- package/src/client/serialization/InstanceData.ts +16 -0
- package/src/client/serialization/InstanceFile.ts +9 -0
- package/src/client/serialization/InstancePayload.ts +126 -0
- package/src/client/serialization/InstancePayloadOptions.ts +28 -0
- package/src/client/serialization/InstanceState.ts +14 -0
- package/src/client/submission/{SubmissionDefinition.ts → SubmissionMeta.ts} +1 -1
- package/src/client/unsupported/UnsupportedControlNode.ts +2 -6
- package/src/entrypoints/FormInstance.ts +55 -0
- package/src/entrypoints/FormResult/BaseFormResult.ts +40 -0
- package/src/entrypoints/FormResult/BaseInstantiableFormResult.ts +109 -0
- package/src/entrypoints/FormResult/FormFailureResult.ts +44 -0
- package/src/entrypoints/FormResult/FormSuccessResult.ts +25 -0
- package/src/entrypoints/FormResult/FormWarningResult.ts +25 -0
- package/src/entrypoints/createInstance.ts +23 -0
- package/src/entrypoints/editInstance.ts +24 -0
- package/src/entrypoints/index.ts +4 -0
- package/src/entrypoints/loadForm.ts +154 -0
- package/src/entrypoints/restoreInstance.ts +27 -0
- package/src/error/LoadFormFailureError.ts +114 -0
- package/src/error/MalformedInstanceDataError.ts +3 -0
- package/src/error/RankMissingValueError.ts +5 -0
- package/src/error/RankValueTypeError.ts +13 -0
- package/src/error/SelectValueTypeError.ts +22 -0
- package/src/error/TemplatedNodeAttributeSerializationError.ts +24 -0
- package/src/error/XFormsSpecViolationError.ts +1 -0
- package/src/index.ts +2 -56
- package/src/instance/Group.ts +17 -15
- package/src/instance/InputControl.ts +58 -12
- package/src/instance/ModelValue.ts +19 -11
- package/src/instance/Note.ts +40 -64
- package/src/instance/PrimaryInstance.ts +70 -31
- package/src/instance/RangeControl.ts +119 -0
- package/src/instance/RankControl.ts +208 -0
- package/src/instance/Root.ts +21 -31
- package/src/instance/SelectControl.ts +228 -0
- package/src/instance/Subtree.ts +17 -15
- package/src/instance/TriggerControl.ts +50 -80
- package/src/instance/abstract/DescendantNode.ts +13 -8
- package/src/instance/abstract/InstanceNode.ts +19 -7
- package/src/instance/abstract/ValueNode.ts +14 -15
- package/src/instance/children/DescendantNodeInitOptions.ts +35 -0
- package/src/instance/children/buildChildren.ts +206 -0
- package/src/instance/children/childrenInitOptions.ts +117 -0
- package/src/instance/children/normalizeChildInitOptions.ts +332 -0
- package/src/instance/hierarchy.ts +21 -16
- package/src/instance/input/InitialInstanceState.ts +108 -0
- package/src/instance/input/InstanceAttachmentMap.ts +142 -0
- package/src/instance/internal-api/InstanceConfig.ts +3 -10
- package/src/instance/internal-api/InstanceValueContext.ts +11 -1
- package/src/instance/internal-api/serialization/ClientReactiveSerializableInstance.ts +20 -0
- package/src/instance/internal-api/serialization/ClientReactiveSerializableLeafNode.ts +43 -0
- package/src/instance/internal-api/serialization/ClientReactiveSerializableParentNode.ts +26 -0
- package/src/instance/internal-api/serialization/ClientReactiveSerializableTemplatedNode.ts +24 -0
- package/src/instance/internal-api/serialization/ClientReactiveSerializableValueNode.ts +28 -0
- package/src/instance/repeat/BaseRepeatRange.ts +21 -24
- package/src/instance/repeat/RepeatInstance.ts +27 -19
- package/src/instance/repeat/RepeatRangeControlled.ts +90 -17
- package/src/instance/repeat/RepeatRangeUncontrolled.ts +10 -9
- package/src/instance/resource.ts +18 -2
- package/src/instance/unsupported/UploadControl.ts +116 -5
- package/src/integration/xpath/EngineXPathEvaluator.ts +2 -2
- package/src/integration/xpath/adapter/kind.ts +1 -28
- package/src/integration/xpath/adapter/names.ts +66 -17
- package/src/integration/xpath/adapter/traversal.ts +12 -11
- package/src/integration/xpath/static-dom/StaticAttribute.ts +16 -7
- package/src/integration/xpath/static-dom/StaticDocument.ts +17 -18
- package/src/integration/xpath/static-dom/StaticElement.ts +211 -52
- package/src/integration/xpath/static-dom/StaticNode.ts +1 -1
- package/src/integration/xpath/static-dom/StaticParentNode.ts +22 -0
- package/src/integration/xpath/static-dom/staticNodeName.ts +20 -0
- package/src/lib/client-reactivity/instance-state/createNodeRangeInstanceState.ts +17 -0
- package/src/lib/client-reactivity/instance-state/createParentNodeInstanceState.ts +22 -0
- package/src/lib/client-reactivity/instance-state/createPrimaryInstanceState.ts +12 -0
- package/src/lib/client-reactivity/instance-state/createRootInstanceState.ts +19 -0
- package/src/lib/client-reactivity/instance-state/createTemplatedNodeInstanceState.ts +31 -0
- package/src/lib/client-reactivity/instance-state/createValueNodeInstanceState.ts +21 -0
- package/src/lib/client-reactivity/instance-state/prepareInstancePayload.ts +173 -0
- package/src/lib/codecs/Geopoint/Geopoint.ts +150 -0
- package/src/lib/codecs/Geopoint/GeopointValueCodec.ts +20 -0
- package/src/lib/codecs/NoteCodec.ts +32 -0
- package/src/lib/codecs/RangeCodec.ts +65 -0
- package/src/lib/codecs/TempUnsupportedControlCodec.ts +32 -0
- package/src/lib/codecs/TriggerCodec.ts +64 -0
- package/src/lib/codecs/ValueArrayCodec.ts +42 -0
- package/src/lib/codecs/ValueCodec.ts +2 -2
- package/src/lib/codecs/getNoteCodec.ts +27 -0
- package/src/lib/codecs/getSelectCodec.ts +27 -0
- package/src/lib/codecs/getSharedValueCodec.ts +5 -3
- package/src/lib/codecs/items/BaseItemCodec.ts +20 -0
- package/src/lib/codecs/items/MultipleValueItemCodec.ts +28 -0
- package/src/lib/codecs/items/SingleValueItemCodec.ts +67 -0
- package/src/lib/dom/query.ts +1 -2
- package/src/lib/names/NamespaceDeclaration.ts +106 -0
- package/src/lib/names/NamespaceDeclarationMap.ts +228 -0
- package/src/lib/names/NamespaceURL.ts +44 -0
- package/src/lib/names/QualifiedName.ts +170 -0
- package/src/lib/names/UnprefixedXFormsName.ts +12 -0
- package/src/lib/number-parsers.ts +25 -0
- package/src/lib/reactivity/createInstanceValueState.ts +69 -43
- package/src/lib/reactivity/{createSelectItems.ts → createItemCollection.ts} +41 -36
- package/src/lib/xml-serialization.ts +76 -9
- package/src/parse/XFormDOM.ts +141 -21
- package/src/parse/XFormDefinition.ts +1 -4
- package/src/parse/body/BodyDefinition.ts +4 -4
- package/src/parse/body/appearance/rangeAppearanceParser.ts +11 -0
- package/src/parse/body/control/InputControlDefinition.ts +9 -0
- package/src/parse/body/control/{select/ItemDefinition.ts → ItemDefinition.ts} +8 -6
- package/src/parse/body/control/{select/ItemsetDefinition.ts → ItemsetDefinition.ts} +11 -9
- package/src/parse/body/control/RangeControlDefinition.ts +91 -6
- package/src/parse/body/control/RankControlDefinition.ts +25 -7
- package/src/parse/body/control/{select/SelectDefinition.ts → SelectControlDefinition.ts} +9 -9
- package/src/parse/expression/ItemsetNodesetExpression.ts +1 -1
- package/src/parse/expression/ItemsetValueExpression.ts +1 -1
- package/src/parse/model/BindDefinition.ts +4 -0
- package/src/parse/model/BindPreloadDefinition.ts +100 -0
- package/src/parse/model/DescendentNodeDefinition.ts +7 -25
- package/src/parse/model/ItextTranslationsDefinition.ts +79 -0
- package/src/parse/model/LeafNodeDefinition.ts +13 -8
- package/src/parse/model/ModelDefinition.ts +36 -3
- package/src/parse/model/NodeDefinition.ts +38 -85
- package/src/parse/model/NoteNodeDefinition.ts +12 -10
- package/src/parse/model/RangeNodeDefinition.ts +119 -0
- package/src/parse/model/RepeatDefinition.ts +382 -0
- package/src/parse/model/RootAttributeDefinition.ts +44 -0
- package/src/parse/model/RootAttributeMap.ts +49 -0
- package/src/parse/model/RootDefinition.ts +42 -43
- package/src/parse/model/SecondaryInstance/SecondaryInstancesDefinition.ts +23 -2
- package/src/parse/model/SecondaryInstance/assertSecondaryInstanceDefinition.ts +14 -0
- package/src/parse/model/SecondaryInstance/defineSecondaryInstance.ts +32 -0
- package/src/parse/model/SecondaryInstance/sources/BlankSecondaryInstanceSource.ts +3 -24
- package/src/parse/model/SecondaryInstance/sources/CSVExternalSecondaryInstance.ts +33 -86
- package/src/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.ts +64 -136
- package/src/parse/model/SecondaryInstance/sources/InternalSecondaryInstanceSource.ts +9 -7
- package/src/parse/model/SecondaryInstance/sources/SecondaryInstanceSource.ts +1 -1
- package/src/parse/model/SecondaryInstance/sources/XMLExternalSecondaryInstanceSource.ts +7 -7
- package/src/parse/model/{FormSubmissionDefinition.ts → SubmissionDefinition.ts} +2 -2
- package/src/parse/model/SubtreeDefinition.ts +15 -16
- package/src/parse/model/nodeDefinitionMap.ts +34 -0
- package/src/parse/shared/parseInstanceXML.ts +79 -0
- package/src/parse/shared/parseStaticDocumentFromDOMSubtree.ts +46 -131
- package/src/parse/text/ItemLabelDefinition.ts +1 -1
- package/src/parse/text/ItemsetLabelDefinition.ts +2 -2
- package/src/parse/text/abstract/TextElementDefinition.ts +1 -1
- package/src/parse/xpath/semantic-analysis.ts +4 -3
- package/dist/client/EngineConfig.d.ts +0 -79
- package/dist/client/submission/SubmissionData.d.ts +0 -7
- package/dist/client/submission/SubmissionInstanceFile.d.ts +0 -6
- package/dist/client/submission/SubmissionOptions.d.ts +0 -23
- package/dist/client/submission/SubmissionResult.d.ts +0 -91
- package/dist/client/submission/SubmissionState.d.ts +0 -12
- package/dist/client/unsupported/RangeNode.d.ts +0 -9
- package/dist/client/unsupported/RankNode.d.ts +0 -9
- package/dist/instance/SelectField.d.ts +0 -58
- package/dist/instance/abstract/UnsupportedControl.d.ts +0 -53
- package/dist/instance/index.d.ts +0 -8
- package/dist/instance/internal-api/ValueContext.d.ts +0 -23
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableInstance.d.ts +0 -14
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.d.ts +0 -31
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableParentNode.d.ts +0 -18
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableValueNode.d.ts +0 -17
- package/dist/instance/unsupported/RangeControl.d.ts +0 -6
- package/dist/instance/unsupported/RankControl.d.ts +0 -6
- package/dist/integration/xpath/static-dom/StaticNamedNode.d.ts +0 -17
- package/dist/lib/client-reactivity/submission/createInstanceSubmissionState.d.ts +0 -3
- package/dist/lib/client-reactivity/submission/createLeafNodeSubmissionState.d.ts +0 -3
- package/dist/lib/client-reactivity/submission/createNodeRangeSubmissionState.d.ts +0 -4
- package/dist/lib/client-reactivity/submission/createParentNodeSubmissionState.d.ts +0 -4
- package/dist/lib/client-reactivity/submission/createValueNodeSubmissionState.d.ts +0 -3
- package/dist/lib/client-reactivity/submission/prepareSubmission.d.ts +0 -8
- package/dist/lib/reactivity/createSelectItems.d.ts +0 -16
- package/dist/lib/reactivity/createValueState.d.ts +0 -40
- package/dist/parse/body/control/select/ItemDefinition.d.ts +0 -13
- package/dist/parse/body/control/select/ItemsetDefinition.d.ts +0 -17
- package/dist/parse/body/control/select/ItemsetNodesetContext.d.ts +0 -9
- package/dist/parse/model/ItextTranslation/ItextTranslationDefinition.d.ts +0 -4
- package/dist/parse/model/ItextTranslation/ItextTranslationRootDefinition.d.ts +0 -8
- package/dist/parse/model/ItextTranslation/ItextTranslationsDefinition.d.ts +0 -8
- package/dist/parse/model/RepeatInstanceDefinition.d.ts +0 -14
- package/dist/parse/model/RepeatRangeDefinition.d.ts +0 -29
- package/dist/parse/model/RepeatTemplateDefinition.d.ts +0 -28
- package/dist/parse/model/SecondaryInstance/SecondaryInstanceDefinition.d.ts +0 -4
- package/dist/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.d.ts +0 -7
- package/src/client/EngineConfig.ts +0 -84
- package/src/client/submission/SubmissionData.ts +0 -12
- package/src/client/submission/SubmissionInstanceFile.ts +0 -9
- package/src/client/submission/SubmissionOptions.ts +0 -28
- package/src/client/submission/SubmissionResult.ts +0 -124
- package/src/client/submission/SubmissionState.ts +0 -14
- package/src/client/unsupported/RangeNode.ts +0 -14
- package/src/client/unsupported/RankNode.ts +0 -14
- package/src/instance/SelectField.ts +0 -263
- package/src/instance/abstract/UnsupportedControl.ts +0 -174
- package/src/instance/children.ts +0 -158
- package/src/instance/index.ts +0 -55
- package/src/instance/internal-api/ValueContext.ts +0 -28
- package/src/instance/internal-api/submission/ClientReactiveSubmittableInstance.ts +0 -20
- package/src/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.ts +0 -42
- package/src/instance/internal-api/submission/ClientReactiveSubmittableParentNode.ts +0 -25
- package/src/instance/internal-api/submission/ClientReactiveSubmittableValueNode.ts +0 -23
- package/src/instance/unsupported/RangeControl.ts +0 -9
- package/src/instance/unsupported/RankControl.ts +0 -9
- package/src/integration/xpath/static-dom/StaticNamedNode.ts +0 -45
- package/src/lib/client-reactivity/submission/createInstanceSubmissionState.ts +0 -12
- package/src/lib/client-reactivity/submission/createLeafNodeSubmissionState.ts +0 -20
- package/src/lib/client-reactivity/submission/createNodeRangeSubmissionState.ts +0 -17
- package/src/lib/client-reactivity/submission/createParentNodeSubmissionState.ts +0 -22
- package/src/lib/client-reactivity/submission/createValueNodeSubmissionState.ts +0 -21
- package/src/lib/client-reactivity/submission/prepareSubmission.ts +0 -172
- package/src/lib/reactivity/createValueState.ts +0 -200
- package/src/parse/body/control/select/ItemsetNodesetContext.ts +0 -21
- package/src/parse/model/ItextTranslation/ItextTranslationDefinition.ts +0 -4
- package/src/parse/model/ItextTranslation/ItextTranslationRootDefinition.ts +0 -41
- package/src/parse/model/ItextTranslation/ItextTranslationsDefinition.ts +0 -31
- package/src/parse/model/RepeatInstanceDefinition.ts +0 -34
- package/src/parse/model/RepeatRangeDefinition.ts +0 -94
- package/src/parse/model/RepeatTemplateDefinition.ts +0 -145
- package/src/parse/model/SecondaryInstance/SecondaryInstanceDefinition.ts +0 -4
- package/src/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.ts +0 -12
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type { ValueType } from '../../client/ValueType.ts';
|
|
2
|
+
import { ErrorProductionDesignPendingError } from '../../error/ErrorProductionDesignPendingError.ts';
|
|
3
|
+
import type { StaticLeafElement } from '../../integration/xpath/static-dom/StaticElement.ts';
|
|
4
|
+
import type { RuntimeValue, SharedValueCodec } from '../../lib/codecs/getSharedValueCodec.ts';
|
|
5
|
+
import { getSharedValueCodec } from '../../lib/codecs/getSharedValueCodec.ts';
|
|
6
|
+
import type {
|
|
7
|
+
RangeControlBoundsDefinition,
|
|
8
|
+
RangeControlDefinition,
|
|
9
|
+
} from '../body/control/RangeControlDefinition.ts';
|
|
10
|
+
import type { BindDefinition } from './BindDefinition.ts';
|
|
11
|
+
import { LeafNodeDefinition } from './LeafNodeDefinition.ts';
|
|
12
|
+
import type { ParentNodeDefinition } from './NodeDefinition.ts';
|
|
13
|
+
|
|
14
|
+
const RANGE_VALUE_TYPES = ['decimal', 'int'] as const;
|
|
15
|
+
|
|
16
|
+
export type RangeValueType = (typeof RANGE_VALUE_TYPES)[number];
|
|
17
|
+
|
|
18
|
+
type AssertedRangeValueType<V extends ValueType> = Extract<V, RangeValueType>;
|
|
19
|
+
|
|
20
|
+
type AssertRangeBindDefinition = <V extends ValueType>(
|
|
21
|
+
bind: BindDefinition<V>
|
|
22
|
+
) => asserts bind is BindDefinition<AssertedRangeValueType<V>>;
|
|
23
|
+
|
|
24
|
+
const assertRangeBindDefinition: AssertRangeBindDefinition = (bind) => {
|
|
25
|
+
if (!RANGE_VALUE_TYPES.includes(bind.type.resolved as RangeValueType)) {
|
|
26
|
+
throw new ErrorProductionDesignPendingError(
|
|
27
|
+
`Expected range to have bind type "decimal" or "int", got: ${bind.type.resolved}`
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export interface RangeLeafNodeDefinition<V extends ValueType = ValueType>
|
|
33
|
+
extends LeafNodeDefinition<V> {
|
|
34
|
+
readonly bodyElement: RangeControlDefinition;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const decodeBoundsValue = <V extends ValueType>(
|
|
38
|
+
codec: SharedValueCodec<V>,
|
|
39
|
+
value: string
|
|
40
|
+
): NonNullable<RuntimeValue<V>> => {
|
|
41
|
+
const decoded = codec.decodeValue(value);
|
|
42
|
+
|
|
43
|
+
if (decoded == null) {
|
|
44
|
+
throw new ErrorProductionDesignPendingError(
|
|
45
|
+
`Failed to decode bounds value (encoded as ${JSON.stringify(value)})`
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return decoded;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
class RangeNodeBoundsDefinition<V extends RangeValueType = RangeValueType> {
|
|
53
|
+
static from<V extends RangeValueType>(
|
|
54
|
+
bounds: RangeControlBoundsDefinition,
|
|
55
|
+
bind: BindDefinition<V>
|
|
56
|
+
): RangeNodeBoundsDefinition<V> {
|
|
57
|
+
const type = bind.type.resolved;
|
|
58
|
+
const codec = getSharedValueCodec(type);
|
|
59
|
+
const min = decodeBoundsValue(codec, bounds.start);
|
|
60
|
+
const max = decodeBoundsValue(codec, bounds.end);
|
|
61
|
+
const step = decodeBoundsValue(codec, bounds.step);
|
|
62
|
+
|
|
63
|
+
return new this(min, max, step);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
constructor(
|
|
67
|
+
readonly min: NonNullable<RuntimeValue<V>>,
|
|
68
|
+
readonly max: NonNullable<RuntimeValue<V>>,
|
|
69
|
+
readonly step: NonNullable<RuntimeValue<V>>
|
|
70
|
+
) {}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @todo We should really consider making `LeafNodeDefinition` an abstract base
|
|
75
|
+
* class, and each node's definition an explicit concrete subclass of that. It
|
|
76
|
+
* would simplify a lot of things, reduce redundancy (and drift!) between
|
|
77
|
+
* various like `*Definition` types, and allow us to reason more clearly about
|
|
78
|
+
* what parse-product-input is used to construct each primary instance node.
|
|
79
|
+
* Furthermore, it would give us a great deal more flexibility to revisit some
|
|
80
|
+
* of the weaker parts of our current data model (e.g. splitting up selects).
|
|
81
|
+
*
|
|
82
|
+
* I explored this refactor as part of the prerequisite work to support range
|
|
83
|
+
* controls. I eventually backed out because it involved more churn than I felt
|
|
84
|
+
* comfortable with, but I do think we should keep an eye out for other
|
|
85
|
+
* opportunities to take on the churn.
|
|
86
|
+
*/
|
|
87
|
+
export class RangeNodeDefinition<V extends RangeValueType = RangeValueType>
|
|
88
|
+
extends LeafNodeDefinition<V>
|
|
89
|
+
implements RangeLeafNodeDefinition<V>
|
|
90
|
+
{
|
|
91
|
+
static from<V extends ValueType>(
|
|
92
|
+
parent: ParentNodeDefinition,
|
|
93
|
+
bind: BindDefinition<V>,
|
|
94
|
+
bodyElement: RangeControlDefinition,
|
|
95
|
+
node: StaticLeafElement
|
|
96
|
+
): RangeNodeDefinition<Extract<V, RangeValueType>> {
|
|
97
|
+
assertRangeBindDefinition(bind);
|
|
98
|
+
|
|
99
|
+
return new this(parent, bind, bodyElement, node);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
readonly bounds: RangeNodeBoundsDefinition<V>;
|
|
103
|
+
|
|
104
|
+
private constructor(
|
|
105
|
+
parent: ParentNodeDefinition,
|
|
106
|
+
override readonly bind: BindDefinition<V>,
|
|
107
|
+
override readonly bodyElement: RangeControlDefinition,
|
|
108
|
+
node: StaticLeafElement
|
|
109
|
+
) {
|
|
110
|
+
super(parent, bind, bodyElement, node);
|
|
111
|
+
|
|
112
|
+
this.bounds = RangeNodeBoundsDefinition.from(bodyElement.bounds, bind);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// prettier-ignore
|
|
117
|
+
export type AnyRangeNodeDefinition =
|
|
118
|
+
| RangeNodeDefinition<'decimal'>
|
|
119
|
+
| RangeNodeDefinition<'int'>;
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
import { JAVAROSA_NAMESPACE_URI } from '@getodk/common/constants/xmlns.ts';
|
|
2
|
+
import type { XFORMS_KNOWN_ATTRIBUTE } from '@getodk/xpath';
|
|
3
|
+
import type { RepeatRange } from '../../instance/hierarchy.ts';
|
|
4
|
+
import type { PrimaryInstance } from '../../instance/PrimaryInstance.ts';
|
|
5
|
+
import type { RepeatInstance } from '../../instance/repeat/RepeatInstance.ts';
|
|
6
|
+
import type {
|
|
7
|
+
StaticAttribute,
|
|
8
|
+
StaticAttributeOptions,
|
|
9
|
+
} from '../../integration/xpath/static-dom/StaticAttribute.ts';
|
|
10
|
+
import { StaticDocument } from '../../integration/xpath/static-dom/StaticDocument.ts';
|
|
11
|
+
import type {
|
|
12
|
+
StaticElement,
|
|
13
|
+
StaticElementOptions,
|
|
14
|
+
} from '../../integration/xpath/static-dom/StaticElement.ts';
|
|
15
|
+
import type { StaticNode } from '../../integration/xpath/static-dom/StaticNode.ts';
|
|
16
|
+
import type { StaticText } from '../../integration/xpath/static-dom/StaticText.ts';
|
|
17
|
+
import { NamespaceDeclarationMap } from '../../lib/names/NamespaceDeclarationMap.ts';
|
|
18
|
+
import type { NamespaceURL } from '../../lib/names/NamespaceURL.ts';
|
|
19
|
+
import type { QualifiedName, QualifiedNameSource } from '../../lib/names/QualifiedName.ts';
|
|
20
|
+
import type { RepeatElementDefinition } from '../body/RepeatElementDefinition.ts';
|
|
21
|
+
import { RepeatCountControlExpression } from '../expression/RepeatCountControlExpression.ts';
|
|
22
|
+
import type { BindDefinition } from './BindDefinition.ts';
|
|
23
|
+
import { DescendentNodeDefinition } from './DescendentNodeDefinition.ts';
|
|
24
|
+
import type { ChildNodeDefinition, ParentNodeDefinition } from './NodeDefinition.ts';
|
|
25
|
+
import type { RootDefinition } from './RootDefinition.ts';
|
|
26
|
+
import type { SubtreeDefinition } from './SubtreeDefinition.ts';
|
|
27
|
+
|
|
28
|
+
interface JavaRosaNamespaceURI extends NamespaceURL {
|
|
29
|
+
readonly href: JAVAROSA_NAMESPACE_URI;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface JRTemplateAttributeName extends QualifiedName {
|
|
33
|
+
readonly namespaceURI: JavaRosaNamespaceURI;
|
|
34
|
+
readonly localName: 'template';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const isJRTemplateAttributeName = (name: QualifiedNameSource) => {
|
|
38
|
+
if (name.localName !== 'template') {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const namespaceURI = (name.namespaceURI as NamespaceURL)?.href ?? name.namespaceURI;
|
|
43
|
+
|
|
44
|
+
return namespaceURI === JAVAROSA_NAMESPACE_URI;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
interface JRTemplateAttribute extends StaticAttribute {
|
|
48
|
+
readonly qualifiedName: JRTemplateAttributeName;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const isJRTemplateAttribute = (attribute: StaticAttribute): attribute is JRTemplateAttribute => {
|
|
52
|
+
return isJRTemplateAttributeName(attribute.qualifiedName);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
interface ExplicitRepeatTemplateElement extends StaticElement {
|
|
56
|
+
readonly [XFORMS_KNOWN_ATTRIBUTE]: 'template';
|
|
57
|
+
|
|
58
|
+
getAttributeValue(localName: 'template'): string;
|
|
59
|
+
getAttributeValue(localName: string): string | null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Determines whether a model instance node is an **explicit** repeat template,
|
|
64
|
+
* as defined by the presence of a `jr:template` attribute on that node.
|
|
65
|
+
*
|
|
66
|
+
* @see {@link https://getodk.github.io/xforms-spec/#default-values-in-repeats}
|
|
67
|
+
*/
|
|
68
|
+
const isExplicitRepeatTemplateElement = (
|
|
69
|
+
sourceElement: StaticElement
|
|
70
|
+
): sourceElement is ExplicitRepeatTemplateElement => {
|
|
71
|
+
return sourceElement.attributes.some(isJRTemplateAttribute);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const cloneStaticAttributeOptions = (attribute: StaticAttribute): StaticAttributeOptions => {
|
|
75
|
+
return {
|
|
76
|
+
name: attribute.qualifiedName,
|
|
77
|
+
value: attribute.value,
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
interface ClonedSubtreeStructure extends StaticElementOptions {
|
|
82
|
+
readonly attributes: readonly StaticAttributeOptions[];
|
|
83
|
+
readonly children: readonly StaticElementOptions[];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const cloneStaticSubtreeStructure = (sourceElement: StaticElement): ClonedSubtreeStructure => {
|
|
87
|
+
const name = sourceElement.qualifiedName;
|
|
88
|
+
const attributes = sourceElement.attributes.map(cloneStaticAttributeOptions);
|
|
89
|
+
const children = sourceElement.childElements.map(cloneStaticSubtreeStructure);
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
name,
|
|
93
|
+
attributes,
|
|
94
|
+
children,
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Clones the **structure** of a {@link StaticElement}, omitting
|
|
100
|
+
* {@link StaticText | text values} of the element itself, and any of its
|
|
101
|
+
* descendants.
|
|
102
|
+
*
|
|
103
|
+
* @todo This function's behavior is **plausibly** general purpose. The function
|
|
104
|
+
* itself, its argument, its local bindings are all named to reflect that fact.
|
|
105
|
+
*
|
|
106
|
+
* However, the **use case** for the function is quite specific: when a form
|
|
107
|
+
* defines a `<repeat>` that isn't associated with an explicit `jr:template`, we
|
|
108
|
+
* fabricate a template by cloning its structure with all text values removed
|
|
109
|
+
* (described in more detail for {@link parseRepeatTemplateElement}).
|
|
110
|
+
*
|
|
111
|
+
* As generalized as this the function is, it's not at all clear how or why we'd
|
|
112
|
+
* use it for other purposes. Even the top-of-mind (at time of writing) use case
|
|
113
|
+
* which might semantically line up with it (i.e. potentially as a basis to
|
|
114
|
+
* reconcile edit instance state into a form definition, as sort of a three-way
|
|
115
|
+
* merge) would effectively be pure overhead. For now, we have something
|
|
116
|
+
* library-ish living here private in this module unless/until we find another
|
|
117
|
+
* good reason to use it elsewhere!
|
|
118
|
+
*
|
|
119
|
+
* If we do find another plausible use case for this behavior, it's pretty
|
|
120
|
+
* likely we'd want to implement it as a part of the {@link StaticElement} (or
|
|
121
|
+
* somewhere else up the class hierarchy to {@link StaticNode}), to encapsulate
|
|
122
|
+
* as much as possible about how it's done. We've been pretty aggressive about
|
|
123
|
+
* changing the internals and signatures of {@link StaticNode}s and the
|
|
124
|
+
* static-dom abstraction. It'd be nice if ongoing changes were a lot more
|
|
125
|
+
* isolated, with far less impact on the growing set of use cases actually
|
|
126
|
+
* consuming the abstraction.
|
|
127
|
+
*/
|
|
128
|
+
const cloneStaticElementStructure = (sourceElement: StaticElement): StaticElement => {
|
|
129
|
+
const { root: clone } = new StaticDocument({
|
|
130
|
+
documentRoot: cloneStaticSubtreeStructure(sourceElement),
|
|
131
|
+
nodesetPrefix: sourceElement.parent.nodeset,
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
return clone;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export type RepeatInstanceNodes = readonly [StaticElement, ...StaticElement[]];
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Produces a consistent "repeat template" interface for each
|
|
141
|
+
* {@link RepeatDefinition}, which is used to produce new repeat instances in
|
|
142
|
+
* {@link PrimaryInstance | runtime form instance state}. How a "repeat
|
|
143
|
+
* template" is parsed is as follows:
|
|
144
|
+
*
|
|
145
|
+
* - If the form definition includes an **explicit template** (as described by
|
|
146
|
+
* {@link isExplicitRepeatTemplateElement}) as the
|
|
147
|
+
* {@link firstRepeatInstanceNode | first} node referenced by a `<repeat
|
|
148
|
+
* nodeset>`, that node is returned as it was already parsed.
|
|
149
|
+
*
|
|
150
|
+
* - If the {@link firstRepeatInstanceNode | first} repeat instance node is
|
|
151
|
+
* **NOT** an explicit template, a template is **implicitly created** from its
|
|
152
|
+
* blank structure, as a
|
|
153
|
+
* {@link cloneStaticElementStructure | clone of its structure}.
|
|
154
|
+
*
|
|
155
|
+
* The latter behavior may sound surprising if unfamiliar, but it is well
|
|
156
|
+
* understood. It is also known to be consistent with Collect (JavaRosa), as
|
|
157
|
+
* demonstrated by affected tests in `@getodk/scenario` which fail when this
|
|
158
|
+
* behavior is changed.
|
|
159
|
+
*
|
|
160
|
+
* - - -
|
|
161
|
+
*
|
|
162
|
+
* Note: this is a vastly simplified evolution of what was previously
|
|
163
|
+
* implemented in
|
|
164
|
+
* {@link https://github.com/getodk/web-forms/blob/99295eb1d6ec78cd6a758385793e97859b6a74cc/packages/xforms-engine/src/parse/model/RepeatTemplateDefinition.ts#L81 | `RepeatTemplateDefinition.parseModelNodes`}
|
|
165
|
+
* (permalink to implementation at time of writing/refactor).
|
|
166
|
+
*
|
|
167
|
+
* That previous implementation was based on a flawed mental model of how a
|
|
168
|
+
* parsed form model relates to the form's instance structure. The following
|
|
169
|
+
* describes the previous flawed mental model, and the reasoning behind revising
|
|
170
|
+
* the mental model established here.
|
|
171
|
+
*
|
|
172
|
+
* - - -
|
|
173
|
+
*
|
|
174
|
+
* **Flawed mental model**
|
|
175
|
+
*
|
|
176
|
+
* Repeat model definitions were composed of a combination of:
|
|
177
|
+
*
|
|
178
|
+
* 1. `RepeatRangeDefinition`: this effectively had a 1:1 correspondence to the
|
|
179
|
+
* `<repeat>` _body element_ referencing the `nodeset` of 1+ instance nodes
|
|
180
|
+
* (as defined in the form's model).
|
|
181
|
+
*
|
|
182
|
+
* 2. `RepeatTemplateDefinition`: this had a 0-1:1 correspondence between an
|
|
183
|
+
* instance node (as defined in the form's model) defining a `jr:template`
|
|
184
|
+
* attribute, if one exists; if none exists, one was synthesized at parse
|
|
185
|
+
* time.
|
|
186
|
+
*
|
|
187
|
+
* 3. `RepeatInstanceDefinition`: these had an N:N correspondence to _every
|
|
188
|
+
* non-template instance node_ (as defined in the form's model).
|
|
189
|
+
*
|
|
190
|
+
* For each instance of a form:
|
|
191
|
+
*
|
|
192
|
+
* - `RepeatRangeControlled` or `RepeatRangeUncontrolled` (engine-internal
|
|
193
|
+
* implementation of the `RepeatRangeControlledNode` and
|
|
194
|
+
* `RepeatRangeUncontrolledNode` client interfaces, respectively) also
|
|
195
|
+
* corresponded 1:1 with a `RepeatRangeDefinition`.
|
|
196
|
+
*
|
|
197
|
+
* - `RepeatInstance` (engine-internal implementation of the
|
|
198
|
+
* `RepeatInstanceNode`) had an N:N relationship with _either_:
|
|
199
|
+
* - `RepeatInstanceDefinition`, if one was defined for that repeat instance's
|
|
200
|
+
* the positional index
|
|
201
|
+
* - `RepeatTemplateDefinition`, otherwise
|
|
202
|
+
*
|
|
203
|
+
* **Revised mental model**
|
|
204
|
+
*
|
|
205
|
+
* 1. `RepeatDefinition`: merges the responsibilities of the former
|
|
206
|
+
* `RepeatRangeDefinition` and `RepeatTemplateDefinition`.
|
|
207
|
+
*
|
|
208
|
+
* 2. Repeat instance nodes (as defined in the form's model) are refereced
|
|
209
|
+
* _during the construction of instance state_ (`PrimaryInstance`):
|
|
210
|
+
*
|
|
211
|
+
* - if an instance node exists at the positional index of the
|
|
212
|
+
* `RepeatInstance` to be created, that node is used to populate the
|
|
213
|
+
* `RepeatInstance`'s initial state
|
|
214
|
+
*
|
|
215
|
+
* - if no instance node exists at that positional index, the template
|
|
216
|
+
* returned by {@link RepeatTemplateDefinition.parseRepeatTemplateElement}
|
|
217
|
+
* is referenced for the `RepeatInstance`'s initial state instead
|
|
218
|
+
*
|
|
219
|
+
* Aside from simplifying the parsing responsibilities associated with repeats,
|
|
220
|
+
* this also creates a roughly 1:1 relationship between the different
|
|
221
|
+
* representations of what we call an "instance node".
|
|
222
|
+
*
|
|
223
|
+
* @todo The above "revised mental model" for repeat definitions pretty much
|
|
224
|
+
* reflects the same principles which will be applied for non-form instance
|
|
225
|
+
* state, i.e. for (a) restoring previously serialized instance state and/or (b)
|
|
226
|
+
* editing previously submitted instance state. It will make sense to reflect
|
|
227
|
+
* that once that aspect of implementation is complete!
|
|
228
|
+
*
|
|
229
|
+
* - - -
|
|
230
|
+
*
|
|
231
|
+
* At time of writing, I believe that detailing the differences between these
|
|
232
|
+
* mental models will provide useful context, in the long term, for reasoning
|
|
233
|
+
* about the relationship between "node definition" and "instance node" (as
|
|
234
|
+
* defined in a form or a serialized and/or submitted instance; also the
|
|
235
|
+
* engine's active, stateful representations of those same nodes).
|
|
236
|
+
*
|
|
237
|
+
* Namely, the revised relationship is _1 (node definition) : N (instance
|
|
238
|
+
* node)_, associated by each instance node's nodeset.
|
|
239
|
+
*/
|
|
240
|
+
const parseRepeatTemplateElement = (firstRepeatInstanceNode: StaticElement) => {
|
|
241
|
+
if (isExplicitRepeatTemplateElement(firstRepeatInstanceNode)) {
|
|
242
|
+
return firstRepeatInstanceNode;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return cloneStaticElementStructure(firstRepeatInstanceNode);
|
|
246
|
+
|
|
247
|
+
// TODO: We previously **intended** to check for duplicate explicit repeat
|
|
248
|
+
// templates (i.e. defined with a `jr:template` attribute). This was
|
|
249
|
+
// **partially** handled by defining a (temporary/local) mapping from the
|
|
250
|
+
// repeat's `BindDefinition` to an already-parsed explicit template element
|
|
251
|
+
// (if any). Identifying duplicates **should** have been handled by
|
|
252
|
+
// determining that an entry for the same binding already existed. **BUT NO
|
|
253
|
+
// ENTRY WAS NEVER WRITTEN!** This comment is now intended to recognize:
|
|
254
|
+
//
|
|
255
|
+
// 1. ... that the intended behavior was never implemented correctly in the
|
|
256
|
+
// first place, and we are not making any changes to that intended aspect
|
|
257
|
+
// of engine behavior/semantics by eliminating the flawed implementation
|
|
258
|
+
// now.
|
|
259
|
+
//
|
|
260
|
+
// 2. ... that whether this behavior should have even been implemented was
|
|
261
|
+
// also an open question! The previous text of this
|
|
262
|
+
// comment's conceptual successor is preserved below, either for clarity in review or for logner-term posterity.
|
|
263
|
+
//
|
|
264
|
+
// - - -
|
|
265
|
+
//
|
|
266
|
+
// Previous text of this comment:
|
|
267
|
+
//
|
|
268
|
+
// > TODO: this is under the assumption that for any depth > 1, if a
|
|
269
|
+
// > template has already been defined for the given form definition, any
|
|
270
|
+
// > subsequent nodes matching the repeat's nodeset are implicitly default
|
|
271
|
+
// > instances. Is this right?
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
export interface ControlledRepeatDefinition extends RepeatDefinition {
|
|
275
|
+
readonly count: RepeatCountControlExpression;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export interface UncontrolledRepeatDefinition extends RepeatDefinition {
|
|
279
|
+
readonly count: null;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Represents a definition of the combined concepts colloquially called a
|
|
284
|
+
* "repeat", as defined by a form, where those concepts include:
|
|
285
|
+
*
|
|
286
|
+
* - A {@link RepeatElementDefinition}—corresponding to a `<repeat>` {@link https://getodk.github.io/xforms-spec/#body-elements | body element}—which is associated with the nodeset referencing the "repeat template" and
|
|
287
|
+
* all "repeat instances" (see below points describing both concepts in more detail). The presence of such a body element determines whether to produce a repeat definition (rather than e.g. a {@link SubtreeDefinition}).
|
|
288
|
+
*
|
|
289
|
+
* - A "repeat template", defined by a form either
|
|
290
|
+
* explicitly,
|
|
291
|
+
* or derived from the structure of the first form-defined "repeat instance"
|
|
292
|
+
* (as described in the next point).
|
|
293
|
+
*
|
|
294
|
+
* - A sequence of one or more model instance nodes, each representing a "repeat instance"
|
|
295
|
+
* defined by the form. These nodes contribute to the definition in the following ways:
|
|
296
|
+
*
|
|
297
|
+
* - If an explicit "repeat template" is not defined for
|
|
298
|
+
* the "repeat", one is derived from the **structure** (but not the values!)
|
|
299
|
+
* of the first such model instance node.
|
|
300
|
+
*
|
|
301
|
+
* - If the "repeat" is {@link ControlledRepeatDefinition | controlled} (i.e. by either a `jr:count` or `jr:noAddRemove` {@link https://getodk.github.io/xforms-spec/#body-attributes | attribute} on the associated {@link RepeatElementDefinition}
|
|
302
|
+
*
|
|
303
|
+
* (For construction of this
|
|
304
|
+
* definition, all other referenced instance nodes are **consumed** in the
|
|
305
|
+
* process of building the repeat definition's subtree of a
|
|
306
|
+
* {@link RootDefinition}, ensuring that one repeat definition is produced for
|
|
307
|
+
* all applicable nodes; they are later referenced for construction of a
|
|
308
|
+
* form's {@link PrimaryInstance | instance state}.)
|
|
309
|
+
*
|
|
310
|
+
* Combined, these concepts produce the details required to instantiate the
|
|
311
|
+
* {@link RepeatRange} and {@link RepeatInstance} instance state nodes
|
|
312
|
+
* associated with a defined repeat.
|
|
313
|
+
*/
|
|
314
|
+
export class RepeatDefinition extends DescendentNodeDefinition<'repeat', RepeatElementDefinition> {
|
|
315
|
+
static from(
|
|
316
|
+
parent: ParentNodeDefinition,
|
|
317
|
+
bind: BindDefinition,
|
|
318
|
+
bodyElement: RepeatElementDefinition,
|
|
319
|
+
instanceNodes: RepeatInstanceNodes
|
|
320
|
+
): AnyRepeatDefinition;
|
|
321
|
+
static from(
|
|
322
|
+
parent: ParentNodeDefinition,
|
|
323
|
+
bind: BindDefinition,
|
|
324
|
+
bodyElement: RepeatElementDefinition,
|
|
325
|
+
instanceNodes: RepeatInstanceNodes
|
|
326
|
+
): RepeatDefinition {
|
|
327
|
+
return new this(parent, bind, bodyElement, instanceNodes);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
readonly type = 'repeat';
|
|
331
|
+
readonly children: readonly ChildNodeDefinition[];
|
|
332
|
+
readonly count: RepeatCountControlExpression | null;
|
|
333
|
+
readonly template: StaticElement;
|
|
334
|
+
readonly namespaceDeclarations: NamespaceDeclarationMap;
|
|
335
|
+
readonly qualifiedName: QualifiedName;
|
|
336
|
+
|
|
337
|
+
private constructor(
|
|
338
|
+
parent: ParentNodeDefinition,
|
|
339
|
+
bind: BindDefinition,
|
|
340
|
+
bodyElement: RepeatElementDefinition,
|
|
341
|
+
instanceNodes: RepeatInstanceNodes
|
|
342
|
+
) {
|
|
343
|
+
super(parent, bind, bodyElement);
|
|
344
|
+
|
|
345
|
+
const { root } = parent;
|
|
346
|
+
const [instanceNode] = instanceNodes;
|
|
347
|
+
const template = parseRepeatTemplateElement(instanceNode);
|
|
348
|
+
const self = this as AnyRepeatDefinition;
|
|
349
|
+
|
|
350
|
+
this.template = template;
|
|
351
|
+
this.qualifiedName = template.qualifiedName;
|
|
352
|
+
this.namespaceDeclarations = new NamespaceDeclarationMap(this);
|
|
353
|
+
this.children = root.buildSubtree(self, template);
|
|
354
|
+
|
|
355
|
+
const initialCount = this.omitTemplate(instanceNodes).length;
|
|
356
|
+
|
|
357
|
+
this.count = RepeatCountControlExpression.from(bodyElement, initialCount);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
isControlled(): this is ControlledRepeatDefinition {
|
|
361
|
+
return this.count != null;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
isUncontrolled(): this is UncontrolledRepeatDefinition {
|
|
365
|
+
return this.count == null;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
omitTemplate(instanceNodes: readonly StaticElement[]): readonly StaticElement[] {
|
|
369
|
+
return instanceNodes.filter((instanceNode) => {
|
|
370
|
+
return instanceNode !== this.template;
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
toJSON(): object {
|
|
375
|
+
return {};
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// prettier-ignore
|
|
380
|
+
export type AnyRepeatDefinition =
|
|
381
|
+
| ControlledRepeatDefinition
|
|
382
|
+
| UncontrolledRepeatDefinition;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { XMLNS_NAMESPACE_URI } from '@getodk/common/constants/xmlns.ts';
|
|
2
|
+
import type { NamedNodeDefinition } from '../../lib/names/NamespaceDeclarationMap.ts';
|
|
3
|
+
import { QualifiedName } from '../../lib/names/QualifiedName.ts';
|
|
4
|
+
import { escapeXMLText } from '../../lib/xml-serialization.ts';
|
|
5
|
+
import type { RootDefinition } from './RootDefinition.ts';
|
|
6
|
+
|
|
7
|
+
interface RootAttributeSource {
|
|
8
|
+
readonly qualifiedName: QualifiedName;
|
|
9
|
+
readonly value: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @todo This class is named and typed to emphasize its intentionally narrow
|
|
14
|
+
* usage and purpose. It **intentionally** avoids addressing the much broader
|
|
15
|
+
* set of concerns around modeling attributes in primary instance/submissions.
|
|
16
|
+
*/
|
|
17
|
+
export class RootAttributeDefinition implements NamedNodeDefinition {
|
|
18
|
+
private readonly serializedXML: string;
|
|
19
|
+
|
|
20
|
+
readonly parent: RootDefinition;
|
|
21
|
+
readonly qualifiedName: QualifiedName;
|
|
22
|
+
readonly value: string;
|
|
23
|
+
|
|
24
|
+
constructor(root: RootDefinition, source: RootAttributeSource) {
|
|
25
|
+
const { qualifiedName, value } = source;
|
|
26
|
+
|
|
27
|
+
this.parent = root;
|
|
28
|
+
this.qualifiedName = qualifiedName;
|
|
29
|
+
this.value = value;
|
|
30
|
+
|
|
31
|
+
// We serialize namespace declarations separately
|
|
32
|
+
if (qualifiedName.namespaceURI?.href === XMLNS_NAMESPACE_URI) {
|
|
33
|
+
this.serializedXML = '';
|
|
34
|
+
} else {
|
|
35
|
+
const nodeName = qualifiedName.getPrefixedName();
|
|
36
|
+
|
|
37
|
+
this.serializedXML = ` ${nodeName}="${escapeXMLText(value, true)}"`;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
serializeAttributeXML(): string {
|
|
42
|
+
return this.serializedXML;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { XMLNS_NAMESPACE_URI } from '@getodk/common/constants/xmlns.ts';
|
|
2
|
+
import type { StaticAttribute } from '../../integration/xpath/static-dom/StaticAttribute.ts';
|
|
3
|
+
import type { StaticElement } from '../../integration/xpath/static-dom/StaticElement.ts';
|
|
4
|
+
import type { QualifiedName } from '../../lib/names/QualifiedName.ts';
|
|
5
|
+
import { RootAttributeDefinition } from './RootAttributeDefinition.ts';
|
|
6
|
+
import type { RootDefinition } from './RootDefinition.ts';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @todo We should probably just distinguish these as separate `StaticNode`
|
|
10
|
+
* subclasses, probably as separate collections on `StaticElement`!
|
|
11
|
+
*/
|
|
12
|
+
const isNonNamespaceAttribute = (attribute: StaticAttribute) => {
|
|
13
|
+
return attribute.qualifiedName.namespaceURI?.href !== XMLNS_NAMESPACE_URI;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @todo This can be trivially expanded to a narrowly general case when we
|
|
18
|
+
* prioritize work to
|
|
19
|
+
* {@link https://github.com/getodk/web-forms/issues/285 | support attributes}
|
|
20
|
+
* (as modeled form nodes on par with elements). It's been deferred here to
|
|
21
|
+
* avoid expanding scope of an already fairly large yak shave.
|
|
22
|
+
*
|
|
23
|
+
* @todo There's a **much more expansive** general case just waiting for a good
|
|
24
|
+
* opportuntity to prioritize it. E.g. a `NamedNodeMap<T>`, where T is any
|
|
25
|
+
* generalized concept of a named node. This expansive generalization would have
|
|
26
|
+
* a ton of value in a variety of known performance optimization
|
|
27
|
+
* targets/solutions (i.e. optimizing the most redundant, suboptimal, frequently
|
|
28
|
+
* performed aspects of any typical XPath expression in a typical XForm).
|
|
29
|
+
*
|
|
30
|
+
* @see {@link QualifiedName} for more detail.
|
|
31
|
+
*/
|
|
32
|
+
export class RootAttributeMap extends Map<QualifiedName, RootAttributeDefinition> {
|
|
33
|
+
static from(root: RootDefinition, instanceNode: StaticElement) {
|
|
34
|
+
const nonNamespaceAttributes = instanceNode.attributes.filter(isNonNamespaceAttribute);
|
|
35
|
+
const definitions = nonNamespaceAttributes.map((attribute) => {
|
|
36
|
+
return new RootAttributeDefinition(root, attribute);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
return new this(definitions);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private constructor(definitions: readonly RootAttributeDefinition[]) {
|
|
43
|
+
super(
|
|
44
|
+
definitions.map((attribute) => {
|
|
45
|
+
return [attribute.qualifiedName, attribute];
|
|
46
|
+
})
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
}
|