@getodk/xforms-engine 0.13.0 → 0.15.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/AttributeNode.d.ts +53 -0
- package/dist/client/BaseItem.d.ts +6 -0
- package/dist/client/GroupNode.d.ts +4 -4
- package/dist/client/MarkdownNode.d.ts +33 -0
- package/dist/client/RankNode.d.ts +2 -4
- package/dist/client/SelectNode.d.ts +2 -5
- package/dist/client/TextRange.d.ts +2 -2
- package/dist/client/hierarchy.d.ts +1 -2
- package/dist/client/index.d.ts +2 -1
- package/dist/client/node-types.d.ts +2 -2
- package/dist/client/validation.d.ts +7 -1
- package/dist/index.js +10758 -402
- package/dist/index.js.map +1 -1
- package/dist/instance/Attribute.d.ts +58 -0
- package/dist/instance/Group.d.ts +4 -0
- package/dist/instance/PrimaryInstance.d.ts +4 -0
- package/dist/instance/Root.d.ts +4 -0
- package/dist/instance/UploadControl.d.ts +4 -0
- package/dist/instance/abstract/InstanceNode.d.ts +7 -4
- package/dist/instance/abstract/ValueNode.d.ts +1 -0
- package/dist/instance/attachments/buildAttributes.d.ts +3 -0
- package/dist/instance/hierarchy.d.ts +6 -6
- package/dist/instance/internal-api/AttributeContext.d.ts +29 -0
- package/dist/instance/internal-api/serialization/ClientReactiveSerializableAttributeNode.d.ts +16 -0
- package/dist/instance/internal-api/serialization/ClientReactiveSerializableParentNode.d.ts +2 -0
- package/dist/instance/internal-api/serialization/ClientReactiveSerializableTemplatedNode.d.ts +2 -2
- package/dist/instance/markdown/MarkdownNode.d.ts +75 -0
- package/dist/instance/repeat/BaseRepeatRange.d.ts +5 -0
- package/dist/instance/repeat/RepeatInstance.d.ts +4 -2
- package/dist/instance/text/TextChunk.d.ts +0 -1
- package/dist/instance/text/TextRange.d.ts +2 -1
- package/dist/instance/text/markdownFormat.d.ts +3 -0
- package/dist/integration/xpath/adapter/XFormsXPathNode.d.ts +2 -2
- package/dist/lib/client-reactivity/instance-state/createAttributeNodeInstanceState.d.ts +3 -0
- package/dist/lib/client-reactivity/instance-state/createTemplatedNodeInstanceState.d.ts +0 -3
- package/dist/lib/names/NamespaceDeclarationMap.d.ts +1 -1
- package/dist/lib/reactivity/createAttributeState.d.ts +16 -0
- package/dist/lib/reactivity/createAttributeValueState.d.ts +15 -0
- package/dist/lib/reactivity/createItemCollection.d.ts +5 -7
- package/dist/lib/xml-serialization.d.ts +5 -9
- package/dist/parse/XFormDOM.d.ts +1 -1
- package/dist/parse/body/BodyDefinition.d.ts +2 -8
- package/dist/parse/body/GroupElementDefinition.d.ts +22 -0
- package/dist/parse/body/control/ItemsetDefinition.d.ts +3 -0
- package/dist/parse/expression/ItemPropertyExpression.d.ts +6 -0
- package/dist/parse/model/AttributeDefinition.d.ts +22 -0
- package/dist/parse/model/{RootAttributeMap.d.ts → AttributeDefinitionMap.d.ts} +4 -10
- package/dist/parse/model/{SubtreeDefinition.d.ts → GroupDefinition.d.ts} +8 -4
- package/dist/parse/model/LeafNodeDefinition.d.ts +1 -0
- package/dist/parse/model/NodeDefinition.d.ts +13 -9
- package/dist/parse/model/RepeatDefinition.d.ts +5 -2
- package/dist/parse/model/RootDefinition.d.ts +3 -3
- package/dist/parse/text/LabelDefinition.d.ts +4 -5
- package/dist/solid.js +10758 -402
- package/dist/solid.js.map +1 -1
- package/package.json +6 -5
- package/src/client/AttributeNode.ts +62 -0
- package/src/client/BaseItem.ts +7 -0
- package/src/client/GroupNode.ts +4 -10
- package/src/client/MarkdownNode.ts +53 -0
- package/src/client/RankNode.ts +2 -5
- package/src/client/SelectNode.ts +2 -6
- package/src/client/TextRange.ts +2 -2
- package/src/client/hierarchy.ts +0 -2
- package/src/client/index.ts +2 -1
- package/src/client/node-types.ts +1 -1
- package/src/client/validation.ts +9 -1
- package/src/instance/Attribute.ts +164 -0
- package/src/instance/Group.ts +17 -1
- package/src/instance/InputControl.ts +1 -0
- package/src/instance/ModelValue.ts +1 -0
- package/src/instance/Note.ts +1 -0
- package/src/instance/PrimaryInstance.ts +17 -0
- package/src/instance/RangeControl.ts +1 -0
- package/src/instance/RankControl.ts +1 -0
- package/src/instance/Root.ts +16 -0
- package/src/instance/SelectControl.ts +1 -0
- package/src/instance/TriggerControl.ts +1 -0
- package/src/instance/UploadControl.ts +14 -0
- package/src/instance/abstract/DescendantNode.ts +5 -1
- package/src/instance/abstract/InstanceNode.ts +6 -3
- package/src/instance/abstract/ValueNode.ts +1 -0
- package/src/instance/attachments/buildAttributes.ts +8 -0
- package/src/instance/children/buildChildren.ts +1 -17
- package/src/instance/children/normalizeChildInitOptions.ts +44 -59
- package/src/instance/hierarchy.ts +3 -7
- package/src/instance/internal-api/AttributeContext.ts +34 -0
- package/src/instance/internal-api/serialization/ClientReactiveSerializableAttributeNode.ts +19 -0
- package/src/instance/internal-api/serialization/ClientReactiveSerializableParentNode.ts +2 -0
- package/src/instance/internal-api/serialization/ClientReactiveSerializableTemplatedNode.ts +2 -3
- package/src/instance/markdown/MarkdownNode.ts +115 -0
- package/src/instance/repeat/BaseRepeatRange.ts +14 -0
- package/src/instance/repeat/RepeatInstance.ts +14 -5
- package/src/instance/text/TextChunk.ts +0 -5
- package/src/instance/text/TextRange.ts +5 -3
- package/src/instance/text/markdownFormat.ts +214 -0
- package/src/integration/xpath/adapter/XFormsXPathNode.ts +3 -1
- package/src/integration/xpath/adapter/names.ts +0 -1
- package/src/lib/client-reactivity/instance-state/createAttributeNodeInstanceState.ts +16 -0
- package/src/lib/client-reactivity/instance-state/createParentNodeInstanceState.ts +5 -5
- package/src/lib/client-reactivity/instance-state/createRootInstanceState.ts +6 -9
- package/src/lib/client-reactivity/instance-state/createTemplatedNodeInstanceState.ts +5 -15
- package/src/lib/names/NamespaceDeclarationMap.ts +1 -1
- package/src/lib/reactivity/createAttributeState.ts +51 -0
- package/src/lib/reactivity/createAttributeValueState.ts +189 -0
- package/src/lib/reactivity/createItemCollection.ts +25 -9
- package/src/lib/xml-serialization.ts +30 -34
- package/src/parse/body/BodyDefinition.ts +7 -34
- package/src/parse/body/GroupElementDefinition.ts +47 -0
- package/src/parse/body/control/ItemsetDefinition.ts +7 -0
- package/src/parse/expression/ItemPropertyExpression.ts +12 -0
- package/src/parse/model/AttributeDefinition.ts +58 -0
- package/src/parse/model/{RootAttributeMap.ts → AttributeDefinitionMap.ts} +7 -13
- package/src/parse/model/{SubtreeDefinition.ts → GroupDefinition.ts} +12 -8
- package/src/parse/model/LeafNodeDefinition.ts +1 -0
- package/src/parse/model/NodeDefinition.ts +19 -12
- package/src/parse/model/RepeatDefinition.ts +10 -3
- package/src/parse/model/RootDefinition.ts +6 -6
- package/src/parse/model/nodeDefinitionMap.ts +1 -1
- package/src/parse/text/LabelDefinition.ts +4 -9
- package/dist/client/SubtreeNode.d.ts +0 -56
- package/dist/error/TemplatedNodeAttributeSerializationError.d.ts +0 -22
- package/dist/instance/Subtree.d.ts +0 -38
- package/dist/instance/text/FormattedTextStub.d.ts +0 -1
- package/dist/parse/body/group/BaseGroupDefinition.d.ts +0 -40
- package/dist/parse/body/group/LogicalGroupDefinition.d.ts +0 -6
- package/dist/parse/body/group/PresentationGroupDefinition.d.ts +0 -11
- package/dist/parse/body/group/StructuralGroupDefinition.d.ts +0 -6
- package/dist/parse/model/RootAttributeDefinition.d.ts +0 -21
- package/src/client/SubtreeNode.ts +0 -61
- package/src/error/TemplatedNodeAttributeSerializationError.ts +0 -24
- package/src/instance/Subtree.ts +0 -102
- package/src/instance/text/FormattedTextStub.ts +0 -8
- package/src/parse/body/group/BaseGroupDefinition.ts +0 -89
- package/src/parse/body/group/LogicalGroupDefinition.ts +0 -11
- package/src/parse/body/group/PresentationGroupDefinition.ts +0 -28
- package/src/parse/body/group/StructuralGroupDefinition.ts +0 -11
- package/src/parse/model/RootAttributeDefinition.ts +0 -44
|
@@ -94,6 +94,7 @@ export class RangeControl<V extends RangeValueType = RangeValueType>
|
|
|
94
94
|
label: createNodeLabel(this, definition),
|
|
95
95
|
hint: createFieldHint(this, definition),
|
|
96
96
|
children: null,
|
|
97
|
+
attributes: null,
|
|
97
98
|
valueOptions: null,
|
|
98
99
|
value: this.valueState,
|
|
99
100
|
instanceValue: this.getInstanceValue,
|
package/src/instance/Root.ts
CHANGED
|
@@ -12,6 +12,10 @@ import type { InstanceState } from '../client/serialization/InstanceState.ts';
|
|
|
12
12
|
import type { AncestorNodeValidationState } from '../client/validation.ts';
|
|
13
13
|
import type { XFormsXPathElement } from '../integration/xpath/adapter/XFormsXPathNode.ts';
|
|
14
14
|
import { createRootInstanceState } from '../lib/client-reactivity/instance-state/createRootInstanceState.ts';
|
|
15
|
+
import {
|
|
16
|
+
createAttributeState,
|
|
17
|
+
type AttributeState,
|
|
18
|
+
} from '../lib/reactivity/createAttributeState.ts';
|
|
15
19
|
import type { ChildrenState } from '../lib/reactivity/createChildrenState.ts';
|
|
16
20
|
import { createChildrenState } from '../lib/reactivity/createChildrenState.ts';
|
|
17
21
|
import type { MaterializedChildren } from '../lib/reactivity/materializeCurrentStateChildren.ts';
|
|
@@ -24,6 +28,8 @@ import { createAggregatedViolations } from '../lib/reactivity/validation/createA
|
|
|
24
28
|
import type { BodyClassList } from '../parse/body/BodyDefinition.ts';
|
|
25
29
|
import type { RootDefinition } from '../parse/model/RootDefinition.ts';
|
|
26
30
|
import { DescendantNode } from './abstract/DescendantNode.ts';
|
|
31
|
+
import { buildAttributes } from './attachments/buildAttributes.ts';
|
|
32
|
+
import { Attribute } from './Attribute.ts';
|
|
27
33
|
import { buildChildren } from './children/buildChildren.ts';
|
|
28
34
|
import type { GeneralChildNode } from './hierarchy.ts';
|
|
29
35
|
import type { EvaluationContext } from './internal-api/EvaluationContext.ts';
|
|
@@ -39,6 +45,7 @@ interface RootStateSpec {
|
|
|
39
45
|
readonly label: null;
|
|
40
46
|
readonly hint: null;
|
|
41
47
|
readonly children: Accessor<readonly FormNodeID[]>;
|
|
48
|
+
readonly attributes: Accessor<readonly Attribute[]>;
|
|
42
49
|
readonly valueOptions: null;
|
|
43
50
|
readonly value: null;
|
|
44
51
|
|
|
@@ -56,6 +63,7 @@ export class Root
|
|
|
56
63
|
ClientReactiveSerializableParentNode<GeneralChildNode>
|
|
57
64
|
{
|
|
58
65
|
private readonly childrenState: ChildrenState<GeneralChildNode>;
|
|
66
|
+
private readonly attributeState: AttributeState;
|
|
59
67
|
|
|
60
68
|
// XFormsXPathElement
|
|
61
69
|
override readonly [XPathNodeKindKey] = 'element';
|
|
@@ -95,8 +103,10 @@ export class Root
|
|
|
95
103
|
this.classes = parent.classes;
|
|
96
104
|
|
|
97
105
|
const childrenState = createChildrenState<Root, GeneralChildNode>(this);
|
|
106
|
+
const attributeState = createAttributeState(this.scope);
|
|
98
107
|
|
|
99
108
|
this.childrenState = childrenState;
|
|
109
|
+
this.attributeState = attributeState;
|
|
100
110
|
this.languages = parent.languages;
|
|
101
111
|
|
|
102
112
|
const state = createSharedNodeState(
|
|
@@ -112,6 +122,7 @@ export class Root
|
|
|
112
122
|
valueOptions: null,
|
|
113
123
|
value: null,
|
|
114
124
|
children: childrenState.childIds,
|
|
125
|
+
attributes: attributeState.getAttributes,
|
|
115
126
|
},
|
|
116
127
|
this.instanceConfig
|
|
117
128
|
);
|
|
@@ -125,6 +136,7 @@ export class Root
|
|
|
125
136
|
);
|
|
126
137
|
|
|
127
138
|
childrenState.setChildren(buildChildren(this));
|
|
139
|
+
attributeState.setAttributes(buildAttributes(this));
|
|
128
140
|
this.validationState = createAggregatedViolations(this, this.instanceConfig);
|
|
129
141
|
this.instanceState = createRootInstanceState(this);
|
|
130
142
|
}
|
|
@@ -133,6 +145,10 @@ export class Root
|
|
|
133
145
|
return this.childrenState.getChildren();
|
|
134
146
|
}
|
|
135
147
|
|
|
148
|
+
getAttributes(): readonly Attribute[] {
|
|
149
|
+
return this.attributeState.getAttributes();
|
|
150
|
+
}
|
|
151
|
+
|
|
136
152
|
// RootNode
|
|
137
153
|
setLanguage(language: FormLanguage): Root {
|
|
138
154
|
this.rootDocument.setLanguage(language);
|
|
@@ -100,6 +100,7 @@ export class TriggerControl
|
|
|
100
100
|
label: createNodeLabel(this, definition),
|
|
101
101
|
hint: createFieldHint(this, definition),
|
|
102
102
|
children: null,
|
|
103
|
+
attributes: null,
|
|
103
104
|
valueOptions: null,
|
|
104
105
|
value: this.valueState,
|
|
105
106
|
instanceValue: this.getInstanceValue,
|
|
@@ -9,6 +9,10 @@ import { UploadValueTypeError } from '../error/UploadValueTypeError.ts';
|
|
|
9
9
|
import type { XFormsXPathElement } from '../integration/xpath/adapter/XFormsXPathNode.ts';
|
|
10
10
|
import type { StaticLeafElement } from '../integration/xpath/static-dom/StaticElement.ts';
|
|
11
11
|
import { createValueNodeInstanceState } from '../lib/client-reactivity/instance-state/createValueNodeInstanceState.ts';
|
|
12
|
+
import {
|
|
13
|
+
createAttributeState,
|
|
14
|
+
type AttributeState,
|
|
15
|
+
} from '../lib/reactivity/createAttributeState.ts';
|
|
12
16
|
import { createInstanceAttachment } from '../lib/reactivity/createInstanceAttachment.ts';
|
|
13
17
|
import type { CurrentState } from '../lib/reactivity/node-state/createCurrentState.ts';
|
|
14
18
|
import type { EngineState } from '../lib/reactivity/node-state/createEngineState.ts';
|
|
@@ -20,6 +24,7 @@ import type { SimpleAtomicState } from '../lib/reactivity/types.ts';
|
|
|
20
24
|
import type { SharedValidationState } from '../lib/reactivity/validation/createValidation.ts';
|
|
21
25
|
import { createValidationState } from '../lib/reactivity/validation/createValidation.ts';
|
|
22
26
|
import type { UnknownAppearanceDefinition } from '../parse/body/appearance/unknownAppearanceParser.ts';
|
|
27
|
+
import type { Attribute } from './Attribute.ts';
|
|
23
28
|
import type { Root } from './Root.ts';
|
|
24
29
|
import type { DescendantNodeStateSpec } from './abstract/DescendantNode.ts';
|
|
25
30
|
import { DescendantNode } from './abstract/DescendantNode.ts';
|
|
@@ -57,6 +62,7 @@ interface UploadControlStateSpec extends DescendantNodeStateSpec<InstanceAttachm
|
|
|
57
62
|
readonly label: Accessor<TextRange<'label'> | null>;
|
|
58
63
|
readonly hint: Accessor<TextRange<'hint'> | null>;
|
|
59
64
|
readonly children: null;
|
|
65
|
+
readonly attributes: Accessor<readonly Attribute[]>;
|
|
60
66
|
readonly valueOptions: null;
|
|
61
67
|
readonly value: SimpleAtomicState<InstanceAttachmentRuntimeValue>;
|
|
62
68
|
readonly instanceValue: Accessor<InstanceAttachmentFileName>;
|
|
@@ -95,6 +101,7 @@ export class UploadControl
|
|
|
95
101
|
|
|
96
102
|
private readonly validation: SharedValidationState;
|
|
97
103
|
private readonly instanceAttachment: InstanceAttachment;
|
|
104
|
+
private readonly attributeState: AttributeState;
|
|
98
105
|
|
|
99
106
|
// XFormsXPathElement
|
|
100
107
|
override readonly [XPathNodeKindKey] = 'element';
|
|
@@ -133,6 +140,8 @@ export class UploadControl
|
|
|
133
140
|
const instanceAttachment = createInstanceAttachment(this);
|
|
134
141
|
|
|
135
142
|
this.instanceAttachment = instanceAttachment;
|
|
143
|
+
const attributeState = createAttributeState(this.scope);
|
|
144
|
+
this.attributeState = attributeState;
|
|
136
145
|
this.decodeInstanceValue = instanceAttachment.decodeInstanceValue;
|
|
137
146
|
this.getXPathValue = instanceAttachment.getInstanceValue;
|
|
138
147
|
|
|
@@ -149,6 +158,7 @@ export class UploadControl
|
|
|
149
158
|
children: null,
|
|
150
159
|
valueOptions: null,
|
|
151
160
|
value: instanceAttachment.valueState,
|
|
161
|
+
attributes: attributeState.getAttributes,
|
|
152
162
|
instanceValue: instanceAttachment.getInstanceValue,
|
|
153
163
|
},
|
|
154
164
|
this.instanceConfig
|
|
@@ -181,4 +191,8 @@ export class UploadControl
|
|
|
181
191
|
|
|
182
192
|
return this.root;
|
|
183
193
|
}
|
|
194
|
+
|
|
195
|
+
getAttributes(): readonly Attribute[] {
|
|
196
|
+
return this.attributeState.getAttributes();
|
|
197
|
+
}
|
|
184
198
|
}
|
|
@@ -13,6 +13,7 @@ import type {
|
|
|
13
13
|
XFormsXPathPrimaryInstanceNodeKind,
|
|
14
14
|
} from '../../integration/xpath/adapter/XFormsXPathNode.ts';
|
|
15
15
|
import type { PrimaryInstanceXPathNode } from '../../integration/xpath/adapter/kind.ts';
|
|
16
|
+
import type { StaticAttribute } from '../../integration/xpath/static-dom/StaticAttribute.ts';
|
|
16
17
|
import type { StaticDocument } from '../../integration/xpath/static-dom/StaticDocument.ts';
|
|
17
18
|
import type { StaticElement } from '../../integration/xpath/static-dom/StaticElement.ts';
|
|
18
19
|
import type { MaterializedChildren } from '../../lib/reactivity/materializeCurrentStateChildren.ts';
|
|
@@ -24,6 +25,7 @@ import { createReactiveScope } from '../../lib/reactivity/scope.ts';
|
|
|
24
25
|
import type { SimpleAtomicState } from '../../lib/reactivity/types.ts';
|
|
25
26
|
import { createUniqueId } from '../../lib/unique-id.ts';
|
|
26
27
|
import type { AnyNodeDefinition } from '../../parse/model/NodeDefinition.ts';
|
|
28
|
+
import type { Attribute } from '../Attribute.ts';
|
|
27
29
|
import type { PrimaryInstance } from '../PrimaryInstance.ts';
|
|
28
30
|
import type { Root } from '../Root.ts';
|
|
29
31
|
import type { AnyChildNode, AnyNode, AnyParentNode } from '../hierarchy.ts';
|
|
@@ -51,6 +53,7 @@ export interface InstanceNodeStateSpec<Value = never> {
|
|
|
51
53
|
readonly label: Accessor<TextRange<'label'> | null> | null;
|
|
52
54
|
readonly hint: Accessor<TextRange<'hint'> | null> | null;
|
|
53
55
|
readonly children: Accessor<readonly FormNodeID[]> | null;
|
|
56
|
+
readonly attributes: Accessor<readonly Attribute[]> | null;
|
|
54
57
|
readonly valueOptions: InstanceNodeValueOptionsStateSpec;
|
|
55
58
|
readonly value: Signal<Value> | SimpleAtomicState<Value> | null;
|
|
56
59
|
}
|
|
@@ -191,7 +194,7 @@ export abstract class InstanceNode<
|
|
|
191
194
|
constructor(
|
|
192
195
|
readonly instanceConfig: InstanceConfig,
|
|
193
196
|
readonly parent: Parent,
|
|
194
|
-
readonly instanceNode: StaticDocument | StaticElement | null,
|
|
197
|
+
readonly instanceNode: StaticAttribute | StaticDocument | StaticElement | null,
|
|
195
198
|
readonly definition: Definition,
|
|
196
199
|
options?: InstanceNodeOptions
|
|
197
200
|
) {
|
|
@@ -237,13 +240,13 @@ export abstract class InstanceNode<
|
|
|
237
240
|
* (though for those nodes it will always be empty). This affords consistency
|
|
238
241
|
* and efficiency of interface for those internal uses.
|
|
239
242
|
*/
|
|
240
|
-
abstract getChildren(this: AnyInstanceNode):
|
|
243
|
+
abstract getChildren(this: AnyInstanceNode): ReadonlyArray<Exclude<AnyChildNode, Attribute>>;
|
|
241
244
|
|
|
242
245
|
// XFormsXPathNode
|
|
243
246
|
/**
|
|
244
247
|
* @todo Values as text nodes(?)
|
|
245
248
|
*/
|
|
246
|
-
getXPathChildNodes():
|
|
249
|
+
getXPathChildNodes(): ReadonlyArray<Exclude<AnyChildNode, Attribute>> {
|
|
247
250
|
return (this as AnyInstanceNode).getChildren().flatMap((child) => {
|
|
248
251
|
switch (child.nodeType) {
|
|
249
252
|
case 'repeat-range:controlled':
|
|
@@ -36,6 +36,7 @@ export type ValueNodeDefinition<V extends ValueType> = LeafNodeDefinition<V>;
|
|
|
36
36
|
|
|
37
37
|
export interface ValueNodeStateSpec<RuntimeValue> extends DescendantNodeStateSpec<RuntimeValue> {
|
|
38
38
|
readonly children: null;
|
|
39
|
+
readonly attributes: null;
|
|
39
40
|
readonly value: SimpleAtomicState<RuntimeValue>;
|
|
40
41
|
readonly instanceValue: Accessor<string>;
|
|
41
42
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Attribute } from '../Attribute';
|
|
2
|
+
import type { AnyParentNode } from '../hierarchy';
|
|
3
|
+
|
|
4
|
+
export function buildAttributes(parent: AnyParentNode): Attribute[] {
|
|
5
|
+
return Array.from(parent.definition.attributes.values()).map((attributeDefinition) => {
|
|
6
|
+
return new Attribute(parent, attributeDefinition, attributeDefinition.template);
|
|
7
|
+
});
|
|
8
|
+
}
|
|
@@ -4,7 +4,6 @@ import type { InputDefinition } from '../../client/InputNode.ts';
|
|
|
4
4
|
import type { ModelValueDefinition } from '../../client/ModelValueNode.ts';
|
|
5
5
|
import type { RankDefinition } from '../../client/RankNode.ts';
|
|
6
6
|
import type { SelectDefinition } from '../../client/SelectNode.ts';
|
|
7
|
-
import type { SubtreeDefinition } from '../../client/SubtreeNode.ts';
|
|
8
7
|
import type { TriggerNodeDefinition } from '../../client/TriggerNode.ts';
|
|
9
8
|
import type { UploadDefinition } from '../../client/UploadNode.ts';
|
|
10
9
|
import { ErrorProductionDesignPendingError } from '../../error/ErrorProductionDesignPendingError.ts';
|
|
@@ -15,7 +14,6 @@ import type {
|
|
|
15
14
|
RangeLeafNodeDefinition,
|
|
16
15
|
} from '../../parse/model/RangeNodeDefinition.ts';
|
|
17
16
|
import { RangeNodeDefinition } from '../../parse/model/RangeNodeDefinition.ts';
|
|
18
|
-
import type { SubtreeDefinition as ModelSubtreeDefinition } from '../../parse/model/SubtreeDefinition.ts';
|
|
19
17
|
import { Group } from '../Group.ts';
|
|
20
18
|
import type { GeneralChildNode, GeneralParentNode } from '../hierarchy.ts';
|
|
21
19
|
import { InputControl } from '../InputControl.ts';
|
|
@@ -26,17 +24,10 @@ import { RankControl } from '../RankControl.ts';
|
|
|
26
24
|
import { RepeatRangeControlled } from '../repeat/RepeatRangeControlled.ts';
|
|
27
25
|
import { RepeatRangeUncontrolled } from '../repeat/RepeatRangeUncontrolled.ts';
|
|
28
26
|
import { SelectControl } from '../SelectControl.ts';
|
|
29
|
-
import { Subtree } from '../Subtree.ts';
|
|
30
27
|
import { TriggerControl } from '../TriggerControl.ts';
|
|
31
28
|
import { UploadControl } from '../UploadControl.ts';
|
|
32
29
|
import { childrenInitOptions } from './childrenInitOptions.ts';
|
|
33
30
|
|
|
34
|
-
const isSubtreeDefinition = (
|
|
35
|
-
definition: ModelSubtreeDefinition
|
|
36
|
-
): definition is SubtreeDefinition => {
|
|
37
|
-
return definition.bodyElement == null;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
31
|
// prettier-ignore
|
|
41
32
|
type ControlNodeDefinition =
|
|
42
33
|
// eslint-disable-next-line @typescript-eslint/sort-type-constituents
|
|
@@ -131,14 +122,7 @@ export const buildChildren = (parent: GeneralParentNode): GeneralChildNode[] =>
|
|
|
131
122
|
const [instanceNode = null] = instanceNodes;
|
|
132
123
|
|
|
133
124
|
switch (definition.type) {
|
|
134
|
-
case '
|
|
135
|
-
if (isSubtreeDefinition(definition)) {
|
|
136
|
-
return new Subtree(parent, instanceNode, definition);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// TODO: it'd be good to be able to do without this type assertion. The
|
|
140
|
-
// only distinction between the types is whether `bodyElement` is
|
|
141
|
-
// `null`, but for some reason that's insufficient to narrow the union.
|
|
125
|
+
case 'group': {
|
|
142
126
|
return new Group(parent, instanceNode, definition as GroupDefinition);
|
|
143
127
|
}
|
|
144
128
|
|
|
@@ -3,21 +3,19 @@ import {
|
|
|
3
3
|
XFORMS_NAMESPACE_URI,
|
|
4
4
|
} from '@getodk/common/constants/xmlns.ts';
|
|
5
5
|
import type { GroupDefinition } from '../../client/GroupNode.ts';
|
|
6
|
-
import type { SubtreeDefinition } from '../../client/SubtreeNode.ts';
|
|
7
6
|
import { ErrorProductionDesignPendingError } from '../../error/ErrorProductionDesignPendingError.ts';
|
|
8
7
|
import { StaticDocument } from '../../integration/xpath/static-dom/StaticDocument.ts';
|
|
9
8
|
import type { StaticLeafElement } from '../../integration/xpath/static-dom/StaticElement.ts';
|
|
10
9
|
import { StaticElement } from '../../integration/xpath/static-dom/StaticElement.ts';
|
|
11
10
|
import type { NamespaceURL } from '../../lib/names/NamespaceURL.ts';
|
|
12
11
|
import type { QualifiedName } from '../../lib/names/QualifiedName.ts';
|
|
12
|
+
import type { GroupDefinition as ModelGroupDefinition } from '../../parse/model/GroupDefinition.ts';
|
|
13
13
|
import { LeafNodeDefinition } from '../../parse/model/LeafNodeDefinition.ts';
|
|
14
|
-
import type { SubtreeDefinition as ModelSubtreeDefinition } from '../../parse/model/SubtreeDefinition.ts';
|
|
15
14
|
import type { XFormDOM } from '../../parse/XFormDOM.ts';
|
|
16
15
|
import type { Group } from '../Group.ts';
|
|
17
16
|
import type { GeneralParentNode } from '../hierarchy.ts';
|
|
18
17
|
import type { PrimaryInstance } from '../PrimaryInstance.ts';
|
|
19
18
|
import type { Root } from '../Root.ts';
|
|
20
|
-
import type { Subtree } from '../Subtree.ts';
|
|
21
19
|
import type { ChildrenInitOptions } from './childrenInitOptions.ts';
|
|
22
20
|
import type { DescendantNodeInitOptions } from './DescendantNodeInitOptions.ts';
|
|
23
21
|
|
|
@@ -65,21 +63,12 @@ interface BaseMetaDefinition {
|
|
|
65
63
|
readonly qualifiedName: MetaName;
|
|
66
64
|
}
|
|
67
65
|
|
|
68
|
-
const isBaseMetaDefinition = <T extends
|
|
66
|
+
const isBaseMetaDefinition = <T extends ModelGroupDefinition>(
|
|
69
67
|
definition: T
|
|
70
68
|
): definition is BaseMetaDefinition & T => {
|
|
71
69
|
return isMetaName(definition.qualifiedName);
|
|
72
70
|
};
|
|
73
71
|
|
|
74
|
-
interface MetaSubtreeDefinition extends SubtreeDefinition {
|
|
75
|
-
readonly qualifiedName: MetaName;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
interface MetaSubtree extends Subtree {
|
|
79
|
-
readonly parent: Root;
|
|
80
|
-
readonly definition: MetaSubtreeDefinition;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
72
|
interface MetaGroupDefinition extends GroupDefinition {
|
|
84
73
|
readonly qualifiedName: MetaName;
|
|
85
74
|
}
|
|
@@ -89,17 +78,15 @@ interface MetaGroup extends Group {
|
|
|
89
78
|
readonly definition: MetaGroupDefinition;
|
|
90
79
|
}
|
|
91
80
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
interface MetaSubrootInitOptions extends ChildrenInitOptions {
|
|
95
|
-
readonly parent: MetaGroup | MetaSubtree;
|
|
81
|
+
interface MetaGroupInitOptions extends ChildrenInitOptions {
|
|
82
|
+
readonly parent: MetaGroup;
|
|
96
83
|
}
|
|
97
84
|
|
|
98
|
-
const
|
|
85
|
+
const isMetaGroup = (options: ChildrenInitOptions): options is MetaGroupInitOptions => {
|
|
99
86
|
const { nodeType } = options.parent;
|
|
100
87
|
|
|
101
88
|
return (
|
|
102
|
-
|
|
89
|
+
nodeType === 'group' &&
|
|
103
90
|
isDirectRootDescendant(options.parent) &&
|
|
104
91
|
isBaseMetaDefinition(options.parent.definition)
|
|
105
92
|
);
|
|
@@ -119,16 +106,16 @@ interface EditModeInstanceDescendant {
|
|
|
119
106
|
readonly rootDocument: EditModeInstance;
|
|
120
107
|
}
|
|
121
108
|
|
|
122
|
-
type
|
|
109
|
+
type EditModeMetaGroup = EditModeInstanceDescendant & MetaGroup;
|
|
123
110
|
|
|
124
|
-
interface
|
|
125
|
-
readonly parent:
|
|
111
|
+
interface EditModeMetaGroupInitOptions extends MetaGroupInitOptions {
|
|
112
|
+
readonly parent: EditModeMetaGroup;
|
|
126
113
|
}
|
|
127
114
|
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
):
|
|
131
|
-
return isEditModeInstance(
|
|
115
|
+
const isEditModeMetaGroup = (
|
|
116
|
+
group: MetaGroupInitOptions
|
|
117
|
+
): group is EditModeMetaGroupInitOptions => {
|
|
118
|
+
return isEditModeInstance(group.parent.rootDocument);
|
|
132
119
|
};
|
|
133
120
|
|
|
134
121
|
interface LeafNodeInitOptions extends DescendantNodeInitOptions {
|
|
@@ -147,13 +134,13 @@ const isLeafNodeInitOptions = (
|
|
|
147
134
|
type MetaLeafChildEntry = readonly [index: number, child: LeafNodeInitOptions];
|
|
148
135
|
|
|
149
136
|
const findMetaLeafChild = (
|
|
150
|
-
|
|
137
|
+
group: MetaGroupInitOptions,
|
|
151
138
|
localName: string
|
|
152
139
|
): MetaLeafChildEntry | null => {
|
|
153
|
-
const metaName =
|
|
140
|
+
const metaName = group.parent.definition.qualifiedName satisfies MetaName;
|
|
154
141
|
const namespaceURI = metaName.namespaceURI.href satisfies MetaNamespaceURIValue;
|
|
155
142
|
|
|
156
|
-
const result = Array.from(
|
|
143
|
+
const result = Array.from(group.children.entries()).find(
|
|
157
144
|
(entry): entry is [number, LeafNodeInitOptions] => {
|
|
158
145
|
const [, child] = entry;
|
|
159
146
|
|
|
@@ -173,8 +160,8 @@ const findMetaLeafChild = (
|
|
|
173
160
|
return result ?? null;
|
|
174
161
|
};
|
|
175
162
|
|
|
176
|
-
const getInstanceIDValue = (
|
|
177
|
-
const [, child = null] = findMetaLeafChild(
|
|
163
|
+
const getInstanceIDValue = (group: MetaGroupInitOptions): string | null => {
|
|
164
|
+
const [, child = null] = findMetaLeafChild(group, INSTANCE_ID_LOCAL_NAME) ?? [];
|
|
178
165
|
|
|
179
166
|
if (child == null) {
|
|
180
167
|
return null;
|
|
@@ -200,11 +187,11 @@ const assertStaticLeafElement: AssertStaticLeafElement = (element) => {
|
|
|
200
187
|
* on {@link populateDeprecatedID}.
|
|
201
188
|
*/
|
|
202
189
|
const buildMetaValueElement = (
|
|
203
|
-
|
|
190
|
+
group: MetaGroupInitOptions,
|
|
204
191
|
localName: string,
|
|
205
192
|
value: string
|
|
206
193
|
): StaticLeafElement => {
|
|
207
|
-
const { qualifiedName, nodeset } =
|
|
194
|
+
const { qualifiedName, nodeset } = group.parent.definition;
|
|
208
195
|
const { namespaceURI, prefix } = qualifiedName;
|
|
209
196
|
const { root } = new StaticDocument({
|
|
210
197
|
documentRoot: {
|
|
@@ -224,21 +211,21 @@ const buildMetaValueElement = (
|
|
|
224
211
|
};
|
|
225
212
|
|
|
226
213
|
const buildDeprecatedIDDefinition = (
|
|
227
|
-
|
|
214
|
+
group: EditModeMetaGroupInitOptions,
|
|
228
215
|
instanceNode: StaticLeafElement
|
|
229
216
|
): LeafNodeDefinition => {
|
|
230
217
|
const nodeset = instanceNode.nodeset;
|
|
231
|
-
const bind =
|
|
218
|
+
const bind = group.model.binds.getOrCreateBindDefinition(nodeset);
|
|
232
219
|
|
|
233
|
-
return new LeafNodeDefinition(
|
|
220
|
+
return new LeafNodeDefinition(group.parent.definition, bind, null, instanceNode);
|
|
234
221
|
};
|
|
235
222
|
|
|
236
223
|
const buildDeprecatedID = (
|
|
237
|
-
|
|
224
|
+
group: EditModeMetaGroupInitOptions,
|
|
238
225
|
value: string
|
|
239
226
|
): LeafNodeInitOptions => {
|
|
240
|
-
const instanceNode = buildMetaValueElement(
|
|
241
|
-
const definition = buildDeprecatedIDDefinition(
|
|
227
|
+
const instanceNode = buildMetaValueElement(group, DEPRECATED_ID_LOCAL_NAME, value);
|
|
228
|
+
const definition = buildDeprecatedIDDefinition(group, instanceNode);
|
|
242
229
|
|
|
243
230
|
return {
|
|
244
231
|
childNodeset: instanceNode.nodeset,
|
|
@@ -248,11 +235,11 @@ const buildDeprecatedID = (
|
|
|
248
235
|
};
|
|
249
236
|
|
|
250
237
|
const updateDeprecatedID = (
|
|
251
|
-
|
|
238
|
+
group: EditModeMetaGroupInitOptions,
|
|
252
239
|
child: LeafNodeInitOptions,
|
|
253
240
|
value: string
|
|
254
241
|
): LeafNodeInitOptions => {
|
|
255
|
-
const instanceNode = buildMetaValueElement(
|
|
242
|
+
const instanceNode = buildMetaValueElement(group, DEPRECATED_ID_LOCAL_NAME, value);
|
|
256
243
|
|
|
257
244
|
return {
|
|
258
245
|
childNodeset: child.childNodeset,
|
|
@@ -288,44 +275,42 @@ const replaceOrConcat = <T>(values: readonly T[], index: number | null, value: T
|
|
|
288
275
|
* hacky normalization for `instanceID`.
|
|
289
276
|
*/
|
|
290
277
|
const populateDeprecatedID = (
|
|
291
|
-
|
|
292
|
-
):
|
|
293
|
-
const value = getInstanceIDValue(
|
|
278
|
+
group: EditModeMetaGroupInitOptions
|
|
279
|
+
): EditModeMetaGroupInitOptions => {
|
|
280
|
+
const value = getInstanceIDValue(group);
|
|
294
281
|
|
|
295
282
|
if (value == null) {
|
|
296
|
-
return
|
|
283
|
+
return group;
|
|
297
284
|
}
|
|
298
285
|
|
|
299
|
-
const [index, currentDeprecatedID] = findMetaLeafChild(
|
|
300
|
-
null,
|
|
301
|
-
];
|
|
286
|
+
const [index, currentDeprecatedID] = findMetaLeafChild(group, DEPRECATED_ID_LOCAL_NAME) ?? [null];
|
|
302
287
|
|
|
303
288
|
let deprecatedID: LeafNodeInitOptions;
|
|
304
289
|
|
|
305
290
|
if (currentDeprecatedID == null) {
|
|
306
|
-
deprecatedID = buildDeprecatedID(
|
|
291
|
+
deprecatedID = buildDeprecatedID(group, value);
|
|
307
292
|
} else {
|
|
308
|
-
deprecatedID = updateDeprecatedID(
|
|
293
|
+
deprecatedID = updateDeprecatedID(group, currentDeprecatedID, value);
|
|
309
294
|
}
|
|
310
295
|
|
|
311
296
|
return {
|
|
312
|
-
model:
|
|
313
|
-
parent:
|
|
314
|
-
children: replaceOrConcat(
|
|
297
|
+
model: group.model,
|
|
298
|
+
parent: group.parent,
|
|
299
|
+
children: replaceOrConcat(group.children, index, deprecatedID),
|
|
315
300
|
};
|
|
316
301
|
};
|
|
317
302
|
|
|
318
|
-
const
|
|
319
|
-
if (
|
|
320
|
-
return populateDeprecatedID(
|
|
303
|
+
const normalizeMetaGroup = (group: MetaGroupInitOptions): MetaGroupInitOptions => {
|
|
304
|
+
if (isEditModeMetaGroup(group)) {
|
|
305
|
+
return populateDeprecatedID(group);
|
|
321
306
|
}
|
|
322
307
|
|
|
323
|
-
return
|
|
308
|
+
return group;
|
|
324
309
|
};
|
|
325
310
|
|
|
326
311
|
export const normalizeChildInitOptions = (options: ChildrenInitOptions): ChildrenInitOptions => {
|
|
327
|
-
if (
|
|
328
|
-
return
|
|
312
|
+
if (isMetaGroup(options)) {
|
|
313
|
+
return normalizeMetaGroup(options);
|
|
329
314
|
}
|
|
330
315
|
|
|
331
316
|
return options;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Attribute } from './Attribute.ts';
|
|
1
2
|
import type { Group } from './Group.ts';
|
|
2
3
|
import type { AnyInputControl } from './InputControl.ts';
|
|
3
4
|
import type { AnyModelValue } from './ModelValue.ts';
|
|
@@ -10,7 +11,6 @@ import type { RepeatRangeControlled } from './repeat/RepeatRangeControlled.ts';
|
|
|
10
11
|
import type { RepeatRangeUncontrolled } from './repeat/RepeatRangeUncontrolled.ts';
|
|
11
12
|
import type { Root } from './Root.ts';
|
|
12
13
|
import type { SelectControl } from './SelectControl.ts';
|
|
13
|
-
import type { Subtree } from './Subtree.ts';
|
|
14
14
|
import type { TriggerControl } from './TriggerControl.ts';
|
|
15
15
|
import type { UploadControl } from './UploadControl.ts';
|
|
16
16
|
|
|
@@ -22,7 +22,6 @@ export type AnyNode =
|
|
|
22
22
|
| PrimaryInstance
|
|
23
23
|
| Root
|
|
24
24
|
| Group
|
|
25
|
-
| Subtree
|
|
26
25
|
| RepeatRange
|
|
27
26
|
| RepeatInstance
|
|
28
27
|
| AnyNote
|
|
@@ -40,7 +39,6 @@ export type AnyParentNode =
|
|
|
40
39
|
| PrimaryInstance
|
|
41
40
|
| Root
|
|
42
41
|
| Group
|
|
43
|
-
| Subtree
|
|
44
42
|
| RepeatRange
|
|
45
43
|
| RepeatInstance;
|
|
46
44
|
|
|
@@ -49,7 +47,6 @@ export type GeneralParentNode =
|
|
|
49
47
|
// eslint-disable-next-line @typescript-eslint/sort-type-constituents
|
|
50
48
|
| Root
|
|
51
49
|
| Group
|
|
52
|
-
| Subtree
|
|
53
50
|
| RepeatInstance;
|
|
54
51
|
|
|
55
52
|
// prettier-ignore
|
|
@@ -57,7 +54,6 @@ export type AnyChildNode =
|
|
|
57
54
|
// eslint-disable-next-line @typescript-eslint/sort-type-constituents
|
|
58
55
|
| Root
|
|
59
56
|
| Group
|
|
60
|
-
| Subtree
|
|
61
57
|
| RepeatRange
|
|
62
58
|
| RepeatInstance
|
|
63
59
|
| AnyModelValue
|
|
@@ -67,13 +63,13 @@ export type AnyChildNode =
|
|
|
67
63
|
| RankControl
|
|
68
64
|
| SelectControl
|
|
69
65
|
| TriggerControl
|
|
70
|
-
| UploadControl
|
|
66
|
+
| UploadControl
|
|
67
|
+
| Attribute;
|
|
71
68
|
|
|
72
69
|
// prettier-ignore
|
|
73
70
|
export type GeneralChildNode =
|
|
74
71
|
// eslint-disable-next-line @typescript-eslint/sort-type-constituents
|
|
75
72
|
| Group
|
|
76
|
-
| Subtree
|
|
77
73
|
| RepeatRange
|
|
78
74
|
| AnyModelValue
|
|
79
75
|
| AnyNote
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { FormInstanceInitializationMode } from '../../client/index.ts';
|
|
2
|
+
import type { StaticAttribute } from '../../integration/xpath/static-dom/StaticAttribute.ts';
|
|
3
|
+
import type { ReactiveScope } from '../../lib/reactivity/scope.ts';
|
|
4
|
+
import type { BindComputationExpression } from '../../parse/expression/BindComputationExpression.ts';
|
|
5
|
+
import type { AnyBindPreloadDefinition } from '../../parse/model/BindPreloadDefinition.ts';
|
|
6
|
+
import type { EvaluationContext } from './EvaluationContext.ts';
|
|
7
|
+
|
|
8
|
+
export interface InstanceAttributeContextDocument {
|
|
9
|
+
readonly initializationMode: FormInstanceInitializationMode;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type DecodeInstanceValue = (value: string) => string;
|
|
13
|
+
|
|
14
|
+
interface InstanceAttributeContextDefinitionBind {
|
|
15
|
+
readonly preload: AnyBindPreloadDefinition | null;
|
|
16
|
+
readonly calculate: BindComputationExpression<'calculate'> | null;
|
|
17
|
+
readonly readonly: BindComputationExpression<'readonly'>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface InstanceAttributeContextDefinition {
|
|
21
|
+
readonly bind: InstanceAttributeContextDefinitionBind;
|
|
22
|
+
readonly template: StaticAttribute;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface AttributeContext extends EvaluationContext {
|
|
26
|
+
readonly scope: ReactiveScope;
|
|
27
|
+
readonly rootDocument: InstanceAttributeContextDocument;
|
|
28
|
+
readonly definition: InstanceAttributeContextDefinition;
|
|
29
|
+
readonly instanceNode: StaticAttribute;
|
|
30
|
+
readonly decodeInstanceValue: DecodeInstanceValue;
|
|
31
|
+
|
|
32
|
+
isReadonly(): boolean;
|
|
33
|
+
isRelevant(): boolean;
|
|
34
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { InstanceState } from '../../../client/serialization/InstanceState.ts';
|
|
2
|
+
import type { QualifiedName } from '../../../lib/names/QualifiedName.ts';
|
|
3
|
+
|
|
4
|
+
export type SerializedInstanceValue = string;
|
|
5
|
+
|
|
6
|
+
interface ClientReactiveSerializableAttributeNodeCurrentState {
|
|
7
|
+
get relevant(): boolean;
|
|
8
|
+
get instanceValue(): SerializedInstanceValue;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface ClientReactiveSerializableAttributeNodeDefinition {
|
|
12
|
+
readonly qualifiedName: QualifiedName;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ClientReactiveSerializableAttributeNode {
|
|
16
|
+
readonly definition: ClientReactiveSerializableAttributeNodeDefinition;
|
|
17
|
+
readonly currentState: ClientReactiveSerializableAttributeNodeCurrentState;
|
|
18
|
+
readonly instanceState: InstanceState;
|
|
19
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { InstanceState } from '../../../client/serialization/InstanceState.ts';
|
|
2
2
|
import type { QualifiedName } from '../../../lib/names/QualifiedName.ts';
|
|
3
|
+
import type { Attribute } from '../../Attribute.ts';
|
|
3
4
|
|
|
4
5
|
export interface ClientReactiveSerializableChildNode {
|
|
5
6
|
readonly instanceState: InstanceState;
|
|
@@ -10,6 +11,7 @@ export interface ClientReactiveSerializableParentNodeCurrentState<
|
|
|
10
11
|
> {
|
|
11
12
|
get relevant(): boolean;
|
|
12
13
|
get children(): readonly Child[];
|
|
14
|
+
get attributes(): readonly Attribute[];
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
export interface ClientReactiveSerializableParentNodeDefinition {
|