@getodk/xforms-engine 0.1.1 → 0.3.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/body/BodyDefinition.d.ts +24 -7
- package/dist/body/BodyElementDefinition.d.ts +4 -3
- package/dist/body/RepeatElementDefinition.d.ts +19 -0
- package/dist/body/appearance/inputAppearanceParser.d.ts +4 -0
- package/dist/body/appearance/selectAppearanceParser.d.ts +4 -0
- package/dist/body/appearance/structureElementAppearanceParser.d.ts +4 -0
- package/dist/body/control/ControlDefinition.d.ts +4 -2
- package/dist/body/control/InputDefinition.d.ts +5 -0
- package/dist/body/control/select/ItemDefinition.d.ts +2 -2
- package/dist/body/control/select/ItemsetDefinition.d.ts +5 -4
- package/dist/body/control/select/SelectDefinition.d.ts +11 -1
- package/dist/body/group/BaseGroupDefinition.d.ts +4 -9
- package/dist/body/group/PresentationGroupDefinition.d.ts +1 -1
- package/dist/client/BaseNode.d.ts +74 -3
- package/dist/client/GroupNode.d.ts +7 -2
- package/dist/client/ModelValueNode.d.ts +37 -0
- package/dist/client/NodeAppearances.d.ts +15 -0
- package/dist/client/NoteNode.d.ts +53 -0
- package/dist/client/RootNode.d.ts +21 -0
- package/dist/client/SelectNode.d.ts +8 -3
- package/dist/client/StringNode.d.ts +8 -3
- package/dist/client/SubtreeNode.d.ts +3 -0
- package/dist/client/TextRange.d.ts +85 -2
- package/dist/client/constants.d.ts +9 -0
- package/dist/client/hierarchy.d.ts +14 -9
- package/dist/client/node-types.d.ts +2 -1
- package/dist/client/{RepeatRangeNode.d.ts → repeat/BaseRepeatRangeNode.d.ts} +19 -15
- package/dist/client/{RepeatInstanceNode.d.ts → repeat/RepeatInstanceNode.d.ts} +11 -7
- package/dist/client/repeat/RepeatRangeControlledNode.d.ts +19 -0
- package/dist/client/repeat/RepeatRangeUncontrolledNode.d.ts +20 -0
- package/dist/client/validation.d.ts +163 -0
- package/dist/expression/DependentExpression.d.ts +12 -8
- package/dist/index.d.ts +9 -4
- package/dist/index.js +3173 -960
- package/dist/index.js.map +1 -1
- package/dist/instance/Group.d.ts +6 -4
- package/dist/instance/ModelValue.d.ts +40 -0
- package/dist/instance/Note.d.ts +42 -0
- package/dist/instance/Root.d.ts +10 -23
- package/dist/instance/SelectField.d.ts +12 -6
- package/dist/instance/StringField.d.ts +13 -7
- package/dist/instance/Subtree.d.ts +3 -1
- package/dist/instance/abstract/DescendantNode.d.ts +16 -9
- package/dist/instance/abstract/InstanceNode.d.ts +28 -29
- package/dist/instance/hierarchy.d.ts +10 -5
- package/dist/instance/internal-api/EvaluationContext.d.ts +5 -4
- package/dist/instance/internal-api/ValidationContext.d.ts +21 -0
- package/dist/instance/internal-api/ValueContext.d.ts +2 -2
- package/dist/instance/repeat/BaseRepeatRange.d.ts +160 -0
- package/dist/instance/{RepeatInstance.d.ts → repeat/RepeatInstance.d.ts} +38 -13
- package/dist/instance/repeat/RepeatRangeControlled.d.ts +16 -0
- package/dist/instance/repeat/RepeatRangeUncontrolled.d.ts +35 -0
- package/dist/instance/text/TextRange.d.ts +4 -4
- package/dist/lib/TokenListParser.d.ts +84 -0
- package/dist/lib/dom/query.d.ts +5 -0
- package/dist/lib/reactivity/createComputedExpression.d.ts +6 -1
- package/dist/lib/reactivity/createNoteReadonlyThunk.d.ts +5 -0
- package/dist/lib/reactivity/materializeCurrentStateChildren.d.ts +2 -1
- package/dist/lib/reactivity/node-state/createSharedNodeState.d.ts +1 -1
- package/dist/lib/reactivity/node-state/createSpecifiedState.d.ts +1 -1
- package/dist/lib/reactivity/text/createFieldHint.d.ts +3 -3
- package/dist/lib/reactivity/text/createNodeLabel.d.ts +2 -2
- package/dist/lib/reactivity/text/createNoteText.d.ts +25 -0
- package/dist/lib/reactivity/text/createTextRange.d.ts +5 -7
- package/dist/lib/reactivity/validation/createAggregatedViolations.d.ts +9 -0
- package/dist/lib/reactivity/validation/createValidation.d.ts +18 -0
- package/dist/model/BindDefinition.d.ts +4 -2
- package/dist/model/BindElement.d.ts +1 -0
- package/dist/model/DescendentNodeDefinition.d.ts +1 -2
- package/dist/model/{ValueNodeDefinition.d.ts → LeafNodeDefinition.d.ts} +3 -4
- package/dist/model/NodeDefinition.d.ts +16 -16
- package/dist/model/RepeatInstanceDefinition.d.ts +5 -6
- package/dist/model/RepeatRangeDefinition.d.ts +30 -0
- package/dist/model/RepeatTemplateDefinition.d.ts +6 -7
- package/dist/model/RootDefinition.d.ts +3 -1
- package/dist/model/SubtreeDefinition.d.ts +2 -2
- package/dist/parse/NoteNodeDefinition.d.ts +31 -0
- package/dist/parse/expression/RepeatCountControlExpression.d.ts +19 -0
- package/dist/parse/text/HintDefinition.d.ts +9 -0
- package/dist/parse/text/ItemLabelDefinition.d.ts +9 -0
- package/dist/parse/text/ItemsetLabelDefinition.d.ts +13 -0
- package/dist/parse/text/LabelDefinition.d.ts +15 -0
- package/dist/parse/text/MessageDefinition.d.ts +15 -0
- package/dist/parse/text/OutputChunkDefinition.d.ts +8 -0
- package/dist/parse/text/ReferenceChunkDefinition.d.ts +8 -0
- package/dist/parse/text/StaticTextChunkDefinition.d.ts +10 -0
- package/dist/parse/text/TranslationChunkDefinition.d.ts +9 -0
- package/dist/parse/text/abstract/TextChunkDefinition.d.ts +18 -0
- package/dist/parse/text/abstract/TextElementDefinition.d.ts +23 -0
- package/dist/parse/text/abstract/TextRangeDefinition.d.ts +35 -0
- package/dist/parse/xpath/dependency-analysis.d.ts +40 -0
- package/dist/parse/xpath/path-resolution.d.ts +70 -0
- package/dist/parse/xpath/predicate-analysis.d.ts +30 -0
- package/dist/parse/xpath/reference-parsing.d.ts +18 -0
- package/dist/parse/xpath/semantic-analysis.d.ts +98 -0
- package/dist/parse/xpath/syntax-traversal.d.ts +69 -0
- package/dist/solid.js +3174 -961
- package/dist/solid.js.map +1 -1
- package/package.json +14 -15
- package/src/XFormDOM.ts +81 -8
- package/src/body/BodyDefinition.ts +38 -23
- package/src/body/BodyElementDefinition.ts +4 -3
- package/src/body/RepeatElementDefinition.ts +58 -0
- package/src/body/appearance/inputAppearanceParser.ts +39 -0
- package/src/body/appearance/selectAppearanceParser.ts +38 -0
- package/src/body/appearance/structureElementAppearanceParser.ts +7 -0
- package/src/body/control/ControlDefinition.ts +8 -3
- package/src/body/control/InputDefinition.ts +13 -0
- package/src/body/control/select/ItemDefinition.ts +3 -3
- package/src/body/control/select/ItemsetDefinition.ts +29 -12
- package/src/body/control/select/ItemsetNodesetExpression.ts +1 -1
- package/src/body/control/select/SelectDefinition.ts +14 -5
- package/src/body/group/BaseGroupDefinition.ts +14 -51
- package/src/body/group/PresentationGroupDefinition.ts +1 -1
- package/src/client/BaseNode.ts +82 -8
- package/src/client/GroupNode.ts +8 -2
- package/src/client/ModelValueNode.ts +40 -0
- package/src/client/NodeAppearances.ts +22 -0
- package/src/client/NoteNode.ts +74 -0
- package/src/client/README.md +1 -0
- package/src/client/RootNode.ts +24 -0
- package/src/client/SelectNode.ts +9 -3
- package/src/client/StringNode.ts +9 -3
- package/src/client/SubtreeNode.ts +3 -0
- package/src/client/TextRange.ts +99 -2
- package/src/client/constants.ts +10 -0
- package/src/client/hierarchy.ts +30 -14
- package/src/client/node-types.ts +8 -1
- package/src/client/{RepeatRangeNode.ts → repeat/BaseRepeatRangeNode.ts} +20 -17
- package/src/client/{RepeatInstanceNode.ts → repeat/RepeatInstanceNode.ts} +13 -7
- package/src/client/repeat/RepeatRangeControlledNode.ts +20 -0
- package/src/client/repeat/RepeatRangeUncontrolledNode.ts +21 -0
- package/src/client/validation.ts +199 -0
- package/src/expression/DependentExpression.ts +45 -27
- package/src/index.ts +15 -8
- package/src/instance/Group.ts +24 -13
- package/src/instance/ModelValue.ts +104 -0
- package/src/instance/Note.ts +142 -0
- package/src/instance/Root.ts +29 -67
- package/src/instance/SelectField.ts +35 -13
- package/src/instance/StringField.ts +40 -13
- package/src/instance/Subtree.ts +19 -10
- package/src/instance/abstract/DescendantNode.ts +50 -49
- package/src/instance/abstract/InstanceNode.ts +89 -92
- package/src/instance/children.ts +47 -10
- package/src/instance/hierarchy.ts +21 -2
- package/src/instance/index.ts +1 -1
- package/src/instance/internal-api/EvaluationContext.ts +5 -6
- package/src/instance/internal-api/ValidationContext.ts +23 -0
- package/src/instance/internal-api/ValueContext.ts +2 -2
- package/src/instance/repeat/BaseRepeatRange.ts +347 -0
- package/src/instance/{RepeatInstance.ts → repeat/RepeatInstance.ts} +85 -36
- 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/lib/TokenListParser.ts +156 -0
- package/src/lib/dom/query.ts +13 -0
- package/src/lib/reactivity/createChildrenState.ts +51 -6
- package/src/lib/reactivity/createComputedExpression.ts +23 -25
- package/src/lib/reactivity/createNoteReadonlyThunk.ts +33 -0
- package/src/lib/reactivity/createSelectItems.ts +25 -20
- package/src/lib/reactivity/createValueState.ts +6 -6
- package/src/lib/reactivity/materializeCurrentStateChildren.ts +3 -1
- package/src/lib/reactivity/node-state/createSharedNodeState.ts +1 -1
- package/src/lib/reactivity/text/createFieldHint.ts +9 -7
- package/src/lib/reactivity/text/createNodeLabel.ts +7 -5
- 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 +70 -0
- package/src/lib/reactivity/validation/createValidation.ts +196 -0
- package/src/model/BindComputation.ts +0 -4
- package/src/model/BindDefinition.ts +8 -6
- package/src/model/BindElement.ts +1 -0
- package/src/model/DescendentNodeDefinition.ts +1 -2
- package/src/model/{ValueNodeDefinition.ts → LeafNodeDefinition.ts} +5 -6
- package/src/model/ModelBindMap.ts +4 -0
- package/src/model/ModelDefinition.ts +1 -1
- package/src/model/NodeDefinition.ts +21 -21
- package/src/model/RepeatInstanceDefinition.ts +8 -13
- package/src/model/RepeatRangeDefinition.ts +94 -0
- package/src/model/RepeatTemplateDefinition.ts +10 -15
- package/src/model/RootDefinition.ts +12 -14
- package/src/model/SubtreeDefinition.ts +3 -3
- package/src/parse/NoteNodeDefinition.ts +70 -0
- package/src/parse/TODO.md +3 -0
- package/src/parse/expression/RepeatCountControlExpression.ts +44 -0
- 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/OutputChunkDefinition.ts +25 -0
- package/src/parse/text/ReferenceChunkDefinition.ts +14 -0
- package/src/parse/text/StaticTextChunkDefinition.ts +19 -0
- package/src/parse/text/TranslationChunkDefinition.ts +38 -0
- package/src/parse/text/abstract/TextChunkDefinition.ts +38 -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/RepeatDefinition.d.ts +0 -16
- package/dist/body/group/RepeatGroupDefinition.d.ts +0 -13
- package/dist/body/text/HintDefinition.d.ts +0 -11
- package/dist/body/text/LabelDefinition.d.ts +0 -20
- 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/instance/RepeatRange.d.ts +0 -80
- package/dist/lib/xpath/analysis.d.ts +0 -23
- package/dist/model/RepeatSequenceDefinition.d.ts +0 -20
- package/src/body/RepeatDefinition.ts +0 -54
- package/src/body/group/RepeatGroupDefinition.ts +0 -91
- package/src/body/text/HintDefinition.ts +0 -26
- package/src/body/text/LabelDefinition.ts +0 -54
- 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/instance/RepeatRange.ts +0 -214
- package/src/lib/xpath/analysis.ts +0 -241
- package/src/model/RepeatSequenceDefinition.ts +0 -53
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import type { XFormsXPathEvaluator } from '@getodk/xpath';
|
|
2
|
-
import {
|
|
2
|
+
import { resolveDependencyNodesets } from '../parse/xpath/dependency-analysis.ts';
|
|
3
|
+
import type {
|
|
4
|
+
ConstantExpression,
|
|
5
|
+
ConstantTruthyExpression,
|
|
6
|
+
} from '../parse/xpath/semantic-analysis.ts';
|
|
7
|
+
import {
|
|
8
|
+
isConstantExpression,
|
|
9
|
+
isConstantTruthyExpression,
|
|
10
|
+
isTranslationExpression,
|
|
11
|
+
} from '../parse/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 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
|
+
|
|
48
57
|
export 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
|
}
|
package/src/index.ts
CHANGED
|
@@ -3,26 +3,33 @@ import { initializeForm as engine__initializeForm } from './instance/index.ts';
|
|
|
3
3
|
|
|
4
4
|
export const initializeForm: InitializeForm = engine__initializeForm;
|
|
5
5
|
|
|
6
|
+
export * as constants from './client/constants.ts';
|
|
6
7
|
export type * from './client/EngineConfig.ts';
|
|
7
8
|
export type * from './client/FormLanguage.ts';
|
|
8
9
|
export type * from './client/GroupNode.ts';
|
|
9
|
-
export type * from './client/OpaqueReactiveObjectFactory.ts';
|
|
10
|
-
export type * from './client/RepeatInstanceNode.ts';
|
|
11
|
-
export type * from './client/RepeatRangeNode.ts';
|
|
12
|
-
export type * from './client/RootNode.ts';
|
|
13
|
-
export type * from './client/SelectNode.ts';
|
|
14
|
-
export type * from './client/StringNode.ts';
|
|
15
|
-
export type * from './client/SubtreeNode.ts';
|
|
16
|
-
export type * from './client/TextRange.ts';
|
|
17
10
|
export type {
|
|
18
11
|
AnyChildNode,
|
|
12
|
+
AnyControlNode,
|
|
19
13
|
AnyLeafNode,
|
|
20
14
|
AnyNode,
|
|
21
15
|
AnyParentNode,
|
|
22
16
|
GeneralChildNode,
|
|
23
17
|
GeneralParentNode,
|
|
18
|
+
RepeatRangeNode,
|
|
24
19
|
} from './client/hierarchy.ts';
|
|
25
20
|
export type * from './client/index.ts';
|
|
21
|
+
export type * from './client/ModelValueNode.ts';
|
|
22
|
+
export type * from './client/NoteNode.ts';
|
|
23
|
+
export type * from './client/OpaqueReactiveObjectFactory.ts';
|
|
24
|
+
export type * from './client/repeat/RepeatInstanceNode.ts';
|
|
25
|
+
export type * from './client/repeat/RepeatRangeControlledNode.ts';
|
|
26
|
+
export type * from './client/repeat/RepeatRangeUncontrolledNode.ts';
|
|
27
|
+
export type * from './client/RootNode.ts';
|
|
28
|
+
export type * from './client/SelectNode.ts';
|
|
29
|
+
export type * from './client/StringNode.ts';
|
|
30
|
+
export type * from './client/SubtreeNode.ts';
|
|
31
|
+
export type * from './client/TextRange.ts';
|
|
32
|
+
export type * from './client/validation.ts';
|
|
26
33
|
|
|
27
34
|
// TODO: notwithstanding potential conflicts with parallel work on `web-forms`
|
|
28
35
|
// (former `ui-vue`), these are the last remaining references **outside of
|
package/src/instance/Group.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Accessor } from 'solid-js';
|
|
2
|
-
import type { GroupDefinition, GroupNode } from '../client/GroupNode.ts';
|
|
3
|
-
import type { TextRange } from '../
|
|
2
|
+
import type { GroupDefinition, GroupNode, GroupNodeAppearances } from '../client/GroupNode.ts';
|
|
3
|
+
import type { TextRange } from '../client/TextRange.ts';
|
|
4
|
+
import type { AncestorNodeValidationState } from '../client/validation.ts';
|
|
4
5
|
import type { ChildrenState } from '../lib/reactivity/createChildrenState.ts';
|
|
5
6
|
import { createChildrenState } from '../lib/reactivity/createChildrenState.ts';
|
|
6
7
|
import type { MaterializedChildren } from '../lib/reactivity/materializeCurrentStateChildren.ts';
|
|
@@ -10,6 +11,7 @@ import type { EngineState } from '../lib/reactivity/node-state/createEngineState
|
|
|
10
11
|
import type { SharedNodeState } from '../lib/reactivity/node-state/createSharedNodeState.ts';
|
|
11
12
|
import { createSharedNodeState } from '../lib/reactivity/node-state/createSharedNodeState.ts';
|
|
12
13
|
import { createNodeLabel } from '../lib/reactivity/text/createNodeLabel.ts';
|
|
14
|
+
import { createAggregatedViolations } from '../lib/reactivity/validation/createAggregatedViolations.ts';
|
|
13
15
|
import type { DescendantNodeSharedStateSpec } from './abstract/DescendantNode.ts';
|
|
14
16
|
import { DescendantNode } from './abstract/DescendantNode.ts';
|
|
15
17
|
import { buildChildren } from './children.ts';
|
|
@@ -38,21 +40,31 @@ export class Group
|
|
|
38
40
|
protected override engineState: EngineState<GroupStateSpec>;
|
|
39
41
|
|
|
40
42
|
// GroupNode
|
|
41
|
-
readonly currentState: MaterializedChildren<CurrentState<GroupStateSpec>, GeneralChildNode>;
|
|
42
|
-
|
|
43
43
|
readonly nodeType = 'group';
|
|
44
|
+
readonly appearances: GroupNodeAppearances;
|
|
45
|
+
readonly currentState: MaterializedChildren<CurrentState<GroupStateSpec>, GeneralChildNode>;
|
|
46
|
+
readonly validationState: AncestorNodeValidationState;
|
|
44
47
|
|
|
45
48
|
constructor(parent: GeneralParentNode, definition: GroupDefinition) {
|
|
46
49
|
super(parent, definition);
|
|
47
50
|
|
|
51
|
+
this.appearances = definition.bodyElement.appearances;
|
|
52
|
+
|
|
48
53
|
const childrenState = createChildrenState<Group, GeneralChildNode>(this);
|
|
49
54
|
|
|
50
55
|
this.childrenState = childrenState;
|
|
51
56
|
|
|
57
|
+
const sharedStateOptions = {
|
|
58
|
+
clientStateFactory: this.engineConfig.stateFactory,
|
|
59
|
+
};
|
|
60
|
+
|
|
52
61
|
const state = createSharedNodeState(
|
|
53
62
|
this.scope,
|
|
54
63
|
{
|
|
55
|
-
|
|
64
|
+
reference: this.contextReference,
|
|
65
|
+
readonly: this.isReadonly,
|
|
66
|
+
relevant: this.isRelevant,
|
|
67
|
+
required: this.isRequired,
|
|
56
68
|
|
|
57
69
|
label: createNodeLabel(this, definition),
|
|
58
70
|
hint: null,
|
|
@@ -60,20 +72,19 @@ export class Group
|
|
|
60
72
|
valueOptions: null,
|
|
61
73
|
value: null,
|
|
62
74
|
},
|
|
63
|
-
|
|
64
|
-
clientStateFactory: this.engineConfig.stateFactory,
|
|
65
|
-
}
|
|
75
|
+
sharedStateOptions
|
|
66
76
|
);
|
|
67
77
|
|
|
68
78
|
this.state = state;
|
|
69
79
|
this.engineState = state.engineState;
|
|
70
|
-
this.currentState = materializeCurrentStateChildren(
|
|
80
|
+
this.currentState = materializeCurrentStateChildren(
|
|
81
|
+
this.scope,
|
|
82
|
+
state.currentState,
|
|
83
|
+
childrenState
|
|
84
|
+
);
|
|
71
85
|
|
|
72
86
|
childrenState.setChildren(buildChildren(this));
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
protected computeReference(parent: GeneralParentNode): string {
|
|
76
|
-
return this.computeChildStepReference(parent);
|
|
87
|
+
this.validationState = createAggregatedViolations(this, sharedStateOptions);
|
|
77
88
|
}
|
|
78
89
|
|
|
79
90
|
getChildren(): readonly GeneralChildNode[] {
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { identity } from '@getodk/common/lib/identity.ts';
|
|
2
|
+
import type { ModelValueNode } from '../client/ModelValueNode.ts';
|
|
3
|
+
import type { AnyViolation, LeafNodeValidationState } from '../client/validation.ts';
|
|
4
|
+
import { createValueState } from '../lib/reactivity/createValueState.ts';
|
|
5
|
+
import type { CurrentState } from '../lib/reactivity/node-state/createCurrentState.ts';
|
|
6
|
+
import type { EngineState } from '../lib/reactivity/node-state/createEngineState.ts';
|
|
7
|
+
import type { SharedNodeState } from '../lib/reactivity/node-state/createSharedNodeState.ts';
|
|
8
|
+
import { createSharedNodeState } from '../lib/reactivity/node-state/createSharedNodeState.ts';
|
|
9
|
+
import type { SimpleAtomicState } from '../lib/reactivity/types.ts';
|
|
10
|
+
import type { SharedValidationState } from '../lib/reactivity/validation/createValidation.ts';
|
|
11
|
+
import { createValidationState } from '../lib/reactivity/validation/createValidation.ts';
|
|
12
|
+
import type { LeafNodeDefinition } from '../model/LeafNodeDefinition.ts';
|
|
13
|
+
import type { DescendantNodeStateSpec } from './abstract/DescendantNode.ts';
|
|
14
|
+
import { DescendantNode } from './abstract/DescendantNode.ts';
|
|
15
|
+
import type { GeneralParentNode } from './hierarchy.ts';
|
|
16
|
+
import type { EvaluationContext } from './internal-api/EvaluationContext.ts';
|
|
17
|
+
import type { SubscribableDependency } from './internal-api/SubscribableDependency.ts';
|
|
18
|
+
import type { ValidationContext } from './internal-api/ValidationContext.ts';
|
|
19
|
+
import type { ValueContext } from './internal-api/ValueContext.ts';
|
|
20
|
+
|
|
21
|
+
export interface ModelValueDefinition extends LeafNodeDefinition {
|
|
22
|
+
readonly bodyElement: null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface ModelValueStateSpec extends DescendantNodeStateSpec<string> {
|
|
26
|
+
readonly label: null;
|
|
27
|
+
readonly hint: null;
|
|
28
|
+
readonly children: null;
|
|
29
|
+
readonly value: SimpleAtomicState<string>;
|
|
30
|
+
readonly valueOptions: null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export class ModelValue
|
|
34
|
+
extends DescendantNode<ModelValueDefinition, ModelValueStateSpec, null>
|
|
35
|
+
implements
|
|
36
|
+
ModelValueNode,
|
|
37
|
+
EvaluationContext,
|
|
38
|
+
SubscribableDependency,
|
|
39
|
+
ValidationContext,
|
|
40
|
+
ValueContext<string>
|
|
41
|
+
{
|
|
42
|
+
private readonly validation: SharedValidationState;
|
|
43
|
+
protected readonly state: SharedNodeState<ModelValueStateSpec>;
|
|
44
|
+
|
|
45
|
+
// InstanceNode
|
|
46
|
+
protected engineState: EngineState<ModelValueStateSpec>;
|
|
47
|
+
|
|
48
|
+
// ModelValueNode
|
|
49
|
+
readonly nodeType = 'model-value';
|
|
50
|
+
readonly appearances = null;
|
|
51
|
+
readonly currentState: CurrentState<ModelValueStateSpec>;
|
|
52
|
+
|
|
53
|
+
get validationState(): LeafNodeValidationState {
|
|
54
|
+
return this.validation.currentState;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// ValueContext
|
|
58
|
+
readonly encodeValue = identity<string>;
|
|
59
|
+
readonly decodeValue = identity<string>;
|
|
60
|
+
|
|
61
|
+
constructor(parent: GeneralParentNode, definition: ModelValueDefinition) {
|
|
62
|
+
super(parent, definition);
|
|
63
|
+
|
|
64
|
+
const sharedStateOptions = {
|
|
65
|
+
clientStateFactory: this.engineConfig.stateFactory,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const state = createSharedNodeState(
|
|
69
|
+
this.scope,
|
|
70
|
+
{
|
|
71
|
+
reference: this.contextReference,
|
|
72
|
+
readonly: this.isReadonly,
|
|
73
|
+
relevant: this.isRelevant,
|
|
74
|
+
required: this.isRequired,
|
|
75
|
+
|
|
76
|
+
label: null,
|
|
77
|
+
hint: null,
|
|
78
|
+
children: null,
|
|
79
|
+
valueOptions: null,
|
|
80
|
+
value: createValueState(this),
|
|
81
|
+
},
|
|
82
|
+
sharedStateOptions
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
this.state = state;
|
|
86
|
+
this.engineState = state.engineState;
|
|
87
|
+
this.currentState = state.currentState;
|
|
88
|
+
this.validation = createValidationState(this, sharedStateOptions);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
getViolation(): AnyViolation | null {
|
|
92
|
+
return this.validation.engineState.violation;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// ValidationContext
|
|
96
|
+
isBlank(): boolean {
|
|
97
|
+
return this.engineState.value === '';
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// InstanceNode
|
|
101
|
+
getChildren(): readonly [] {
|
|
102
|
+
return [];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { UnreachableError } from '@getodk/common/lib/error/UnreachableError.ts';
|
|
2
|
+
import { identity } from '@getodk/common/lib/identity.ts';
|
|
3
|
+
import type { Accessor } from 'solid-js';
|
|
4
|
+
import type { NoteNode, NoteNodeAppearances } from '../client/NoteNode.ts';
|
|
5
|
+
import type { TextRange } from '../client/TextRange.ts';
|
|
6
|
+
import type { AnyViolation, LeafNodeValidationState } from '../client/validation.ts';
|
|
7
|
+
import { createNoteReadonlyThunk } from '../lib/reactivity/createNoteReadonlyThunk.ts';
|
|
8
|
+
import { createValueState } from '../lib/reactivity/createValueState.ts';
|
|
9
|
+
import type { CurrentState } from '../lib/reactivity/node-state/createCurrentState.ts';
|
|
10
|
+
import type { EngineState } from '../lib/reactivity/node-state/createEngineState.ts';
|
|
11
|
+
import type { SharedNodeState } from '../lib/reactivity/node-state/createSharedNodeState.ts';
|
|
12
|
+
import { createSharedNodeState } from '../lib/reactivity/node-state/createSharedNodeState.ts';
|
|
13
|
+
import { createFieldHint } from '../lib/reactivity/text/createFieldHint.ts';
|
|
14
|
+
import { createNodeLabel } from '../lib/reactivity/text/createNodeLabel.ts';
|
|
15
|
+
import { createNoteText, type ComputedNoteText } from '../lib/reactivity/text/createNoteText.ts';
|
|
16
|
+
import type { SimpleAtomicState } from '../lib/reactivity/types.ts';
|
|
17
|
+
import type { SharedValidationState } from '../lib/reactivity/validation/createValidation.ts';
|
|
18
|
+
import { createValidationState } from '../lib/reactivity/validation/createValidation.ts';
|
|
19
|
+
import type { NoteNodeDefinition } from '../parse/NoteNodeDefinition.ts';
|
|
20
|
+
import type { DescendantNodeStateSpec } from './abstract/DescendantNode.ts';
|
|
21
|
+
import { DescendantNode } from './abstract/DescendantNode.ts';
|
|
22
|
+
import type { GeneralParentNode } from './hierarchy.ts';
|
|
23
|
+
import type { EvaluationContext } from './internal-api/EvaluationContext.ts';
|
|
24
|
+
import type { SubscribableDependency } from './internal-api/SubscribableDependency.ts';
|
|
25
|
+
import type { ValidationContext } from './internal-api/ValidationContext.ts';
|
|
26
|
+
import type { ValueContext } from './internal-api/ValueContext.ts';
|
|
27
|
+
|
|
28
|
+
interface NoteStateSpec extends DescendantNodeStateSpec<string> {
|
|
29
|
+
readonly readonly: Accessor<true>;
|
|
30
|
+
readonly noteText: ComputedNoteText;
|
|
31
|
+
readonly label: Accessor<TextRange<'label', 'form'> | null>;
|
|
32
|
+
readonly hint: Accessor<TextRange<'hint', 'form'> | null>;
|
|
33
|
+
readonly children: null;
|
|
34
|
+
readonly value: SimpleAtomicState<string>;
|
|
35
|
+
readonly valueOptions: null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export class Note
|
|
39
|
+
extends DescendantNode<NoteNodeDefinition, NoteStateSpec, null>
|
|
40
|
+
implements
|
|
41
|
+
NoteNode,
|
|
42
|
+
EvaluationContext,
|
|
43
|
+
SubscribableDependency,
|
|
44
|
+
ValidationContext,
|
|
45
|
+
ValueContext<string>
|
|
46
|
+
{
|
|
47
|
+
private readonly validation: SharedValidationState;
|
|
48
|
+
protected readonly state: SharedNodeState<NoteStateSpec>;
|
|
49
|
+
|
|
50
|
+
// InstanceNode
|
|
51
|
+
protected engineState: EngineState<NoteStateSpec>;
|
|
52
|
+
|
|
53
|
+
// NoteNode
|
|
54
|
+
readonly nodeType = 'note';
|
|
55
|
+
readonly appearances: NoteNodeAppearances;
|
|
56
|
+
readonly currentState: CurrentState<NoteStateSpec>;
|
|
57
|
+
|
|
58
|
+
get validationState(): LeafNodeValidationState {
|
|
59
|
+
return this.validation.currentState;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ValueContext
|
|
63
|
+
readonly encodeValue = identity<string>;
|
|
64
|
+
|
|
65
|
+
readonly decodeValue = identity<string>;
|
|
66
|
+
|
|
67
|
+
constructor(parent: GeneralParentNode, definition: NoteNodeDefinition) {
|
|
68
|
+
super(parent, definition);
|
|
69
|
+
|
|
70
|
+
this.appearances = definition.bodyElement.appearances;
|
|
71
|
+
|
|
72
|
+
const sharedStateOptions = {
|
|
73
|
+
clientStateFactory: this.engineConfig.stateFactory,
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const isReadonly = createNoteReadonlyThunk(this, definition.bind.readonly);
|
|
77
|
+
const noteTextComputation = createNoteText(this, definition.noteTextDefinition);
|
|
78
|
+
|
|
79
|
+
let noteText: ComputedNoteText;
|
|
80
|
+
let label: Accessor<TextRange<'label', 'form'> | null>;
|
|
81
|
+
let hint: Accessor<TextRange<'hint', 'form'> | null>;
|
|
82
|
+
|
|
83
|
+
switch (noteTextComputation.role) {
|
|
84
|
+
case 'label': {
|
|
85
|
+
noteText = noteTextComputation.label;
|
|
86
|
+
label = noteTextComputation.label;
|
|
87
|
+
hint = createFieldHint(this, definition);
|
|
88
|
+
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
case 'hint': {
|
|
93
|
+
noteText = noteTextComputation.hint;
|
|
94
|
+
label = createNodeLabel(this, definition);
|
|
95
|
+
hint = noteTextComputation.hint;
|
|
96
|
+
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
default:
|
|
101
|
+
throw new UnreachableError(noteTextComputation);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const state = createSharedNodeState(
|
|
105
|
+
this.scope,
|
|
106
|
+
{
|
|
107
|
+
reference: this.contextReference,
|
|
108
|
+
readonly: isReadonly,
|
|
109
|
+
relevant: this.isRelevant,
|
|
110
|
+
required: this.isRequired,
|
|
111
|
+
|
|
112
|
+
label,
|
|
113
|
+
hint,
|
|
114
|
+
noteText,
|
|
115
|
+
|
|
116
|
+
children: null,
|
|
117
|
+
valueOptions: null,
|
|
118
|
+
value: createValueState(this),
|
|
119
|
+
},
|
|
120
|
+
sharedStateOptions
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
this.state = state;
|
|
124
|
+
this.engineState = state.engineState;
|
|
125
|
+
this.currentState = state.currentState;
|
|
126
|
+
this.validation = createValidationState(this, sharedStateOptions);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
getViolation(): AnyViolation | null {
|
|
130
|
+
return this.validation.engineState.violation;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// ValidationContext
|
|
134
|
+
isBlank(): boolean {
|
|
135
|
+
return this.engineState.value === '';
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// InstanceNode
|
|
139
|
+
getChildren(): readonly [] {
|
|
140
|
+
return [];
|
|
141
|
+
}
|
|
142
|
+
}
|
package/src/instance/Root.ts
CHANGED
|
@@ -2,8 +2,10 @@ import type { XFormsXPathEvaluator } from '@getodk/xpath';
|
|
|
2
2
|
import type { Accessor, Signal } from 'solid-js';
|
|
3
3
|
import { createSignal } from 'solid-js';
|
|
4
4
|
import type { XFormDOM } from '../XFormDOM.ts';
|
|
5
|
+
import type { BodyClassList } from '../body/BodyDefinition.ts';
|
|
5
6
|
import type { ActiveLanguage, FormLanguage, FormLanguages } from '../client/FormLanguage.ts';
|
|
6
7
|
import type { RootNode } from '../client/RootNode.ts';
|
|
8
|
+
import type { AncestorNodeValidationState } from '../client/validation.ts';
|
|
7
9
|
import type { ChildrenState } from '../lib/reactivity/createChildrenState.ts';
|
|
8
10
|
import { createChildrenState } from '../lib/reactivity/createChildrenState.ts';
|
|
9
11
|
import type { MaterializedChildren } from '../lib/reactivity/materializeCurrentStateChildren.ts';
|
|
@@ -12,6 +14,7 @@ import type { CurrentState } from '../lib/reactivity/node-state/createCurrentSta
|
|
|
12
14
|
import type { EngineState } from '../lib/reactivity/node-state/createEngineState.ts';
|
|
13
15
|
import type { SharedNodeState } from '../lib/reactivity/node-state/createSharedNodeState.ts';
|
|
14
16
|
import { createSharedNodeState } from '../lib/reactivity/node-state/createSharedNodeState.ts';
|
|
17
|
+
import { createAggregatedViolations } from '../lib/reactivity/validation/createAggregatedViolations.ts';
|
|
15
18
|
import type { RootDefinition } from '../model/RootDefinition.ts';
|
|
16
19
|
import { InstanceNode } from './abstract/InstanceNode.ts';
|
|
17
20
|
import { buildChildren } from './children.ts';
|
|
@@ -98,28 +101,22 @@ export class Root
|
|
|
98
101
|
SubscribableDependency,
|
|
99
102
|
TranslationContext
|
|
100
103
|
{
|
|
101
|
-
static async initialize(
|
|
102
|
-
xformDOM: XFormDOM,
|
|
103
|
-
definition: RootDefinition,
|
|
104
|
-
engineConfig: InstanceConfig
|
|
105
|
-
): Promise<Root> {
|
|
106
|
-
const instance = new Root(xformDOM, definition, engineConfig);
|
|
107
|
-
|
|
108
|
-
await instance.formStateInitialized();
|
|
109
|
-
|
|
110
|
-
return instance;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
104
|
private readonly childrenState: ChildrenState<GeneralChildNode>;
|
|
114
105
|
|
|
115
106
|
// InstanceNode
|
|
107
|
+
readonly hasReadonlyAncestor = () => false;
|
|
108
|
+
readonly isReadonly = () => false;
|
|
109
|
+
readonly hasNonRelevantAncestor = () => false;
|
|
110
|
+
readonly isRelevant = () => true;
|
|
116
111
|
protected readonly state: SharedNodeState<RootStateSpec>;
|
|
117
112
|
protected readonly engineState: EngineState<RootStateSpec>;
|
|
118
113
|
|
|
119
114
|
// RootNode
|
|
120
115
|
readonly nodeType = 'root';
|
|
121
|
-
|
|
116
|
+
readonly appearances = null;
|
|
117
|
+
readonly classes: BodyClassList;
|
|
122
118
|
readonly currentState: MaterializedChildren<CurrentState<RootStateSpec>, GeneralChildNode>;
|
|
119
|
+
readonly validationState: AncestorNodeValidationState;
|
|
123
120
|
|
|
124
121
|
protected readonly instanceDOM: XFormDOM;
|
|
125
122
|
|
|
@@ -129,12 +126,6 @@ export class Root
|
|
|
129
126
|
// EvaluationContext
|
|
130
127
|
readonly evaluator: XFormsXPathEvaluator;
|
|
131
128
|
|
|
132
|
-
private readonly rootReference: string;
|
|
133
|
-
|
|
134
|
-
override get contextReference(): string {
|
|
135
|
-
return this.rootReference;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
129
|
readonly contextNode: Element;
|
|
139
130
|
|
|
140
131
|
// RootNode
|
|
@@ -147,25 +138,27 @@ export class Root
|
|
|
147
138
|
return this.engineState.activeLanguage;
|
|
148
139
|
}
|
|
149
140
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
definition: RootDefinition,
|
|
153
|
-
engineConfig: InstanceConfig
|
|
154
|
-
) {
|
|
155
|
-
super(engineConfig, null, definition);
|
|
141
|
+
constructor(xformDOM: XFormDOM, definition: RootDefinition, engineConfig: InstanceConfig) {
|
|
142
|
+
const reference = definition.nodeset;
|
|
156
143
|
|
|
157
|
-
|
|
144
|
+
super(engineConfig, null, definition, {
|
|
145
|
+
computeReference: () => reference,
|
|
146
|
+
});
|
|
158
147
|
|
|
159
|
-
this.
|
|
148
|
+
this.classes = definition.classes;
|
|
160
149
|
|
|
161
|
-
const
|
|
150
|
+
const childrenState = createChildrenState<Root, GeneralChildNode>(this);
|
|
162
151
|
|
|
163
|
-
this.
|
|
152
|
+
this.childrenState = childrenState;
|
|
164
153
|
|
|
165
154
|
const instanceDOM = xformDOM.createInstance();
|
|
166
155
|
const evaluator = instanceDOM.primaryInstanceEvaluator;
|
|
167
156
|
const { translations } = evaluator;
|
|
168
157
|
const { defaultLanguage, languages } = getInitialLanguageState(translations);
|
|
158
|
+
const sharedStateOptions = {
|
|
159
|
+
clientStateFactory: this.engineConfig.stateFactory,
|
|
160
|
+
};
|
|
161
|
+
|
|
169
162
|
const state = createSharedNodeState(
|
|
170
163
|
this.scope,
|
|
171
164
|
{
|
|
@@ -180,14 +173,16 @@ export class Root
|
|
|
180
173
|
value: null,
|
|
181
174
|
children: childrenState.childIds,
|
|
182
175
|
},
|
|
183
|
-
|
|
184
|
-
clientStateFactory: engineConfig.stateFactory,
|
|
185
|
-
}
|
|
176
|
+
sharedStateOptions
|
|
186
177
|
);
|
|
187
178
|
|
|
188
179
|
this.state = state;
|
|
189
180
|
this.engineState = state.engineState;
|
|
190
|
-
this.currentState = materializeCurrentStateChildren(
|
|
181
|
+
this.currentState = materializeCurrentStateChildren(
|
|
182
|
+
this.scope,
|
|
183
|
+
state.currentState,
|
|
184
|
+
childrenState
|
|
185
|
+
);
|
|
191
186
|
|
|
192
187
|
const contextNode = instanceDOM.xformDocument.createElement(definition.nodeName);
|
|
193
188
|
|
|
@@ -199,40 +194,7 @@ export class Root
|
|
|
199
194
|
this.languages = languages;
|
|
200
195
|
|
|
201
196
|
childrenState.setChildren(buildChildren(this));
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Waits until form state is fully initialized.
|
|
206
|
-
*
|
|
207
|
-
* As much as possible, all instance state computations are implemented so
|
|
208
|
-
* that they complete synchronously.
|
|
209
|
-
*
|
|
210
|
-
* There is currently one exception: because instance nodes may form
|
|
211
|
-
* computation dependencies into their descendants as well as their ancestors,
|
|
212
|
-
* there is an allowance **during form initialization only** to account for
|
|
213
|
-
* this chicken/egg scenario. Note that this allowance is intentionally,
|
|
214
|
-
* strictly limited: if form state initialization is not resolved within a
|
|
215
|
-
* single microtask tick we throw/reject.
|
|
216
|
-
*
|
|
217
|
-
* All subsequent computations are always performed synchronously (and we will
|
|
218
|
-
* use tests to validate this, by utilizing the synchronously returned `Root`
|
|
219
|
-
* state from client-facing write interfaces).
|
|
220
|
-
*/
|
|
221
|
-
async formStateInitialized(): Promise<void> {
|
|
222
|
-
await new Promise<void>((resolve) => {
|
|
223
|
-
queueMicrotask(resolve);
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
if (!this.isStateInitialized()) {
|
|
227
|
-
throw new Error(
|
|
228
|
-
'Form state initialization failed to complete in a single frame. Has some aspect of reactive computation been made asynchronous by mistake?'
|
|
229
|
-
);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
// InstanceNode
|
|
234
|
-
protected computeReference(_parent: null, definition: RootDefinition): string {
|
|
235
|
-
return definition.nodeset;
|
|
197
|
+
this.validationState = createAggregatedViolations(this, sharedStateOptions);
|
|
236
198
|
}
|
|
237
199
|
|
|
238
200
|
getChildren(): readonly GeneralChildNode[] {
|