@getodk/xforms-engine 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/BaseNode.d.ts +69 -4
- package/dist/client/EngineConfig.d.ts +0 -1
- package/dist/client/GroupNode.d.ts +4 -3
- package/dist/client/ModelValueNode.d.ts +36 -0
- package/dist/client/NodeAppearances.d.ts +1 -2
- package/dist/client/NoteNode.d.ts +52 -0
- package/dist/client/RootNode.d.ts +4 -3
- package/dist/client/SelectNode.d.ts +6 -5
- package/dist/client/StringNode.d.ts +6 -5
- package/dist/client/SubtreeNode.d.ts +3 -2
- package/dist/client/TextRange.d.ts +85 -3
- package/dist/client/TriggerNode.d.ts +25 -0
- package/dist/client/constants.d.ts +8 -0
- package/dist/client/hierarchy.d.ts +19 -10
- package/dist/client/index.d.ts +0 -1
- package/dist/client/node-types.d.ts +3 -1
- package/dist/client/{RepeatRangeNode.d.ts → repeat/BaseRepeatRangeNode.d.ts} +18 -18
- package/dist/client/{RepeatInstanceNode.d.ts → repeat/RepeatInstanceNode.d.ts} +9 -9
- package/dist/client/repeat/RepeatRangeControlledNode.d.ts +18 -0
- package/dist/client/repeat/RepeatRangeUncontrolledNode.d.ts +19 -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 +162 -0
- package/dist/index.d.ts +14 -6
- package/dist/index.js +39696 -36151
- package/dist/index.js.map +1 -1
- package/dist/instance/Group.d.ts +3 -2
- package/dist/instance/ModelValue.d.ts +39 -0
- package/dist/instance/Note.d.ts +41 -0
- package/dist/instance/Root.d.ts +5 -4
- package/dist/instance/SelectField.d.ts +11 -6
- package/dist/instance/StringField.d.ts +12 -7
- package/dist/instance/Subtree.d.ts +2 -1
- package/dist/instance/TriggerControl.d.ts +40 -0
- package/dist/instance/abstract/DescendantNode.d.ts +8 -10
- package/dist/instance/abstract/InstanceNode.d.ts +3 -2
- package/dist/instance/abstract/UnsupportedControl.d.ts +46 -0
- package/dist/instance/children.d.ts +0 -1
- package/dist/instance/hierarchy.d.ts +15 -6
- package/dist/instance/index.d.ts +0 -1
- package/dist/instance/internal-api/EvaluationContext.d.ts +0 -1
- package/dist/instance/internal-api/InstanceConfig.d.ts +0 -1
- package/dist/instance/internal-api/SubscribableDependency.d.ts +0 -1
- package/dist/instance/internal-api/TranslationContext.d.ts +0 -1
- package/dist/instance/internal-api/ValidationContext.d.ts +28 -0
- package/dist/instance/internal-api/ValueContext.d.ts +3 -4
- package/dist/instance/{RepeatRange.d.ts → repeat/BaseRepeatRange.d.ts} +46 -46
- package/dist/instance/{RepeatInstance.d.ts → repeat/RepeatInstance.d.ts} +13 -13
- package/dist/instance/repeat/RepeatRangeControlled.d.ts +15 -0
- package/dist/instance/repeat/RepeatRangeUncontrolled.d.ts +34 -0
- package/dist/instance/resource.d.ts +0 -1
- package/dist/instance/text/TextChunk.d.ts +0 -1
- package/dist/instance/text/TextRange.d.ts +4 -5
- package/dist/instance/unsupported/RangeControl.d.ts +4 -0
- package/dist/instance/unsupported/RankControl.d.ts +4 -0
- package/dist/instance/unsupported/UploadControl.d.ts +4 -0
- package/dist/lib/TokenListParser.d.ts +3 -3
- package/dist/lib/dom/query.d.ts +1 -2
- package/dist/lib/reactivity/createChildrenState.d.ts +0 -1
- package/dist/lib/reactivity/createComputedExpression.d.ts +7 -3
- package/dist/lib/reactivity/createNoteReadonlyThunk.d.ts +4 -0
- package/dist/lib/reactivity/createSelectItems.d.ts +0 -1
- package/dist/lib/reactivity/createValueState.d.ts +0 -1
- package/dist/lib/reactivity/materializeCurrentStateChildren.d.ts +0 -1
- 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 +1 -2
- package/dist/lib/reactivity/node-state/createSpecifiedPropertyDescriptor.d.ts +0 -1
- package/dist/lib/reactivity/node-state/createSpecifiedState.d.ts +1 -2
- 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 +3 -4
- package/dist/lib/reactivity/text/createNodeLabel.d.ts +3 -4
- package/dist/lib/reactivity/text/createNoteText.d.ts +24 -0
- package/dist/lib/reactivity/text/createTextRange.d.ts +5 -8
- package/dist/lib/reactivity/types.d.ts +0 -1
- package/dist/lib/reactivity/validation/createAggregatedViolations.d.ts +8 -0
- package/dist/lib/reactivity/validation/createValidation.d.ts +17 -0
- package/dist/{XFormDOM.d.ts → parse/XFormDOM.d.ts} +1 -2
- package/dist/{XFormDataType.d.ts → parse/XFormDataType.d.ts} +2 -4
- package/dist/{XFormDefinition.d.ts → parse/XFormDefinition.d.ts} +2 -3
- package/dist/{body → parse/body}/BodyDefinition.d.ts +15 -10
- package/dist/{body → parse/body}/BodyElementDefinition.d.ts +8 -7
- package/dist/{body → parse/body}/RepeatElementDefinition.d.ts +4 -5
- package/dist/{body → parse/body}/UnsupportedBodyElementDefinition.d.ts +0 -1
- package/dist/{body → parse/body}/appearance/inputAppearanceParser.d.ts +1 -2
- 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 → parse/body}/control/InputDefinition.d.ts +1 -2
- 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 +3 -4
- package/dist/{body → parse/body}/control/select/ItemsetDefinition.d.ts +7 -7
- package/dist/{body → parse/body}/control/select/ItemsetNodesetContext.d.ts +2 -3
- 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 +18 -0
- 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/{expression → parse/expression/abstract}/DependencyContext.d.ts +0 -1
- package/dist/{expression → parse/expression/abstract}/DependentExpression.d.ts +13 -10
- package/dist/parse/expression/abstract/TextChunkExpression.d.ts +17 -0
- package/dist/parse/model/BindDefinition.d.ts +39 -0
- package/dist/{model → parse/model}/BindElement.d.ts +1 -0
- package/dist/{model → parse/model}/DescendentNodeDefinition.d.ts +0 -1
- package/dist/{model/ValueNodeDefinition.d.ts → parse/model/LeafNodeDefinition.d.ts} +3 -4
- package/dist/{model → parse/model}/ModelBindMap.d.ts +0 -1
- package/dist/{model → parse/model}/ModelDefinition.d.ts +1 -2
- package/dist/{model → parse/model}/NodeDefinition.d.ts +8 -9
- package/dist/parse/model/NoteNodeDefinition.d.ts +30 -0
- package/dist/{model → parse/model}/RepeatInstanceDefinition.d.ts +3 -4
- package/dist/{model → parse/model}/RepeatRangeDefinition.d.ts +14 -5
- package/dist/{model → parse/model}/RepeatTemplateDefinition.d.ts +2 -3
- package/dist/{model → parse/model}/RootDefinition.d.ts +2 -3
- package/dist/{model → parse/model}/SubtreeDefinition.d.ts +1 -2
- package/dist/parse/text/HintDefinition.d.ts +8 -0
- package/dist/parse/text/ItemLabelDefinition.d.ts +8 -0
- package/dist/parse/text/ItemsetLabelDefinition.d.ts +12 -0
- package/dist/parse/text/LabelDefinition.d.ts +14 -0
- package/dist/parse/text/MessageDefinition.d.ts +14 -0
- package/dist/parse/text/abstract/TextElementDefinition.d.ts +22 -0
- package/dist/parse/text/abstract/TextRangeDefinition.d.ts +34 -0
- package/dist/parse/xpath/dependency-analysis.d.ts +40 -0
- package/dist/parse/xpath/path-resolution.d.ts +69 -0
- package/dist/parse/xpath/predicate-analysis.d.ts +29 -0
- package/dist/parse/xpath/reference-parsing.d.ts +17 -0
- package/dist/parse/xpath/semantic-analysis.d.ts +97 -0
- package/dist/parse/xpath/syntax-traversal.d.ts +68 -0
- package/dist/solid.js +8745 -5186
- package/dist/solid.js.map +1 -1
- package/package.json +15 -16
- package/src/client/BaseNode.ts +74 -8
- package/src/client/GroupNode.ts +4 -2
- package/src/client/ModelValueNode.ts +40 -0
- package/src/client/NodeAppearances.ts +1 -1
- package/src/client/NoteNode.ts +74 -0
- package/src/client/README.md +1 -0
- package/src/client/RootNode.ts +4 -2
- package/src/client/SelectNode.ts +6 -4
- package/src/client/StringNode.ts +6 -4
- package/src/client/SubtreeNode.ts +3 -1
- package/src/client/TextRange.ts +98 -2
- package/src/client/TriggerNode.ts +29 -0
- package/src/client/constants.ts +10 -0
- package/src/client/hierarchy.ts +43 -15
- package/src/client/node-types.ts +17 -2
- package/src/client/{RepeatRangeNode.ts → repeat/BaseRepeatRangeNode.ts} +18 -19
- package/src/client/{RepeatInstanceNode.ts → repeat/RepeatInstanceNode.ts} +10 -8
- package/src/client/repeat/RepeatRangeControlledNode.ts +20 -0
- package/src/client/repeat/RepeatRangeUncontrolledNode.ts +21 -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 +199 -0
- package/src/index.ts +21 -9
- package/src/instance/Group.ts +10 -4
- package/src/instance/ModelValue.ts +104 -0
- package/src/instance/Note.ts +142 -0
- package/src/instance/Root.ts +16 -6
- package/src/instance/SelectField.ts +29 -7
- package/src/instance/StringField.ts +36 -10
- package/src/instance/Subtree.ts +9 -3
- package/src/instance/TriggerControl.ts +134 -0
- package/src/instance/abstract/DescendantNode.ts +9 -10
- package/src/instance/abstract/InstanceNode.ts +29 -7
- package/src/instance/abstract/UnsupportedControl.ts +151 -0
- package/src/instance/children.ts +113 -16
- package/src/instance/hierarchy.ts +42 -5
- package/src/instance/index.ts +1 -1
- package/src/instance/internal-api/EvaluationContext.ts +1 -1
- package/src/instance/internal-api/ValidationContext.ts +32 -0
- package/src/instance/internal-api/ValueContext.ts +3 -3
- package/src/instance/{RepeatRange.ts → repeat/BaseRepeatRange.ts} +114 -99
- package/src/instance/{RepeatInstance.ts → repeat/RepeatInstance.ts} +27 -22
- package/src/instance/repeat/RepeatRangeControlled.ts +82 -0
- package/src/instance/repeat/RepeatRangeUncontrolled.ts +67 -0
- package/src/instance/text/TextRange.ts +10 -4
- package/src/instance/unsupported/RangeControl.ts +5 -0
- package/src/instance/unsupported/RankControl.ts +5 -0
- package/src/instance/unsupported/UploadControl.ts +5 -0
- package/src/lib/TokenListParser.ts +11 -7
- package/src/lib/dom/query.ts +1 -1
- package/src/lib/reactivity/createComputedExpression.ts +25 -27
- package/src/lib/reactivity/createNoteReadonlyThunk.ts +33 -0
- package/src/lib/reactivity/createSelectItems.ts +23 -16
- package/src/lib/reactivity/createValueState.ts +3 -3
- package/src/lib/reactivity/node-state/createSharedNodeState.ts +1 -1
- package/src/lib/reactivity/node-state/createSpecifiedState.ts +1 -1
- package/src/lib/reactivity/text/createFieldHint.ts +9 -7
- package/src/lib/reactivity/text/createNodeLabel.ts +8 -6
- package/src/lib/reactivity/text/createNoteText.ts +72 -0
- package/src/lib/reactivity/text/createTextRange.ts +17 -90
- package/src/lib/reactivity/validation/createAggregatedViolations.ts +75 -0
- package/src/lib/reactivity/validation/createValidation.ts +196 -0
- package/src/{XFormDataType.ts → parse/XFormDataType.ts} +1 -3
- package/src/{XFormDefinition.ts → parse/XFormDefinition.ts} +2 -2
- package/src/{body → parse/body}/BodyDefinition.ts +44 -27
- package/src/{body → parse/body}/BodyElementDefinition.ts +13 -6
- package/src/{body → parse/body}/RepeatElementDefinition.ts +10 -20
- package/src/{body → parse/body}/appearance/inputAppearanceParser.ts +1 -1
- 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 +5 -4
- 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 +4 -4
- package/src/parse/body/control/select/ItemsetDefinition.ts +53 -0
- package/src/{body → parse/body}/control/select/ItemsetNodesetContext.ts +2 -2
- package/src/{body → parse/body}/control/select/SelectDefinition.ts +3 -11
- package/src/{body → parse/body}/group/BaseGroupDefinition.ts +11 -21
- package/src/{body → parse/body}/group/PresentationGroupDefinition.ts +1 -1
- package/src/{model/BindComputation.ts → parse/expression/BindComputationExpression.ts} +8 -12
- package/src/parse/expression/ItemsetNodesetExpression.ts +8 -0
- package/src/{body/control/select → parse/expression}/ItemsetValueExpression.ts +2 -2
- package/src/parse/expression/RepeatCountControlExpression.ts +44 -0
- package/src/parse/expression/TextLiteralExpression.ts +19 -0
- package/src/parse/expression/TextOutputExpression.ts +25 -0
- package/src/parse/expression/TextReferenceExpression.ts +14 -0
- package/src/parse/expression/TextTranslationExpression.ts +38 -0
- package/src/{expression → parse/expression/abstract}/DependentExpression.ts +46 -28
- package/src/parse/expression/abstract/TextChunkExpression.ts +38 -0
- package/src/{model → parse/model}/BindDefinition.ts +30 -27
- package/src/{model → parse/model}/BindElement.ts +1 -0
- package/src/{model/ValueNodeDefinition.ts → parse/model/LeafNodeDefinition.ts} +4 -4
- package/src/{model → parse/model}/ModelBindMap.ts +4 -0
- package/src/{model → parse/model}/NodeDefinition.ts +12 -12
- package/src/parse/model/NoteNodeDefinition.ts +70 -0
- package/src/{model → parse/model}/RepeatInstanceDefinition.ts +2 -2
- package/src/parse/model/RepeatRangeDefinition.ts +94 -0
- package/src/{model → parse/model}/RootDefinition.ts +8 -4
- package/src/parse/text/HintDefinition.ts +25 -0
- package/src/parse/text/ItemLabelDefinition.ts +25 -0
- package/src/parse/text/ItemsetLabelDefinition.ts +44 -0
- package/src/parse/text/LabelDefinition.ts +61 -0
- package/src/parse/text/MessageDefinition.ts +49 -0
- package/src/parse/text/abstract/TextElementDefinition.ts +71 -0
- package/src/parse/text/abstract/TextRangeDefinition.ts +70 -0
- package/src/parse/xpath/dependency-analysis.ts +105 -0
- package/src/parse/xpath/path-resolution.ts +475 -0
- package/src/parse/xpath/predicate-analysis.ts +61 -0
- package/src/parse/xpath/reference-parsing.ts +90 -0
- package/src/parse/xpath/semantic-analysis.ts +466 -0
- package/src/parse/xpath/syntax-traversal.ts +129 -0
- package/dist/body/text/HintDefinition.d.ts +0 -11
- package/dist/body/text/LabelDefinition.d.ts +0 -22
- package/dist/body/text/TextElementDefinition.d.ts +0 -33
- package/dist/body/text/TextElementOutputPart.d.ts +0 -13
- package/dist/body/text/TextElementPart.d.ts +0 -13
- package/dist/body/text/TextElementReferencePart.d.ts +0 -7
- package/dist/body/text/TextElementStaticPart.d.ts +0 -7
- package/dist/lib/xpath/analysis.d.ts +0 -23
- package/dist/model/BindDefinition.d.ts +0 -32
- package/src/body/control/select/ItemsetDefinition.ts +0 -36
- package/src/body/control/select/ItemsetNodesetExpression.ts +0 -8
- package/src/body/text/HintDefinition.ts +0 -26
- package/src/body/text/LabelDefinition.ts +0 -68
- package/src/body/text/TextElementDefinition.ts +0 -97
- package/src/body/text/TextElementOutputPart.ts +0 -27
- package/src/body/text/TextElementPart.ts +0 -31
- package/src/body/text/TextElementReferencePart.ts +0 -21
- package/src/body/text/TextElementStaticPart.ts +0 -26
- package/src/lib/xpath/analysis.ts +0 -241
- package/src/model/RepeatRangeDefinition.ts +0 -53
- package/src/{XFormDOM.ts → parse/XFormDOM.ts} +0 -0
- package/src/{body → parse/body}/UnsupportedBodyElementDefinition.ts +0 -0
- package/src/{body → parse/body}/control/InputDefinition.ts +1 -1
- /package/src/{body → parse/body}/group/LogicalGroupDefinition.ts +0 -0
- /package/src/{body → parse/body}/group/StructuralGroupDefinition.ts +0 -0
- /package/src/{expression → parse/expression/abstract}/DependencyContext.ts +0 -0
- /package/src/{model → parse/model}/DescendentNodeDefinition.ts +0 -0
- /package/src/{model → parse/model}/ModelDefinition.ts +0 -0
- /package/src/{model → parse/model}/RepeatTemplateDefinition.ts +0 -0
- /package/src/{model → parse/model}/SubtreeDefinition.ts +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { AnyBodyElementDefinition } from '../body/BodyDefinition.ts';
|
|
2
2
|
import type { RepeatElementDefinition } from '../body/RepeatElementDefinition.ts';
|
|
3
3
|
import type { BindDefinition } from './BindDefinition.ts';
|
|
4
|
+
import type { LeafNodeDefinition } from './LeafNodeDefinition.ts';
|
|
4
5
|
import type { RepeatInstanceDefinition } from './RepeatInstanceDefinition.ts';
|
|
5
|
-
import type {
|
|
6
|
+
import type { AnyRepeatRangeDefinition } from './RepeatRangeDefinition.ts';
|
|
6
7
|
import type { RepeatTemplateDefinition } from './RepeatTemplateDefinition.ts';
|
|
7
8
|
import type { RootDefinition } from './RootDefinition.ts';
|
|
8
9
|
import type { SubtreeDefinition } from './SubtreeDefinition.ts';
|
|
9
|
-
import type { ValueNodeDefinition } from './ValueNodeDefinition.ts';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Corresponds to the model/entry DOM root node, i.e.:
|
|
@@ -49,7 +49,7 @@ export type SubtreeNodeType = 'subtree';
|
|
|
49
49
|
* - An element with no child elements
|
|
50
50
|
* - Any attribute corresponding to a bind's `nodeset` expression
|
|
51
51
|
*/
|
|
52
|
-
export type
|
|
52
|
+
export type LeafNodeType = 'leaf-node';
|
|
53
53
|
|
|
54
54
|
// prettier-ignore
|
|
55
55
|
export type NodeDefinitionType =
|
|
@@ -59,7 +59,7 @@ export type NodeDefinitionType =
|
|
|
59
59
|
| RepeatTemplateType
|
|
60
60
|
| RepeatInstanceType
|
|
61
61
|
| SubtreeNodeType
|
|
62
|
-
|
|
|
62
|
+
| LeafNodeType;
|
|
63
63
|
|
|
64
64
|
// prettier-ignore
|
|
65
65
|
export type ParentNodeDefinition =
|
|
@@ -71,9 +71,9 @@ export type ParentNodeDefinition =
|
|
|
71
71
|
|
|
72
72
|
// prettier-ignore
|
|
73
73
|
export type ChildNodeDefinition =
|
|
74
|
-
|
|
|
75
|
-
|
|
|
76
|
-
|
|
|
74
|
+
| AnyRepeatRangeDefinition
|
|
75
|
+
| LeafNodeDefinition
|
|
76
|
+
| SubtreeDefinition;
|
|
77
77
|
|
|
78
78
|
// prettier-ignore
|
|
79
79
|
export type ChildNodeInstanceDefinition =
|
|
@@ -81,7 +81,7 @@ export type ChildNodeInstanceDefinition =
|
|
|
81
81
|
| RepeatTemplateDefinition
|
|
82
82
|
| RepeatInstanceDefinition
|
|
83
83
|
| SubtreeDefinition
|
|
84
|
-
|
|
|
84
|
+
| LeafNodeDefinition;
|
|
85
85
|
|
|
86
86
|
// prettier-ignore
|
|
87
87
|
export type NodeChildren<Type extends NodeDefinitionType> =
|
|
@@ -101,7 +101,7 @@ export type NodeParent<Type extends NodeDefinitionType> =
|
|
|
101
101
|
? ParentNodeDefinition
|
|
102
102
|
: null;
|
|
103
103
|
|
|
104
|
-
// TODO:
|
|
104
|
+
// TODO: leaf-node may be Attr
|
|
105
105
|
// prettier-ignore
|
|
106
106
|
export type ModelNode<Type extends NodeDefinitionType> =
|
|
107
107
|
Type extends 'repeat-range'
|
|
@@ -110,7 +110,7 @@ export type ModelNode<Type extends NodeDefinitionType> =
|
|
|
110
110
|
|
|
111
111
|
// prettier-ignore
|
|
112
112
|
export type NodeDefaultValue<Type extends NodeDefinitionType> =
|
|
113
|
-
Type extends '
|
|
113
|
+
Type extends 'leaf-node'
|
|
114
114
|
? string
|
|
115
115
|
: null;
|
|
116
116
|
|
|
@@ -137,10 +137,10 @@ export interface NodeDefinition<Type extends NodeDefinitionType> {
|
|
|
137
137
|
export type AnyNodeDefinition =
|
|
138
138
|
// eslint-disable-next-line @typescript-eslint/sort-type-constituents
|
|
139
139
|
| RootDefinition
|
|
140
|
-
|
|
|
140
|
+
| AnyRepeatRangeDefinition
|
|
141
141
|
| RepeatTemplateDefinition
|
|
142
142
|
| RepeatInstanceDefinition
|
|
143
143
|
| SubtreeDefinition
|
|
144
|
-
|
|
|
144
|
+
| LeafNodeDefinition;
|
|
145
145
|
|
|
146
146
|
export type TypedNodeDefinition<Type> = Extract<AnyNodeDefinition, { readonly type: Type }>;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { NoteNode } from '../../client/NoteNode.ts';
|
|
2
|
+
import type { AnyBodyElementDefinition } from '../body/BodyDefinition.ts';
|
|
3
|
+
import type { InputDefinition } from '../body/control/InputDefinition.ts';
|
|
4
|
+
import { BindComputationExpression } from '../expression/BindComputationExpression.ts';
|
|
5
|
+
import type { ConstantTruthyDependentExpression } from '../expression/abstract/DependentExpression.ts';
|
|
6
|
+
import type { HintDefinition } from '../text/HintDefinition.ts';
|
|
7
|
+
import type { LabelDefinition } from '../text/LabelDefinition.ts';
|
|
8
|
+
import type { BindDefinition } from './BindDefinition.ts';
|
|
9
|
+
import { LeafNodeDefinition } from './LeafNodeDefinition.ts';
|
|
10
|
+
import type { ParentNodeDefinition } from './NodeDefinition.ts';
|
|
11
|
+
|
|
12
|
+
// prettier-ignore
|
|
13
|
+
export type NoteReadonlyDefinition =
|
|
14
|
+
& BindComputationExpression<'readonly'>
|
|
15
|
+
& ConstantTruthyDependentExpression;
|
|
16
|
+
|
|
17
|
+
export interface NoteBindDefinition extends BindDefinition {
|
|
18
|
+
readonly readonly: NoteReadonlyDefinition;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const isNoteBindDefinition = (bind: BindDefinition): bind is NoteBindDefinition => {
|
|
22
|
+
return bind.readonly.isConstantTruthyExpression();
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// prettier-ignore
|
|
26
|
+
export type NoteTextDefinition =
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/sort-type-constituents
|
|
28
|
+
| LabelDefinition
|
|
29
|
+
| HintDefinition;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @package This class is used internally, both in static types and at runtime,
|
|
33
|
+
* to guard and guide the distinction between instance state nodes for 'note'
|
|
34
|
+
* and 'string' node types. It is intentionally package-private! The less
|
|
35
|
+
* specific {@link NoteNode.definition} type, if it has any client value at all,
|
|
36
|
+
* should be more than sufficient. Clients are otherwise expected to use other
|
|
37
|
+
* aspects of the node's interface (such as its {@link NoteNode.nodeType} and
|
|
38
|
+
* distinct {@link NoteNode.currentState} types) to handle note-specific logic.
|
|
39
|
+
*/
|
|
40
|
+
export class NoteNodeDefinition extends LeafNodeDefinition {
|
|
41
|
+
static from(
|
|
42
|
+
parent: ParentNodeDefinition,
|
|
43
|
+
bind: BindDefinition,
|
|
44
|
+
bodyElement: AnyBodyElementDefinition | null,
|
|
45
|
+
node: Element
|
|
46
|
+
): NoteNodeDefinition | null {
|
|
47
|
+
if (!isNoteBindDefinition(bind) || bodyElement?.type !== 'input') {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const { label, hint } = bodyElement;
|
|
52
|
+
const noteTextDefinition = label ?? hint;
|
|
53
|
+
|
|
54
|
+
if (noteTextDefinition == null) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return new this(parent, bind, bodyElement, noteTextDefinition, node);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
constructor(
|
|
62
|
+
parent: ParentNodeDefinition,
|
|
63
|
+
override readonly bind: NoteBindDefinition,
|
|
64
|
+
override readonly bodyElement: InputDefinition,
|
|
65
|
+
readonly noteTextDefinition: NoteTextDefinition,
|
|
66
|
+
node: Element
|
|
67
|
+
) {
|
|
68
|
+
super(parent, bind, bodyElement, node);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RepeatElementDefinition } from '../body/RepeatElementDefinition.ts';
|
|
2
2
|
import { DescendentNodeDefinition } from './DescendentNodeDefinition.ts';
|
|
3
3
|
import type { ChildNodeDefinition, NodeDefinition } from './NodeDefinition.ts';
|
|
4
|
-
import type {
|
|
4
|
+
import type { AnyRepeatRangeDefinition } from './RepeatRangeDefinition.ts';
|
|
5
5
|
|
|
6
6
|
export class RepeatInstanceDefinition
|
|
7
7
|
extends DescendentNodeDefinition<'repeat-instance', RepeatElementDefinition>
|
|
@@ -15,7 +15,7 @@ export class RepeatInstanceDefinition
|
|
|
15
15
|
readonly defaultValue = null;
|
|
16
16
|
|
|
17
17
|
constructor(
|
|
18
|
-
range:
|
|
18
|
+
range: AnyRepeatRangeDefinition,
|
|
19
19
|
readonly node: Element
|
|
20
20
|
) {
|
|
21
21
|
const { bind, bodyElement, parent, root } = range;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { RepeatElementDefinition } from '../body/RepeatElementDefinition.ts';
|
|
2
|
+
import { RepeatCountControlExpression } from '../expression/RepeatCountControlExpression.ts';
|
|
3
|
+
import type { BindDefinition } from './BindDefinition.ts';
|
|
4
|
+
import { DescendentNodeDefinition } from './DescendentNodeDefinition.ts';
|
|
5
|
+
import type { NodeDefinition, ParentNodeDefinition } from './NodeDefinition.ts';
|
|
6
|
+
import { RepeatInstanceDefinition } from './RepeatInstanceDefinition.ts';
|
|
7
|
+
import { RepeatTemplateDefinition } from './RepeatTemplateDefinition.ts';
|
|
8
|
+
|
|
9
|
+
export interface ControlledRepeatRangeDefinition extends RepeatRangeDefinition {
|
|
10
|
+
readonly count: RepeatCountControlExpression;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface UncontrolledRepeatRangeDefinition extends RepeatRangeDefinition {
|
|
14
|
+
readonly count: null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// prettier-ignore
|
|
18
|
+
export type AnyRepeatRangeDefinition =
|
|
19
|
+
| ControlledRepeatRangeDefinition
|
|
20
|
+
| UncontrolledRepeatRangeDefinition;
|
|
21
|
+
|
|
22
|
+
type AssertRepeatRangeDefinitionUnion = (
|
|
23
|
+
definition: RepeatRangeDefinition
|
|
24
|
+
) => asserts definition is AnyRepeatRangeDefinition;
|
|
25
|
+
|
|
26
|
+
const assertRepeatRangeDefinitionUnion: AssertRepeatRangeDefinitionUnion = (_definition) => {
|
|
27
|
+
// Intentional no-op, used to guide the type checker. Implementation would
|
|
28
|
+
// check _definition.count == null || _definition.count != null, which is
|
|
29
|
+
// tautologically true!
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export class RepeatRangeDefinition
|
|
33
|
+
extends DescendentNodeDefinition<'repeat-range', RepeatElementDefinition>
|
|
34
|
+
implements NodeDefinition<'repeat-range'>
|
|
35
|
+
{
|
|
36
|
+
static from(
|
|
37
|
+
parent: ParentNodeDefinition,
|
|
38
|
+
bind: BindDefinition,
|
|
39
|
+
bodyElement: RepeatElementDefinition,
|
|
40
|
+
modelNodes: readonly [Element, ...Element[]]
|
|
41
|
+
): AnyRepeatRangeDefinition {
|
|
42
|
+
const definition = new this(parent, bind, bodyElement, modelNodes);
|
|
43
|
+
|
|
44
|
+
assertRepeatRangeDefinitionUnion(definition);
|
|
45
|
+
|
|
46
|
+
return definition;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
readonly type = 'repeat-range';
|
|
50
|
+
|
|
51
|
+
readonly template: RepeatTemplateDefinition;
|
|
52
|
+
readonly children = null;
|
|
53
|
+
readonly instances: RepeatInstanceDefinition[];
|
|
54
|
+
readonly count: RepeatCountControlExpression | null;
|
|
55
|
+
|
|
56
|
+
readonly node = null;
|
|
57
|
+
readonly nodeName: string;
|
|
58
|
+
readonly defaultValue = null;
|
|
59
|
+
|
|
60
|
+
private constructor(
|
|
61
|
+
parent: ParentNodeDefinition,
|
|
62
|
+
bind: BindDefinition,
|
|
63
|
+
bodyElement: RepeatElementDefinition,
|
|
64
|
+
modelNodes: readonly [Element, ...Element[]]
|
|
65
|
+
) {
|
|
66
|
+
super(parent, bind, bodyElement);
|
|
67
|
+
|
|
68
|
+
const { template, instanceNodes } = RepeatTemplateDefinition.parseModelNodes(this, modelNodes);
|
|
69
|
+
|
|
70
|
+
this.template = template;
|
|
71
|
+
this.nodeName = template.nodeName;
|
|
72
|
+
this.count = RepeatCountControlExpression.from(bodyElement, instanceNodes.length);
|
|
73
|
+
|
|
74
|
+
assertRepeatRangeDefinitionUnion(this);
|
|
75
|
+
|
|
76
|
+
this.instances = instanceNodes.map((element) => {
|
|
77
|
+
return new RepeatInstanceDefinition(this, element);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
isControlled(): this is ControlledRepeatRangeDefinition {
|
|
82
|
+
return this.count != null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
isUncontrolled(): this is UncontrolledRepeatRangeDefinition {
|
|
86
|
+
return this.count == null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
toJSON() {
|
|
90
|
+
const { bind, bodyElement: groupDefinition, parent, root, ...rest } = this;
|
|
91
|
+
|
|
92
|
+
return rest;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import type { XFormDefinition } from '../XFormDefinition.ts';
|
|
2
1
|
import type { BodyClassList } from '../body/BodyDefinition.ts';
|
|
2
|
+
import type { XFormDefinition } from '../XFormDefinition.ts';
|
|
3
3
|
import type { BindDefinition } from './BindDefinition.ts';
|
|
4
|
+
import { LeafNodeDefinition } from './LeafNodeDefinition.ts';
|
|
4
5
|
import type { ModelDefinition } from './ModelDefinition.ts';
|
|
5
6
|
import type {
|
|
6
7
|
ChildNodeDefinition,
|
|
7
8
|
NodeDefinition,
|
|
8
9
|
ParentNodeDefinition,
|
|
9
10
|
} from './NodeDefinition.ts';
|
|
11
|
+
import { NoteNodeDefinition } from './NoteNodeDefinition.ts';
|
|
10
12
|
import { RepeatRangeDefinition } from './RepeatRangeDefinition.ts';
|
|
11
13
|
import { SubtreeDefinition } from './SubtreeDefinition.ts';
|
|
12
|
-
import { ValueNodeDefinition } from './ValueNodeDefinition.ts';
|
|
13
14
|
|
|
14
15
|
export class RootDefinition implements NodeDefinition<'root'> {
|
|
15
16
|
readonly type = 'root';
|
|
@@ -89,7 +90,7 @@ export class RootDefinition implements NodeDefinition<'root'> {
|
|
|
89
90
|
const [firstChild, ...restChildren] = children;
|
|
90
91
|
|
|
91
92
|
if (bodyElement?.type === 'repeat') {
|
|
92
|
-
return
|
|
93
|
+
return RepeatRangeDefinition.from(parent, bind, bodyElement, children);
|
|
93
94
|
}
|
|
94
95
|
|
|
95
96
|
if (restChildren.length) {
|
|
@@ -100,7 +101,10 @@ export class RootDefinition implements NodeDefinition<'root'> {
|
|
|
100
101
|
const isLeafNode = element.childElementCount === 0;
|
|
101
102
|
|
|
102
103
|
if (isLeafNode) {
|
|
103
|
-
return
|
|
104
|
+
return (
|
|
105
|
+
NoteNodeDefinition.from(parent, bind, bodyElement, element) ??
|
|
106
|
+
new LeafNodeDefinition(parent, bind, bodyElement, element)
|
|
107
|
+
);
|
|
104
108
|
}
|
|
105
109
|
|
|
106
110
|
return new SubtreeDefinition(parent, bind, bodyElement, element);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { LocalNamedElement } from '@getodk/common/types/dom.ts';
|
|
2
|
+
import { getHintElement } from '../../lib/dom/query.ts';
|
|
3
|
+
import type { XFormDefinition } from '../../parse/XFormDefinition.ts';
|
|
4
|
+
import type { AnyControlDefinition } from '../body/control/ControlDefinition.ts';
|
|
5
|
+
import { TextElementDefinition } from './abstract/TextElementDefinition.ts';
|
|
6
|
+
|
|
7
|
+
interface HintElement extends LocalNamedElement<'hint'> {}
|
|
8
|
+
|
|
9
|
+
export class HintDefinition extends TextElementDefinition<'hint'> {
|
|
10
|
+
static forElement(form: XFormDefinition, owner: AnyControlDefinition): HintDefinition | null {
|
|
11
|
+
const hintElement = getHintElement(owner.element);
|
|
12
|
+
|
|
13
|
+
if (hintElement == null) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return new this(form, owner, hintElement);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
readonly role = 'hint';
|
|
21
|
+
|
|
22
|
+
private constructor(form: XFormDefinition, owner: AnyControlDefinition, element: HintElement) {
|
|
23
|
+
super(form, owner, element);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { LocalNamedElement } from '@getodk/common/types/dom.ts';
|
|
2
|
+
import { getLabelElement } from '../../lib/dom/query.ts';
|
|
3
|
+
import type { XFormDefinition } from '../../parse/XFormDefinition.ts';
|
|
4
|
+
import type { ItemDefinition } from '../body/control/select/ItemDefinition.ts';
|
|
5
|
+
import { TextElementDefinition } from './abstract/TextElementDefinition.ts';
|
|
6
|
+
|
|
7
|
+
interface LabelElement extends LocalNamedElement<'label'> {}
|
|
8
|
+
|
|
9
|
+
export class ItemLabelDefinition extends TextElementDefinition<'item-label'> {
|
|
10
|
+
static from(form: XFormDefinition, owner: ItemDefinition): ItemLabelDefinition | null {
|
|
11
|
+
const labelElement = getLabelElement(owner.element);
|
|
12
|
+
|
|
13
|
+
if (labelElement == null) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return new this(form, owner, labelElement);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
readonly role = 'item-label';
|
|
21
|
+
|
|
22
|
+
private constructor(form: XFormDefinition, owner: ItemDefinition, element: LabelElement) {
|
|
23
|
+
super(form, owner, element);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { LocalNamedElement } from '@getodk/common/types/dom.ts';
|
|
2
|
+
import { getLabelElement } from '../../lib/dom/query.ts';
|
|
3
|
+
import type { XFormDefinition } from '../../parse/XFormDefinition.ts';
|
|
4
|
+
import type { ItemDefinition } from '../body/control/select/ItemDefinition.ts';
|
|
5
|
+
import type { ItemsetDefinition } from '../body/control/select/ItemsetDefinition.ts';
|
|
6
|
+
import { TextReferenceExpression } from '../expression/TextReferenceExpression.ts';
|
|
7
|
+
import { TextTranslationExpression } from '../expression/TextTranslationExpression.ts';
|
|
8
|
+
import type { RefAttributeChunk } from './abstract/TextElementDefinition.ts';
|
|
9
|
+
import { TextRangeDefinition } from './abstract/TextRangeDefinition.ts';
|
|
10
|
+
|
|
11
|
+
export type ItemLabelOwner = ItemDefinition | ItemsetDefinition;
|
|
12
|
+
|
|
13
|
+
interface LabelElement extends LocalNamedElement<'label'> {}
|
|
14
|
+
|
|
15
|
+
export class ItemsetLabelDefinition extends TextRangeDefinition<'item-label'> {
|
|
16
|
+
static from(form: XFormDefinition, owner: ItemsetDefinition): ItemsetLabelDefinition | null {
|
|
17
|
+
const labelElement = getLabelElement(owner.element);
|
|
18
|
+
|
|
19
|
+
if (labelElement == null) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return new this(form, owner, labelElement);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
readonly role = 'item-label';
|
|
27
|
+
readonly chunks: readonly [RefAttributeChunk];
|
|
28
|
+
|
|
29
|
+
private constructor(form: XFormDefinition, owner: ItemsetDefinition, element: LabelElement) {
|
|
30
|
+
super(form, owner, element);
|
|
31
|
+
|
|
32
|
+
const refExpression = element.getAttribute('ref');
|
|
33
|
+
|
|
34
|
+
if (refExpression == null) {
|
|
35
|
+
throw new Error('<itemset><label> missing ref attribute');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const refChunk =
|
|
39
|
+
TextTranslationExpression.from(this, refExpression) ??
|
|
40
|
+
TextReferenceExpression.from(this, refExpression);
|
|
41
|
+
|
|
42
|
+
this.chunks = [refChunk];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { LocalNamedElement } from '@getodk/common/types/dom.ts';
|
|
2
|
+
import { getLabelElement, getRepeatGroupLabelElement } from '../../lib/dom/query.ts';
|
|
3
|
+
import type { XFormDefinition } from '../../parse/XFormDefinition.ts';
|
|
4
|
+
import type { AnyGroupElementDefinition } from '../../parse/body/BodyDefinition.ts';
|
|
5
|
+
import type { RepeatElementDefinition } from '../body/RepeatElementDefinition.ts';
|
|
6
|
+
import type { AnyControlDefinition } from '../body/control/ControlDefinition.ts';
|
|
7
|
+
import type { BaseGroupDefinition } from '../body/group/BaseGroupDefinition.ts';
|
|
8
|
+
import { TextElementDefinition } from './abstract/TextElementDefinition.ts';
|
|
9
|
+
|
|
10
|
+
// prettier-ignore
|
|
11
|
+
export type LabelOwner =
|
|
12
|
+
| AnyControlDefinition
|
|
13
|
+
| AnyGroupElementDefinition
|
|
14
|
+
| RepeatElementDefinition;
|
|
15
|
+
|
|
16
|
+
interface LabelElement extends LocalNamedElement<'label'> {}
|
|
17
|
+
|
|
18
|
+
export class LabelDefinition extends TextElementDefinition<'label'> {
|
|
19
|
+
static forControl(form: XFormDefinition, control: AnyControlDefinition): LabelDefinition | null {
|
|
20
|
+
const labelElement = getLabelElement(control.element);
|
|
21
|
+
|
|
22
|
+
if (labelElement == null) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return new this(form, control, labelElement);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static forRepeatGroup(
|
|
30
|
+
form: XFormDefinition,
|
|
31
|
+
repeat: RepeatElementDefinition
|
|
32
|
+
): LabelDefinition | null {
|
|
33
|
+
const repeatGroupLabel = getRepeatGroupLabelElement(repeat.element);
|
|
34
|
+
|
|
35
|
+
if (repeatGroupLabel == null) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return new this(form, repeat, repeatGroupLabel);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static forGroup(
|
|
43
|
+
form: XFormDefinition,
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
|
+
group: BaseGroupDefinition<any>
|
|
46
|
+
): LabelDefinition | null {
|
|
47
|
+
const labelElement = getLabelElement(group.element);
|
|
48
|
+
|
|
49
|
+
if (labelElement == null) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return new this(form, group, labelElement);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
readonly role = 'label';
|
|
57
|
+
|
|
58
|
+
private constructor(form: XFormDefinition, owner: LabelOwner, element: LabelElement) {
|
|
59
|
+
super(form, owner, element);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { JAVAROSA_NAMESPACE_URI } from '@getodk/common/constants/xmlns.ts';
|
|
2
|
+
import { TextLiteralExpression } from '../expression/TextLiteralExpression.ts';
|
|
3
|
+
import { TextTranslationExpression } from '../expression/TextTranslationExpression.ts';
|
|
4
|
+
import type { BindDefinition } from '../model/BindDefinition.ts';
|
|
5
|
+
import type { TextBindAttributeLocalName, TextSourceNode } from './abstract/TextRangeDefinition.ts';
|
|
6
|
+
import { TextRangeDefinition } from './abstract/TextRangeDefinition.ts';
|
|
7
|
+
|
|
8
|
+
export type MessageSourceNode = TextSourceNode<TextBindAttributeLocalName>;
|
|
9
|
+
|
|
10
|
+
// prettier-ignore
|
|
11
|
+
type MessageChunk =
|
|
12
|
+
| TextLiteralExpression
|
|
13
|
+
| TextTranslationExpression;
|
|
14
|
+
|
|
15
|
+
export class MessageDefinition<
|
|
16
|
+
Type extends TextBindAttributeLocalName,
|
|
17
|
+
> extends TextRangeDefinition<Type> {
|
|
18
|
+
static from<Type extends TextBindAttributeLocalName>(
|
|
19
|
+
bind: BindDefinition,
|
|
20
|
+
type: Type
|
|
21
|
+
): MessageDefinition<Type> | null {
|
|
22
|
+
const message = bind.bindElement.getAttributeNS(JAVAROSA_NAMESPACE_URI, type);
|
|
23
|
+
|
|
24
|
+
if (message == null) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return new this(bind, type, message);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
readonly chunks: readonly [MessageChunk];
|
|
32
|
+
|
|
33
|
+
private constructor(
|
|
34
|
+
bind: BindDefinition,
|
|
35
|
+
readonly role: Type,
|
|
36
|
+
message: string
|
|
37
|
+
) {
|
|
38
|
+
super(bind.form, bind, null);
|
|
39
|
+
|
|
40
|
+
const chunk: MessageChunk =
|
|
41
|
+
TextTranslationExpression.fromMessage(this, message) ??
|
|
42
|
+
TextLiteralExpression.from(this, message);
|
|
43
|
+
|
|
44
|
+
this.chunks = [chunk];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// prettier-ignore
|
|
49
|
+
export type AnyMessageDefinition = MessageDefinition<TextBindAttributeLocalName>;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { isElementNode, isTextNode } from '@getodk/common/lib/dom/predicates.ts';
|
|
2
|
+
import type { ElementTextRole } from '../../../client/TextRange.ts';
|
|
3
|
+
import type { XFormDefinition } from '../../../parse/XFormDefinition.ts';
|
|
4
|
+
import type { ItemDefinition } from '../../body/control/select/ItemDefinition.ts';
|
|
5
|
+
import { TextLiteralExpression } from '../../expression/TextLiteralExpression.ts';
|
|
6
|
+
import { TextOutputExpression } from '../../expression/TextOutputExpression.ts';
|
|
7
|
+
import { TextReferenceExpression } from '../../expression/TextReferenceExpression.ts';
|
|
8
|
+
import { TextTranslationExpression } from '../../expression/TextTranslationExpression.ts';
|
|
9
|
+
import { parseNodesetReference } from '../../xpath/reference-parsing.ts';
|
|
10
|
+
import type { HintDefinition } from '../HintDefinition.ts';
|
|
11
|
+
import type { ItemLabelDefinition } from '../ItemLabelDefinition.ts';
|
|
12
|
+
import type { ItemsetLabelDefinition } from '../ItemsetLabelDefinition.ts';
|
|
13
|
+
import type { LabelDefinition, LabelOwner } from '../LabelDefinition.ts';
|
|
14
|
+
import type { TextSourceNode } from './TextRangeDefinition.ts';
|
|
15
|
+
import { TextRangeDefinition } from './TextRangeDefinition.ts';
|
|
16
|
+
|
|
17
|
+
// prettier-ignore
|
|
18
|
+
export type RefAttributeChunk =
|
|
19
|
+
| TextReferenceExpression
|
|
20
|
+
| TextTranslationExpression;
|
|
21
|
+
|
|
22
|
+
// prettier-ignore
|
|
23
|
+
type TextElementChildChunk =
|
|
24
|
+
| TextOutputExpression
|
|
25
|
+
| TextLiteralExpression;
|
|
26
|
+
|
|
27
|
+
// prettier-ignore
|
|
28
|
+
type TextElementChunks =
|
|
29
|
+
| readonly [RefAttributeChunk]
|
|
30
|
+
| readonly TextElementChildChunk[];
|
|
31
|
+
|
|
32
|
+
type TextElementOwner = ItemDefinition | LabelOwner;
|
|
33
|
+
|
|
34
|
+
export abstract class TextElementDefinition<
|
|
35
|
+
Role extends ElementTextRole,
|
|
36
|
+
> extends TextRangeDefinition<Role> {
|
|
37
|
+
readonly chunks: TextElementChunks;
|
|
38
|
+
|
|
39
|
+
constructor(form: XFormDefinition, owner: TextElementOwner, sourceNode: TextSourceNode<Role>) {
|
|
40
|
+
super(form, owner, sourceNode);
|
|
41
|
+
|
|
42
|
+
const context = this as AnyTextElementDefinition;
|
|
43
|
+
const refExpression = parseNodesetReference(owner, sourceNode, 'ref');
|
|
44
|
+
|
|
45
|
+
if (refExpression == null) {
|
|
46
|
+
this.chunks = Array.from(sourceNode.childNodes).flatMap((childNode) => {
|
|
47
|
+
if (isElementNode(childNode)) {
|
|
48
|
+
return TextOutputExpression.from(context, childNode) ?? [];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (isTextNode(childNode)) {
|
|
52
|
+
return TextLiteralExpression.from(context, childNode.data);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return [];
|
|
56
|
+
});
|
|
57
|
+
} else {
|
|
58
|
+
const refChunk =
|
|
59
|
+
TextTranslationExpression.from(context, refExpression) ??
|
|
60
|
+
TextReferenceExpression.from(context, refExpression);
|
|
61
|
+
this.chunks = [refChunk];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// prettier-ignore
|
|
67
|
+
export type AnyTextElementDefinition =
|
|
68
|
+
| HintDefinition
|
|
69
|
+
| ItemLabelDefinition
|
|
70
|
+
| ItemsetLabelDefinition
|
|
71
|
+
| LabelDefinition;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { LocalNamedElement } from '@getodk/common/types/dom.ts';
|
|
2
|
+
import type { TextRole } from '../../../client/TextRange.ts';
|
|
3
|
+
import type { XFormDefinition } from '../../../parse/XFormDefinition.ts';
|
|
4
|
+
import { DependencyContext } from '../../expression/abstract/DependencyContext.ts';
|
|
5
|
+
import type { AnyDependentExpression } from '../../expression/abstract/DependentExpression.ts';
|
|
6
|
+
import type { AnyTextChunkExpression } from '../../expression/abstract/TextChunkExpression.ts';
|
|
7
|
+
import type { AnyMessageDefinition } from '../MessageDefinition.ts';
|
|
8
|
+
import type { AnyTextElementDefinition } from './TextElementDefinition.ts';
|
|
9
|
+
|
|
10
|
+
export type TextBindAttributeLocalName = 'constraintMsg' | 'requiredMsg';
|
|
11
|
+
export type TextBodyElementLocalName = 'hint' | 'label';
|
|
12
|
+
|
|
13
|
+
interface TextSourceNodes {
|
|
14
|
+
readonly constraintMsg: null;
|
|
15
|
+
readonly hint: LocalNamedElement<'hint'>;
|
|
16
|
+
readonly label: LocalNamedElement<'label'>;
|
|
17
|
+
readonly 'item-label': LocalNamedElement<'label'>;
|
|
18
|
+
readonly requiredMsg: null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type TextSourceNode<Type extends TextRole> = TextSourceNodes[Type];
|
|
22
|
+
|
|
23
|
+
export abstract class TextRangeDefinition<Role extends TextRole> extends DependencyContext {
|
|
24
|
+
abstract readonly role: Role;
|
|
25
|
+
readonly parentReference: string | null;
|
|
26
|
+
readonly reference: string | null;
|
|
27
|
+
|
|
28
|
+
abstract readonly chunks: readonly AnyTextChunkExpression[];
|
|
29
|
+
|
|
30
|
+
override get isTranslated(): boolean {
|
|
31
|
+
return (
|
|
32
|
+
this.ownerContext.isTranslated || this.chunks.some((chunk) => chunk.source === 'translation')
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
override set isTranslated(value: true) {
|
|
37
|
+
if (this.ownerContext != null) {
|
|
38
|
+
this.ownerContext.isTranslated = value;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
super.isTranslated = value;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
protected constructor(
|
|
45
|
+
readonly form: XFormDefinition,
|
|
46
|
+
readonly ownerContext: DependencyContext,
|
|
47
|
+
readonly sourceNode: TextSourceNode<Role>
|
|
48
|
+
) {
|
|
49
|
+
super();
|
|
50
|
+
|
|
51
|
+
this.reference = ownerContext.reference;
|
|
52
|
+
this.parentReference = ownerContext.parentReference;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
override registerDependentExpression(expression: AnyDependentExpression): void {
|
|
56
|
+
this.ownerContext.registerDependentExpression(expression);
|
|
57
|
+
super.registerDependentExpression(expression);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
toJSON(): object {
|
|
61
|
+
const { form, ownerContext, ...rest } = this;
|
|
62
|
+
|
|
63
|
+
return rest;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// prettier-ignore
|
|
68
|
+
export type AnyTextRangeDefinition =
|
|
69
|
+
| AnyMessageDefinition
|
|
70
|
+
| AnyTextElementDefinition;
|