@getodk/xforms-engine 0.6.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/dist/client/BaseNode.d.ts +4 -4
- package/dist/client/BaseValueNode.d.ts +7 -3
- package/dist/client/RootNode.d.ts +20 -16
- 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/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/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/TemplatedNodeAttributeSerializationError.d.ts +22 -0
- package/dist/index.d.ts +2 -33
- package/dist/index.js +1915 -1419
- package/dist/index.js.map +1 -1
- package/dist/instance/Group.d.ts +6 -5
- package/dist/instance/InputControl.d.ts +5 -4
- package/dist/instance/ModelValue.d.ts +5 -4
- package/dist/instance/Note.d.ts +4 -3
- package/dist/instance/PrimaryInstance.d.ts +35 -8
- package/dist/instance/RangeControl.d.ts +5 -4
- package/dist/instance/RankControl.d.ts +6 -5
- package/dist/instance/Root.d.ts +7 -9
- package/dist/instance/SelectControl.d.ts +4 -3
- package/dist/instance/Subtree.d.ts +6 -5
- package/dist/instance/TriggerControl.d.ts +4 -3
- package/dist/instance/abstract/DescendantNode.d.ts +10 -1
- package/dist/instance/abstract/InstanceNode.d.ts +7 -4
- package/dist/instance/abstract/ValueNode.d.ts +7 -5
- 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/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 +8 -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 +10 -8
- package/dist/instance/repeat/RepeatInstance.d.ts +10 -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/static-dom/StaticAttribute.d.ts +4 -5
- package/dist/integration/xpath/static-dom/StaticDocument.d.ts +13 -10
- package/dist/integration/xpath/static-dom/StaticElement.d.ts +21 -22
- 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/TempUnsupportedControlCodec.d.ts +7 -0
- package/dist/lib/names/UnprefixedXFormsName.d.ts +4 -0
- package/dist/lib/reactivity/createInstanceValueState.d.ts +2 -27
- package/dist/parse/XFormDOM.d.ts +1 -1
- package/dist/parse/model/BindDefinition.d.ts +1 -1
- package/dist/parse/model/ItextTranslationsDefinition.d.ts +18 -0
- package/dist/parse/model/LeafNodeDefinition.d.ts +4 -5
- package/dist/parse/model/ModelBindMap.d.ts +1 -1
- package/dist/parse/model/ModelDefinition.d.ts +9 -2
- package/dist/parse/model/NodeDefinition.d.ts +18 -30
- package/dist/parse/model/NoteNodeDefinition.d.ts +3 -2
- package/dist/parse/model/RangeNodeDefinition.d.ts +2 -1
- package/dist/parse/model/RepeatDefinition.d.ts +62 -0
- package/dist/parse/model/RootAttributeDefinition.d.ts +1 -4
- package/dist/parse/model/RootAttributeMap.d.ts +2 -1
- package/dist/parse/model/RootDefinition.d.ts +7 -8
- 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 +4 -5
- 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 -21
- package/dist/solid.js +1709 -1213
- package/dist/solid.js.map +1 -1
- package/package.json +1 -1
- package/src/client/BaseNode.ts +4 -4
- package/src/client/BaseValueNode.ts +7 -3
- package/src/client/RootNode.ts +27 -19
- 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/index.ts +47 -29
- package/src/client/node-types.ts +2 -4
- 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/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/TemplatedNodeAttributeSerializationError.ts +24 -0
- package/src/index.ts +2 -46
- package/src/instance/Group.ts +16 -15
- package/src/instance/InputControl.ts +17 -11
- package/src/instance/ModelValue.ts +17 -11
- package/src/instance/Note.ts +10 -9
- package/src/instance/PrimaryInstance.ts +69 -31
- package/src/instance/RangeControl.ts +17 -11
- package/src/instance/RankControl.ts +28 -19
- package/src/instance/Root.ts +20 -31
- package/src/instance/SelectControl.ts +21 -12
- package/src/instance/Subtree.ts +16 -15
- package/src/instance/TriggerControl.ts +21 -12
- package/src/instance/abstract/DescendantNode.ts +12 -2
- package/src/instance/abstract/InstanceNode.ts +9 -5
- package/src/instance/abstract/ValueNode.ts +11 -13
- package/src/instance/children/DescendantNodeInitOptions.ts +35 -0
- package/src/instance/{children.ts → children/buildChildren.ts} +55 -48
- package/src/instance/children/childrenInitOptions.ts +117 -0
- package/src/instance/children/normalizeChildInitOptions.ts +332 -0
- 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 +9 -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 +19 -24
- package/src/instance/repeat/RepeatInstance.ts +26 -19
- package/src/instance/repeat/RepeatRangeControlled.ts +90 -17
- package/src/instance/repeat/RepeatRangeUncontrolled.ts +10 -9
- package/src/instance/resource.ts +14 -1
- 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/traversal.ts +2 -2
- package/src/integration/xpath/static-dom/StaticAttribute.ts +6 -5
- package/src/integration/xpath/static-dom/StaticDocument.ts +17 -16
- package/src/integration/xpath/static-dom/StaticElement.ts +196 -50
- 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/{submission/createRootSubmissionState.ts → instance-state/createRootInstanceState.ts} +4 -4
- 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/TempUnsupportedControlCodec.ts +32 -0
- package/src/lib/names/UnprefixedXFormsName.ts +12 -0
- package/src/lib/reactivity/createInstanceValueState.ts +27 -51
- package/src/parse/model/ItextTranslationsDefinition.ts +79 -0
- package/src/parse/model/LeafNodeDefinition.ts +3 -5
- package/src/parse/model/ModelDefinition.ts +36 -3
- package/src/parse/model/NodeDefinition.ts +19 -45
- package/src/parse/model/NoteNodeDefinition.ts +4 -3
- package/src/parse/model/RangeNodeDefinition.ts +3 -2
- package/src/parse/model/RepeatDefinition.ts +382 -0
- package/src/parse/model/RootAttributeDefinition.ts +6 -7
- package/src/parse/model/RootAttributeMap.ts +15 -10
- package/src/parse/model/RootDefinition.ts +17 -19
- 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 -137
- 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 +4 -5
- package/src/parse/model/nodeDefinitionMap.ts +34 -0
- package/src/parse/shared/parseInstanceXML.ts +79 -0
- package/src/parse/shared/parseStaticDocumentFromDOMSubtree.ts +45 -130
- 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/instance/abstract/UnsupportedControl.d.ts +0 -54
- 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 -32
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableParentNode.d.ts +0 -19
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableValueNode.d.ts +0 -18
- 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/createRootSubmissionState.d.ts +0 -3
- 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/createValueState.d.ts +0 -40
- package/dist/parse/model/ItextTranslation/ItextTranslationDefinition.d.ts +0 -4
- package/dist/parse/model/ItextTranslation/ItextTranslationRootDefinition.d.ts +0 -9
- package/dist/parse/model/ItextTranslation/ItextTranslationsDefinition.d.ts +0 -8
- package/dist/parse/model/RepeatInstanceDefinition.d.ts +0 -17
- package/dist/parse/model/RepeatRangeDefinition.d.ts +0 -32
- package/dist/parse/model/RepeatTemplateDefinition.d.ts +0 -31
- 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/instance/abstract/UnsupportedControl.ts +0 -175
- 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 -43
- package/src/instance/internal-api/submission/ClientReactiveSubmittableParentNode.ts +0 -26
- package/src/instance/internal-api/submission/ClientReactiveSubmittableValueNode.ts +0 -24
- 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/model/ItextTranslation/ItextTranslationDefinition.ts +0 -4
- package/src/parse/model/ItextTranslation/ItextTranslationRootDefinition.ts +0 -42
- package/src/parse/model/ItextTranslation/ItextTranslationsDefinition.ts +0 -31
- package/src/parse/model/RepeatInstanceDefinition.ts +0 -38
- package/src/parse/model/RepeatRangeDefinition.ts +0 -98
- package/src/parse/model/RepeatTemplateDefinition.ts +0 -149
- package/src/parse/model/SecondaryInstance/SecondaryInstanceDefinition.ts +0 -4
- package/src/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.ts +0 -12
|
@@ -1,21 +1,54 @@
|
|
|
1
|
+
import { ErrorProductionDesignPendingError } from '../../error/ErrorProductionDesignPendingError.ts';
|
|
2
|
+
import type { StaticDocument } from '../../integration/xpath/static-dom/StaticDocument.ts';
|
|
3
|
+
import { parseStaticDocumentFromDOMSubtree } from '../shared/parseStaticDocumentFromDOMSubtree.ts';
|
|
1
4
|
import type { XFormDefinition } from '../XFormDefinition.ts';
|
|
2
|
-
import {
|
|
3
|
-
import { ItextTranslationsDefinition } from './ItextTranslation/ItextTranslationsDefinition.ts';
|
|
5
|
+
import { ItextTranslationsDefinition } from './ItextTranslationsDefinition.ts';
|
|
4
6
|
import { ModelBindMap } from './ModelBindMap.ts';
|
|
7
|
+
import type { AnyNodeDefinition } from './NodeDefinition.ts';
|
|
8
|
+
import type { NodeDefinitionMap } from './nodeDefinitionMap.ts';
|
|
9
|
+
import { nodeDefinitionMap } from './nodeDefinitionMap.ts';
|
|
5
10
|
import { RootDefinition } from './RootDefinition.ts';
|
|
11
|
+
import { SubmissionDefinition } from './SubmissionDefinition.ts';
|
|
6
12
|
|
|
7
13
|
export class ModelDefinition {
|
|
8
14
|
readonly binds: ModelBindMap;
|
|
9
15
|
readonly root: RootDefinition;
|
|
16
|
+
readonly nodes: NodeDefinitionMap;
|
|
17
|
+
readonly instance: StaticDocument;
|
|
10
18
|
readonly itextTranslations: ItextTranslationsDefinition;
|
|
11
19
|
|
|
12
20
|
constructor(readonly form: XFormDefinition) {
|
|
13
|
-
const submission = new
|
|
21
|
+
const submission = new SubmissionDefinition(form.xformDOM);
|
|
22
|
+
|
|
14
23
|
this.binds = ModelBindMap.fromModel(this);
|
|
24
|
+
this.instance = parseStaticDocumentFromDOMSubtree(form.xformDOM.primaryInstanceRoot, {
|
|
25
|
+
nodesetPrefix: '/',
|
|
26
|
+
});
|
|
15
27
|
this.root = new RootDefinition(form, this, submission, form.body.classes);
|
|
28
|
+
this.nodes = nodeDefinitionMap(this.root);
|
|
16
29
|
this.itextTranslations = ItextTranslationsDefinition.from(form.xformDOM);
|
|
17
30
|
}
|
|
18
31
|
|
|
32
|
+
getNodeDefinition(nodeset: string): AnyNodeDefinition {
|
|
33
|
+
const definition = this.nodes.get(nodeset);
|
|
34
|
+
|
|
35
|
+
if (definition == null) {
|
|
36
|
+
throw new ErrorProductionDesignPendingError(`No definition for nodeset: ${nodeset}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return definition;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
getRootDefinition(instance: StaticDocument): RootDefinition {
|
|
43
|
+
const definition = this.getNodeDefinition(instance.root.nodeset);
|
|
44
|
+
|
|
45
|
+
if (definition !== this.root) {
|
|
46
|
+
throw new ErrorProductionDesignPendingError();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return definition;
|
|
50
|
+
}
|
|
51
|
+
|
|
19
52
|
toJSON() {
|
|
20
53
|
const { form, ...rest } = this;
|
|
21
54
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { StaticElement } from '../../integration/xpath/static-dom/StaticElement.ts';
|
|
1
2
|
import type {
|
|
2
3
|
NamedSubtreeDefinition,
|
|
3
4
|
NamespaceDeclarationMap,
|
|
@@ -7,14 +8,12 @@ import type { AnyBodyElementDefinition } from '../body/BodyDefinition.ts';
|
|
|
7
8
|
import type { RepeatElementDefinition } from '../body/RepeatElementDefinition.ts';
|
|
8
9
|
import type { BindDefinition } from './BindDefinition.ts';
|
|
9
10
|
import type { LeafNodeDefinition } from './LeafNodeDefinition.ts';
|
|
10
|
-
import type {
|
|
11
|
-
import type { AnyRepeatRangeDefinition } from './RepeatRangeDefinition.ts';
|
|
12
|
-
import type { RepeatTemplateDefinition } from './RepeatTemplateDefinition.ts';
|
|
11
|
+
import type { AnyRepeatDefinition } from './RepeatDefinition.ts';
|
|
13
12
|
import type { RootDefinition } from './RootDefinition.ts';
|
|
14
13
|
import type { SubtreeDefinition } from './SubtreeDefinition.ts';
|
|
15
14
|
|
|
16
15
|
/**
|
|
17
|
-
* Corresponds to
|
|
16
|
+
* Corresponds to a model instance root node, i.e.:
|
|
18
17
|
*
|
|
19
18
|
* - the element matching `/*` in primary instance expressions, a.k.a.
|
|
20
19
|
* - `/h:html/h:head/xf:model/xf:instance[1]/*`
|
|
@@ -22,34 +21,25 @@ import type { SubtreeDefinition } from './SubtreeDefinition.ts';
|
|
|
22
21
|
export type RootNodeType = 'root';
|
|
23
22
|
|
|
24
23
|
/**
|
|
25
|
-
* Corresponds to
|
|
26
|
-
*
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
*
|
|
32
|
-
* an explicit `jr:template=""` attribute in the form definition or is inferred
|
|
33
|
-
* as a template from the form's first element matched by a <repeat nodeset>.
|
|
34
|
-
*/
|
|
35
|
-
export type RepeatTemplateType = 'repeat-template';
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Corresponds to a single instance of a model/entry DOM subtree which
|
|
39
|
-
* in turn corresponds to a <repeat> in the form body definition, and a
|
|
40
|
-
* 'repeat-range' definition.
|
|
24
|
+
* Corresponds to the combined concepts defining a "repeat".
|
|
25
|
+
*
|
|
26
|
+
* @see {@link RepeatDefinition} for details on these concepts and how they are used to produce a "repeat definition", as such.
|
|
27
|
+
*
|
|
28
|
+
* , including or
|
|
29
|
+
* referencing all of the following:
|
|
30
|
+
*
|
|
41
31
|
*/
|
|
42
|
-
export type
|
|
32
|
+
export type RepeatType = 'repeat';
|
|
43
33
|
|
|
44
34
|
/**
|
|
45
|
-
* Corresponds to a model
|
|
35
|
+
* Corresponds to a model instance subtree which **does not** correspond to a
|
|
46
36
|
* <repeat> in the form definition. This will typically correspond to a <group>,
|
|
47
37
|
* but this is not strictly necessary per spec (hence the distinct name).
|
|
48
38
|
*/
|
|
49
39
|
export type SubtreeNodeType = 'subtree';
|
|
50
40
|
|
|
51
41
|
/**
|
|
52
|
-
* Corresponds to a model
|
|
42
|
+
* Corresponds to a model instance leaf node, i.e. one of:
|
|
53
43
|
*
|
|
54
44
|
* - An element with no child elements
|
|
55
45
|
* - Any attribute corresponding to a bind's `nodeset` expression
|
|
@@ -60,9 +50,7 @@ export type LeafNodeType = 'leaf-node';
|
|
|
60
50
|
export type NodeDefinitionType =
|
|
61
51
|
// eslint-disable-next-line @typescript-eslint/sort-type-constituents
|
|
62
52
|
| RootNodeType
|
|
63
|
-
|
|
|
64
|
-
| RepeatTemplateType
|
|
65
|
-
| RepeatInstanceType
|
|
53
|
+
| RepeatType
|
|
66
54
|
| SubtreeNodeType
|
|
67
55
|
| LeafNodeType;
|
|
68
56
|
|
|
@@ -70,24 +58,15 @@ export type NodeDefinitionType =
|
|
|
70
58
|
export type ParentNodeDefinition =
|
|
71
59
|
// eslint-disable-next-line @typescript-eslint/sort-type-constituents
|
|
72
60
|
| RootDefinition
|
|
73
|
-
|
|
|
74
|
-
| RepeatInstanceDefinition
|
|
61
|
+
| AnyRepeatDefinition
|
|
75
62
|
| SubtreeDefinition;
|
|
76
63
|
|
|
77
64
|
// prettier-ignore
|
|
78
65
|
export type ChildNodeDefinition =
|
|
79
|
-
|
|
|
66
|
+
| AnyRepeatDefinition
|
|
80
67
|
| LeafNodeDefinition
|
|
81
68
|
| SubtreeDefinition;
|
|
82
69
|
|
|
83
|
-
// prettier-ignore
|
|
84
|
-
export type ChildNodeInstanceDefinition =
|
|
85
|
-
// eslint-disable-next-line @typescript-eslint/sort-type-constituents
|
|
86
|
-
| RepeatTemplateDefinition
|
|
87
|
-
| RepeatInstanceDefinition
|
|
88
|
-
| SubtreeDefinition
|
|
89
|
-
| LeafNodeDefinition;
|
|
90
|
-
|
|
91
70
|
export abstract class NodeDefinition<Type extends NodeDefinitionType>
|
|
92
71
|
implements NamedSubtreeDefinition
|
|
93
72
|
{
|
|
@@ -98,12 +77,8 @@ export abstract class NodeDefinition<Type extends NodeDefinitionType>
|
|
|
98
77
|
abstract readonly isTranslated: boolean;
|
|
99
78
|
abstract readonly root: RootDefinition;
|
|
100
79
|
abstract readonly parent: ParentNodeDefinition | null;
|
|
80
|
+
abstract readonly template: StaticElement;
|
|
101
81
|
abstract readonly children: readonly ChildNodeDefinition[] | null;
|
|
102
|
-
abstract readonly instances: readonly RepeatInstanceDefinition[] | null;
|
|
103
|
-
abstract readonly defaultValue: string | null;
|
|
104
|
-
|
|
105
|
-
/** @todo leaf-node may be Attr */
|
|
106
|
-
abstract readonly node: Element | null;
|
|
107
82
|
|
|
108
83
|
readonly nodeset: string;
|
|
109
84
|
|
|
@@ -112,11 +87,10 @@ export abstract class NodeDefinition<Type extends NodeDefinitionType>
|
|
|
112
87
|
}
|
|
113
88
|
}
|
|
114
89
|
|
|
90
|
+
// prettier-ignore
|
|
115
91
|
export type AnyNodeDefinition =
|
|
116
92
|
// eslint-disable-next-line @typescript-eslint/sort-type-constituents
|
|
117
93
|
| RootDefinition
|
|
118
|
-
|
|
|
119
|
-
| RepeatTemplateDefinition
|
|
120
|
-
| RepeatInstanceDefinition
|
|
94
|
+
| AnyRepeatDefinition
|
|
121
95
|
| SubtreeDefinition
|
|
122
96
|
| LeafNodeDefinition;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { NoteNode } from '../../client/NoteNode.ts';
|
|
2
2
|
import type { ValueType } from '../../client/ValueType.ts';
|
|
3
|
+
import type { StaticLeafElement } from '../../integration/xpath/static-dom/StaticElement.ts';
|
|
3
4
|
import type { AnyBodyElementDefinition } from '../body/BodyDefinition.ts';
|
|
4
5
|
import type { InputControlDefinition } from '../body/control/InputControlDefinition.ts';
|
|
5
6
|
import { BindComputationExpression } from '../expression/BindComputationExpression.ts';
|
|
@@ -43,7 +44,7 @@ export class NoteNodeDefinition<V extends ValueType = ValueType> extends LeafNod
|
|
|
43
44
|
parent: ParentNodeDefinition,
|
|
44
45
|
bind: BindDefinition<V>,
|
|
45
46
|
bodyElement: AnyBodyElementDefinition | null,
|
|
46
|
-
node:
|
|
47
|
+
node: StaticLeafElement
|
|
47
48
|
): NoteNodeDefinition<V> | null {
|
|
48
49
|
if (!isNoteBindDefinition(bind) || bodyElement?.type !== 'input') {
|
|
49
50
|
return null;
|
|
@@ -64,8 +65,8 @@ export class NoteNodeDefinition<V extends ValueType = ValueType> extends LeafNod
|
|
|
64
65
|
override readonly bind: NoteBindDefinition<V>,
|
|
65
66
|
override readonly bodyElement: InputControlDefinition,
|
|
66
67
|
readonly noteTextDefinition: NoteTextDefinition,
|
|
67
|
-
|
|
68
|
+
template: StaticLeafElement
|
|
68
69
|
) {
|
|
69
|
-
super(parent, bind, bodyElement,
|
|
70
|
+
super(parent, bind, bodyElement, template);
|
|
70
71
|
}
|
|
71
72
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ValueType } from '../../client/ValueType.ts';
|
|
2
2
|
import { ErrorProductionDesignPendingError } from '../../error/ErrorProductionDesignPendingError.ts';
|
|
3
|
+
import type { StaticLeafElement } from '../../integration/xpath/static-dom/StaticElement.ts';
|
|
3
4
|
import type { RuntimeValue, SharedValueCodec } from '../../lib/codecs/getSharedValueCodec.ts';
|
|
4
5
|
import { getSharedValueCodec } from '../../lib/codecs/getSharedValueCodec.ts';
|
|
5
6
|
import type {
|
|
@@ -91,7 +92,7 @@ export class RangeNodeDefinition<V extends RangeValueType = RangeValueType>
|
|
|
91
92
|
parent: ParentNodeDefinition,
|
|
92
93
|
bind: BindDefinition<V>,
|
|
93
94
|
bodyElement: RangeControlDefinition,
|
|
94
|
-
node:
|
|
95
|
+
node: StaticLeafElement
|
|
95
96
|
): RangeNodeDefinition<Extract<V, RangeValueType>> {
|
|
96
97
|
assertRangeBindDefinition(bind);
|
|
97
98
|
|
|
@@ -104,7 +105,7 @@ export class RangeNodeDefinition<V extends RangeValueType = RangeValueType>
|
|
|
104
105
|
parent: ParentNodeDefinition,
|
|
105
106
|
override readonly bind: BindDefinition<V>,
|
|
106
107
|
override readonly bodyElement: RangeControlDefinition,
|
|
107
|
-
node:
|
|
108
|
+
node: StaticLeafElement
|
|
108
109
|
) {
|
|
109
110
|
super(parent, bind, bodyElement, node);
|
|
110
111
|
|
|
@@ -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;
|
|
@@ -5,10 +5,7 @@ import { escapeXMLText } from '../../lib/xml-serialization.ts';
|
|
|
5
5
|
import type { RootDefinition } from './RootDefinition.ts';
|
|
6
6
|
|
|
7
7
|
interface RootAttributeSource {
|
|
8
|
-
readonly
|
|
9
|
-
readonly nodeName: string;
|
|
10
|
-
readonly prefix: string | null;
|
|
11
|
-
readonly localName: string;
|
|
8
|
+
readonly qualifiedName: QualifiedName;
|
|
12
9
|
readonly value: string;
|
|
13
10
|
}
|
|
14
11
|
|
|
@@ -25,16 +22,18 @@ export class RootAttributeDefinition implements NamedNodeDefinition {
|
|
|
25
22
|
readonly value: string;
|
|
26
23
|
|
|
27
24
|
constructor(root: RootDefinition, source: RootAttributeSource) {
|
|
28
|
-
const {
|
|
25
|
+
const { qualifiedName, value } = source;
|
|
29
26
|
|
|
30
27
|
this.parent = root;
|
|
31
|
-
this.qualifiedName =
|
|
28
|
+
this.qualifiedName = qualifiedName;
|
|
32
29
|
this.value = value;
|
|
33
30
|
|
|
34
31
|
// We serialize namespace declarations separately
|
|
35
|
-
if (namespaceURI === XMLNS_NAMESPACE_URI) {
|
|
32
|
+
if (qualifiedName.namespaceURI?.href === XMLNS_NAMESPACE_URI) {
|
|
36
33
|
this.serializedXML = '';
|
|
37
34
|
} else {
|
|
35
|
+
const nodeName = qualifiedName.getPrefixedName();
|
|
36
|
+
|
|
38
37
|
this.serializedXML = ` ${nodeName}="${escapeXMLText(value, true)}"`;
|
|
39
38
|
}
|
|
40
39
|
}
|