@getodk/xforms-engine 0.3.0 → 0.5.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 +15 -5
- package/dist/client/BaseValueNode.d.ts +32 -0
- package/dist/client/EngineConfig.d.ts +49 -49
- package/dist/client/GroupNode.d.ts +2 -3
- package/dist/client/InputNode.d.ts +53 -0
- package/dist/client/ModelValueNode.d.ts +13 -9
- package/dist/client/NodeAppearances.d.ts +1 -2
- package/dist/client/NoteNode.d.ts +3 -4
- package/dist/client/RootNode.d.ts +36 -10
- package/dist/client/SelectNode.d.ts +4 -5
- package/dist/client/SubtreeNode.d.ts +1 -2
- package/dist/client/TextRange.d.ts +3 -4
- package/dist/client/TriggerNode.d.ts +25 -0
- package/dist/client/ValueType.d.ts +3 -0
- package/dist/client/constants.d.ts +50 -1
- package/dist/client/hierarchy.d.ts +9 -5
- package/dist/client/identity.d.ts +14 -0
- package/dist/client/index.d.ts +0 -1
- package/dist/client/node-types.d.ts +3 -1
- package/dist/client/repeat/BaseRepeatRangeNode.d.ts +1 -2
- package/dist/client/repeat/RepeatInstanceNode.d.ts +2 -3
- package/dist/client/repeat/RepeatRangeControlledNode.d.ts +1 -2
- package/dist/client/repeat/RepeatRangeUncontrolledNode.d.ts +1 -2
- package/dist/client/resources.d.ts +93 -0
- package/dist/client/submission/SubmissionData.d.ts +7 -0
- package/dist/client/submission/SubmissionDefinition.d.ts +14 -0
- package/dist/client/submission/SubmissionInstanceFile.d.ts +6 -0
- package/dist/client/submission/SubmissionOptions.d.ts +23 -0
- package/dist/client/submission/SubmissionResult.d.ts +91 -0
- package/dist/client/submission/SubmissionState.d.ts +12 -0
- package/dist/client/unsupported/RangeNode.d.ts +9 -0
- package/dist/client/unsupported/RankNode.d.ts +9 -0
- package/dist/client/unsupported/UnsupportedControlNode.d.ts +32 -0
- package/dist/client/unsupported/UploadNode.d.ts +9 -0
- package/dist/client/validation.d.ts +2 -3
- package/dist/error/ErrorProductionDesignPendingError.d.ts +7 -0
- package/dist/error/ValueTypeInvariantError.d.ts +17 -0
- package/dist/error/XPathFunctionalityError.d.ts +14 -0
- package/dist/error/XPathFunctionalityNotSupportedError.d.ts +7 -0
- package/dist/error/XPathFunctionalityPendingError.d.ts +7 -0
- package/dist/index.d.ts +16 -4
- package/dist/index.js +8559 -4700
- package/dist/index.js.map +1 -1
- package/dist/instance/Group.d.ts +9 -5
- package/dist/instance/InputControl.d.ts +36 -0
- package/dist/instance/ModelValue.d.ts +16 -27
- package/dist/instance/Note.d.ts +11 -5
- package/dist/instance/PrimaryInstance.d.ts +84 -0
- package/dist/instance/Root.d.ts +31 -28
- package/dist/instance/SelectField.d.ts +13 -6
- package/dist/instance/Subtree.d.ts +10 -6
- package/dist/instance/TriggerControl.d.ts +47 -0
- package/dist/instance/abstract/DescendantNode.d.ts +33 -26
- package/dist/instance/abstract/InstanceNode.d.ts +50 -31
- package/dist/instance/abstract/UnsupportedControl.d.ts +53 -0
- package/dist/instance/abstract/ValueNode.d.ts +48 -0
- package/dist/instance/children.d.ts +0 -1
- package/dist/instance/hierarchy.d.ts +13 -8
- package/dist/instance/identity.d.ts +2 -7
- package/dist/instance/index.d.ts +0 -1
- package/dist/instance/internal-api/EvaluationContext.d.ts +53 -13
- package/dist/instance/internal-api/InstanceConfig.d.ts +8 -3
- package/dist/instance/internal-api/InstanceValueContext.d.ts +20 -0
- package/dist/instance/internal-api/PrimaryInstanceDocument.d.ts +36 -0
- package/dist/instance/internal-api/TranslationContext.d.ts +3 -3
- package/dist/instance/internal-api/ValidationContext.d.ts +12 -6
- package/dist/instance/internal-api/ValueContext.d.ts +5 -5
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableInstance.d.ts +14 -0
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.d.ts +31 -0
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableParentNode.d.ts +18 -0
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableValueNode.d.ts +17 -0
- package/dist/instance/repeat/BaseRepeatRange.d.ts +40 -85
- package/dist/instance/repeat/RepeatInstance.d.ts +11 -30
- package/dist/instance/repeat/RepeatRangeControlled.d.ts +3 -4
- package/dist/instance/repeat/RepeatRangeUncontrolled.d.ts +3 -4
- package/dist/instance/resource.d.ts +1 -2
- package/dist/instance/text/TextChunk.d.ts +0 -1
- package/dist/instance/text/TextRange.d.ts +1 -2
- package/dist/instance/unsupported/RangeControl.d.ts +6 -0
- package/dist/instance/unsupported/RankControl.d.ts +6 -0
- package/dist/instance/unsupported/UploadControl.d.ts +6 -0
- package/dist/integration/xpath/EngineXPathEvaluator.d.ts +14 -0
- package/dist/integration/xpath/adapter/XFormsXPathNode.d.ts +71 -0
- package/dist/integration/xpath/adapter/engineDOMAdapter.d.ts +5 -0
- package/dist/integration/xpath/adapter/kind.d.ts +32 -0
- package/dist/integration/xpath/adapter/names.d.ts +16 -0
- package/dist/integration/xpath/adapter/traversal.d.ts +25 -0
- package/dist/integration/xpath/adapter/values.d.ts +2 -0
- package/dist/integration/xpath/static-dom/StaticAttribute.d.ts +19 -0
- package/dist/integration/xpath/static-dom/StaticDocument.d.ts +16 -0
- package/dist/integration/xpath/static-dom/StaticElement.d.ts +40 -0
- package/dist/integration/xpath/static-dom/StaticNamedNode.d.ts +17 -0
- package/dist/integration/xpath/static-dom/StaticNode.d.ts +33 -0
- package/dist/integration/xpath/static-dom/StaticText.d.ts +16 -0
- package/dist/lib/TokenListParser.d.ts +3 -3
- package/dist/lib/client-reactivity/submission/createInstanceSubmissionState.d.ts +3 -0
- package/dist/lib/client-reactivity/submission/createLeafNodeSubmissionState.d.ts +3 -0
- package/dist/lib/client-reactivity/submission/createNodeRangeSubmissionState.d.ts +4 -0
- package/dist/lib/client-reactivity/submission/createParentNodeSubmissionState.d.ts +4 -0
- package/dist/lib/client-reactivity/submission/createValueNodeSubmissionState.d.ts +3 -0
- package/dist/lib/client-reactivity/submission/prepareSubmission.d.ts +8 -0
- package/dist/lib/codecs/DecimalValueCodec.d.ts +6 -0
- package/dist/lib/codecs/IntValueCodec.d.ts +6 -0
- package/dist/lib/codecs/StringValueCodec.d.ts +4 -0
- package/dist/lib/codecs/ValueCodec.d.ts +30 -0
- package/dist/lib/codecs/ValueTypePlaceholderCodec.d.ts +12 -0
- package/dist/lib/codecs/getSharedValueCodec.d.ts +47 -0
- package/dist/lib/dom/query.d.ts +4 -2
- package/dist/lib/reactivity/createChildrenState.d.ts +7 -6
- package/dist/lib/reactivity/createComputedExpression.d.ts +19 -7
- package/dist/lib/reactivity/createInstanceValueState.d.ts +40 -0
- package/dist/lib/reactivity/createNoteReadonlyThunk.d.ts +2 -3
- package/dist/lib/reactivity/createSelectItems.d.ts +0 -1
- package/dist/lib/reactivity/createTranslationState.d.ts +19 -0
- package/dist/lib/reactivity/createValueState.d.ts +6 -11
- package/dist/lib/reactivity/materializeCurrentStateChildren.d.ts +4 -5
- package/dist/lib/reactivity/node-state/createClientState.d.ts +0 -1
- package/dist/lib/reactivity/node-state/createCurrentState.d.ts +0 -1
- package/dist/lib/reactivity/node-state/createEngineState.d.ts +0 -1
- package/dist/lib/reactivity/node-state/createSharedNodeState.d.ts +0 -1
- package/dist/lib/reactivity/node-state/createSpecifiedPropertyDescriptor.d.ts +0 -1
- package/dist/lib/reactivity/node-state/createSpecifiedState.d.ts +0 -1
- package/dist/lib/reactivity/node-state/representations.d.ts +0 -1
- package/dist/lib/reactivity/scope.d.ts +0 -1
- package/dist/lib/reactivity/text/createFieldHint.d.ts +1 -2
- package/dist/lib/reactivity/text/createNodeLabel.d.ts +1 -2
- package/dist/lib/reactivity/text/createNoteText.d.ts +1 -2
- package/dist/lib/reactivity/text/createTextRange.d.ts +0 -1
- package/dist/lib/reactivity/types.d.ts +0 -1
- package/dist/lib/reactivity/validation/createAggregatedViolations.d.ts +0 -1
- package/dist/lib/reactivity/validation/createValidation.d.ts +0 -1
- package/dist/lib/xml-serialization.d.ts +41 -0
- package/dist/parse/XFormDOM.d.ts +42 -0
- package/dist/{XFormDefinition.d.ts → parse/XFormDefinition.d.ts} +3 -5
- package/dist/parse/attachments/FormAttachmentResource.d.ts +27 -0
- package/dist/{body → parse/body}/BodyDefinition.d.ts +16 -11
- package/dist/{body → parse/body}/BodyElementDefinition.d.ts +7 -7
- package/dist/{body → parse/body}/RepeatElementDefinition.d.ts +3 -4
- package/dist/{body → parse/body}/UnsupportedBodyElementDefinition.d.ts +0 -1
- package/dist/parse/body/appearance/inputAppearanceParser.d.ts +3 -0
- package/dist/{body → parse/body}/appearance/selectAppearanceParser.d.ts +1 -2
- package/dist/{body → parse/body}/appearance/structureElementAppearanceParser.d.ts +1 -2
- package/dist/parse/body/appearance/unknownAppearanceParser.d.ts +3 -0
- package/dist/{body → parse/body}/control/ControlDefinition.d.ts +3 -4
- package/dist/{body/control/InputDefinition.d.ts → parse/body/control/InputControlDefinition.d.ts} +2 -3
- package/dist/parse/body/control/RangeControlDefinition.d.ts +11 -0
- package/dist/parse/body/control/RankControlDefinition.d.ts +11 -0
- package/dist/parse/body/control/TriggerControlDefinition.d.ts +11 -0
- package/dist/parse/body/control/UploadControlDefinition.d.ts +11 -0
- package/dist/{body → parse/body}/control/select/ItemDefinition.d.ts +2 -3
- package/dist/{body → parse/body}/control/select/ItemsetDefinition.d.ts +4 -5
- package/dist/{body → parse/body}/control/select/ItemsetNodesetContext.d.ts +1 -4
- package/dist/{body → parse/body}/control/select/SelectDefinition.d.ts +3 -12
- package/dist/{body → parse/body}/group/BaseGroupDefinition.d.ts +3 -5
- package/dist/{body → parse/body}/group/LogicalGroupDefinition.d.ts +0 -1
- package/dist/{body → parse/body}/group/PresentationGroupDefinition.d.ts +1 -2
- package/dist/{body → parse/body}/group/StructuralGroupDefinition.d.ts +0 -1
- package/dist/{model/BindComputation.d.ts → parse/expression/BindComputationExpression.d.ts} +5 -6
- package/dist/{body/control/select → parse/expression}/ItemsetNodesetExpression.d.ts +2 -3
- package/dist/{body/control/select → parse/expression}/ItemsetValueExpression.d.ts +2 -3
- package/dist/parse/expression/RepeatCountControlExpression.d.ts +2 -3
- package/dist/parse/expression/TextLiteralExpression.d.ts +9 -0
- package/dist/parse/expression/TextOutputExpression.d.ts +7 -0
- package/dist/parse/expression/TextReferenceExpression.d.ts +7 -0
- package/dist/parse/expression/TextTranslationExpression.d.ts +8 -0
- package/dist/parse/expression/abstract/DependencyContext.d.ts +7 -0
- package/dist/{expression → parse/expression/abstract}/DependentExpression.d.ts +4 -6
- package/dist/parse/expression/abstract/TextChunkExpression.d.ts +17 -0
- package/dist/parse/model/BindDefinition.d.ts +38 -0
- package/dist/parse/model/BindTypeDefinition.d.ts +20 -0
- package/dist/{model → parse/model}/DescendentNodeDefinition.d.ts +0 -2
- package/dist/parse/model/FormSubmissionDefinition.d.ts +8 -0
- package/dist/parse/model/ItextTranslation/ItextTranslationDefinition.d.ts +4 -0
- package/dist/parse/model/ItextTranslation/ItextTranslationRootDefinition.d.ts +8 -0
- package/dist/parse/model/ItextTranslation/ItextTranslationsDefinition.d.ts +8 -0
- package/dist/{model → parse/model}/LeafNodeDefinition.d.ts +4 -3
- package/dist/{model → parse/model}/ModelBindMap.d.ts +1 -2
- package/dist/{model → parse/model}/ModelDefinition.d.ts +3 -2
- package/dist/{model → parse/model}/NodeDefinition.d.ts +0 -2
- package/dist/parse/{NoteNodeDefinition.d.ts → model/NoteNodeDefinition.d.ts} +12 -13
- package/dist/{model → parse/model}/RepeatInstanceDefinition.d.ts +1 -2
- package/dist/{model → parse/model}/RepeatRangeDefinition.d.ts +2 -3
- package/dist/{model → parse/model}/RepeatTemplateDefinition.d.ts +2 -3
- package/dist/{model → parse/model}/RootDefinition.d.ts +5 -5
- package/dist/parse/model/SecondaryInstance/SecondaryInstanceDefinition.d.ts +4 -0
- package/dist/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.d.ts +7 -0
- package/dist/parse/model/SecondaryInstance/SecondaryInstancesDefinition.d.ts +13 -0
- package/dist/parse/model/SecondaryInstance/sources/BlankSecondaryInstanceSource.d.ts +14 -0
- package/dist/parse/model/SecondaryInstance/sources/CSVExternalSecondaryInstance.d.ts +22 -0
- package/dist/parse/model/SecondaryInstance/sources/ExternalSecondaryInstanceResource.d.ts +23 -0
- package/dist/parse/model/SecondaryInstance/sources/ExternalSecondaryInstanceSource.d.ts +9 -0
- package/dist/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.d.ts +5 -0
- package/dist/parse/model/SecondaryInstance/sources/InternalSecondaryInstanceSource.d.ts +7 -0
- package/dist/parse/model/SecondaryInstance/sources/SecondaryInstanceSource.d.ts +13 -0
- package/dist/parse/model/SecondaryInstance/sources/XMLExternalSecondaryInstanceSource.d.ts +12 -0
- package/dist/{model → parse/model}/SubtreeDefinition.d.ts +1 -2
- package/dist/parse/shared/parseStaticDocumentFromDOMSubtree.d.ts +24 -0
- package/dist/parse/text/HintDefinition.d.ts +2 -3
- package/dist/parse/text/ItemLabelDefinition.d.ts +2 -3
- package/dist/parse/text/ItemsetLabelDefinition.d.ts +3 -4
- package/dist/parse/text/LabelDefinition.d.ts +5 -6
- package/dist/parse/text/MessageDefinition.d.ts +4 -5
- package/dist/parse/text/abstract/TextElementDefinition.d.ts +8 -9
- package/dist/parse/text/abstract/TextRangeDefinition.d.ts +4 -7
- package/dist/parse/xpath/path-resolution.d.ts +0 -1
- package/dist/parse/xpath/predicate-analysis.d.ts +0 -1
- package/dist/parse/xpath/reference-parsing.d.ts +0 -1
- package/dist/parse/xpath/semantic-analysis.d.ts +5 -1
- package/dist/parse/xpath/syntax-traversal.d.ts +0 -1
- package/dist/solid.js +8398 -4543
- package/dist/solid.js.map +1 -1
- package/package.json +14 -12
- package/src/client/BaseNode.ts +17 -7
- package/src/client/BaseValueNode.ts +35 -0
- package/src/client/EngineConfig.ts +52 -51
- package/src/client/GroupNode.ts +2 -2
- package/src/client/InputNode.ts +77 -0
- package/src/client/ModelValueNode.ts +31 -8
- package/src/client/NodeAppearances.ts +1 -1
- package/src/client/NoteNode.ts +3 -3
- package/src/client/RootNode.ts +39 -9
- package/src/client/SelectNode.ts +5 -5
- package/src/client/SubtreeNode.ts +1 -1
- package/src/client/TextRange.ts +4 -5
- package/src/client/TriggerNode.ts +29 -0
- package/src/client/ValueType.ts +4 -0
- package/src/client/constants.ts +67 -0
- package/src/client/hierarchy.ts +16 -4
- package/src/client/identity.ts +16 -0
- package/src/client/node-types.ts +19 -5
- package/src/client/repeat/BaseRepeatRangeNode.ts +1 -1
- package/src/client/repeat/RepeatInstanceNode.ts +2 -2
- package/src/client/repeat/RepeatRangeControlledNode.ts +1 -1
- package/src/client/repeat/RepeatRangeUncontrolledNode.ts +1 -1
- package/src/client/resources.ts +118 -0
- package/src/client/submission/SubmissionData.ts +12 -0
- package/src/client/submission/SubmissionDefinition.ts +16 -0
- package/src/client/submission/SubmissionInstanceFile.ts +9 -0
- package/src/client/submission/SubmissionOptions.ts +28 -0
- package/src/client/submission/SubmissionResult.ts +124 -0
- package/src/client/submission/SubmissionState.ts +14 -0
- package/src/client/unsupported/RangeNode.ts +14 -0
- package/src/client/unsupported/RankNode.ts +14 -0
- package/src/client/unsupported/UnsupportedControlNode.ts +40 -0
- package/src/client/unsupported/UploadNode.ts +14 -0
- package/src/client/validation.ts +2 -2
- package/src/error/ErrorProductionDesignPendingError.ts +6 -0
- package/src/error/ValueTypeInvariantError.ts +22 -0
- package/src/error/XPathFunctionalityError.ts +26 -0
- package/src/error/XPathFunctionalityNotSupportedError.ts +18 -0
- package/src/error/XPathFunctionalityPendingError.ts +18 -0
- package/src/index.ts +16 -2
- package/src/instance/Group.ts +17 -5
- package/src/instance/InputControl.ts +119 -0
- package/src/instance/ModelValue.ts +47 -54
- package/src/instance/Note.ts +26 -10
- package/src/instance/PrimaryInstance.ts +244 -0
- package/src/instance/Root.ts +64 -132
- package/src/instance/SelectField.ts +62 -25
- package/src/instance/Subtree.ts +19 -7
- package/src/instance/{StringField.ts → TriggerControl.ts} +61 -30
- package/src/instance/abstract/DescendantNode.ts +92 -47
- package/src/instance/abstract/InstanceNode.ts +104 -98
- package/src/instance/abstract/UnsupportedControl.ts +174 -0
- package/src/instance/abstract/ValueNode.ts +127 -0
- package/src/instance/children.ts +83 -14
- package/src/instance/hierarchy.ts +36 -14
- package/src/instance/identity.ts +3 -9
- package/src/instance/index.ts +26 -8
- package/src/instance/internal-api/EvaluationContext.ts +61 -14
- package/src/instance/internal-api/InstanceConfig.ts +9 -2
- package/src/instance/internal-api/InstanceValueContext.ts +24 -0
- package/src/instance/internal-api/PrimaryInstanceDocument.ts +53 -0
- package/src/instance/internal-api/TranslationContext.ts +3 -2
- package/src/instance/internal-api/ValidationContext.ts +13 -5
- package/src/instance/internal-api/ValueContext.ts +5 -4
- package/src/instance/internal-api/submission/ClientReactiveSubmittableInstance.ts +20 -0
- package/src/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.ts +42 -0
- package/src/instance/internal-api/submission/ClientReactiveSubmittableParentNode.ts +25 -0
- package/src/instance/internal-api/submission/ClientReactiveSubmittableValueNode.ts +23 -0
- package/src/instance/repeat/BaseRepeatRange.ts +51 -132
- package/src/instance/repeat/RepeatInstance.ts +20 -46
- package/src/instance/repeat/RepeatRangeControlled.ts +6 -6
- package/src/instance/repeat/RepeatRangeUncontrolled.ts +3 -5
- package/src/instance/resource.ts +1 -1
- package/src/instance/text/TextChunk.ts +1 -1
- package/src/instance/unsupported/RangeControl.ts +9 -0
- package/src/instance/unsupported/RankControl.ts +9 -0
- package/src/instance/unsupported/UploadControl.ts +9 -0
- package/src/integration/xpath/EngineXPathEvaluator.ts +22 -0
- package/src/integration/xpath/adapter/XFormsXPathNode.ts +126 -0
- package/src/integration/xpath/adapter/engineDOMAdapter.ts +57 -0
- package/src/integration/xpath/adapter/kind.ts +114 -0
- package/src/integration/xpath/adapter/names.ts +99 -0
- package/src/integration/xpath/adapter/traversal.ts +228 -0
- package/src/integration/xpath/adapter/values.ts +5 -0
- package/src/integration/xpath/static-dom/StaticAttribute.ts +33 -0
- package/src/integration/xpath/static-dom/StaticDocument.ts +38 -0
- package/src/integration/xpath/static-dom/StaticElement.ts +106 -0
- package/src/integration/xpath/static-dom/StaticNamedNode.ts +45 -0
- package/src/integration/xpath/static-dom/StaticNode.ts +68 -0
- package/src/integration/xpath/static-dom/StaticText.ts +28 -0
- package/src/lib/TokenListParser.ts +11 -7
- package/src/lib/client-reactivity/README.md +0 -0
- package/src/lib/client-reactivity/submission/createInstanceSubmissionState.ts +12 -0
- package/src/lib/client-reactivity/submission/createLeafNodeSubmissionState.ts +20 -0
- package/src/lib/client-reactivity/submission/createNodeRangeSubmissionState.ts +17 -0
- package/src/lib/client-reactivity/submission/createParentNodeSubmissionState.ts +22 -0
- package/src/lib/client-reactivity/submission/createValueNodeSubmissionState.ts +21 -0
- package/src/lib/client-reactivity/submission/prepareSubmission.ts +172 -0
- package/src/lib/codecs/DecimalValueCodec.ts +46 -0
- package/src/lib/codecs/IntValueCodec.ts +100 -0
- package/src/lib/codecs/StringValueCodec.ts +11 -0
- package/src/lib/codecs/ValueCodec.ts +106 -0
- package/src/lib/codecs/ValueTypePlaceholderCodec.ts +19 -0
- package/src/lib/codecs/getSharedValueCodec.ts +77 -0
- package/src/lib/dom/query.ts +8 -1
- package/src/lib/reactivity/createChildrenState.ts +8 -6
- package/src/lib/reactivity/createComputedExpression.ts +59 -36
- package/src/lib/reactivity/createInstanceValueState.ts +166 -0
- package/src/lib/reactivity/createNoteReadonlyThunk.ts +12 -7
- package/src/lib/reactivity/createSelectItems.ts +23 -23
- package/src/lib/reactivity/createTranslationState.ts +61 -0
- package/src/lib/reactivity/createValueState.ts +64 -122
- package/src/lib/reactivity/materializeCurrentStateChildren.ts +7 -7
- package/src/lib/reactivity/node-state/createSpecifiedState.ts +1 -1
- package/src/lib/reactivity/text/createFieldHint.ts +1 -1
- package/src/lib/reactivity/text/createNodeLabel.ts +1 -1
- package/src/lib/reactivity/text/createNoteText.ts +1 -1
- package/src/lib/reactivity/text/createTextRange.ts +8 -7
- package/src/lib/reactivity/validation/createAggregatedViolations.ts +9 -4
- package/src/lib/reactivity/validation/createValidation.ts +2 -3
- package/src/lib/xml-serialization.ts +96 -0
- package/src/{XFormDOM.ts → parse/XFormDOM.ts} +110 -75
- package/src/{XFormDefinition.ts → parse/XFormDefinition.ts} +3 -8
- package/src/parse/attachments/FormAttachmentResource.ts +40 -0
- package/src/{body → parse/body}/BodyDefinition.ts +46 -29
- package/src/{body → parse/body}/BodyElementDefinition.ts +12 -6
- package/src/{body → parse/body}/RepeatElementDefinition.ts +7 -5
- package/src/{body → parse/body}/appearance/inputAppearanceParser.ts +2 -2
- package/src/{body → parse/body}/appearance/selectAppearanceParser.ts +1 -1
- package/src/{body → parse/body}/appearance/structureElementAppearanceParser.ts +1 -1
- package/src/parse/body/appearance/unknownAppearanceParser.ts +5 -0
- package/src/{body → parse/body}/control/ControlDefinition.ts +4 -4
- package/src/{body/control/InputDefinition.ts → parse/body/control/InputControlDefinition.ts} +3 -5
- package/src/parse/body/control/RangeControlDefinition.ts +26 -0
- package/src/parse/body/control/RankControlDefinition.ts +27 -0
- package/src/parse/body/control/TriggerControlDefinition.ts +26 -0
- package/src/parse/body/control/UploadControlDefinition.ts +26 -0
- package/src/{body → parse/body}/control/select/ItemDefinition.ts +2 -2
- package/src/{body → parse/body}/control/select/ItemsetDefinition.ts +5 -5
- package/src/{body → parse/body}/control/select/ItemsetNodesetContext.ts +1 -6
- package/src/{body → parse/body}/control/select/SelectDefinition.ts +3 -11
- package/src/{body → parse/body}/group/BaseGroupDefinition.ts +11 -22
- package/src/{body → parse/body}/group/PresentationGroupDefinition.ts +1 -1
- package/src/{model/BindComputation.ts → parse/expression/BindComputationExpression.ts} +8 -8
- package/src/{body/control/select → parse/expression}/ItemsetNodesetExpression.ts +2 -2
- package/src/{body/control/select → parse/expression}/ItemsetValueExpression.ts +2 -2
- package/src/parse/expression/RepeatCountControlExpression.ts +2 -2
- package/src/parse/expression/TextLiteralExpression.ts +19 -0
- package/src/parse/{text/OutputChunkDefinition.ts → expression/TextOutputExpression.ts} +4 -4
- package/src/parse/{text/ReferenceChunkDefinition.ts → expression/TextReferenceExpression.ts} +4 -4
- package/src/parse/{text/TranslationChunkDefinition.ts → expression/TextTranslationExpression.ts} +4 -4
- package/src/{expression → parse/expression/abstract}/DependencyContext.ts +0 -26
- package/src/{expression → parse/expression/abstract}/DependentExpression.ts +5 -16
- package/src/parse/expression/abstract/TextChunkExpression.ts +38 -0
- package/src/parse/model/BindDefinition.ts +104 -0
- package/src/parse/model/BindTypeDefinition.ts +175 -0
- package/src/{model → parse/model}/DescendentNodeDefinition.ts +0 -6
- package/src/parse/model/FormSubmissionDefinition.ts +44 -0
- package/src/parse/model/ItextTranslation/ItextTranslationDefinition.ts +4 -0
- package/src/parse/model/ItextTranslation/ItextTranslationRootDefinition.ts +41 -0
- package/src/parse/model/ItextTranslation/ItextTranslationsDefinition.ts +31 -0
- package/src/{model → parse/model}/LeafNodeDefinition.ts +4 -1
- package/src/{model → parse/model}/ModelBindMap.ts +6 -8
- package/src/parse/model/ModelDefinition.ts +24 -0
- package/src/{model → parse/model}/NodeDefinition.ts +0 -3
- package/src/parse/{NoteNodeDefinition.ts → model/NoteNodeDefinition.ts} +12 -12
- package/src/{model → parse/model}/RepeatRangeDefinition.ts +1 -1
- package/src/{model → parse/model}/RootDefinition.ts +4 -3
- package/src/parse/model/SecondaryInstance/SecondaryInstanceDefinition.ts +4 -0
- package/src/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.ts +12 -0
- package/src/parse/model/SecondaryInstance/SecondaryInstancesDefinition.ts +102 -0
- package/src/parse/model/SecondaryInstance/sources/BlankSecondaryInstanceSource.ts +40 -0
- package/src/parse/model/SecondaryInstance/sources/CSVExternalSecondaryInstance.ts +288 -0
- package/src/parse/model/SecondaryInstance/sources/ExternalSecondaryInstanceResource.ts +222 -0
- package/src/parse/model/SecondaryInstance/sources/ExternalSecondaryInstanceSource.ts +22 -0
- package/src/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.ts +414 -0
- package/src/parse/model/SecondaryInstance/sources/InternalSecondaryInstanceSource.ts +19 -0
- package/src/parse/model/SecondaryInstance/sources/SecondaryInstanceSource.ts +29 -0
- package/src/parse/model/SecondaryInstance/sources/XMLExternalSecondaryInstanceSource.ts +32 -0
- package/src/parse/shared/parseStaticDocumentFromDOMSubtree.ts +149 -0
- package/src/parse/text/HintDefinition.ts +2 -2
- package/src/parse/text/ItemLabelDefinition.ts +2 -2
- package/src/parse/text/ItemsetLabelDefinition.ts +7 -7
- package/src/parse/text/LabelDefinition.ts +5 -5
- package/src/parse/text/MessageDefinition.ts +7 -7
- package/src/parse/text/abstract/TextElementDefinition.ts +14 -14
- package/src/parse/text/abstract/TextRangeDefinition.ts +4 -10
- package/src/parse/xpath/semantic-analysis.ts +29 -0
- package/dist/XFormDOM.d.ts +0 -32
- package/dist/XFormDataType.d.ts +0 -27
- package/dist/body/appearance/inputAppearanceParser.d.ts +0 -4
- package/dist/client/StringNode.d.ts +0 -47
- package/dist/expression/DependencyContext.d.ts +0 -13
- package/dist/instance/StringField.d.ts +0 -45
- package/dist/instance/internal-api/SubscribableDependency.d.ts +0 -60
- package/dist/model/BindDefinition.d.ts +0 -34
- package/dist/parse/text/OutputChunkDefinition.d.ts +0 -8
- package/dist/parse/text/ReferenceChunkDefinition.d.ts +0 -8
- package/dist/parse/text/StaticTextChunkDefinition.d.ts +0 -10
- package/dist/parse/text/TranslationChunkDefinition.d.ts +0 -9
- package/dist/parse/text/abstract/TextChunkDefinition.d.ts +0 -18
- package/src/XFormDataType.ts +0 -64
- package/src/client/StringNode.ts +0 -52
- package/src/instance/internal-api/SubscribableDependency.ts +0 -61
- package/src/model/BindDefinition.ts +0 -106
- package/src/model/ModelDefinition.ts +0 -19
- package/src/parse/TODO.md +0 -3
- package/src/parse/text/StaticTextChunkDefinition.ts +0 -19
- package/src/parse/text/abstract/TextChunkDefinition.ts +0 -38
- /package/dist/{model → parse/model}/BindElement.d.ts +0 -0
- /package/src/{body → parse/body}/UnsupportedBodyElementDefinition.ts +0 -0
- /package/src/{body → parse/body}/group/LogicalGroupDefinition.ts +0 -0
- /package/src/{body → parse/body}/group/StructuralGroupDefinition.ts +0 -0
- /package/src/{model → parse/model}/BindElement.ts +0 -0
- /package/src/{model → parse/model}/RepeatInstanceDefinition.ts +0 -0
- /package/src/{model → parse/model}/RepeatTemplateDefinition.ts +0 -0
- /package/src/{model → parse/model}/SubtreeDefinition.ts +0 -0
|
@@ -80,7 +80,7 @@ export type ComputedPropertySpec<T> = Accessor<T>;
|
|
|
80
80
|
/**
|
|
81
81
|
* @see {@link StaticPropertySpec}
|
|
82
82
|
*/
|
|
83
|
-
// eslint-disable-next-line @typescript-eslint/
|
|
83
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type, @typescript-eslint/no-explicit-any
|
|
84
84
|
type NonStaticValue = Function | Signal<any> | SimpleAtomicState<any>;
|
|
85
85
|
|
|
86
86
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Accessor } from 'solid-js';
|
|
2
2
|
import type { TextRange } from '../../../client/TextRange.ts';
|
|
3
3
|
import type { EvaluationContext } from '../../../instance/internal-api/EvaluationContext.ts';
|
|
4
|
-
import type { LeafNodeDefinition } from '../../../model/LeafNodeDefinition.ts';
|
|
4
|
+
import type { LeafNodeDefinition } from '../../../parse/model/LeafNodeDefinition.ts';
|
|
5
5
|
import { createTextRange } from './createTextRange.ts';
|
|
6
6
|
|
|
7
7
|
export const createFieldHint = (
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Accessor } from 'solid-js';
|
|
2
2
|
import type { TextRange } from '../../../client/TextRange.ts';
|
|
3
3
|
import type { EvaluationContext } from '../../../instance/internal-api/EvaluationContext.ts';
|
|
4
|
-
import type { AnyNodeDefinition } from '../../../model/NodeDefinition.ts';
|
|
4
|
+
import type { AnyNodeDefinition } from '../../../parse/model/NodeDefinition.ts';
|
|
5
5
|
import { createTextRange } from './createTextRange.ts';
|
|
6
6
|
|
|
7
7
|
export const createNodeLabel = (
|
|
@@ -2,7 +2,7 @@ import { UnreachableError } from '@getodk/common/lib/error/UnreachableError.ts';
|
|
|
2
2
|
import type { Accessor } from 'solid-js';
|
|
3
3
|
import type { TextRange } from '../../../client/TextRange.ts';
|
|
4
4
|
import type { EvaluationContext } from '../../../instance/internal-api/EvaluationContext.ts';
|
|
5
|
-
import type { NoteTextDefinition } from '../../../parse/NoteNodeDefinition.ts';
|
|
5
|
+
import type { NoteTextDefinition } from '../../../parse/model/NoteNodeDefinition.ts';
|
|
6
6
|
import { createTextRange } from './createTextRange.ts';
|
|
7
7
|
|
|
8
8
|
// eslint-disable-next-line @typescript-eslint/sort-type-constituents
|
|
@@ -4,7 +4,7 @@ import type { TextChunkSource, TextRole } from '../../../client/TextRange.ts';
|
|
|
4
4
|
import type { EvaluationContext } from '../../../instance/internal-api/EvaluationContext.ts';
|
|
5
5
|
import { TextChunk } from '../../../instance/text/TextChunk.ts';
|
|
6
6
|
import { TextRange } from '../../../instance/text/TextRange.ts';
|
|
7
|
-
import type {
|
|
7
|
+
import type { AnyTextChunkExpression } from '../../../parse/expression/abstract/TextChunkExpression.ts';
|
|
8
8
|
import type { TextRangeDefinition } from '../../../parse/text/abstract/TextRangeDefinition.ts';
|
|
9
9
|
import { createComputedExpression } from '../createComputedExpression.ts';
|
|
10
10
|
|
|
@@ -15,11 +15,11 @@ interface TextChunkComputation {
|
|
|
15
15
|
|
|
16
16
|
const createComputedTextChunk = (
|
|
17
17
|
context: EvaluationContext,
|
|
18
|
-
textSource:
|
|
18
|
+
textSource: AnyTextChunkExpression
|
|
19
19
|
): TextChunkComputation => {
|
|
20
20
|
const { source } = textSource;
|
|
21
21
|
|
|
22
|
-
if (source === '
|
|
22
|
+
if (source === 'literal') {
|
|
23
23
|
const { stringValue } = textSource;
|
|
24
24
|
|
|
25
25
|
return {
|
|
@@ -29,7 +29,9 @@ const createComputedTextChunk = (
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
return context.scope.runTask(() => {
|
|
32
|
-
const getText = createComputedExpression(context, textSource
|
|
32
|
+
const getText = createComputedExpression(context, textSource, {
|
|
33
|
+
defaultValue: '',
|
|
34
|
+
});
|
|
33
35
|
|
|
34
36
|
return {
|
|
35
37
|
source,
|
|
@@ -40,17 +42,16 @@ const createComputedTextChunk = (
|
|
|
40
42
|
|
|
41
43
|
const createTextChunks = (
|
|
42
44
|
context: EvaluationContext,
|
|
43
|
-
textSources: readonly
|
|
45
|
+
textSources: readonly AnyTextChunkExpression[]
|
|
44
46
|
): Accessor<readonly TextChunk[]> => {
|
|
45
47
|
return context.scope.runTask(() => {
|
|
46
|
-
const { root } = context;
|
|
47
48
|
const chunkComputations = textSources.map((textSource) => {
|
|
48
49
|
return createComputedTextChunk(context, textSource);
|
|
49
50
|
});
|
|
50
51
|
|
|
51
52
|
return createMemo(() => {
|
|
52
53
|
return chunkComputations.map(({ source, getText }) => {
|
|
53
|
-
return new TextChunk(
|
|
54
|
+
return new TextChunk(context, source, getText());
|
|
54
55
|
});
|
|
55
56
|
});
|
|
56
57
|
});
|
|
@@ -4,10 +4,11 @@ import type {
|
|
|
4
4
|
AncestorNodeValidationState,
|
|
5
5
|
DescendantNodeViolationReference,
|
|
6
6
|
} from '../../../client/validation.ts';
|
|
7
|
-
import type { AnyParentNode
|
|
7
|
+
import type { AnyParentNode } from '../../../instance/hierarchy.ts';
|
|
8
|
+
import type { ValidationContext } from '../../../instance/internal-api/ValidationContext.ts';
|
|
8
9
|
import { createSharedNodeState } from '../node-state/createSharedNodeState.ts';
|
|
9
10
|
|
|
10
|
-
const violationReference = (node:
|
|
11
|
+
const violationReference = (node: ValidationContext): DescendantNodeViolationReference | null => {
|
|
11
12
|
const violation = node.getViolation();
|
|
12
13
|
|
|
13
14
|
if (violation == null) {
|
|
@@ -31,9 +32,13 @@ const collectViolationReferences = (
|
|
|
31
32
|
return context.getChildren().flatMap((child) => {
|
|
32
33
|
switch (child.nodeType) {
|
|
33
34
|
case 'model-value':
|
|
35
|
+
case 'input':
|
|
34
36
|
case 'note':
|
|
35
|
-
case '
|
|
36
|
-
case '
|
|
37
|
+
case 'select':
|
|
38
|
+
case 'range':
|
|
39
|
+
case 'rank':
|
|
40
|
+
case 'trigger':
|
|
41
|
+
case 'upload': {
|
|
37
42
|
const reference = violationReference(child);
|
|
38
43
|
|
|
39
44
|
if (reference == null) {
|
|
@@ -33,7 +33,7 @@ const engineViolationMessage = <Role extends ValidationTextRole>(
|
|
|
33
33
|
role: Role
|
|
34
34
|
): Accessor<EngineViolationMessage<Role>> => {
|
|
35
35
|
const messageText = VALIDATION_TEXT[role];
|
|
36
|
-
const chunk = new TextChunk(context
|
|
36
|
+
const chunk = new TextChunk(context, 'literal', messageText);
|
|
37
37
|
const message = new TextRange('engine', role, [chunk]);
|
|
38
38
|
|
|
39
39
|
return () => message;
|
|
@@ -75,9 +75,8 @@ const createConstraintValidation = (
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
const isValid = createComputedExpression(context, constraint, {
|
|
78
|
-
|
|
78
|
+
defaultValue: true,
|
|
79
79
|
});
|
|
80
|
-
|
|
81
80
|
const message = createViolationMessage(context, 'constraintMsg', constraintMsg);
|
|
82
81
|
|
|
83
82
|
return createMemo(() => {
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
declare const ESCAPED_XML_TEXT_BRAND: unique symbol;
|
|
2
|
+
|
|
3
|
+
export type EscapedXMLText = string & { readonly [ESCAPED_XML_TEXT_BRAND]: true };
|
|
4
|
+
|
|
5
|
+
const ATTR_REGEX = /[&<>"]/;
|
|
6
|
+
const CONTENT_REGEX = /[&<>]/;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* This is based on the `escapeHTML` implementation in
|
|
10
|
+
* {@link https://github.com/ryansolid/dom-expressions} (Solid's JSX transform).
|
|
11
|
+
*
|
|
12
|
+
* @see {@link https://github.com/ryansolid/dom-expressions/pull/27} for
|
|
13
|
+
* motivation to derive this implementation approach.
|
|
14
|
+
*
|
|
15
|
+
* The intent is that this can be updated easily if the base implementation
|
|
16
|
+
* changes. As such, some aspects of this implementation differ from some of our
|
|
17
|
+
* typical code style preferences.
|
|
18
|
+
*
|
|
19
|
+
* Notable changes from the base implementation:
|
|
20
|
+
*
|
|
21
|
+
* - Formatting: automated only.
|
|
22
|
+
* - Naming: the {@link text} parameter is named `html` in the base
|
|
23
|
+
* implementation. That would be confusing if preserved.
|
|
24
|
+
* - Types:
|
|
25
|
+
* - Parameter types are added (of course)
|
|
26
|
+
* - Return type is branded as {@link EscapedXMLText}, to allow downstream
|
|
27
|
+
* checks that escaping has been performed. Return statements are cast
|
|
28
|
+
* accordingly.
|
|
29
|
+
* - {@link text} attempts to minimize risk of double-escaping by excluding
|
|
30
|
+
* that same branded type.
|
|
31
|
+
* - The '>' character is also escaped, necessary for producing valid XML.
|
|
32
|
+
*
|
|
33
|
+
* As with the base implementation, we leave some characters unescaped:
|
|
34
|
+
*
|
|
35
|
+
* - " (double quote): except when {@link attr} is `true`.
|
|
36
|
+
*
|
|
37
|
+
* - ' (single quote): on the assumption that attributes are always serialized
|
|
38
|
+
* in double quotes. If we ever move this to `@getodk/common`, we'd want to
|
|
39
|
+
* reconsider this assumption.
|
|
40
|
+
*/
|
|
41
|
+
export const escapeXMLText = <Text extends string>(
|
|
42
|
+
text: Exclude<Text, EscapedXMLText>,
|
|
43
|
+
attr?: boolean
|
|
44
|
+
): EscapedXMLText => {
|
|
45
|
+
const match = (attr ? ATTR_REGEX : CONTENT_REGEX).exec(text);
|
|
46
|
+
if (!match) return text as string as EscapedXMLText;
|
|
47
|
+
let index = 0;
|
|
48
|
+
let lastIndex = 0;
|
|
49
|
+
let out = '';
|
|
50
|
+
let escape = '';
|
|
51
|
+
for (index = match.index; index < text.length; index++) {
|
|
52
|
+
switch (text.charCodeAt(index)) {
|
|
53
|
+
case 34: // "
|
|
54
|
+
if (!attr) continue;
|
|
55
|
+
escape = '"';
|
|
56
|
+
break;
|
|
57
|
+
case 38: // &
|
|
58
|
+
escape = '&';
|
|
59
|
+
break;
|
|
60
|
+
case 60: // <
|
|
61
|
+
escape = '<';
|
|
62
|
+
break;
|
|
63
|
+
case 62: // >
|
|
64
|
+
escape = '>';
|
|
65
|
+
break;
|
|
66
|
+
default:
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (lastIndex !== index) out += text.substring(lastIndex, index);
|
|
70
|
+
lastIndex = index + 1;
|
|
71
|
+
out += escape;
|
|
72
|
+
}
|
|
73
|
+
return lastIndex !== index
|
|
74
|
+
? ((out + text.substring(lastIndex, index)) as EscapedXMLText)
|
|
75
|
+
: (out as EscapedXMLText);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const serializeElementXML = (nodeName: string, children: string): string => {
|
|
79
|
+
if (children === '') {
|
|
80
|
+
return `<${nodeName}/>`;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// TODO: attributes
|
|
84
|
+
return `<${nodeName}>${children}</${nodeName}>`;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const serializeParentElementXML = (
|
|
88
|
+
nodeName: string,
|
|
89
|
+
serializedChildren: readonly string[]
|
|
90
|
+
): string => {
|
|
91
|
+
return serializeElementXML(nodeName, serializedChildren.join(''));
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export const serializeLeafElementXML = (nodeName: string, xmlValue: EscapedXMLText): string => {
|
|
95
|
+
return serializeElementXML(nodeName, xmlValue.normalize());
|
|
96
|
+
};
|
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
import { XFORMS_NAMESPACE_URI, XMLNS_NAMESPACE_URI } from '@getodk/common/constants/xmlns.ts';
|
|
2
|
-
import {
|
|
2
|
+
import type {
|
|
3
|
+
KnownAttributeLocalNamedElement,
|
|
4
|
+
LocalNamedElement,
|
|
5
|
+
} from '@getodk/common/types/dom.ts';
|
|
6
|
+
import { DefaultEvaluator } from '@getodk/xpath';
|
|
7
|
+
|
|
8
|
+
interface DOMBindElement extends KnownAttributeLocalNamedElement<'bind', 'nodeset'> {}
|
|
9
|
+
|
|
10
|
+
export interface DOMItextTranslationElement
|
|
11
|
+
extends KnownAttributeLocalNamedElement<'translation', 'lang'> {}
|
|
12
|
+
|
|
13
|
+
interface DOMInstanceElement extends LocalNamedElement<'instance'> {}
|
|
14
|
+
|
|
15
|
+
export interface DOMSecondaryInstanceElement
|
|
16
|
+
extends KnownAttributeLocalNamedElement<'instance', 'id'> {}
|
|
17
|
+
|
|
18
|
+
type AssertDOMSecondaryInstanceElement = (
|
|
19
|
+
element: DOMInstanceElement
|
|
20
|
+
) => asserts element is DOMSecondaryInstanceElement;
|
|
21
|
+
|
|
22
|
+
const assertDOMSecondaryInstanceElement: AssertDOMSecondaryInstanceElement = (element) => {
|
|
23
|
+
if (!element.hasAttribute('id')) {
|
|
24
|
+
throw new Error('Invalid secondary instance element: missing `id` attribute');
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
type AssertDOMSecondaryInstanceElements = (
|
|
29
|
+
elements: readonly DOMInstanceElement[]
|
|
30
|
+
) => asserts elements is readonly DOMSecondaryInstanceElement[];
|
|
31
|
+
|
|
32
|
+
const assertDOMSecondaryInstanceElements: AssertDOMSecondaryInstanceElements = (elements) => {
|
|
33
|
+
elements.forEach(assertDOMSecondaryInstanceElement);
|
|
34
|
+
};
|
|
3
35
|
|
|
4
36
|
const domParser = new DOMParser();
|
|
5
37
|
|
|
@@ -145,61 +177,33 @@ const normalizeRepeatGroups = (body: Element): void => {
|
|
|
145
177
|
}
|
|
146
178
|
};
|
|
147
179
|
|
|
148
|
-
interface NormalizedXForm {
|
|
149
|
-
readonly xformDocument: XMLDocument;
|
|
150
|
-
readonly rootEvaluator: XFormsXPathEvaluator;
|
|
151
|
-
readonly html: Element;
|
|
152
|
-
readonly body: Element;
|
|
153
|
-
readonly normalizedXML: string;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
interface XFormDOMNormalizationOptions {
|
|
157
|
-
readonly isNormalized: boolean;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
180
|
/**
|
|
161
|
-
* Performs preprocess operations to normalize certain aspects of an
|
|
162
|
-
*
|
|
181
|
+
* Performs preprocess operations to normalize certain aspects of the body of an
|
|
182
|
+
* XForm, for consistency when parsing its runtime representations.
|
|
183
|
+
*
|
|
163
184
|
* Currently this preprocessing:
|
|
164
185
|
*
|
|
165
|
-
* - Ensures consistent use of `ref` and `nodeset` where ambiguous in the
|
|
166
|
-
*
|
|
167
|
-
* - Ensures `<repeat>` body elements are always enclosed by a `<group>`
|
|
168
|
-
*
|
|
186
|
+
* - Ensures consistent use of `ref` and `nodeset` where ambiguous in the ODK
|
|
187
|
+
* XForms spec
|
|
188
|
+
* - Ensures `<repeat>` body elements are always enclosed by a `<group>` with
|
|
189
|
+
* the same `ref`
|
|
169
190
|
*/
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
): NormalizedXForm => {
|
|
174
|
-
const xformDocument: XMLDocument = domParser.parseFromString(sourceXML, 'text/xml');
|
|
175
|
-
const rootEvaluator = new XFormsXPathEvaluator({
|
|
176
|
-
rootNode: xformDocument,
|
|
177
|
-
});
|
|
178
|
-
const html = rootEvaluator.evaluateNonNullElement('/h:html');
|
|
179
|
-
const body = rootEvaluator.evaluateNonNullElement('./h:body', {
|
|
180
|
-
contextNode: html,
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
let normalizedXML: string;
|
|
191
|
+
const normalizeXFormBody = <T extends Element>(body: T): T => {
|
|
192
|
+
normalizeBodyRefNodesetAttributes(body);
|
|
193
|
+
normalizeRepeatGroups(body);
|
|
184
194
|
|
|
185
|
-
|
|
186
|
-
normalizedXML = sourceXML;
|
|
187
|
-
} else {
|
|
188
|
-
normalizeBodyRefNodesetAttributes(body);
|
|
189
|
-
normalizeRepeatGroups(body);
|
|
190
|
-
|
|
191
|
-
normalizedXML = html.outerHTML;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
return {
|
|
195
|
-
xformDocument,
|
|
196
|
-
rootEvaluator,
|
|
197
|
-
html,
|
|
198
|
-
body,
|
|
199
|
-
normalizedXML,
|
|
200
|
-
};
|
|
195
|
+
return body;
|
|
201
196
|
};
|
|
202
197
|
|
|
198
|
+
interface XFormDOMOptions {
|
|
199
|
+
readonly isNormalized: boolean;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* @todo **Everything** in this class should be cacheable. Maybe not worth it
|
|
204
|
+
* for small forms, but may make a pretty substantial difference for very large
|
|
205
|
+
* forms (in bytes) in sessions creating multiple instances of the same form.
|
|
206
|
+
*/
|
|
203
207
|
export class XFormDOM {
|
|
204
208
|
static from(sourceXML: string) {
|
|
205
209
|
return new this(sourceXML, { isNormalized: false });
|
|
@@ -207,10 +211,6 @@ export class XFormDOM {
|
|
|
207
211
|
|
|
208
212
|
protected readonly normalizedXML: string;
|
|
209
213
|
|
|
210
|
-
// XPath
|
|
211
|
-
readonly rootEvaluator: XFormsXPathEvaluator;
|
|
212
|
-
readonly primaryInstanceEvaluator: XFormsXPathEvaluator;
|
|
213
|
-
|
|
214
214
|
// Commonly accessed landmark nodes
|
|
215
215
|
readonly xformDocument: XMLDocument;
|
|
216
216
|
|
|
@@ -220,59 +220,94 @@ export class XFormDOM {
|
|
|
220
220
|
readonly title: Element;
|
|
221
221
|
|
|
222
222
|
readonly model: Element;
|
|
223
|
+
readonly binds: readonly DOMBindElement[];
|
|
223
224
|
readonly primaryInstance: Element;
|
|
224
225
|
readonly primaryInstanceRoot: Element;
|
|
225
226
|
|
|
227
|
+
readonly itextTranslationElements: readonly DOMItextTranslationElement[];
|
|
228
|
+
readonly secondaryInstanceElements: readonly DOMSecondaryInstanceElement[];
|
|
229
|
+
|
|
226
230
|
readonly body: Element;
|
|
227
231
|
|
|
228
232
|
protected constructor(
|
|
229
233
|
protected readonly sourceXML: string,
|
|
230
|
-
options:
|
|
234
|
+
options: XFormDOMOptions
|
|
231
235
|
) {
|
|
232
|
-
const
|
|
233
|
-
const
|
|
234
|
-
const
|
|
236
|
+
const evaluator = new DefaultEvaluator();
|
|
237
|
+
const xformDocument: XMLDocument = domParser.parseFromString(sourceXML, 'text/xml');
|
|
238
|
+
const html = evaluator.evaluateNonNullElement('/h:html', {
|
|
239
|
+
contextNode: xformDocument,
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
let body = evaluator.evaluateNonNullElement('./h:body', {
|
|
235
243
|
contextNode: html,
|
|
236
244
|
});
|
|
237
|
-
|
|
245
|
+
let normalizedXML: string;
|
|
246
|
+
|
|
247
|
+
if (options.isNormalized) {
|
|
248
|
+
normalizedXML = sourceXML;
|
|
249
|
+
} else {
|
|
250
|
+
body = normalizeXFormBody(body);
|
|
251
|
+
|
|
252
|
+
// TODO: if we keep doing normalization this way long term (or using the DOM
|
|
253
|
+
// for parsing long term, for that matter!), we should measure this. And we
|
|
254
|
+
// should measure against XMLSerializer while we're at it!
|
|
255
|
+
normalizedXML = xformDocument.documentElement.outerHTML;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const head = evaluator.evaluateNonNullElement('./h:head', {
|
|
259
|
+
contextNode: html,
|
|
260
|
+
});
|
|
261
|
+
const title = evaluator.evaluateNonNullElement('./h:title', {
|
|
238
262
|
contextNode: head,
|
|
239
263
|
});
|
|
240
|
-
const model =
|
|
264
|
+
const model = evaluator.evaluateNonNullElement('./xf:model', {
|
|
241
265
|
contextNode: head,
|
|
242
266
|
});
|
|
243
|
-
|
|
244
|
-
const primaryInstanceRoot = rootEvaluator.evaluateNonNullElement('./xf:instance/*[@id]', {
|
|
267
|
+
const binds = evaluator.evaluateNodes<DOMBindElement>('./xf:bind[@nodeset]', {
|
|
245
268
|
contextNode: model,
|
|
246
269
|
});
|
|
247
|
-
|
|
248
|
-
const
|
|
249
|
-
contextNode:
|
|
270
|
+
|
|
271
|
+
const instances = evaluator.evaluateNodes<DOMInstanceElement>('./xf:instance', {
|
|
272
|
+
contextNode: model,
|
|
250
273
|
});
|
|
251
274
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
275
|
+
const [primaryInstance, ...secondaryInstanceElements] = instances;
|
|
276
|
+
|
|
277
|
+
assertDOMSecondaryInstanceElements(secondaryInstanceElements);
|
|
278
|
+
|
|
279
|
+
if (primaryInstance == null) {
|
|
280
|
+
throw new Error('Form is missing primary instance');
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// TODO: Evidently primary instance root will not always have an id
|
|
284
|
+
const primaryInstanceRoot = evaluator.evaluateNonNullElement('./*[@id]', {
|
|
285
|
+
contextNode: primaryInstance,
|
|
256
286
|
});
|
|
287
|
+
|
|
288
|
+
const itextTranslationElements = evaluator.evaluateNodes<DOMItextTranslationElement>(
|
|
289
|
+
'./xf:itext/xf:translation[@lang]',
|
|
290
|
+
{
|
|
291
|
+
contextNode: model,
|
|
292
|
+
}
|
|
293
|
+
);
|
|
294
|
+
|
|
295
|
+
this.normalizedXML = normalizedXML;
|
|
257
296
|
this.xformDocument = xformDocument;
|
|
258
297
|
this.html = html;
|
|
259
298
|
this.head = head;
|
|
260
299
|
this.title = title;
|
|
261
300
|
this.model = model;
|
|
301
|
+
this.binds = binds;
|
|
262
302
|
this.primaryInstance = primaryInstance;
|
|
263
303
|
this.primaryInstanceRoot = primaryInstanceRoot;
|
|
304
|
+
this.itextTranslationElements = itextTranslationElements;
|
|
305
|
+
this.secondaryInstanceElements = secondaryInstanceElements;
|
|
264
306
|
this.body = body;
|
|
265
307
|
}
|
|
266
308
|
|
|
267
|
-
// TODO: anticipating this will be an entry point for edits as well
|
|
268
|
-
createInstance(): XFormDOM {
|
|
269
|
-
return new XFormDOM(this.normalizedXML, { isNormalized: true });
|
|
270
|
-
}
|
|
271
|
-
|
|
272
309
|
toJSON() {
|
|
273
310
|
const {
|
|
274
|
-
rootEvaluator,
|
|
275
|
-
primaryInstanceEvaluator,
|
|
276
311
|
html,
|
|
277
312
|
head,
|
|
278
313
|
title,
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { BodyDefinition } from './body/BodyDefinition.ts';
|
|
1
|
+
import { BodyDefinition } from '../parse/body/BodyDefinition.ts';
|
|
3
2
|
import { ModelDefinition } from './model/ModelDefinition.ts';
|
|
3
|
+
import { XFormDOM } from './XFormDOM.ts';
|
|
4
4
|
|
|
5
5
|
export class XFormDefinition {
|
|
6
|
-
readonly xformDOM: XFormDOM;
|
|
7
6
|
readonly xformDocument: XMLDocument;
|
|
8
7
|
|
|
9
8
|
readonly id: string;
|
|
@@ -14,11 +13,7 @@ export class XFormDefinition {
|
|
|
14
13
|
readonly body: BodyDefinition;
|
|
15
14
|
readonly model: ModelDefinition;
|
|
16
15
|
|
|
17
|
-
constructor(readonly
|
|
18
|
-
const xformDOM = XFormDOM.from(sourceXML);
|
|
19
|
-
|
|
20
|
-
this.xformDOM = xformDOM;
|
|
21
|
-
|
|
16
|
+
constructor(readonly xformDOM: XFormDOM) {
|
|
22
17
|
const { primaryInstanceRoot, title, xformDocument } = xformDOM;
|
|
23
18
|
const id = primaryInstanceRoot.getAttribute('id');
|
|
24
19
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { JRResourceURL } from '@getodk/common/jr-resources/JRResourceURL.ts';
|
|
2
|
+
|
|
3
|
+
export type FormAttachmentDataType = 'media' | 'secondary-instance';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @todo This type anticipates work to support media form attachments, which
|
|
7
|
+
* will tend to be associated with binary data. The
|
|
8
|
+
* expectation is that:
|
|
9
|
+
*
|
|
10
|
+
* - {@link Blob} would be appropriate for representing data from attachment
|
|
11
|
+
* resources which are conventionally loaded to completion (where network
|
|
12
|
+
* conditions are favorable), such as images
|
|
13
|
+
*
|
|
14
|
+
* - {@link MediaSource} or {@link ReadableStream} may be more appropriate for
|
|
15
|
+
* representing data from resources which are conventionally streamed in a
|
|
16
|
+
* browser context (often regardless of network conditions), such as video and
|
|
17
|
+
* audio
|
|
18
|
+
*/
|
|
19
|
+
// prettier-ignore
|
|
20
|
+
export type FormAttachmentMediaData =
|
|
21
|
+
| Blob
|
|
22
|
+
| MediaSource
|
|
23
|
+
| ReadableStream<unknown>;
|
|
24
|
+
|
|
25
|
+
export type FormAttachmentSecondaryInstanceData = string;
|
|
26
|
+
|
|
27
|
+
// prettier-ignore
|
|
28
|
+
type FormAttachmentData<DataType extends FormAttachmentDataType> =
|
|
29
|
+
DataType extends 'media'
|
|
30
|
+
? FormAttachmentMediaData
|
|
31
|
+
: FormAttachmentSecondaryInstanceData;
|
|
32
|
+
|
|
33
|
+
export abstract class FormAttachmentResource<DataType extends FormAttachmentDataType> {
|
|
34
|
+
protected constructor(
|
|
35
|
+
readonly dataType: DataType,
|
|
36
|
+
readonly resourceURL: JRResourceURL,
|
|
37
|
+
readonly contentType: string,
|
|
38
|
+
readonly data: FormAttachmentData<DataType>
|
|
39
|
+
) {}
|
|
40
|
+
}
|