@getodk/xforms-engine 0.5.0 → 0.6.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/README.md +1 -1
- package/dist/client/BaseNode.d.ts +4 -0
- package/dist/client/BaseValueNode.d.ts +1 -1
- package/dist/client/GroupNode.d.ts +1 -0
- package/dist/client/InputNode.d.ts +32 -3
- package/dist/client/ModelValueNode.d.ts +1 -0
- package/dist/client/NoteNode.d.ts +24 -7
- package/dist/client/RangeNode.d.ts +36 -0
- package/dist/client/RankNode.d.ts +46 -0
- package/dist/client/RootNode.d.ts +6 -3
- package/dist/client/SelectNode.d.ts +47 -25
- package/dist/client/SubtreeNode.d.ts +1 -0
- package/dist/client/TriggerNode.d.ts +10 -6
- package/dist/client/hierarchy.d.ts +5 -5
- package/dist/client/node-types.d.ts +2 -2
- package/dist/client/unsupported/UnsupportedControlNode.d.ts +1 -3
- package/dist/error/RankMissingValueError.d.ts +3 -0
- package/dist/error/RankValueTypeError.d.ts +6 -0
- package/dist/error/SelectValueTypeError.d.ts +15 -0
- package/dist/error/XFormsSpecViolationError.d.ts +2 -0
- package/dist/index.d.ts +2 -3
- package/dist/index.js +5604 -4666
- package/dist/index.js.map +1 -1
- package/dist/instance/Group.d.ts +1 -0
- package/dist/instance/InputControl.d.ts +5 -3
- package/dist/instance/ModelValue.d.ts +2 -0
- package/dist/instance/Note.d.ts +13 -25
- package/dist/instance/PrimaryInstance.d.ts +1 -0
- package/dist/instance/RangeControl.d.ts +34 -0
- package/dist/instance/RankControl.d.ts +40 -0
- package/dist/instance/Root.d.ts +1 -0
- package/dist/instance/SelectControl.d.ts +66 -0
- package/dist/instance/Subtree.d.ts +1 -0
- package/dist/instance/TriggerControl.d.ts +9 -22
- package/dist/instance/abstract/DescendantNode.d.ts +1 -2
- package/dist/instance/abstract/InstanceNode.d.ts +3 -1
- package/dist/instance/abstract/UnsupportedControl.d.ts +1 -0
- package/dist/instance/abstract/ValueNode.d.ts +0 -1
- package/dist/instance/hierarchy.d.ts +9 -9
- package/dist/instance/internal-api/InstanceValueContext.d.ts +2 -0
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.d.ts +2 -1
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableParentNode.d.ts +2 -1
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableValueNode.d.ts +2 -1
- package/dist/instance/repeat/BaseRepeatRange.d.ts +1 -0
- package/dist/instance/repeat/RepeatInstance.d.ts +1 -0
- package/dist/integration/xpath/adapter/names.d.ts +1 -11
- package/dist/integration/xpath/adapter/traversal.d.ts +10 -9
- package/dist/integration/xpath/static-dom/StaticAttribute.d.ts +10 -3
- package/dist/integration/xpath/static-dom/StaticDocument.d.ts +0 -1
- package/dist/integration/xpath/static-dom/StaticElement.d.ts +12 -4
- package/dist/lib/client-reactivity/submission/createRootSubmissionState.d.ts +3 -0
- package/dist/lib/codecs/Geopoint/Geopoint.d.ts +48 -0
- package/dist/lib/codecs/Geopoint/GeopointValueCodec.d.ts +5 -0
- package/dist/lib/codecs/NoteCodec.d.ts +8 -0
- package/dist/lib/codecs/RangeCodec.d.ts +8 -0
- package/dist/lib/codecs/TriggerCodec.d.ts +7 -0
- package/dist/lib/codecs/ValueArrayCodec.d.ts +11 -0
- package/dist/lib/codecs/ValueCodec.d.ts +2 -2
- package/dist/lib/codecs/getNoteCodec.d.ts +3 -0
- package/dist/lib/codecs/getSelectCodec.d.ts +5 -0
- package/dist/lib/codecs/getSharedValueCodec.d.ts +3 -2
- package/dist/lib/codecs/items/BaseItemCodec.d.ts +9 -0
- package/dist/lib/codecs/items/MultipleValueItemCodec.d.ts +14 -0
- package/dist/lib/codecs/items/SingleValueItemCodec.d.ts +24 -0
- package/dist/lib/dom/query.d.ts +1 -2
- package/dist/lib/names/NamespaceDeclaration.d.ts +45 -0
- package/dist/lib/names/NamespaceDeclarationMap.d.ts +137 -0
- package/dist/lib/names/NamespaceURL.d.ts +30 -0
- package/dist/lib/names/QualifiedName.d.ts +113 -0
- package/dist/lib/number-parsers.d.ts +2 -0
- package/dist/lib/reactivity/createItemCollection.d.ts +21 -0
- package/dist/lib/xml-serialization.d.ts +11 -2
- package/dist/parse/XFormDOM.d.ts +1 -1
- package/dist/parse/body/BodyDefinition.d.ts +2 -2
- package/dist/parse/body/appearance/rangeAppearanceParser.d.ts +3 -0
- package/dist/parse/body/control/InputControlDefinition.d.ts +3 -0
- package/dist/parse/body/control/ItemDefinition.d.ts +14 -0
- package/dist/parse/body/control/ItemsetDefinition.d.ts +18 -0
- package/dist/parse/body/control/RangeControlDefinition.d.ts +31 -2
- package/dist/parse/body/control/RankControlDefinition.d.ts +7 -3
- package/dist/parse/body/control/{select/SelectDefinition.d.ts → SelectControlDefinition.d.ts} +9 -9
- package/dist/parse/expression/ItemsetNodesetExpression.d.ts +1 -1
- package/dist/parse/expression/ItemsetValueExpression.d.ts +1 -1
- package/dist/parse/model/BindDefinition.d.ts +3 -1
- package/dist/parse/model/BindPreloadDefinition.d.ts +42 -0
- package/dist/parse/model/DescendentNodeDefinition.d.ts +4 -13
- package/dist/parse/model/ItextTranslation/ItextTranslationRootDefinition.d.ts +2 -1
- package/dist/parse/model/LeafNodeDefinition.d.ts +7 -4
- package/dist/parse/model/ModelBindMap.d.ts +1 -1
- package/dist/parse/model/NodeDefinition.d.ts +16 -19
- package/dist/parse/model/NoteNodeDefinition.d.ts +6 -5
- package/dist/parse/model/RangeNodeDefinition.d.ts +41 -0
- package/dist/parse/model/RepeatInstanceDefinition.d.ts +7 -4
- package/dist/parse/model/RepeatRangeDefinition.d.ts +7 -4
- package/dist/parse/model/RepeatTemplateDefinition.d.ts +7 -4
- package/dist/parse/model/RootAttributeDefinition.d.ts +24 -0
- package/dist/parse/model/RootAttributeMap.d.ts +23 -0
- package/dist/parse/model/RootDefinition.d.ts +9 -7
- package/dist/parse/model/SubtreeDefinition.d.ts +7 -4
- package/dist/parse/shared/parseStaticDocumentFromDOMSubtree.d.ts +2 -3
- package/dist/parse/text/ItemLabelDefinition.d.ts +1 -1
- package/dist/parse/text/ItemsetLabelDefinition.d.ts +2 -2
- package/dist/parse/text/abstract/TextElementDefinition.d.ts +1 -1
- package/dist/parse/xpath/semantic-analysis.d.ts +1 -3
- package/dist/solid.js +5603 -4665
- package/dist/solid.js.map +1 -1
- package/package.json +15 -12
- package/src/client/BaseNode.ts +5 -0
- package/src/client/BaseValueNode.ts +1 -1
- package/src/client/GroupNode.ts +1 -0
- package/src/client/InputNode.ts +38 -2
- package/src/client/ModelValueNode.ts +1 -0
- package/src/client/NoteNode.ts +43 -7
- package/src/client/RangeNode.ts +51 -0
- package/src/client/RankNode.ts +54 -0
- package/src/client/RootNode.ts +11 -5
- package/src/client/SelectNode.ts +53 -26
- package/src/client/SubtreeNode.ts +1 -0
- package/src/client/TriggerNode.ts +12 -6
- package/src/client/hierarchy.ts +7 -8
- package/src/client/node-types.ts +1 -1
- package/src/client/unsupported/UnsupportedControlNode.ts +2 -6
- package/src/error/RankMissingValueError.ts +5 -0
- package/src/error/RankValueTypeError.ts +13 -0
- package/src/error/SelectValueTypeError.ts +22 -0
- package/src/error/XFormsSpecViolationError.ts +1 -0
- package/src/index.ts +2 -12
- package/src/instance/Group.ts +1 -0
- package/src/instance/InputControl.ts +42 -2
- package/src/instance/ModelValue.ts +2 -0
- package/src/instance/Note.ts +34 -59
- package/src/instance/PrimaryInstance.ts +1 -0
- package/src/instance/RangeControl.ts +113 -0
- package/src/instance/RankControl.ts +199 -0
- package/src/instance/Root.ts +3 -2
- package/src/instance/SelectControl.ts +219 -0
- package/src/instance/Subtree.ts +1 -0
- package/src/instance/TriggerControl.ts +36 -75
- package/src/instance/abstract/DescendantNode.ts +1 -6
- package/src/instance/abstract/InstanceNode.ts +10 -2
- package/src/instance/abstract/UnsupportedControl.ts +1 -0
- package/src/instance/abstract/ValueNode.ts +3 -2
- package/src/instance/children.ts +71 -30
- package/src/instance/hierarchy.ts +21 -16
- package/src/instance/internal-api/InstanceValueContext.ts +2 -0
- package/src/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.ts +2 -1
- package/src/instance/internal-api/submission/ClientReactiveSubmittableParentNode.ts +2 -1
- package/src/instance/internal-api/submission/ClientReactiveSubmittableValueNode.ts +2 -1
- package/src/instance/repeat/BaseRepeatRange.ts +2 -0
- package/src/instance/repeat/RepeatInstance.ts +1 -0
- package/src/instance/resource.ts +4 -1
- package/src/integration/xpath/adapter/names.ts +66 -17
- package/src/integration/xpath/adapter/traversal.ts +10 -9
- package/src/integration/xpath/static-dom/StaticAttribute.ts +15 -7
- package/src/integration/xpath/static-dom/StaticDocument.ts +0 -2
- package/src/integration/xpath/static-dom/StaticElement.ts +21 -8
- package/src/lib/client-reactivity/submission/createLeafNodeSubmissionState.ts +1 -1
- package/src/lib/client-reactivity/submission/createParentNodeSubmissionState.ts +1 -1
- package/src/lib/client-reactivity/submission/createRootSubmissionState.ts +19 -0
- package/src/lib/client-reactivity/submission/createValueNodeSubmissionState.ts +2 -2
- package/src/lib/codecs/Geopoint/Geopoint.ts +150 -0
- package/src/lib/codecs/Geopoint/GeopointValueCodec.ts +20 -0
- package/src/lib/codecs/NoteCodec.ts +32 -0
- package/src/lib/codecs/RangeCodec.ts +65 -0
- package/src/lib/codecs/TriggerCodec.ts +64 -0
- package/src/lib/codecs/ValueArrayCodec.ts +42 -0
- package/src/lib/codecs/ValueCodec.ts +2 -2
- package/src/lib/codecs/getNoteCodec.ts +27 -0
- package/src/lib/codecs/getSelectCodec.ts +27 -0
- package/src/lib/codecs/getSharedValueCodec.ts +5 -3
- package/src/lib/codecs/items/BaseItemCodec.ts +20 -0
- package/src/lib/codecs/items/MultipleValueItemCodec.ts +28 -0
- package/src/lib/codecs/items/SingleValueItemCodec.ts +67 -0
- package/src/lib/dom/query.ts +1 -2
- package/src/lib/names/NamespaceDeclaration.ts +106 -0
- package/src/lib/names/NamespaceDeclarationMap.ts +228 -0
- package/src/lib/names/NamespaceURL.ts +44 -0
- package/src/lib/names/QualifiedName.ts +170 -0
- package/src/lib/number-parsers.ts +25 -0
- package/src/lib/reactivity/createInstanceValueState.ts +50 -0
- package/src/lib/reactivity/{createSelectItems.ts → createItemCollection.ts} +41 -36
- package/src/lib/xml-serialization.ts +76 -9
- package/src/parse/XFormDOM.ts +141 -21
- package/src/parse/XFormDefinition.ts +1 -4
- package/src/parse/body/BodyDefinition.ts +4 -4
- package/src/parse/body/appearance/rangeAppearanceParser.ts +11 -0
- package/src/parse/body/control/InputControlDefinition.ts +9 -0
- package/src/parse/body/control/{select/ItemDefinition.ts → ItemDefinition.ts} +8 -6
- package/src/parse/body/control/{select/ItemsetDefinition.ts → ItemsetDefinition.ts} +11 -9
- package/src/parse/body/control/RangeControlDefinition.ts +91 -6
- package/src/parse/body/control/RankControlDefinition.ts +25 -7
- package/src/parse/body/control/{select/SelectDefinition.ts → SelectControlDefinition.ts} +9 -9
- package/src/parse/expression/ItemsetNodesetExpression.ts +1 -1
- package/src/parse/expression/ItemsetValueExpression.ts +1 -1
- package/src/parse/model/BindDefinition.ts +4 -0
- package/src/parse/model/BindPreloadDefinition.ts +100 -0
- package/src/parse/model/DescendentNodeDefinition.ts +7 -25
- package/src/parse/model/ItextTranslation/ItextTranslationRootDefinition.ts +2 -1
- package/src/parse/model/LeafNodeDefinition.ts +11 -4
- package/src/parse/model/NodeDefinition.ts +24 -45
- package/src/parse/model/NoteNodeDefinition.ts +8 -7
- package/src/parse/model/RangeNodeDefinition.ts +118 -0
- package/src/parse/model/RepeatInstanceDefinition.ts +11 -7
- package/src/parse/model/RepeatRangeDefinition.ts +11 -7
- package/src/parse/model/RepeatTemplateDefinition.ts +11 -7
- package/src/parse/model/RootAttributeDefinition.ts +45 -0
- package/src/parse/model/RootAttributeMap.ts +44 -0
- package/src/parse/model/RootDefinition.ts +29 -28
- package/src/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.ts +1 -0
- package/src/parse/model/SubtreeDefinition.ts +12 -12
- package/src/parse/shared/parseStaticDocumentFromDOMSubtree.ts +3 -3
- package/src/parse/text/ItemLabelDefinition.ts +1 -1
- package/src/parse/text/ItemsetLabelDefinition.ts +2 -2
- package/src/parse/text/abstract/TextElementDefinition.ts +1 -1
- package/src/parse/xpath/semantic-analysis.ts +4 -3
- package/dist/client/unsupported/RangeNode.d.ts +0 -9
- package/dist/client/unsupported/RankNode.d.ts +0 -9
- package/dist/instance/SelectField.d.ts +0 -58
- package/dist/instance/unsupported/RangeControl.d.ts +0 -6
- package/dist/instance/unsupported/RankControl.d.ts +0 -6
- package/dist/integration/xpath/static-dom/StaticNamedNode.d.ts +0 -17
- package/dist/lib/reactivity/createSelectItems.d.ts +0 -16
- package/dist/parse/body/control/select/ItemDefinition.d.ts +0 -13
- package/dist/parse/body/control/select/ItemsetDefinition.d.ts +0 -17
- package/dist/parse/body/control/select/ItemsetNodesetContext.d.ts +0 -9
- package/src/client/unsupported/RangeNode.ts +0 -14
- package/src/client/unsupported/RankNode.ts +0 -14
- package/src/instance/SelectField.ts +0 -263
- package/src/instance/unsupported/RangeControl.ts +0 -9
- package/src/instance/unsupported/RankControl.ts +0 -9
- package/src/integration/xpath/static-dom/StaticNamedNode.ts +0 -45
- package/src/parse/body/control/select/ItemsetNodesetContext.ts +0 -21
|
@@ -1,23 +1,108 @@
|
|
|
1
|
+
import { ErrorProductionDesignPendingError } from '../../../error/ErrorProductionDesignPendingError.ts';
|
|
1
2
|
import type { XFormDefinition } from '../../XFormDefinition.ts';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
type UnknownAppearanceDefinition,
|
|
5
|
-
} from '../appearance/unknownAppearanceParser.ts';
|
|
3
|
+
import type { RangeAppearanceDefinition } from '../appearance/rangeAppearanceParser.ts';
|
|
4
|
+
import { rangeAppearanceParser } from '../appearance/rangeAppearanceParser.ts';
|
|
6
5
|
import type { BodyElementParentContext } from '../BodyDefinition.ts';
|
|
7
6
|
import { ControlDefinition } from './ControlDefinition.ts';
|
|
8
7
|
|
|
8
|
+
type NumericString = `${number}`;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @todo this should likely become a basis for generalizing how we parse number
|
|
12
|
+
* values from strings. Note for when we take that on: number semantics vary
|
|
13
|
+
* between:
|
|
14
|
+
*
|
|
15
|
+
* - {@link https://www.w3.org/TR/1999/REC-xpath-19991116/#numbers | XPath}:
|
|
16
|
+
* XPath "64-bit [...] IEEE 754" number values are almost totally consistent
|
|
17
|
+
* with JavaScript numbers; the main difference is that JavaScript's
|
|
18
|
+
* {@link Number} factory is more flexible in casting from string than the
|
|
19
|
+
* casting semantics specified by XPath
|
|
20
|
+
*
|
|
21
|
+
* - {@link https://getodk.github.io/xforms-spec/#data-types | [ODK] XForms}:
|
|
22
|
+
* specifies both `int` and `decimal` types. Decimals are **NOT** expected to
|
|
23
|
+
* have the same precision tradeoffs as IEEE 754 numbers, and we'll want to
|
|
24
|
+
* take special care that parsing does not introduce precision errors.
|
|
25
|
+
*/
|
|
26
|
+
const NUMERIC_STRING_PATTERN = /^-?\d+(\.\d+)?$/;
|
|
27
|
+
|
|
28
|
+
const isNumericString = (value: string): value is NumericString => {
|
|
29
|
+
return NUMERIC_STRING_PATTERN.test(value);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
type AssertNumericStringAttribute = (
|
|
33
|
+
localName: string,
|
|
34
|
+
value: string | null
|
|
35
|
+
) => asserts value is NumericString;
|
|
36
|
+
|
|
37
|
+
const assertNumericStringAttribute: AssertNumericStringAttribute = (localName, value) => {
|
|
38
|
+
if (value == null) {
|
|
39
|
+
throw new ErrorProductionDesignPendingError(`Expected attribute ${localName} is not defined`);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!isNumericString(value)) {
|
|
43
|
+
throw new ErrorProductionDesignPendingError(
|
|
44
|
+
`Expected attribute ${localName} to be defined with numeric string, got: ${JSON.stringify(value)}`
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const parseNumericStringAttribute = (element: Element, localName: string): NumericString => {
|
|
50
|
+
const value = element.getAttribute(localName);
|
|
51
|
+
|
|
52
|
+
assertNumericStringAttribute(localName, value);
|
|
53
|
+
|
|
54
|
+
return value;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Per
|
|
59
|
+
* {@link https://getodk.github.io/xforms-spec/#body-elements | ODK XForms spec},
|
|
60
|
+
* the following attributes are required:
|
|
61
|
+
*
|
|
62
|
+
* - `start`
|
|
63
|
+
* - `end`
|
|
64
|
+
* - `step`
|
|
65
|
+
*
|
|
66
|
+
* While we also know that a `<range>` control is expected to have a bind type
|
|
67
|
+
* of either `decimal` or `int`, at this parsing stage we do not yet know which
|
|
68
|
+
* type is associated with the control. So we parse the attributes as strings,
|
|
69
|
+
* checking only that they appear to be numeric values. We also preserve the
|
|
70
|
+
* attributes' names here, for consistency with the spec.
|
|
71
|
+
*
|
|
72
|
+
* Downstream, we parse these to their appropriate numeric runtime types, and
|
|
73
|
+
* alias them to their more conventional names (i.e. "start" -> "min", "end" ->
|
|
74
|
+
* "max").
|
|
75
|
+
*/
|
|
76
|
+
export class RangeControlBoundsDefinition {
|
|
77
|
+
static from(element: Element) {
|
|
78
|
+
const start = parseNumericStringAttribute(element, 'start');
|
|
79
|
+
const end = parseNumericStringAttribute(element, 'end');
|
|
80
|
+
const step = parseNumericStringAttribute(element, 'step');
|
|
81
|
+
|
|
82
|
+
return new this(start, end, step);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
constructor(
|
|
86
|
+
readonly start: NumericString,
|
|
87
|
+
readonly end: NumericString,
|
|
88
|
+
readonly step: NumericString
|
|
89
|
+
) {}
|
|
90
|
+
}
|
|
91
|
+
|
|
9
92
|
export class RangeControlDefinition extends ControlDefinition<'range'> {
|
|
10
93
|
static override isCompatible(localName: string): boolean {
|
|
11
94
|
return localName === 'range';
|
|
12
95
|
}
|
|
13
96
|
|
|
14
97
|
readonly type = 'range';
|
|
15
|
-
readonly appearances:
|
|
98
|
+
readonly appearances: RangeAppearanceDefinition;
|
|
99
|
+
readonly bounds: RangeControlBoundsDefinition;
|
|
16
100
|
|
|
17
101
|
constructor(form: XFormDefinition, parent: BodyElementParentContext, element: Element) {
|
|
18
102
|
super(form, parent, element);
|
|
19
103
|
|
|
20
|
-
this.appearances =
|
|
104
|
+
this.appearances = rangeAppearanceParser.parseFrom(element, 'appearance');
|
|
105
|
+
this.bounds = RangeControlBoundsDefinition.from(element);
|
|
21
106
|
}
|
|
22
107
|
|
|
23
108
|
override toJSON(): object {
|
|
@@ -1,27 +1,45 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getItemElements, getItemsetElement } from '../../../lib/dom/query.ts';
|
|
2
2
|
import type { XFormDefinition } from '../../XFormDefinition.ts';
|
|
3
|
+
import type { BodyElementParentContext } from '../BodyDefinition.ts';
|
|
4
|
+
import { ControlDefinition } from './ControlDefinition.ts';
|
|
5
|
+
import { ItemsetDefinition } from './ItemsetDefinition.ts';
|
|
6
|
+
import { ItemDefinition } from './ItemDefinition.ts';
|
|
3
7
|
import {
|
|
4
|
-
unknownAppearanceParser,
|
|
5
8
|
type UnknownAppearanceDefinition,
|
|
9
|
+
unknownAppearanceParser,
|
|
6
10
|
} from '../appearance/unknownAppearanceParser.ts';
|
|
7
|
-
import type { BodyElementParentContext } from '../BodyDefinition.ts';
|
|
8
|
-
import { ControlDefinition } from './ControlDefinition.ts';
|
|
9
11
|
|
|
10
12
|
export class RankControlDefinition extends ControlDefinition<'rank'> {
|
|
11
|
-
static override isCompatible(localName: string
|
|
12
|
-
return localName === 'rank'
|
|
13
|
+
static override isCompatible(localName: string): boolean {
|
|
14
|
+
return localName === 'rank';
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
readonly type = 'rank';
|
|
16
18
|
readonly appearances: UnknownAppearanceDefinition;
|
|
19
|
+
readonly itemset: ItemsetDefinition | null;
|
|
20
|
+
readonly items: readonly ItemDefinition[];
|
|
17
21
|
|
|
18
22
|
constructor(form: XFormDefinition, parent: BodyElementParentContext, element: Element) {
|
|
19
23
|
super(form, parent, element);
|
|
20
24
|
|
|
21
25
|
this.appearances = unknownAppearanceParser.parseFrom(element, 'appearance');
|
|
26
|
+
const itemsetElement = getItemsetElement(element);
|
|
27
|
+
const itemElements = getItemElements(element);
|
|
28
|
+
|
|
29
|
+
if (itemsetElement === null || itemElements === undefined) {
|
|
30
|
+
this.itemset = null;
|
|
31
|
+
this.items = itemElements.map((itemElement) => new ItemDefinition(form, this, itemElement));
|
|
32
|
+
} else {
|
|
33
|
+
if (itemElements.length > 0) {
|
|
34
|
+
throw new Error(`<${element.nodeName}> has both <itemset> and <item> children`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
this.items = [];
|
|
38
|
+
this.itemset = new ItemsetDefinition(form, this, itemsetElement);
|
|
39
|
+
}
|
|
22
40
|
}
|
|
23
41
|
|
|
24
|
-
override toJSON()
|
|
42
|
+
override toJSON() {
|
|
25
43
|
return {};
|
|
26
44
|
}
|
|
27
45
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
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 '
|
|
4
|
-
import type { XFormDefinition } from '
|
|
5
|
-
import type { SelectAppearanceDefinition } from '
|
|
6
|
-
import { selectAppearanceParser } from '
|
|
7
|
-
import type { AnyBodyElementDefinition, BodyElementParentContext } from '
|
|
8
|
-
import { ControlDefinition } from '
|
|
3
|
+
import { getItemElements, getItemsetElement } from '../../../lib/dom/query.ts';
|
|
4
|
+
import type { XFormDefinition } from '../../XFormDefinition.ts';
|
|
5
|
+
import type { SelectAppearanceDefinition } from '../appearance/selectAppearanceParser.ts';
|
|
6
|
+
import { selectAppearanceParser } from '../appearance/selectAppearanceParser.ts';
|
|
7
|
+
import type { AnyBodyElementDefinition, BodyElementParentContext } from '../BodyDefinition.ts';
|
|
8
|
+
import { ControlDefinition } from './ControlDefinition.ts';
|
|
9
9
|
import { ItemDefinition } from './ItemDefinition.ts';
|
|
10
10
|
import { ItemsetDefinition } from './ItemsetDefinition.ts';
|
|
11
11
|
|
|
@@ -22,12 +22,12 @@ const isSelectElement = (
|
|
|
22
22
|
return selectLocalNames.has(localName as SelectType);
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
export class
|
|
25
|
+
export class SelectControlDefinition<Type extends SelectType> extends ControlDefinition<Type> {
|
|
26
26
|
static override isCompatible(localName: string, element: Element): boolean {
|
|
27
27
|
return isSelectElement(element, localName);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
static isSelect(element: AnyBodyElementDefinition): element is
|
|
30
|
+
static isSelect(element: AnyBodyElementDefinition): element is AnySelectControlDefinition {
|
|
31
31
|
return selectLocalNames.has(element.type as SelectType);
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -72,4 +72,4 @@ export class SelectDefinition<Type extends SelectType> extends ControlDefinition
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
export type
|
|
75
|
+
export type AnySelectControlDefinition = SelectControlDefinition<SelectType>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ItemsetDefinition } from '../body/control/
|
|
1
|
+
import type { ItemsetDefinition } from '../body/control/ItemsetDefinition.ts';
|
|
2
2
|
import { DependentExpression } from './abstract/DependentExpression.ts';
|
|
3
3
|
|
|
4
4
|
export class ItemsetNodesetExpression extends DependentExpression<'nodes'> {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ItemsetDefinition } from '../body/control/
|
|
1
|
+
import type { ItemsetDefinition } from '../body/control/ItemsetDefinition.ts';
|
|
2
2
|
import { DependentExpression } from './abstract/DependentExpression.ts';
|
|
3
3
|
|
|
4
4
|
export class ItemsetValueExpression extends DependentExpression<'string'> {
|
|
@@ -4,6 +4,7 @@ import { BindComputationExpression } from '../expression/BindComputationExpressi
|
|
|
4
4
|
import { MessageDefinition } from '../text/MessageDefinition.ts';
|
|
5
5
|
import type { XFormDefinition } from '../XFormDefinition.ts';
|
|
6
6
|
import type { BindElement } from './BindElement.ts';
|
|
7
|
+
import { BindPreloadDefinition, type AnyBindPreloadDefinition } from './BindPreloadDefinition.ts';
|
|
7
8
|
import type { BindType } from './BindTypeDefinition.ts';
|
|
8
9
|
import { BindTypeDefinition } from './BindTypeDefinition.ts';
|
|
9
10
|
import type { ModelDefinition } from './ModelDefinition.ts';
|
|
@@ -12,6 +13,8 @@ export class BindDefinition<T extends BindType = BindType> extends DependencyCon
|
|
|
12
13
|
readonly type: BindTypeDefinition<T>;
|
|
13
14
|
readonly parentNodeset: string | null;
|
|
14
15
|
|
|
16
|
+
readonly preload: AnyBindPreloadDefinition | null;
|
|
17
|
+
|
|
15
18
|
readonly calculate: BindComputationExpression<'calculate'> | null;
|
|
16
19
|
readonly readonly: BindComputationExpression<'readonly'>;
|
|
17
20
|
readonly relevant: BindComputationExpression<'relevant'>;
|
|
@@ -82,6 +85,7 @@ export class BindDefinition<T extends BindType = BindType> extends DependencyCon
|
|
|
82
85
|
const parentNodeset = nodeset.replace(/\/[^/]+$/, '');
|
|
83
86
|
|
|
84
87
|
this.parentNodeset = parentNodeset.length > 1 ? parentNodeset : null;
|
|
88
|
+
this.preload = BindPreloadDefinition.from(bindElement);
|
|
85
89
|
this.calculate = BindComputationExpression.forComputation(this, 'calculate');
|
|
86
90
|
this.readonly = BindComputationExpression.forComputation(this, 'readonly');
|
|
87
91
|
this.relevant = BindComputationExpression.forComputation(this, 'relevant');
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { JAVAROSA_NAMESPACE_URI } from '@getodk/common/constants/xmlns.ts';
|
|
2
|
+
import type { PartiallyKnownString } from '@getodk/common/types/string/PartiallyKnownString.ts';
|
|
3
|
+
import type { BindElement } from './BindElement.ts';
|
|
4
|
+
|
|
5
|
+
type PartiallyKnownPreloadParameter<Known extends string> =
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/sort-type-constituents
|
|
7
|
+
PartiallyKnownString<NonNullable<Known>> | Extract<Known, null>;
|
|
8
|
+
|
|
9
|
+
interface PreloadParametersByType {
|
|
10
|
+
readonly uid: string | null;
|
|
11
|
+
readonly date: PartiallyKnownPreloadParameter<'today'>;
|
|
12
|
+
readonly timestamp: PartiallyKnownPreloadParameter<'end' | 'start'>;
|
|
13
|
+
|
|
14
|
+
readonly property: PartiallyKnownPreloadParameter<
|
|
15
|
+
// prettier-ignore
|
|
16
|
+
'deviceid' | 'email' | 'phonenumber' | 'username'
|
|
17
|
+
>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type PreloadType = PartiallyKnownString<keyof PreloadParametersByType>;
|
|
21
|
+
|
|
22
|
+
// prettier-ignore
|
|
23
|
+
type PreloadParameter<Type extends PreloadType> =
|
|
24
|
+
Type extends keyof PreloadParametersByType
|
|
25
|
+
? PreloadParametersByType[Type]
|
|
26
|
+
: string | null;
|
|
27
|
+
|
|
28
|
+
interface PreloadInput<Type extends PreloadType> {
|
|
29
|
+
readonly type: Type;
|
|
30
|
+
readonly parameter: PreloadParameter<Type>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
type AnyPreloadInput = {
|
|
34
|
+
[Type in PreloadType]: PreloadInput<Type>;
|
|
35
|
+
}[PreloadType];
|
|
36
|
+
|
|
37
|
+
const getPreloadInput = (bindElement: BindElement): AnyPreloadInput | null => {
|
|
38
|
+
const type = bindElement.getAttributeNS(JAVAROSA_NAMESPACE_URI, 'preload');
|
|
39
|
+
|
|
40
|
+
if (type == null) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const parameter: PreloadParameter<typeof type> = bindElement.getAttributeNS(
|
|
45
|
+
JAVAROSA_NAMESPACE_URI,
|
|
46
|
+
'preloadParams'
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
type,
|
|
51
|
+
parameter,
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Parsed representation of
|
|
57
|
+
* {@link https://getodk.github.io/xforms-spec/#preload-attributes | Preload Attributes}.
|
|
58
|
+
* If specified on a
|
|
59
|
+
* {@link https://getodk.github.io/xforms-spec/#bindings | binding}, this will
|
|
60
|
+
* be parsed to define:
|
|
61
|
+
*
|
|
62
|
+
* - {@link type}, a `jr:preload`
|
|
63
|
+
* - {@link parameter}, an associated `jr:preloadParams` value
|
|
64
|
+
*
|
|
65
|
+
* @todo It would probably make sense for the _definition_ to also convey:
|
|
66
|
+
*
|
|
67
|
+
* 1. Which {@link https://getodk.github.io/xforms-spec/#events | event} the
|
|
68
|
+
* preload is semantically associated with (noting that the spec may be a tad
|
|
69
|
+
* overzealous about this association).
|
|
70
|
+
*
|
|
71
|
+
* 2. The constant XPath expression (or other computation?) expressed by the
|
|
72
|
+
* combined {@link type} and {@link parameter}.
|
|
73
|
+
*/
|
|
74
|
+
export class BindPreloadDefinition<Type extends PreloadType> implements PreloadInput<Type> {
|
|
75
|
+
static from(bindElement: BindElement): AnyBindPreloadDefinition | null {
|
|
76
|
+
const input = getPreloadInput(bindElement);
|
|
77
|
+
|
|
78
|
+
if (input == null) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return new this(input);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
readonly type: Type;
|
|
86
|
+
readonly parameter: PreloadParameter<Type>;
|
|
87
|
+
|
|
88
|
+
private constructor(input: PreloadInput<Type>) {
|
|
89
|
+
this.type = input.type;
|
|
90
|
+
this.parameter = input.parameter;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// prettier-ignore
|
|
95
|
+
export type AnyBindPreloadDefinition =
|
|
96
|
+
// eslint-disable-next-line @typescript-eslint/sort-type-constituents
|
|
97
|
+
| BindPreloadDefinition<'uid'>
|
|
98
|
+
| BindPreloadDefinition<'timestamp'>
|
|
99
|
+
| BindPreloadDefinition<'property'>
|
|
100
|
+
| BindPreloadDefinition<string>;
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
import type { AnyBodyElementDefinition } from '../body/BodyDefinition.ts';
|
|
2
2
|
import type { BindDefinition } from './BindDefinition.ts';
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
NodeChildren,
|
|
6
|
-
NodeDefaultValue,
|
|
7
|
-
NodeDefinition,
|
|
8
|
-
NodeDefinitionType,
|
|
9
|
-
NodeInstances,
|
|
10
|
-
NodeParent,
|
|
11
|
-
} from './NodeDefinition.ts';
|
|
3
|
+
import type { NodeDefinitionType, ParentNodeDefinition } from './NodeDefinition.ts';
|
|
4
|
+
import { NodeDefinition } from './NodeDefinition.ts';
|
|
12
5
|
import type { RootDefinition } from './RootDefinition.ts';
|
|
13
6
|
|
|
14
7
|
export type DescendentNodeType = Exclude<NodeDefinitionType, 'root'>;
|
|
@@ -18,32 +11,21 @@ type DescendentNodeBodyElement = AnyBodyElementDefinition;
|
|
|
18
11
|
export abstract class DescendentNodeDefinition<
|
|
19
12
|
Type extends DescendentNodeType,
|
|
20
13
|
BodyElement extends DescendentNodeBodyElement | null = DescendentNodeBodyElement | null,
|
|
21
|
-
>
|
|
22
|
-
{
|
|
23
|
-
abstract readonly type: Type;
|
|
24
|
-
abstract readonly children: NodeChildren<Type>;
|
|
25
|
-
abstract readonly instances: NodeInstances<Type>;
|
|
26
|
-
abstract readonly defaultValue: NodeDefaultValue<Type>;
|
|
27
|
-
abstract readonly node: ModelNode<Type>;
|
|
28
|
-
abstract readonly nodeName: string;
|
|
29
|
-
|
|
14
|
+
> extends NodeDefinition<Type> {
|
|
30
15
|
readonly root: RootDefinition;
|
|
31
|
-
readonly nodeset: string;
|
|
32
16
|
readonly isTranslated: boolean = false;
|
|
33
17
|
|
|
34
18
|
constructor(
|
|
35
|
-
readonly parent:
|
|
36
|
-
|
|
19
|
+
readonly parent: ParentNodeDefinition,
|
|
20
|
+
bind: BindDefinition,
|
|
37
21
|
readonly bodyElement: BodyElement
|
|
38
22
|
) {
|
|
23
|
+
super(bind);
|
|
24
|
+
|
|
39
25
|
this.root = parent.root;
|
|
40
|
-
this.nodeset = bind.nodeset;
|
|
41
26
|
|
|
42
27
|
if (bind.isTranslated || bodyElement?.isTranslated) {
|
|
43
28
|
this.isTranslated = true;
|
|
44
29
|
}
|
|
45
30
|
}
|
|
46
31
|
}
|
|
47
|
-
|
|
48
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
49
|
-
export type AnyDescendantNodeDefinition = DescendentNodeDefinition<any, any>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { XFormsItextTranslationElement } from '@getodk/xpath';
|
|
2
2
|
import { XFORMS_KNOWN_ATTRIBUTE, XFORMS_LOCAL_NAME } from '@getodk/xpath';
|
|
3
3
|
import { StaticElement } from '../../../integration/xpath/static-dom/StaticElement.ts';
|
|
4
|
+
import type { ItextTranslationDefinition } from './ItextTranslationDefinition.ts';
|
|
4
5
|
|
|
5
6
|
// prettier-ignore
|
|
6
7
|
type ItextTranslationRootKnownAttributeValue<LocalName extends string> =
|
|
@@ -21,7 +22,7 @@ const assertItextTranslationRootKnownAttributeValue: AssertItextTranslationRootK
|
|
|
21
22
|
};
|
|
22
23
|
|
|
23
24
|
export class ItextTranslationRootDefinition
|
|
24
|
-
extends StaticElement
|
|
25
|
+
extends StaticElement<ItextTranslationDefinition>
|
|
25
26
|
implements XFormsItextTranslationElement<ItextTranslationRootDefinition>
|
|
26
27
|
{
|
|
27
28
|
override readonly [XFORMS_LOCAL_NAME] = 'translation';
|
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
import type { ValueType } from '../../client/ValueType.ts';
|
|
2
|
+
import {
|
|
3
|
+
NamespaceDeclarationMap,
|
|
4
|
+
type NamedSubtreeDefinition,
|
|
5
|
+
} from '../../lib/names/NamespaceDeclarationMap.ts';
|
|
6
|
+
import { QualifiedName } from '../../lib/names/QualifiedName.ts';
|
|
2
7
|
import type { AnyBodyElementDefinition, ControlElementDefinition } from '../body/BodyDefinition.ts';
|
|
3
8
|
import type { BindDefinition } from './BindDefinition.ts';
|
|
4
9
|
import { DescendentNodeDefinition } from './DescendentNodeDefinition.ts';
|
|
5
|
-
import type {
|
|
10
|
+
import type { ParentNodeDefinition } from './NodeDefinition.ts';
|
|
6
11
|
|
|
7
12
|
export class LeafNodeDefinition<V extends ValueType = ValueType>
|
|
8
13
|
extends DescendentNodeDefinition<'leaf-node', ControlElementDefinition | null>
|
|
9
|
-
implements
|
|
14
|
+
implements NamedSubtreeDefinition
|
|
10
15
|
{
|
|
11
16
|
readonly type = 'leaf-node';
|
|
12
17
|
readonly valueType: V;
|
|
13
18
|
|
|
14
|
-
readonly
|
|
19
|
+
readonly namespaceDeclarations: NamespaceDeclarationMap;
|
|
20
|
+
readonly qualifiedName: QualifiedName;
|
|
15
21
|
readonly children = null;
|
|
16
22
|
readonly instances = null;
|
|
17
23
|
readonly defaultValue: string;
|
|
@@ -29,7 +35,8 @@ export class LeafNodeDefinition<V extends ValueType = ValueType>
|
|
|
29
35
|
super(parent, bind, bodyElement);
|
|
30
36
|
|
|
31
37
|
this.valueType = bind.type.resolved satisfies ValueType as V;
|
|
32
|
-
this.
|
|
38
|
+
this.qualifiedName = new QualifiedName(node);
|
|
39
|
+
this.namespaceDeclarations = new NamespaceDeclarationMap(this);
|
|
33
40
|
this.defaultValue = node.textContent ?? '';
|
|
34
41
|
}
|
|
35
42
|
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
NamedSubtreeDefinition,
|
|
3
|
+
NamespaceDeclarationMap,
|
|
4
|
+
} from '../../lib/names/NamespaceDeclarationMap.ts';
|
|
5
|
+
import type { QualifiedName } from '../../lib/names/QualifiedName.ts';
|
|
1
6
|
import type { AnyBodyElementDefinition } from '../body/BodyDefinition.ts';
|
|
2
7
|
import type { RepeatElementDefinition } from '../body/RepeatElementDefinition.ts';
|
|
3
8
|
import type { BindDefinition } from './BindDefinition.ts';
|
|
@@ -83,52 +88,28 @@ export type ChildNodeInstanceDefinition =
|
|
|
83
88
|
| SubtreeDefinition
|
|
84
89
|
| LeafNodeDefinition;
|
|
85
90
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
91
|
+
export abstract class NodeDefinition<Type extends NodeDefinitionType>
|
|
92
|
+
implements NamedSubtreeDefinition
|
|
93
|
+
{
|
|
94
|
+
abstract readonly type: Type;
|
|
95
|
+
abstract readonly namespaceDeclarations: NamespaceDeclarationMap;
|
|
96
|
+
abstract readonly qualifiedName: QualifiedName;
|
|
97
|
+
abstract readonly bodyElement: AnyBodyElementDefinition | RepeatElementDefinition | null;
|
|
98
|
+
abstract readonly isTranslated: boolean;
|
|
99
|
+
abstract readonly root: RootDefinition;
|
|
100
|
+
abstract readonly parent: ParentNodeDefinition | null;
|
|
101
|
+
abstract readonly children: readonly ChildNodeDefinition[] | null;
|
|
102
|
+
abstract readonly instances: readonly RepeatInstanceDefinition[] | null;
|
|
103
|
+
abstract readonly defaultValue: string | null;
|
|
104
|
+
|
|
105
|
+
/** @todo leaf-node may be Attr */
|
|
106
|
+
abstract readonly node: Element | null;
|
|
97
107
|
|
|
98
|
-
// prettier-ignore
|
|
99
|
-
export type NodeParent<Type extends NodeDefinitionType> =
|
|
100
|
-
Type extends ChildNodeDefinition['type'] | ChildNodeInstanceDefinition['type']
|
|
101
|
-
? ParentNodeDefinition
|
|
102
|
-
: null;
|
|
103
|
-
|
|
104
|
-
// TODO: leaf-node may be Attr
|
|
105
|
-
// prettier-ignore
|
|
106
|
-
export type ModelNode<Type extends NodeDefinitionType> =
|
|
107
|
-
Type extends 'repeat-range'
|
|
108
|
-
? null
|
|
109
|
-
: Element;
|
|
110
|
-
|
|
111
|
-
// prettier-ignore
|
|
112
|
-
export type NodeDefaultValue<Type extends NodeDefinitionType> =
|
|
113
|
-
Type extends 'leaf-node'
|
|
114
|
-
? string
|
|
115
|
-
: null;
|
|
116
|
-
|
|
117
|
-
export interface NodeDefinition<Type extends NodeDefinitionType> {
|
|
118
|
-
readonly type: Type;
|
|
119
|
-
|
|
120
|
-
readonly bind: BindDefinition;
|
|
121
108
|
readonly nodeset: string;
|
|
122
|
-
readonly nodeName: string;
|
|
123
|
-
readonly bodyElement: AnyBodyElementDefinition | RepeatElementDefinition | null;
|
|
124
|
-
readonly isTranslated: boolean;
|
|
125
|
-
readonly root: RootDefinition;
|
|
126
|
-
readonly parent: NodeParent<Type>;
|
|
127
|
-
readonly children: NodeChildren<Type>;
|
|
128
|
-
readonly instances: NodeInstances<Type>;
|
|
129
109
|
|
|
130
|
-
readonly
|
|
131
|
-
|
|
110
|
+
constructor(readonly bind: BindDefinition) {
|
|
111
|
+
this.nodeset = bind.nodeset;
|
|
112
|
+
}
|
|
132
113
|
}
|
|
133
114
|
|
|
134
115
|
export type AnyNodeDefinition =
|
|
@@ -139,5 +120,3 @@ export type AnyNodeDefinition =
|
|
|
139
120
|
| RepeatInstanceDefinition
|
|
140
121
|
| SubtreeDefinition
|
|
141
122
|
| LeafNodeDefinition;
|
|
142
|
-
|
|
143
|
-
export type TypedNodeDefinition<Type> = Extract<AnyNodeDefinition, { readonly type: Type }>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { NoteNode } from '../../client/NoteNode.ts';
|
|
2
|
+
import type { ValueType } from '../../client/ValueType.ts';
|
|
2
3
|
import type { AnyBodyElementDefinition } from '../body/BodyDefinition.ts';
|
|
3
4
|
import type { InputControlDefinition } from '../body/control/InputControlDefinition.ts';
|
|
4
5
|
import { BindComputationExpression } from '../expression/BindComputationExpression.ts';
|
|
@@ -14,11 +15,11 @@ export type NoteReadonlyDefinition =
|
|
|
14
15
|
& BindComputationExpression<'readonly'>
|
|
15
16
|
& ConstantTruthyDependentExpression;
|
|
16
17
|
|
|
17
|
-
export interface NoteBindDefinition extends BindDefinition {
|
|
18
|
+
export interface NoteBindDefinition<V extends ValueType> extends BindDefinition<V> {
|
|
18
19
|
readonly readonly: NoteReadonlyDefinition;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
const isNoteBindDefinition = (bind: BindDefinition): bind is NoteBindDefinition => {
|
|
22
|
+
const isNoteBindDefinition = (bind: BindDefinition): bind is NoteBindDefinition<ValueType> => {
|
|
22
23
|
return bind.readonly.isConstantTruthyExpression();
|
|
23
24
|
};
|
|
24
25
|
|
|
@@ -37,13 +38,13 @@ export type NoteTextDefinition =
|
|
|
37
38
|
* aspects of the node's interface (such as its {@link NoteNode.nodeType} and
|
|
38
39
|
* distinct {@link NoteNode.currentState} types) to handle note-specific logic.
|
|
39
40
|
*/
|
|
40
|
-
export class NoteNodeDefinition extends LeafNodeDefinition {
|
|
41
|
-
static from(
|
|
41
|
+
export class NoteNodeDefinition<V extends ValueType = ValueType> extends LeafNodeDefinition<V> {
|
|
42
|
+
static from<V extends ValueType>(
|
|
42
43
|
parent: ParentNodeDefinition,
|
|
43
|
-
bind: BindDefinition
|
|
44
|
+
bind: BindDefinition<V>,
|
|
44
45
|
bodyElement: AnyBodyElementDefinition | null,
|
|
45
46
|
node: Element
|
|
46
|
-
): NoteNodeDefinition | null {
|
|
47
|
+
): NoteNodeDefinition<V> | null {
|
|
47
48
|
if (!isNoteBindDefinition(bind) || bodyElement?.type !== 'input') {
|
|
48
49
|
return null;
|
|
49
50
|
}
|
|
@@ -60,7 +61,7 @@ export class NoteNodeDefinition extends LeafNodeDefinition {
|
|
|
60
61
|
|
|
61
62
|
constructor(
|
|
62
63
|
parent: ParentNodeDefinition,
|
|
63
|
-
override readonly bind: NoteBindDefinition
|
|
64
|
+
override readonly bind: NoteBindDefinition<V>,
|
|
64
65
|
override readonly bodyElement: InputControlDefinition,
|
|
65
66
|
readonly noteTextDefinition: NoteTextDefinition,
|
|
66
67
|
node: Element
|