@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
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { getValueElement, type ItemsetElement } from '../../../../lib/dom/query.ts';
|
|
2
|
+
import { ItemsetNodesetExpression } from '../../../expression/ItemsetNodesetExpression.ts';
|
|
3
|
+
import { ItemsetValueExpression } from '../../../expression/ItemsetValueExpression.ts';
|
|
4
|
+
import { ItemsetLabelDefinition } from '../../../text/ItemsetLabelDefinition.ts';
|
|
5
|
+
import type { XFormDefinition } from '../../../XFormDefinition.ts';
|
|
6
|
+
import { parseNodesetReference } from '../../../xpath/reference-parsing.ts';
|
|
7
|
+
import { BodyElementDefinition } from '../../BodyElementDefinition.ts';
|
|
8
|
+
import type { AnySelectDefinition } from './SelectDefinition.ts';
|
|
9
|
+
|
|
10
|
+
export class ItemsetDefinition extends BodyElementDefinition<'itemset'> {
|
|
11
|
+
override readonly category = 'support';
|
|
12
|
+
readonly type = 'itemset';
|
|
13
|
+
|
|
14
|
+
override readonly reference: string;
|
|
15
|
+
override readonly label: ItemsetLabelDefinition | null;
|
|
16
|
+
|
|
17
|
+
readonly nodes: ItemsetNodesetExpression;
|
|
18
|
+
readonly value: ItemsetValueExpression;
|
|
19
|
+
|
|
20
|
+
constructor(
|
|
21
|
+
form: XFormDefinition,
|
|
22
|
+
override readonly parent: AnySelectDefinition,
|
|
23
|
+
element: ItemsetElement
|
|
24
|
+
) {
|
|
25
|
+
super(form, parent, element);
|
|
26
|
+
|
|
27
|
+
const nodesetExpression = parseNodesetReference(parent, element, 'nodeset');
|
|
28
|
+
|
|
29
|
+
this.nodes = new ItemsetNodesetExpression(this, nodesetExpression);
|
|
30
|
+
this.reference = nodesetExpression;
|
|
31
|
+
|
|
32
|
+
const valueElement = getValueElement(element);
|
|
33
|
+
|
|
34
|
+
if (valueElement == null) {
|
|
35
|
+
throw new Error('<itemset> has no <value>');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const valueExpression = parseNodesetReference(
|
|
39
|
+
{
|
|
40
|
+
reference: null,
|
|
41
|
+
},
|
|
42
|
+
valueElement,
|
|
43
|
+
'ref'
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
if (valueExpression == null) {
|
|
47
|
+
throw new Error(`<itemset> has no <value>`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
this.value = new ItemsetValueExpression(this, valueExpression);
|
|
51
|
+
this.label = ItemsetLabelDefinition.from(form, this);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { DependencyContext } from '../../../expression/DependencyContext.ts';
|
|
2
|
-
import type { AnyDependentExpression } from '../../../expression/DependentExpression.ts';
|
|
1
|
+
import { DependencyContext } from '../../../expression/abstract/DependencyContext.ts';
|
|
2
|
+
import type { AnyDependentExpression } from '../../../expression/abstract/DependentExpression.ts';
|
|
3
3
|
import type { ItemsetDefinition } from './ItemsetDefinition.ts';
|
|
4
4
|
|
|
5
5
|
export class ItemsetNodesetContext extends DependencyContext {
|
|
@@ -1,23 +1,15 @@
|
|
|
1
1
|
import type { CollectionValues } from '@getodk/common/types/collections/CollectionValues.ts';
|
|
2
2
|
import type { LocalNamedElement } from '@getodk/common/types/dom.ts';
|
|
3
|
+
import { getItemElements, getItemsetElement } from '../../../../lib/dom/query.ts';
|
|
3
4
|
import type { XFormDefinition } from '../../../XFormDefinition.ts';
|
|
4
|
-
import { getItemElements, getItemsetElement } from '../../../lib/dom/query.ts';
|
|
5
|
-
import type { AnyBodyElementDefinition, BodyElementParentContext } from '../../BodyDefinition.ts';
|
|
6
5
|
import type { SelectAppearanceDefinition } from '../../appearance/selectAppearanceParser.ts';
|
|
7
6
|
import { selectAppearanceParser } from '../../appearance/selectAppearanceParser.ts';
|
|
7
|
+
import type { AnyBodyElementDefinition, BodyElementParentContext } from '../../BodyDefinition.ts';
|
|
8
8
|
import { ControlDefinition } from '../ControlDefinition.ts';
|
|
9
9
|
import { ItemDefinition } from './ItemDefinition.ts';
|
|
10
10
|
import { ItemsetDefinition } from './ItemsetDefinition.ts';
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
* @todo We were previously a bit overzealous about introducing `<rank>` support
|
|
14
|
-
* here. It'll likely still fit, but we should approach it with more intention.
|
|
15
|
-
*
|
|
16
|
-
* @todo `<trigger>` is *almost* reasonable to support here too. The main
|
|
17
|
-
* hesitation is that its single, implicit "item" does not have a distinct
|
|
18
|
-
* <label>, and presumably has different UX **and translation** considerations.
|
|
19
|
-
*/
|
|
20
|
-
const selectLocalNames = new Set([/* 'rank', */ 'select', 'select1'] as const);
|
|
12
|
+
const selectLocalNames = new Set(['select', 'select1'] as const);
|
|
21
13
|
|
|
22
14
|
export type SelectType = CollectionValues<typeof selectLocalNames>;
|
|
23
15
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { UpsertableMap } from '@getodk/common/lib/collections/UpsertableMap.ts';
|
|
2
|
+
import { getLabelElement } from '../../../lib/dom/query.ts';
|
|
3
|
+
import { LabelDefinition } from '../../text/LabelDefinition.ts';
|
|
2
4
|
import type { XFormDefinition } from '../../XFormDefinition.ts';
|
|
3
|
-
import {
|
|
5
|
+
import { parseNodesetReference } from '../../xpath/reference-parsing.ts';
|
|
6
|
+
import type { StructureElementAppearanceDefinition } from '../appearance/structureElementAppearanceParser.ts';
|
|
7
|
+
import { structureElementAppearanceParser } from '../appearance/structureElementAppearanceParser.ts';
|
|
4
8
|
import {
|
|
5
|
-
BodyDefinition,
|
|
6
9
|
type BodyElementDefinitionArray,
|
|
7
10
|
type BodyElementParentContext,
|
|
8
11
|
} from '../BodyDefinition.ts';
|
|
9
12
|
import { BodyElementDefinition } from '../BodyElementDefinition.ts';
|
|
10
|
-
import type { StructureElementAppearanceDefinition } from '../appearance/structureElementAppearanceParser.ts';
|
|
11
|
-
import { structureElementAppearanceParser } from '../appearance/structureElementAppearanceParser.ts';
|
|
12
|
-
import { LabelDefinition } from '../text/LabelDefinition.ts';
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* These type names are derived from **and expand upon** the language used in
|
|
@@ -72,28 +72,18 @@ export abstract class BaseGroupDefinition<
|
|
|
72
72
|
readonly appearances: StructureElementAppearanceDefinition;
|
|
73
73
|
override readonly label: LabelDefinition | null;
|
|
74
74
|
|
|
75
|
-
constructor(
|
|
76
|
-
form: XFormDefinition,
|
|
77
|
-
parent: BodyElementParentContext,
|
|
78
|
-
element: Element,
|
|
79
|
-
children?: BodyElementDefinitionArray
|
|
80
|
-
) {
|
|
75
|
+
constructor(form: XFormDefinition, parent: BodyElementParentContext, element: Element) {
|
|
81
76
|
super(form, parent, element);
|
|
82
77
|
|
|
83
|
-
|
|
84
|
-
this.reference = element.getAttribute('ref');
|
|
85
|
-
this.appearances = structureElementAppearanceParser.parseFrom(element, 'appearance');
|
|
86
|
-
this.label = LabelDefinition.forGroup(form, this);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
getChildren(element: Element): BodyElementDefinitionArray {
|
|
90
|
-
const { form } = this;
|
|
91
|
-
const children = Array.from(element.children).filter((child) => {
|
|
78
|
+
const childElements = Array.from(element.children).filter((child) => {
|
|
92
79
|
const childName = child.localName;
|
|
93
80
|
|
|
94
81
|
return childName !== 'label';
|
|
95
82
|
});
|
|
96
83
|
|
|
97
|
-
|
|
84
|
+
this.children = this.body.getChildElementDefinitions(form, this, element, childElements);
|
|
85
|
+
this.reference = parseNodesetReference(parent, element, 'ref');
|
|
86
|
+
this.appearances = structureElementAppearanceParser.parseFrom(element, 'appearance');
|
|
87
|
+
this.label = LabelDefinition.forGroup(form, this);
|
|
98
88
|
}
|
|
99
89
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { LabelDefinition } from '../../text/LabelDefinition.ts';
|
|
1
2
|
import type { XFormDefinition } from '../../XFormDefinition.ts';
|
|
2
3
|
import type { BodyElementParentContext } from '../BodyDefinition.ts';
|
|
3
|
-
import { LabelDefinition } from '../text/LabelDefinition.ts';
|
|
4
4
|
import { BaseGroupDefinition } from './BaseGroupDefinition.ts';
|
|
5
5
|
|
|
6
6
|
export class PresentationGroupDefinition extends BaseGroupDefinition<'presentation-group'> {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import type { BindDefinition } from '../model/BindDefinition.ts';
|
|
2
|
+
import { DependentExpression } from './abstract/DependentExpression.ts';
|
|
3
3
|
|
|
4
4
|
const defaultBindComputationExpressions = {
|
|
5
5
|
calculate: null,
|
|
@@ -16,8 +16,8 @@ export type BindComputationType = keyof DefaultBindComputationExpressions;
|
|
|
16
16
|
|
|
17
17
|
type BindComputationFactoryResult<Type extends BindComputationType> =
|
|
18
18
|
DefaultBindComputationExpressions[Type] extends null
|
|
19
|
-
?
|
|
20
|
-
:
|
|
19
|
+
? BindComputationExpression<Type> | null
|
|
20
|
+
: BindComputationExpression<Type>;
|
|
21
21
|
|
|
22
22
|
const bindComputationResultTypes = {
|
|
23
23
|
calculate: 'string',
|
|
@@ -33,10 +33,10 @@ type BindComputationResultTypes = typeof bindComputationResultTypes;
|
|
|
33
33
|
export type BindComputationResultType<Computation extends BindComputationType> =
|
|
34
34
|
BindComputationResultTypes[Computation];
|
|
35
35
|
|
|
36
|
-
export class
|
|
37
|
-
|
|
38
|
-
> {
|
|
39
|
-
static
|
|
36
|
+
export class BindComputationExpression<
|
|
37
|
+
Computation extends BindComputationType,
|
|
38
|
+
> extends DependentExpression<BindComputationResultType<Computation>> {
|
|
39
|
+
static forComputation<Type extends BindComputationType>(
|
|
40
40
|
bind: BindDefinition,
|
|
41
41
|
computation: Type
|
|
42
42
|
): BindComputationFactoryResult<Type> {
|
|
@@ -57,7 +57,6 @@ export class BindComputation<Computation extends BindComputationType> extends De
|
|
|
57
57
|
readonly computation: Computation,
|
|
58
58
|
expression: string | null
|
|
59
59
|
) {
|
|
60
|
-
const isInherited = computation === 'readonly' || computation === 'relevant';
|
|
61
60
|
const ignoreContextReference = computation === 'constraint';
|
|
62
61
|
|
|
63
62
|
let isDefaultExpression: boolean;
|
|
@@ -78,9 +77,6 @@ export class BindComputation<Computation extends BindComputationType> extends De
|
|
|
78
77
|
|
|
79
78
|
super(bind, bindComputationResultTypes[computation], resolvedExpression, {
|
|
80
79
|
ignoreContextReference,
|
|
81
|
-
semanticDependencies: {
|
|
82
|
-
parentContext: isInherited,
|
|
83
|
-
},
|
|
84
80
|
});
|
|
85
81
|
|
|
86
82
|
this.isDefaultExpression = isDefaultExpression;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ItemsetDefinition } from '../body/control/select/ItemsetDefinition.ts';
|
|
2
|
+
import { DependentExpression } from './abstract/DependentExpression.ts';
|
|
3
|
+
|
|
4
|
+
export class ItemsetNodesetExpression extends DependentExpression<'nodes'> {
|
|
5
|
+
constructor(itemset: ItemsetDefinition, nodesetExpression: string) {
|
|
6
|
+
super(itemset.parent, 'nodes', nodesetExpression);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import type { ItemsetDefinition } from '../body/control/select/ItemsetDefinition.ts';
|
|
2
|
+
import { DependentExpression } from './abstract/DependentExpression.ts';
|
|
3
3
|
|
|
4
4
|
export class ItemsetValueExpression extends DependentExpression<'string'> {
|
|
5
5
|
constructor(
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { RepeatRangeControlledNode } from '../../client/repeat/RepeatRangeControlledNode.ts';
|
|
2
|
+
import { RepeatElementDefinition } from '../body/RepeatElementDefinition.ts';
|
|
3
|
+
import { isConstantTruthyExpression } from '../xpath/semantic-analysis.ts';
|
|
4
|
+
import { DependentExpression } from './abstract/DependentExpression.ts';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Represents either of these
|
|
8
|
+
* {@link https://getodk.github.io/xforms-spec/#body-attributes | body attributes}:
|
|
9
|
+
*
|
|
10
|
+
* - `jr:count`
|
|
11
|
+
* - `jr:noAddRemove`
|
|
12
|
+
*
|
|
13
|
+
* In both cases, the downstream effect is that the engine is responsible for
|
|
14
|
+
* controlling the count of a repeat range's instances. Representing both cases
|
|
15
|
+
* should simplify client usage, as well as implementation of the internal
|
|
16
|
+
* representation of {@link RepeatRangeControlledNode}.
|
|
17
|
+
*/
|
|
18
|
+
export class RepeatCountControlExpression extends DependentExpression<'number'> {
|
|
19
|
+
static from(
|
|
20
|
+
bodyElement: RepeatElementDefinition,
|
|
21
|
+
initialCount: number
|
|
22
|
+
): RepeatCountControlExpression | null {
|
|
23
|
+
const { countExpression, noAddRemoveExpression } = bodyElement;
|
|
24
|
+
|
|
25
|
+
if (countExpression != null) {
|
|
26
|
+
return new this(bodyElement, countExpression);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (noAddRemoveExpression != null && isConstantTruthyExpression(noAddRemoveExpression)) {
|
|
30
|
+
// Assumption: `noAddRemove` with no form-defined repeat instances has no
|
|
31
|
+
// purpose. Infer intent as a single repeat instance, as defined by the
|
|
32
|
+
// repeat's template.
|
|
33
|
+
const fixedCountExpression = String(Math.max(initialCount, 1));
|
|
34
|
+
|
|
35
|
+
return new this(bodyElement, fixedCountExpression);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private constructor(context: RepeatElementDefinition, expression: string) {
|
|
42
|
+
super(context, 'number', expression);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { AnyTextRangeDefinition } from '../text/abstract/TextRangeDefinition.ts';
|
|
2
|
+
import { TextChunkExpression } from './abstract/TextChunkExpression.ts';
|
|
3
|
+
|
|
4
|
+
export type TextLiteralSourceNode = Attr | Text;
|
|
5
|
+
|
|
6
|
+
export class TextLiteralExpression extends TextChunkExpression<'literal'> {
|
|
7
|
+
static from(context: AnyTextRangeDefinition, stringValue: string): TextLiteralExpression {
|
|
8
|
+
return new this(context, stringValue);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
readonly source = 'literal';
|
|
12
|
+
|
|
13
|
+
private constructor(
|
|
14
|
+
context: AnyTextRangeDefinition,
|
|
15
|
+
override readonly stringValue: string
|
|
16
|
+
) {
|
|
17
|
+
super(context, 'null');
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { KnownAttributeLocalNamedElement } from '@getodk/common/types/dom.ts';
|
|
2
|
+
import type { AnyTextRangeDefinition } from '../text/abstract/TextRangeDefinition.ts';
|
|
3
|
+
import { TextChunkExpression } from './abstract/TextChunkExpression.ts';
|
|
4
|
+
|
|
5
|
+
interface OutputElement extends KnownAttributeLocalNamedElement<'output', 'value'> {}
|
|
6
|
+
|
|
7
|
+
const isOutputElement = (element: Element): element is OutputElement => {
|
|
8
|
+
return element.localName === 'output' && element.hasAttribute('value');
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export class TextOutputExpression extends TextChunkExpression<'output'> {
|
|
12
|
+
static from(context: AnyTextRangeDefinition, element: Element): TextOutputExpression | null {
|
|
13
|
+
if (isOutputElement(element)) {
|
|
14
|
+
return new this(context, element);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
readonly source = 'output';
|
|
21
|
+
|
|
22
|
+
private constructor(context: AnyTextRangeDefinition, element: OutputElement) {
|
|
23
|
+
super(context, element.getAttribute('value'));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AnyTextRangeDefinition } from '../text/abstract/TextRangeDefinition.ts';
|
|
2
|
+
import { TextChunkExpression } from './abstract/TextChunkExpression.ts';
|
|
3
|
+
|
|
4
|
+
export class TextReferenceExpression extends TextChunkExpression<'reference'> {
|
|
5
|
+
static from(context: AnyTextRangeDefinition, refExpression: string): TextReferenceExpression {
|
|
6
|
+
return new this(context, refExpression);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
readonly source = 'reference';
|
|
10
|
+
|
|
11
|
+
private constructor(context: AnyTextRangeDefinition, refExpression: string) {
|
|
12
|
+
super(context, refExpression);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { expressionParser } from '@getodk/xpath/expressionParser.js';
|
|
2
|
+
import type { AnyTextRangeDefinition } from '../text/abstract/TextRangeDefinition.ts';
|
|
3
|
+
import type { TranslationExpression } from '../xpath/semantic-analysis.ts';
|
|
4
|
+
import { isTranslationExpression } from '../xpath/semantic-analysis.ts';
|
|
5
|
+
import { TextChunkExpression } from './abstract/TextChunkExpression.ts';
|
|
6
|
+
|
|
7
|
+
export class TextTranslationExpression extends TextChunkExpression<'translation'> {
|
|
8
|
+
static fromMessage(
|
|
9
|
+
context: AnyTextRangeDefinition,
|
|
10
|
+
maybeExpression: string
|
|
11
|
+
): TextTranslationExpression | null {
|
|
12
|
+
try {
|
|
13
|
+
expressionParser.parse(maybeExpression);
|
|
14
|
+
} catch {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (isTranslationExpression(maybeExpression)) {
|
|
19
|
+
return new this(context, maybeExpression);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static from(context: AnyTextRangeDefinition, maybeExpression: string) {
|
|
26
|
+
if (isTranslationExpression(maybeExpression)) {
|
|
27
|
+
return new this(context, maybeExpression);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
readonly source = 'translation';
|
|
34
|
+
|
|
35
|
+
private constructor(context: AnyTextRangeDefinition, expression: TranslationExpression) {
|
|
36
|
+
super(context, expression, { isTranslated: true });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import type { XFormsXPathEvaluator } from '@getodk/xpath';
|
|
2
|
-
import {
|
|
2
|
+
import { resolveDependencyNodesets } from '../../xpath/dependency-analysis.ts';
|
|
3
|
+
import type {
|
|
4
|
+
ConstantExpression,
|
|
5
|
+
ConstantTruthyExpression,
|
|
6
|
+
} from '../../xpath/semantic-analysis.ts';
|
|
7
|
+
import {
|
|
8
|
+
isConstantExpression,
|
|
9
|
+
isConstantTruthyExpression,
|
|
10
|
+
isTranslationExpression,
|
|
11
|
+
} from '../../xpath/semantic-analysis.ts';
|
|
3
12
|
import type { DependencyContext } from './DependencyContext.ts';
|
|
4
13
|
|
|
5
14
|
const evaluatorMethodsByResultType = {
|
|
6
15
|
boolean: 'evaluateBoolean',
|
|
7
16
|
nodes: 'evaluateNodes',
|
|
17
|
+
number: 'evaluateNumber',
|
|
8
18
|
string: 'evaluateString',
|
|
9
19
|
} as const;
|
|
10
20
|
|
|
@@ -20,11 +30,6 @@ export type DependentExpressionResult<Type extends DependentExpressionResultType
|
|
|
20
30
|
>;
|
|
21
31
|
|
|
22
32
|
interface SemanticDependencyOptions {
|
|
23
|
-
/**
|
|
24
|
-
* @default false
|
|
25
|
-
*/
|
|
26
|
-
readonly parentContext?: boolean | undefined;
|
|
27
|
-
|
|
28
33
|
/**
|
|
29
34
|
* @default false
|
|
30
35
|
*/
|
|
@@ -37,18 +42,24 @@ interface DependentExpressionOptions {
|
|
|
37
42
|
*/
|
|
38
43
|
readonly ignoreContextReference?: boolean;
|
|
39
44
|
|
|
40
|
-
/**
|
|
41
|
-
* @default true
|
|
42
|
-
*/
|
|
43
|
-
readonly ignoreNullExpressions?: boolean;
|
|
44
|
-
|
|
45
45
|
readonly semanticDependencies?: SemanticDependencyOptions;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
export
|
|
48
|
+
export interface ConstantDependentExpression<Type extends DependentExpressionResultType>
|
|
49
|
+
extends DependentExpression<Type> {
|
|
50
|
+
readonly expression: ConstantExpression;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface ConstantTruthyDependentExpression extends ConstantDependentExpression<'boolean'> {
|
|
54
|
+
readonly expression: ConstantTruthyExpression;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export abstract class DependentExpression<Type extends DependentExpressionResultType> {
|
|
49
58
|
readonly dependencyReferences: ReadonlySet<string> = new Set();
|
|
50
59
|
readonly isTranslated: boolean = false;
|
|
51
60
|
readonly evaluatorMethod: DependentExpressionEvaluatorMethod<Type>;
|
|
61
|
+
readonly constantExpression: ConstantExpression | null;
|
|
62
|
+
readonly constantTruthyExpression: ConstantTruthyExpression | null;
|
|
52
63
|
|
|
53
64
|
constructor(
|
|
54
65
|
context: DependencyContext,
|
|
@@ -56,34 +67,33 @@ export class DependentExpression<Type extends DependentExpressionResultType> {
|
|
|
56
67
|
readonly expression: string,
|
|
57
68
|
options: DependentExpressionOptions = {}
|
|
58
69
|
) {
|
|
70
|
+
if (resultType === 'boolean' && isConstantTruthyExpression(expression)) {
|
|
71
|
+
this.constantTruthyExpression = expression;
|
|
72
|
+
this.constantExpression = expression;
|
|
73
|
+
} else if (isConstantExpression(expression)) {
|
|
74
|
+
this.constantTruthyExpression = null;
|
|
75
|
+
this.constantExpression = expression;
|
|
76
|
+
} else {
|
|
77
|
+
this.constantTruthyExpression = null;
|
|
78
|
+
this.constantExpression = null;
|
|
79
|
+
}
|
|
80
|
+
|
|
59
81
|
this.evaluatorMethod = evaluatorMethodsByResultType[resultType];
|
|
60
82
|
|
|
61
83
|
const {
|
|
62
84
|
ignoreContextReference = false,
|
|
63
|
-
ignoreNullExpressions = true,
|
|
64
85
|
semanticDependencies = {
|
|
65
|
-
parentContext: false,
|
|
66
86
|
translations: false,
|
|
67
87
|
},
|
|
68
88
|
} = options;
|
|
69
89
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
ignoreContextReference,
|
|
74
|
-
ignoreNullExpressions,
|
|
90
|
+
this.dependencyReferences = new Set(
|
|
91
|
+
resolveDependencyNodesets(context.reference, expression, {
|
|
92
|
+
ignoreReferenceToContextPath: ignoreContextReference,
|
|
75
93
|
})
|
|
76
94
|
);
|
|
77
95
|
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
if (parentDependency != null) {
|
|
81
|
-
dependencyReferences.add(parentDependency);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
this.dependencyReferences = dependencyReferences;
|
|
85
|
-
|
|
86
|
-
const isTranslated = semanticDependencies.translations && isItextFunctionCalled(expression);
|
|
96
|
+
const isTranslated = semanticDependencies.translations && isTranslationExpression(expression);
|
|
87
97
|
|
|
88
98
|
if (isTranslated) {
|
|
89
99
|
this.isTranslated = true;
|
|
@@ -93,6 +103,14 @@ export class DependentExpression<Type extends DependentExpressionResultType> {
|
|
|
93
103
|
context.registerDependentExpression(this);
|
|
94
104
|
}
|
|
95
105
|
|
|
106
|
+
isConstantExpression(): this is ConstantDependentExpression<Type> {
|
|
107
|
+
return this.constantExpression != null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
isConstantTruthyExpression(): this is ConstantTruthyDependentExpression {
|
|
111
|
+
return this.resultType === 'boolean' && this.constantTruthyExpression != null;
|
|
112
|
+
}
|
|
113
|
+
|
|
96
114
|
toString(): string | null {
|
|
97
115
|
return this.expression;
|
|
98
116
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { TextChunkSource } from '../../../client/TextRange.ts';
|
|
2
|
+
import type { AnyTextRangeDefinition } from '../../text/abstract/TextRangeDefinition.ts';
|
|
3
|
+
import type { TextLiteralExpression } from '../TextLiteralExpression.ts';
|
|
4
|
+
import type { TextOutputExpression } from '../TextOutputExpression.ts';
|
|
5
|
+
import type { TextReferenceExpression } from '../TextReferenceExpression.ts';
|
|
6
|
+
import type { TextTranslationExpression } from '../TextTranslationExpression.ts';
|
|
7
|
+
import { DependentExpression } from './DependentExpression.ts';
|
|
8
|
+
|
|
9
|
+
interface TextChunkExpressionOptions {
|
|
10
|
+
readonly isTranslated?: true;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export abstract class TextChunkExpression<
|
|
14
|
+
Source extends TextChunkSource,
|
|
15
|
+
> extends DependentExpression<'string'> {
|
|
16
|
+
abstract readonly source: Source;
|
|
17
|
+
readonly stringValue?: string;
|
|
18
|
+
|
|
19
|
+
constructor(
|
|
20
|
+
context: AnyTextRangeDefinition,
|
|
21
|
+
expression: string,
|
|
22
|
+
options: TextChunkExpressionOptions = {}
|
|
23
|
+
) {
|
|
24
|
+
super(context, 'string', expression, {
|
|
25
|
+
semanticDependencies: {
|
|
26
|
+
translations: options.isTranslated,
|
|
27
|
+
},
|
|
28
|
+
ignoreContextReference: true,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// prettier-ignore
|
|
34
|
+
export type AnyTextChunkExpression =
|
|
35
|
+
| TextLiteralExpression
|
|
36
|
+
| TextOutputExpression
|
|
37
|
+
| TextReferenceExpression
|
|
38
|
+
| TextTranslationExpression;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { DependencyContext } from '../expression/abstract/DependencyContext.ts';
|
|
2
|
+
import type { DependentExpression } from '../expression/abstract/DependentExpression.ts';
|
|
3
|
+
import { BindComputationExpression } from '../expression/BindComputationExpression.ts';
|
|
4
|
+
import { MessageDefinition } from '../text/MessageDefinition.ts';
|
|
1
5
|
import type { XFormDataType } from '../XFormDataType.ts';
|
|
2
6
|
import { bindDataType } from '../XFormDataType.ts';
|
|
3
7
|
import type { XFormDefinition } from '../XFormDefinition.ts';
|
|
4
|
-
import { DependencyContext } from '../expression/DependencyContext.ts';
|
|
5
|
-
import type { DependentExpression } from '../expression/DependentExpression.ts';
|
|
6
|
-
import { BindComputation } from './BindComputation.ts';
|
|
7
8
|
import type { BindElement } from './BindElement.ts';
|
|
8
9
|
import type { ModelDefinition } from './ModelDefinition.ts';
|
|
9
10
|
|
|
@@ -12,28 +13,30 @@ export class BindDefinition extends DependencyContext {
|
|
|
12
13
|
readonly dataType: XFormDataType;
|
|
13
14
|
readonly parentNodeset: string | null;
|
|
14
15
|
|
|
15
|
-
readonly calculate:
|
|
16
|
-
readonly readonly:
|
|
17
|
-
readonly relevant:
|
|
18
|
-
readonly required:
|
|
16
|
+
readonly calculate: BindComputationExpression<'calculate'> | null;
|
|
17
|
+
readonly readonly: BindComputationExpression<'readonly'>;
|
|
18
|
+
readonly relevant: BindComputationExpression<'relevant'>;
|
|
19
|
+
readonly required: BindComputationExpression<'required'>;
|
|
19
20
|
|
|
20
|
-
// According to
|
|
21
|
-
//
|
|
22
|
-
// this is not stored in the DAG. In contrast, we do compute constraint
|
|
23
|
-
// dependencies, but self-references are ignored (handled by `BindComputation`
|
|
24
|
-
// and its `DependentExpression` parent class).
|
|
25
21
|
/**
|
|
26
|
-
* Diverges from
|
|
22
|
+
* Diverges from
|
|
23
|
+
* {@link https://github.com/getodk/javarosa/blob/059321160e6f8dbb3e81d9add61d68dd35b13cc8/dag.md | JavaRosa's},
|
|
24
|
+
* which excludes `constraint` expressions. We compute `constraint`
|
|
25
|
+
* dependencies like the other <bind> computation expressions, but explicitly
|
|
26
|
+
* ignore self-references (this is currently handled by
|
|
27
|
+
* {@link BindComputationExpression}, via its {@link DependentExpression}
|
|
28
|
+
* super class).
|
|
27
29
|
*/
|
|
28
|
-
readonly constraint:
|
|
30
|
+
readonly constraint: BindComputationExpression<'constraint'>;
|
|
31
|
+
|
|
32
|
+
readonly constraintMsg: MessageDefinition<'constraintMsg'> | null;
|
|
33
|
+
readonly requiredMsg: MessageDefinition<'requiredMsg'> | null;
|
|
29
34
|
|
|
30
35
|
// TODO: it is unclear whether this will need to be supported.
|
|
31
36
|
// https://github.com/getodk/collect/issues/3758 mentions deprecation.
|
|
32
|
-
readonly saveIncomplete:
|
|
37
|
+
readonly saveIncomplete: BindComputationExpression<'saveIncomplete'>;
|
|
33
38
|
|
|
34
|
-
// TODO: these are deferred
|
|
35
|
-
// readonly requiredMsg: string | null;
|
|
36
|
-
// readonly constraintMsg: string | null;
|
|
39
|
+
// TODO: these are deferred until prioritized
|
|
37
40
|
// readonly preload: string | null;
|
|
38
41
|
// readonly preloadParams: string | null;
|
|
39
42
|
// readonly 'max-pixels': string | null;
|
|
@@ -82,15 +85,15 @@ export class BindDefinition extends DependencyContext {
|
|
|
82
85
|
const parentNodeset = nodeset.replace(/\/[^/]+$/, '');
|
|
83
86
|
|
|
84
87
|
this.parentNodeset = parentNodeset.length > 1 ? parentNodeset : null;
|
|
85
|
-
this.calculate =
|
|
86
|
-
this.readonly =
|
|
87
|
-
this.relevant =
|
|
88
|
-
this.required =
|
|
89
|
-
this.constraint =
|
|
90
|
-
this.saveIncomplete =
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
88
|
+
this.calculate = BindComputationExpression.forComputation(this, 'calculate');
|
|
89
|
+
this.readonly = BindComputationExpression.forComputation(this, 'readonly');
|
|
90
|
+
this.relevant = BindComputationExpression.forComputation(this, 'relevant');
|
|
91
|
+
this.required = BindComputationExpression.forComputation(this, 'required');
|
|
92
|
+
this.constraint = BindComputationExpression.forComputation(this, 'constraint');
|
|
93
|
+
this.saveIncomplete = BindComputationExpression.forComputation(this, 'saveIncomplete');
|
|
94
|
+
this.constraintMsg = MessageDefinition.from(this, 'constraintMsg');
|
|
95
|
+
this.requiredMsg = MessageDefinition.from(this, 'requiredMsg');
|
|
96
|
+
|
|
94
97
|
// this.preload = BindComputation.forExpression(this, 'preload');
|
|
95
98
|
// this.preloadParams = BindComputation.forExpression(this, 'preloadParams');
|
|
96
99
|
// this['max-pixels'] = BindComputation.forExpression(this, 'max-pixels');
|
|
@@ -3,11 +3,11 @@ import type { BindDefinition } from './BindDefinition.ts';
|
|
|
3
3
|
import { DescendentNodeDefinition } from './DescendentNodeDefinition.ts';
|
|
4
4
|
import type { NodeDefinition, ParentNodeDefinition } from './NodeDefinition.ts';
|
|
5
5
|
|
|
6
|
-
export class
|
|
7
|
-
extends DescendentNodeDefinition<'
|
|
8
|
-
implements NodeDefinition<'
|
|
6
|
+
export class LeafNodeDefinition
|
|
7
|
+
extends DescendentNodeDefinition<'leaf-node', ControlElementDefinition | null>
|
|
8
|
+
implements NodeDefinition<'leaf-node'>
|
|
9
9
|
{
|
|
10
|
-
readonly type = '
|
|
10
|
+
readonly type = 'leaf-node';
|
|
11
11
|
|
|
12
12
|
readonly nodeName: string;
|
|
13
13
|
readonly children = null;
|