@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.
Files changed (228) hide show
  1. package/dist/body/BodyDefinition.d.ts +24 -7
  2. package/dist/body/BodyElementDefinition.d.ts +4 -3
  3. package/dist/body/RepeatElementDefinition.d.ts +19 -0
  4. package/dist/body/appearance/inputAppearanceParser.d.ts +4 -0
  5. package/dist/body/appearance/selectAppearanceParser.d.ts +4 -0
  6. package/dist/body/appearance/structureElementAppearanceParser.d.ts +4 -0
  7. package/dist/body/control/ControlDefinition.d.ts +4 -2
  8. package/dist/body/control/InputDefinition.d.ts +5 -0
  9. package/dist/body/control/select/ItemDefinition.d.ts +2 -2
  10. package/dist/body/control/select/ItemsetDefinition.d.ts +5 -4
  11. package/dist/body/control/select/SelectDefinition.d.ts +11 -1
  12. package/dist/body/group/BaseGroupDefinition.d.ts +4 -9
  13. package/dist/body/group/PresentationGroupDefinition.d.ts +1 -1
  14. package/dist/client/BaseNode.d.ts +74 -3
  15. package/dist/client/GroupNode.d.ts +7 -2
  16. package/dist/client/ModelValueNode.d.ts +37 -0
  17. package/dist/client/NodeAppearances.d.ts +15 -0
  18. package/dist/client/NoteNode.d.ts +53 -0
  19. package/dist/client/RootNode.d.ts +21 -0
  20. package/dist/client/SelectNode.d.ts +8 -3
  21. package/dist/client/StringNode.d.ts +8 -3
  22. package/dist/client/SubtreeNode.d.ts +3 -0
  23. package/dist/client/TextRange.d.ts +85 -2
  24. package/dist/client/constants.d.ts +9 -0
  25. package/dist/client/hierarchy.d.ts +14 -9
  26. package/dist/client/node-types.d.ts +2 -1
  27. package/dist/client/{RepeatRangeNode.d.ts → repeat/BaseRepeatRangeNode.d.ts} +19 -15
  28. package/dist/client/{RepeatInstanceNode.d.ts → repeat/RepeatInstanceNode.d.ts} +11 -7
  29. package/dist/client/repeat/RepeatRangeControlledNode.d.ts +19 -0
  30. package/dist/client/repeat/RepeatRangeUncontrolledNode.d.ts +20 -0
  31. package/dist/client/validation.d.ts +163 -0
  32. package/dist/expression/DependentExpression.d.ts +12 -8
  33. package/dist/index.d.ts +9 -4
  34. package/dist/index.js +3173 -960
  35. package/dist/index.js.map +1 -1
  36. package/dist/instance/Group.d.ts +6 -4
  37. package/dist/instance/ModelValue.d.ts +40 -0
  38. package/dist/instance/Note.d.ts +42 -0
  39. package/dist/instance/Root.d.ts +10 -23
  40. package/dist/instance/SelectField.d.ts +12 -6
  41. package/dist/instance/StringField.d.ts +13 -7
  42. package/dist/instance/Subtree.d.ts +3 -1
  43. package/dist/instance/abstract/DescendantNode.d.ts +16 -9
  44. package/dist/instance/abstract/InstanceNode.d.ts +28 -29
  45. package/dist/instance/hierarchy.d.ts +10 -5
  46. package/dist/instance/internal-api/EvaluationContext.d.ts +5 -4
  47. package/dist/instance/internal-api/ValidationContext.d.ts +21 -0
  48. package/dist/instance/internal-api/ValueContext.d.ts +2 -2
  49. package/dist/instance/repeat/BaseRepeatRange.d.ts +160 -0
  50. package/dist/instance/{RepeatInstance.d.ts → repeat/RepeatInstance.d.ts} +38 -13
  51. package/dist/instance/repeat/RepeatRangeControlled.d.ts +16 -0
  52. package/dist/instance/repeat/RepeatRangeUncontrolled.d.ts +35 -0
  53. package/dist/instance/text/TextRange.d.ts +4 -4
  54. package/dist/lib/TokenListParser.d.ts +84 -0
  55. package/dist/lib/dom/query.d.ts +5 -0
  56. package/dist/lib/reactivity/createComputedExpression.d.ts +6 -1
  57. package/dist/lib/reactivity/createNoteReadonlyThunk.d.ts +5 -0
  58. package/dist/lib/reactivity/materializeCurrentStateChildren.d.ts +2 -1
  59. package/dist/lib/reactivity/node-state/createSharedNodeState.d.ts +1 -1
  60. package/dist/lib/reactivity/node-state/createSpecifiedState.d.ts +1 -1
  61. package/dist/lib/reactivity/text/createFieldHint.d.ts +3 -3
  62. package/dist/lib/reactivity/text/createNodeLabel.d.ts +2 -2
  63. package/dist/lib/reactivity/text/createNoteText.d.ts +25 -0
  64. package/dist/lib/reactivity/text/createTextRange.d.ts +5 -7
  65. package/dist/lib/reactivity/validation/createAggregatedViolations.d.ts +9 -0
  66. package/dist/lib/reactivity/validation/createValidation.d.ts +18 -0
  67. package/dist/model/BindDefinition.d.ts +4 -2
  68. package/dist/model/BindElement.d.ts +1 -0
  69. package/dist/model/DescendentNodeDefinition.d.ts +1 -2
  70. package/dist/model/{ValueNodeDefinition.d.ts → LeafNodeDefinition.d.ts} +3 -4
  71. package/dist/model/NodeDefinition.d.ts +16 -16
  72. package/dist/model/RepeatInstanceDefinition.d.ts +5 -6
  73. package/dist/model/RepeatRangeDefinition.d.ts +30 -0
  74. package/dist/model/RepeatTemplateDefinition.d.ts +6 -7
  75. package/dist/model/RootDefinition.d.ts +3 -1
  76. package/dist/model/SubtreeDefinition.d.ts +2 -2
  77. package/dist/parse/NoteNodeDefinition.d.ts +31 -0
  78. package/dist/parse/expression/RepeatCountControlExpression.d.ts +19 -0
  79. package/dist/parse/text/HintDefinition.d.ts +9 -0
  80. package/dist/parse/text/ItemLabelDefinition.d.ts +9 -0
  81. package/dist/parse/text/ItemsetLabelDefinition.d.ts +13 -0
  82. package/dist/parse/text/LabelDefinition.d.ts +15 -0
  83. package/dist/parse/text/MessageDefinition.d.ts +15 -0
  84. package/dist/parse/text/OutputChunkDefinition.d.ts +8 -0
  85. package/dist/parse/text/ReferenceChunkDefinition.d.ts +8 -0
  86. package/dist/parse/text/StaticTextChunkDefinition.d.ts +10 -0
  87. package/dist/parse/text/TranslationChunkDefinition.d.ts +9 -0
  88. package/dist/parse/text/abstract/TextChunkDefinition.d.ts +18 -0
  89. package/dist/parse/text/abstract/TextElementDefinition.d.ts +23 -0
  90. package/dist/parse/text/abstract/TextRangeDefinition.d.ts +35 -0
  91. package/dist/parse/xpath/dependency-analysis.d.ts +40 -0
  92. package/dist/parse/xpath/path-resolution.d.ts +70 -0
  93. package/dist/parse/xpath/predicate-analysis.d.ts +30 -0
  94. package/dist/parse/xpath/reference-parsing.d.ts +18 -0
  95. package/dist/parse/xpath/semantic-analysis.d.ts +98 -0
  96. package/dist/parse/xpath/syntax-traversal.d.ts +69 -0
  97. package/dist/solid.js +3174 -961
  98. package/dist/solid.js.map +1 -1
  99. package/package.json +14 -15
  100. package/src/XFormDOM.ts +81 -8
  101. package/src/body/BodyDefinition.ts +38 -23
  102. package/src/body/BodyElementDefinition.ts +4 -3
  103. package/src/body/RepeatElementDefinition.ts +58 -0
  104. package/src/body/appearance/inputAppearanceParser.ts +39 -0
  105. package/src/body/appearance/selectAppearanceParser.ts +38 -0
  106. package/src/body/appearance/structureElementAppearanceParser.ts +7 -0
  107. package/src/body/control/ControlDefinition.ts +8 -3
  108. package/src/body/control/InputDefinition.ts +13 -0
  109. package/src/body/control/select/ItemDefinition.ts +3 -3
  110. package/src/body/control/select/ItemsetDefinition.ts +29 -12
  111. package/src/body/control/select/ItemsetNodesetExpression.ts +1 -1
  112. package/src/body/control/select/SelectDefinition.ts +14 -5
  113. package/src/body/group/BaseGroupDefinition.ts +14 -51
  114. package/src/body/group/PresentationGroupDefinition.ts +1 -1
  115. package/src/client/BaseNode.ts +82 -8
  116. package/src/client/GroupNode.ts +8 -2
  117. package/src/client/ModelValueNode.ts +40 -0
  118. package/src/client/NodeAppearances.ts +22 -0
  119. package/src/client/NoteNode.ts +74 -0
  120. package/src/client/README.md +1 -0
  121. package/src/client/RootNode.ts +24 -0
  122. package/src/client/SelectNode.ts +9 -3
  123. package/src/client/StringNode.ts +9 -3
  124. package/src/client/SubtreeNode.ts +3 -0
  125. package/src/client/TextRange.ts +99 -2
  126. package/src/client/constants.ts +10 -0
  127. package/src/client/hierarchy.ts +30 -14
  128. package/src/client/node-types.ts +8 -1
  129. package/src/client/{RepeatRangeNode.ts → repeat/BaseRepeatRangeNode.ts} +20 -17
  130. package/src/client/{RepeatInstanceNode.ts → repeat/RepeatInstanceNode.ts} +13 -7
  131. package/src/client/repeat/RepeatRangeControlledNode.ts +20 -0
  132. package/src/client/repeat/RepeatRangeUncontrolledNode.ts +21 -0
  133. package/src/client/validation.ts +199 -0
  134. package/src/expression/DependentExpression.ts +45 -27
  135. package/src/index.ts +15 -8
  136. package/src/instance/Group.ts +24 -13
  137. package/src/instance/ModelValue.ts +104 -0
  138. package/src/instance/Note.ts +142 -0
  139. package/src/instance/Root.ts +29 -67
  140. package/src/instance/SelectField.ts +35 -13
  141. package/src/instance/StringField.ts +40 -13
  142. package/src/instance/Subtree.ts +19 -10
  143. package/src/instance/abstract/DescendantNode.ts +50 -49
  144. package/src/instance/abstract/InstanceNode.ts +89 -92
  145. package/src/instance/children.ts +47 -10
  146. package/src/instance/hierarchy.ts +21 -2
  147. package/src/instance/index.ts +1 -1
  148. package/src/instance/internal-api/EvaluationContext.ts +5 -6
  149. package/src/instance/internal-api/ValidationContext.ts +23 -0
  150. package/src/instance/internal-api/ValueContext.ts +2 -2
  151. package/src/instance/repeat/BaseRepeatRange.ts +347 -0
  152. package/src/instance/{RepeatInstance.ts → repeat/RepeatInstance.ts} +85 -36
  153. package/src/instance/repeat/RepeatRangeControlled.ts +82 -0
  154. package/src/instance/repeat/RepeatRangeUncontrolled.ts +67 -0
  155. package/src/instance/text/TextRange.ts +10 -4
  156. package/src/lib/TokenListParser.ts +156 -0
  157. package/src/lib/dom/query.ts +13 -0
  158. package/src/lib/reactivity/createChildrenState.ts +51 -6
  159. package/src/lib/reactivity/createComputedExpression.ts +23 -25
  160. package/src/lib/reactivity/createNoteReadonlyThunk.ts +33 -0
  161. package/src/lib/reactivity/createSelectItems.ts +25 -20
  162. package/src/lib/reactivity/createValueState.ts +6 -6
  163. package/src/lib/reactivity/materializeCurrentStateChildren.ts +3 -1
  164. package/src/lib/reactivity/node-state/createSharedNodeState.ts +1 -1
  165. package/src/lib/reactivity/text/createFieldHint.ts +9 -7
  166. package/src/lib/reactivity/text/createNodeLabel.ts +7 -5
  167. package/src/lib/reactivity/text/createNoteText.ts +72 -0
  168. package/src/lib/reactivity/text/createTextRange.ts +17 -90
  169. package/src/lib/reactivity/validation/createAggregatedViolations.ts +70 -0
  170. package/src/lib/reactivity/validation/createValidation.ts +196 -0
  171. package/src/model/BindComputation.ts +0 -4
  172. package/src/model/BindDefinition.ts +8 -6
  173. package/src/model/BindElement.ts +1 -0
  174. package/src/model/DescendentNodeDefinition.ts +1 -2
  175. package/src/model/{ValueNodeDefinition.ts → LeafNodeDefinition.ts} +5 -6
  176. package/src/model/ModelBindMap.ts +4 -0
  177. package/src/model/ModelDefinition.ts +1 -1
  178. package/src/model/NodeDefinition.ts +21 -21
  179. package/src/model/RepeatInstanceDefinition.ts +8 -13
  180. package/src/model/RepeatRangeDefinition.ts +94 -0
  181. package/src/model/RepeatTemplateDefinition.ts +10 -15
  182. package/src/model/RootDefinition.ts +12 -14
  183. package/src/model/SubtreeDefinition.ts +3 -3
  184. package/src/parse/NoteNodeDefinition.ts +70 -0
  185. package/src/parse/TODO.md +3 -0
  186. package/src/parse/expression/RepeatCountControlExpression.ts +44 -0
  187. package/src/parse/text/HintDefinition.ts +25 -0
  188. package/src/parse/text/ItemLabelDefinition.ts +25 -0
  189. package/src/parse/text/ItemsetLabelDefinition.ts +44 -0
  190. package/src/parse/text/LabelDefinition.ts +61 -0
  191. package/src/parse/text/MessageDefinition.ts +49 -0
  192. package/src/parse/text/OutputChunkDefinition.ts +25 -0
  193. package/src/parse/text/ReferenceChunkDefinition.ts +14 -0
  194. package/src/parse/text/StaticTextChunkDefinition.ts +19 -0
  195. package/src/parse/text/TranslationChunkDefinition.ts +38 -0
  196. package/src/parse/text/abstract/TextChunkDefinition.ts +38 -0
  197. package/src/parse/text/abstract/TextElementDefinition.ts +71 -0
  198. package/src/parse/text/abstract/TextRangeDefinition.ts +70 -0
  199. package/src/parse/xpath/dependency-analysis.ts +105 -0
  200. package/src/parse/xpath/path-resolution.ts +475 -0
  201. package/src/parse/xpath/predicate-analysis.ts +61 -0
  202. package/src/parse/xpath/reference-parsing.ts +90 -0
  203. package/src/parse/xpath/semantic-analysis.ts +466 -0
  204. package/src/parse/xpath/syntax-traversal.ts +129 -0
  205. package/dist/body/RepeatDefinition.d.ts +0 -16
  206. package/dist/body/group/RepeatGroupDefinition.d.ts +0 -13
  207. package/dist/body/text/HintDefinition.d.ts +0 -11
  208. package/dist/body/text/LabelDefinition.d.ts +0 -20
  209. package/dist/body/text/TextElementDefinition.d.ts +0 -33
  210. package/dist/body/text/TextElementOutputPart.d.ts +0 -13
  211. package/dist/body/text/TextElementPart.d.ts +0 -13
  212. package/dist/body/text/TextElementReferencePart.d.ts +0 -7
  213. package/dist/body/text/TextElementStaticPart.d.ts +0 -7
  214. package/dist/instance/RepeatRange.d.ts +0 -80
  215. package/dist/lib/xpath/analysis.d.ts +0 -23
  216. package/dist/model/RepeatSequenceDefinition.d.ts +0 -20
  217. package/src/body/RepeatDefinition.ts +0 -54
  218. package/src/body/group/RepeatGroupDefinition.ts +0 -91
  219. package/src/body/text/HintDefinition.ts +0 -26
  220. package/src/body/text/LabelDefinition.ts +0 -54
  221. package/src/body/text/TextElementDefinition.ts +0 -97
  222. package/src/body/text/TextElementOutputPart.ts +0 -27
  223. package/src/body/text/TextElementPart.ts +0 -31
  224. package/src/body/text/TextElementReferencePart.ts +0 -21
  225. package/src/body/text/TextElementStaticPart.ts +0 -26
  226. package/src/instance/RepeatRange.ts +0 -214
  227. package/src/lib/xpath/analysis.ts +0 -241
  228. package/src/model/RepeatSequenceDefinition.ts +0 -53
@@ -1,27 +1,26 @@
1
1
  import { XFormDefinition } from '../XFormDefinition.ts';
2
2
  import { DependencyContext } from '../expression/DependencyContext.ts';
3
+ import { ParsedTokenList, TokenListParser } from '../lib/TokenListParser.ts';
4
+ import { RepeatElementDefinition } from './RepeatElementDefinition.ts';
3
5
  import { UnsupportedBodyElementDefinition } from './UnsupportedBodyElementDefinition.ts';
4
6
  import { InputDefinition } from './control/InputDefinition.ts';
5
7
  import { AnySelectDefinition } from './control/select/SelectDefinition.ts';
6
8
  import { LogicalGroupDefinition } from './group/LogicalGroupDefinition.ts';
7
9
  import { PresentationGroupDefinition } from './group/PresentationGroupDefinition.ts';
8
- import { RepeatGroupDefinition } from './group/RepeatGroupDefinition.ts';
9
10
  import { StructuralGroupDefinition } from './group/StructuralGroupDefinition.ts';
10
11
 
11
12
  export interface BodyElementParentContext {
12
13
  readonly reference: string | null;
13
14
  readonly element: Element;
14
15
  }
15
- type SupportedBodyElementDefinition = RepeatGroupDefinition | LogicalGroupDefinition | PresentationGroupDefinition | StructuralGroupDefinition | InputDefinition | AnySelectDefinition;
16
+ export type ControlElementDefinition = AnySelectDefinition | InputDefinition;
17
+ type SupportedBodyElementDefinition = RepeatElementDefinition | LogicalGroupDefinition | PresentationGroupDefinition | StructuralGroupDefinition | ControlElementDefinition;
16
18
  export type AnyBodyElementDefinition = SupportedBodyElementDefinition | UnsupportedBodyElementDefinition;
17
19
  export type BodyElementDefinitionArray = readonly AnyBodyElementDefinition[];
18
20
  export type AnyBodyElementType = AnyBodyElementDefinition['type'];
19
21
  export type AnyGroupElementDefinition = Extract<AnyBodyElementDefinition, {
20
22
  readonly type: `${string}-group`;
21
23
  }>;
22
- export type NonRepeatGroupElementDefinition = Exclude<AnyGroupElementDefinition, {
23
- readonly type: 'repeat-group';
24
- }>;
25
24
  export declare const groupElementDefinition: (element: AnyBodyElementDefinition) => AnyGroupElementDefinition | null;
26
25
  export type AnyControlElementDefinition = Extract<AnyBodyElementDefinition, {
27
26
  readonly category: 'control';
@@ -37,17 +36,35 @@ declare class BodyElementMap extends Map<BodyElementReference, AnyBodyElementDef
37
36
  [k: string]: AnyBodyElementDefinition;
38
37
  };
39
38
  }
39
+ declare const bodyClassParser: TokenListParser<"pages", "pages">;
40
+ export type BodyClassList = ParsedTokenList<typeof bodyClassParser>;
40
41
  export declare class BodyDefinition extends DependencyContext {
41
42
  protected readonly form: XFormDefinition;
42
43
  static getChildElementDefinitions(form: XFormDefinition, parent: BodyElementParentContext, parentElement: Element, children?: readonly Element[]): readonly AnyBodyElementDefinition[];
43
44
  readonly element: Element;
45
+ /**
46
+ * @todo this class is already an oddity in that it's **like** an element
47
+ * definition, but it isn't one itself. Adding this property here emphasizes
48
+ * that awkwardness. It also extends the applicable scope where instances of
49
+ * this class are accessed. While it's still ephemeral, it's anticipated that
50
+ * this extension might cause some disomfort. If so, the most plausible
51
+ * alternative is an additional refactor to:
52
+ *
53
+ * 1. Introduce a `BodyElementDefinition` sublass for `<h:body>`.
54
+ * 2. Disambiguate the respective names of those, in some reasonable way.
55
+ * 3. Add a layer of indirection between this class and that new body element
56
+ * definition's class.
57
+ * 4. At that point, we may as well prioritize the little bit of grunt work to
58
+ * pass the `BodyDefinition` instance by reference rather than assigning it
59
+ * to anything.
60
+ */
61
+ readonly classes: BodyClassList;
44
62
  readonly elements: readonly AnyBodyElementDefinition[];
45
63
  protected readonly elementsByReference: BodyElementMap;
46
64
  readonly parentReference: null;
47
65
  readonly reference: string;
48
66
  constructor(form: XFormDefinition);
49
67
  getBodyElement(reference: string): AnyBodyElementDefinition | null;
50
- getRepeatGroup(reference: string): RepeatGroupDefinition | null;
51
- toJSON(): Omit<this, "toJSON" | "form" | "isTranslated" | "registerDependentExpression" | "dependencyExpressions" | "getBodyElement" | "getRepeatGroup">;
68
+ toJSON(): Omit<this, "toJSON" | "form" | "isTranslated" | "registerDependentExpression" | "dependencyExpressions" | "getBodyElement">;
52
69
  }
53
70
  export {};
@@ -1,8 +1,9 @@
1
1
  import { XFormDefinition } from '../XFormDefinition.ts';
2
2
  import { DependencyContext } from '../expression/DependencyContext.ts';
3
+ import { HintDefinition } from '../parse/text/HintDefinition.ts';
4
+ import { ItemLabelDefinition } from '../parse/text/ItemLabelDefinition.ts';
5
+ import { LabelDefinition } from '../parse/text/LabelDefinition.ts';
3
6
  import { BodyElementParentContext } from './BodyDefinition.ts';
4
- import { HintDefinition } from './text/HintDefinition.ts';
5
- import { LabelDefinition } from './text/LabelDefinition.ts';
6
7
 
7
8
  /**
8
9
  * These category names roughly correspond to each of the ODK XForms spec's
@@ -18,7 +19,7 @@ export declare abstract class BodyElementDefinition<Type extends string> extends
18
19
  abstract readonly category: BodyElementCategory;
19
20
  abstract readonly type: Type;
20
21
  readonly hint: HintDefinition | null;
21
- readonly label: LabelDefinition | null;
22
+ readonly label: ItemLabelDefinition | LabelDefinition | null;
22
23
  readonly reference: string | null;
23
24
  readonly parentReference: string | null;
24
25
  protected constructor(form: XFormDefinition, parent: BodyElementParentContext, element: Element);
@@ -0,0 +1,19 @@
1
+ import { XFormDefinition } from '../XFormDefinition.ts';
2
+ import { LabelDefinition } from '../parse/text/LabelDefinition.ts';
3
+ import { BodyElementDefinitionArray, BodyElementParentContext } from './BodyDefinition.ts';
4
+ import { BodyElementDefinition } from './BodyElementDefinition.ts';
5
+ import { StructureElementAppearanceDefinition } from './appearance/structureElementAppearanceParser.ts';
6
+
7
+ export declare class RepeatElementDefinition extends BodyElementDefinition<'repeat'> {
8
+ static isCompatible(localName: string): boolean;
9
+ readonly category = "structure";
10
+ readonly type = "repeat";
11
+ readonly reference: string;
12
+ readonly appearances: StructureElementAppearanceDefinition;
13
+ readonly label: LabelDefinition | null;
14
+ readonly countExpression: string | null;
15
+ readonly noAddRemoveExpression: string | null;
16
+ readonly children: BodyElementDefinitionArray;
17
+ constructor(form: XFormDefinition, parent: BodyElementParentContext, element: Element);
18
+ toJSON(): Omit<this, "toJSON" | "form" | "parent" | "isTranslated" | "registerDependentExpression" | "dependencyExpressions">;
19
+ }
@@ -0,0 +1,4 @@
1
+ import { TokenListParser, ParsedTokenList } from '../../lib/TokenListParser.ts';
2
+
3
+ export declare const inputAppearanceParser: TokenListParser<"multiline" | "numbers" | "url" | "thousand-sep" | "no-calendar" | "month-year" | "year" | "ethiopian" | "coptic" | "islamic" | "bikram-sambat" | "myanmar" | "persian" | "placement-map" | "maps" | "hidden-answer" | "annotate" | "draw" | "signature" | "new-front" | "new" | "front" | "printer" | "masked", "multiline" | "numbers" | "url" | "thousand-sep" | "no-calendar" | "month-year" | "year" | "ethiopian" | "coptic" | "islamic" | "bikram-sambat" | "myanmar" | "persian" | "placement-map" | "maps" | "hidden-answer" | "annotate" | "draw" | "signature" | "new-front" | "new" | "front" | "printer" | "masked">;
4
+ export type InputAppearanceDefinition = ParsedTokenList<typeof inputAppearanceParser>;
@@ -0,0 +1,4 @@
1
+ import { TokenListParser, ParsedTokenList } from '../../lib/TokenListParser.ts';
2
+
3
+ export declare const selectAppearanceParser: TokenListParser<"map" | "label" | "compact" | "horizontal" | "horizontal-compact" | "list-nolabel" | "minimal" | "columns" | "columns-1" | "columns-2" | "columns-3" | "columns-4" | "columns-5" | "columns-pack" | "autocomplete" | "likert" | "quick" | "quickcompact", "autocomplete">;
4
+ export type SelectAppearanceDefinition = ParsedTokenList<typeof selectAppearanceParser>;
@@ -0,0 +1,4 @@
1
+ import { TokenListParser, ParsedTokenList } from '../../lib/TokenListParser.ts';
2
+
3
+ export declare const structureElementAppearanceParser: TokenListParser<"field-list" | "table-list", "field-list" | "table-list">;
4
+ export type StructureElementAppearanceDefinition = ParsedTokenList<typeof structureElementAppearanceParser>;
@@ -1,8 +1,9 @@
1
1
  import { XFormDefinition } from '../../XFormDefinition.ts';
2
+ import { ParsedTokenList } from '../../lib/TokenListParser.ts';
3
+ import { HintDefinition } from '../../parse/text/HintDefinition.ts';
4
+ import { LabelDefinition } from '../../parse/text/LabelDefinition.ts';
2
5
  import { BodyElementParentContext } from '../BodyDefinition.ts';
3
6
  import { BodyElementDefinition } from '../BodyElementDefinition.ts';
4
- import { HintDefinition } from '../text/HintDefinition.ts';
5
- import { LabelDefinition } from '../text/LabelDefinition.ts';
6
7
 
7
8
  type ControlType = 'input' | 'range' | 'rank' | 'select' | 'select1' | 'trigger' | 'upload';
8
9
  export declare abstract class ControlDefinition<Type extends ControlType> extends BodyElementDefinition<Type> {
@@ -11,6 +12,7 @@ export declare abstract class ControlDefinition<Type extends ControlType> extend
11
12
  readonly reference: string;
12
13
  readonly label: LabelDefinition | null;
13
14
  readonly hint: HintDefinition | null;
15
+ abstract readonly appearances: ParsedTokenList<any>;
14
16
  constructor(form: XFormDefinition, parent: BodyElementParentContext, element: Element);
15
17
  }
16
18
  export type AnyControlDefinition = ControlDefinition<any>;
@@ -1,6 +1,11 @@
1
+ import { XFormDefinition } from '../../XFormDefinition.ts';
2
+ import { BodyElementParentContext } from '../BodyDefinition.ts';
3
+ import { InputAppearanceDefinition } from '../appearance/inputAppearanceParser.ts';
1
4
  import { ControlDefinition } from './ControlDefinition.ts';
2
5
 
3
6
  export declare class InputDefinition extends ControlDefinition<'input'> {
4
7
  static isCompatible(localName: string): boolean;
5
8
  readonly type = "input";
9
+ readonly appearances: InputAppearanceDefinition;
10
+ constructor(form: XFormDefinition, parent: BodyElementParentContext, element: Element);
6
11
  }
@@ -1,14 +1,14 @@
1
1
  import { ItemElement } from '../../../lib/dom/query.ts';
2
+ import { ItemLabelDefinition } from '../../../parse/text/ItemLabelDefinition.ts';
2
3
  import { XFormDefinition } from '../../../XFormDefinition.ts';
3
4
  import { BodyElementDefinition } from '../../BodyElementDefinition.ts';
4
- import { LabelDefinition } from '../../text/LabelDefinition.ts';
5
5
  import { AnySelectDefinition } from './SelectDefinition.ts';
6
6
 
7
7
  export declare class ItemDefinition extends BodyElementDefinition<'item'> {
8
8
  readonly parent: AnySelectDefinition;
9
9
  readonly category = "support";
10
10
  readonly type = "item";
11
- readonly label: LabelDefinition | null;
11
+ readonly label: ItemLabelDefinition | null;
12
12
  readonly value: string;
13
13
  constructor(form: XFormDefinition, parent: AnySelectDefinition, element: ItemElement);
14
14
  }
@@ -1,17 +1,18 @@
1
- import { ItemsetElement } from '../../../lib/dom/query.ts';
2
1
  import { XFormDefinition } from '../../../XFormDefinition.ts';
2
+ import { ItemsetElement } from '../../../lib/dom/query.ts';
3
+ import { ItemsetLabelDefinition } from '../../../parse/text/ItemsetLabelDefinition.ts';
3
4
  import { BodyElementDefinition } from '../../BodyElementDefinition.ts';
4
- import { LabelDefinition } from '../../text/LabelDefinition.ts';
5
5
  import { ItemsetNodesetExpression } from './ItemsetNodesetExpression.ts';
6
6
  import { ItemsetValueExpression } from './ItemsetValueExpression.ts';
7
7
  import { AnySelectDefinition } from './SelectDefinition.ts';
8
8
 
9
9
  export declare class ItemsetDefinition extends BodyElementDefinition<'itemset'> {
10
+ readonly parent: AnySelectDefinition;
10
11
  readonly category = "support";
11
12
  readonly type = "itemset";
12
13
  readonly reference: string;
13
- readonly label: LabelDefinition | null;
14
+ readonly label: ItemsetLabelDefinition | null;
14
15
  readonly nodes: ItemsetNodesetExpression;
15
16
  readonly value: ItemsetValueExpression;
16
- constructor(form: XFormDefinition, select: AnySelectDefinition, element: ItemsetElement);
17
+ constructor(form: XFormDefinition, parent: AnySelectDefinition, element: ItemsetElement);
17
18
  }
@@ -2,11 +2,20 @@ import { CollectionValues } from '../../../../../common/types/collections/Collec
2
2
  import { LocalNamedElement } from '../../../../../common/types/dom.ts';
3
3
  import { XFormDefinition } from '../../../XFormDefinition.ts';
4
4
  import { AnyBodyElementDefinition, BodyElementParentContext } from '../../BodyDefinition.ts';
5
+ import { SelectAppearanceDefinition } from '../../appearance/selectAppearanceParser.ts';
5
6
  import { ControlDefinition } from '../ControlDefinition.ts';
6
7
  import { ItemDefinition } from './ItemDefinition.ts';
7
8
  import { ItemsetDefinition } from './ItemsetDefinition.ts';
8
9
 
9
- declare const selectLocalNames: Set<"select" | "rank" | "select1">;
10
+ /**
11
+ * @todo We were previously a bit overzealous about introducing `<rank>` support
12
+ * here. It'll likely still fit, but we should approach it with more intention.
13
+ *
14
+ * @todo `<trigger>` is *almost* reasonable to support here too. The main
15
+ * hesitation is that its single, implicit "item" does not have a distinct
16
+ * <label>, and presumably has different UX **and translation** considerations.
17
+ */
18
+ declare const selectLocalNames: Set<"select" | "select1">;
10
19
  export type SelectType = CollectionValues<typeof selectLocalNames>;
11
20
  export interface SelectElement extends LocalNamedElement<SelectType> {
12
21
  }
@@ -15,6 +24,7 @@ export declare class SelectDefinition<Type extends SelectType> extends ControlDe
15
24
  static isSelect(element: AnyBodyElementDefinition): element is AnySelectDefinition;
16
25
  readonly type: Type;
17
26
  readonly element: SelectElement;
27
+ readonly appearances: SelectAppearanceDefinition;
18
28
  readonly itemset: ItemsetDefinition | null;
19
29
  readonly items: readonly ItemDefinition[];
20
30
  constructor(form: XFormDefinition, parent: BodyElementParentContext, element: Element);
@@ -1,7 +1,8 @@
1
1
  import { XFormDefinition } from '../../XFormDefinition.ts';
2
+ import { LabelDefinition } from '../../parse/text/LabelDefinition.ts';
2
3
  import { BodyElementDefinitionArray, BodyElementParentContext } from '../BodyDefinition.ts';
3
4
  import { BodyElementDefinition } from '../BodyElementDefinition.ts';
4
- import { LabelDefinition } from '../text/LabelDefinition.ts';
5
+ import { StructureElementAppearanceDefinition } from '../appearance/structureElementAppearanceParser.ts';
5
6
 
6
7
  /**
7
8
  * These type names are derived from **and expand upon** the language used in
@@ -16,10 +17,6 @@ import { LabelDefinition } from '../text/LabelDefinition.ts';
16
17
  * - `presentation-group` is a group with a `<label>` child; its usage here
17
18
  * differs from the spec language in that `presentation-group` does **not**
18
19
  * have a `ref`
19
- * - `repeat-group` is not mentioned by the spec; it is an extension of
20
- * `logical-group`, wherein its `ref` is the same as its immediate `<repeat>`
21
- * child's `nodeset` (usage of each attribute is normalized during
22
- * initialization, in {@link XFormDOM})
23
20
  * - `structural-group` is any `<group>` element which does not satisfy any of
24
21
  * the other usage scenarios; this isn't exactly the terminology used, but is
25
22
  * the most closely fitting name for the concept where the other sceanarios
@@ -27,21 +24,19 @@ import { LabelDefinition } from '../text/LabelDefinition.ts';
27
24
  *
28
25
  * A more succinct decision tree:
29
26
  *
30
- * - `<group ref="$ref"><repeat nodeset="$ref">` -> `repeat-group`, else
31
27
  * - `<group ref="$ref">` -> `logical-group`, else
32
28
  * - `<group><label>` -> `presentation-group`, else
33
29
  * - `<group>` -> `structural-group`
34
30
  */
35
- export type GroupType = 'logical-group' | 'presentation-group' | 'repeat-group' | 'structural-group';
31
+ export type GroupType = 'logical-group' | 'presentation-group' | 'structural-group';
36
32
  export declare abstract class BaseGroupDefinition<Type extends GroupType> extends BodyElementDefinition<Type> {
37
33
  private static groupTypes;
38
34
  protected static getGroupType(localName: string, element: Element): GroupType | null;
39
35
  readonly category = "structure";
40
36
  readonly children: BodyElementDefinitionArray;
41
37
  readonly reference: string | null;
38
+ readonly appearances: StructureElementAppearanceDefinition;
42
39
  readonly label: LabelDefinition | null;
43
40
  constructor(form: XFormDefinition, parent: BodyElementParentContext, element: Element, children?: BodyElementDefinitionArray);
44
41
  getChildren(element: Element): BodyElementDefinitionArray;
45
42
  }
46
- export declare const repeatGroup: <T extends BaseGroupDefinition<any>>(groupDefinition: T) => Extract<T, BaseGroupDefinition<'repeat-group'>> | null;
47
- export declare const nonRepeatGroup: <T extends BaseGroupDefinition<any>>(groupDefinition: T) => Exclude<T, BaseGroupDefinition<'repeat-group'>> | null;
@@ -1,6 +1,6 @@
1
1
  import { XFormDefinition } from '../../XFormDefinition.ts';
2
+ import { LabelDefinition } from '../../parse/text/LabelDefinition.ts';
2
3
  import { BodyElementParentContext } from '../BodyDefinition.ts';
3
- import { LabelDefinition } from '../text/LabelDefinition.ts';
4
4
  import { BaseGroupDefinition } from './BaseGroupDefinition.ts';
5
5
 
6
6
  export declare class PresentationGroupDefinition extends BaseGroupDefinition<'presentation-group'> {
@@ -1,6 +1,8 @@
1
1
  import { AnyNodeDefinition } from '../model/NodeDefinition.ts';
2
- import { InstanceNodeType } from './node-types.js';
2
+ import { NodeAppearances } from './NodeAppearances.ts';
3
3
  import { TextRange } from './TextRange.ts';
4
+ import { InstanceNodeType } from './node-types.ts';
5
+ import { NodeValidationState } from './validation.ts';
4
6
 
5
7
  export interface BaseNodeState {
6
8
  /**
@@ -37,6 +39,17 @@ export interface BaseNodeState {
37
39
  * {@link BaseNode.parent | parent node}.
38
40
  */
39
41
  get relevant(): boolean;
42
+ /**
43
+ * Specifies whether the node must have a non-blank value to be valid (see
44
+ * {@link value} for details).
45
+ *
46
+ * @see {@link https://getodk.github.io/xforms-spec/#bind-attributes}
47
+ *
48
+ * @default false
49
+ *
50
+ * @todo What is the expected behavior of `required` expressions defined for
51
+ * non-leaf/value nodes?
52
+ */
40
53
  get required(): boolean;
41
54
  /**
42
55
  * Interfaces for nodes which cannot provide a label should override this to
@@ -90,6 +103,14 @@ export interface BaseNodeState {
90
103
  *
91
104
  * Parent nodes, i.e. nodes which can contain {@link children}, do not store a
92
105
  * value state. For those nodes, their value state should always be `null`.
106
+ *
107
+ * A node's value is considered "blank" when its primary instance state is an
108
+ * empty string, and it is considered "non-blank" otherwise. The engine may
109
+ * represent node values according to aspects of the node's definition (such
110
+ * as its defined data type, its associated control type if any). The node's
111
+ * value being blank or non-blank may contribute to satisfying conditions of
112
+ * the node's validity ({@link constraint}, {@link required}). Otherwise, it
113
+ * is an internal engine consideration.
93
114
  */
94
115
  get value(): unknown;
95
116
  }
@@ -108,6 +129,10 @@ export interface BaseNode {
108
129
  * the lifetime of an active session filling a form.
109
130
  */
110
131
  readonly nodeId: FormNodeID;
132
+ /**
133
+ * @see {@link TokenListParser} for details.
134
+ */
135
+ readonly appearances: NodeAppearances<any> | null;
111
136
  /**
112
137
  * Each node has a definition which specifies aspects of the node defined in
113
138
  * the form. These aspects include (but are not limited to) the node's data
@@ -131,9 +156,55 @@ export interface BaseNode {
131
156
  */
132
157
  readonly parent: BaseNode | null;
133
158
  /**
134
- * Each node provides a discrete object representing the stateful aspects of
135
- * that node which will change over time. When a client provides a {@link OpaqueReactiveObjectFactory}
159
+ * Each node provides a discrete object representing the stateful aspects\* of
160
+ * that node which will change over time. When a client provides a
161
+ * {@link OpaqueReactiveObjectFactory}, the engine will update the properties
162
+ * of this object as their respective states change, so a client can implement
163
+ * reactive updates that respond to changes as they occur.
164
+ *
165
+ * \* This includes state which is either client-/user-mutable, or state which
166
+ * is computed based on the core XForms computation model. Each node also
167
+ * exposes {@link validationState}, which reflects the validity of the
168
+ * node, or its descendants.
136
169
  */
137
170
  readonly currentState: BaseNodeState;
171
+ /**
172
+ * Represents the validation state of a the node itself, or its descendants.
173
+ *
174
+ * @see {@link AncestorNodeValidationState} and
175
+ * {@link LeafNodeValidationState} for additional details.
176
+ *
177
+ * While filling a form (i.e. prior to submission), validation state can be
178
+ * viewed as computed metadata about the form state. The validation conditions
179
+ * and their violation messages produced by a node _may be computed on
180
+ * demand_. Clients should assume:
181
+ *
182
+ * 1. Validation state **will be current** when directly read by the client.
183
+ * Accessing validation state _may_ invoke engine computation of that state
184
+ * _at that time_.
185
+ *
186
+ * It **may** also be pre-computed by the engine so that direct reads are
187
+ * less computationally expensive, but such optimizations cannot be
188
+ * guaranteed by the engine at this time.
189
+ *
190
+ * 2. For clients providing an {@link OpaqueReactiveObjectFactory}, accessing
191
+ * validation state within a reactive context **will produce updates** to
192
+ * the validation state, as long as the client retains a subscription to
193
+ * that state.
194
+ *
195
+ * If it is possible to detect interruption of such client- reactive
196
+ * subscriptions, the engine _may defer computations_ until subsequent
197
+ * client read/re-subscription, in order to reduce unnecessary
198
+ * computational overhead. Again, such optimizations cannot be guaranteed
199
+ * by the engine at this time.
200
+ *
201
+ * @todo it's easier to conceive a reliable, general solution to optimizing
202
+ * the direct read case, than it is for the client-reactive case (largely
203
+ * because our solution for client reactivity is intentionally opaque). If it
204
+ * turns out that such optimizations are crucial for overall usability, the
205
+ * client-reactive case may best be served by additional APIs for reactive
206
+ * clients to explicitly pause and resume recomputation.
207
+ */
208
+ readonly validationState: NodeValidationState;
138
209
  }
139
210
  export {};
@@ -1,8 +1,10 @@
1
- import { NonRepeatGroupElementDefinition } from '../body/BodyDefinition.ts';
1
+ import { AnyGroupElementDefinition } from '../body/BodyDefinition.ts';
2
2
  import { SubtreeDefinition } from '../model/SubtreeDefinition.ts';
3
3
  import { BaseNode, BaseNodeState } from './BaseNode.ts';
4
+ import { NodeAppearances } from './NodeAppearances.ts';
4
5
  import { RootNode } from './RootNode.ts';
5
6
  import { GeneralChildNode, GeneralParentNode } from './hierarchy.ts';
7
+ import { AncestorNodeValidationState } from './validation.ts';
6
8
 
7
9
  export interface GroupNodeState extends BaseNodeState {
8
10
  get hint(): null;
@@ -11,15 +13,18 @@ export interface GroupNodeState extends BaseNodeState {
11
13
  get value(): null;
12
14
  }
13
15
  export interface GroupDefinition extends SubtreeDefinition {
14
- readonly bodyElement: NonRepeatGroupElementDefinition;
16
+ readonly bodyElement: AnyGroupElementDefinition;
15
17
  }
18
+ export type GroupNodeAppearances = NodeAppearances<GroupDefinition>;
16
19
  /**
17
20
  * A node corresponding to an XForms `<group>`.
18
21
  */
19
22
  export interface GroupNode extends BaseNode {
20
23
  readonly nodeType: 'group';
24
+ readonly appearances: GroupNodeAppearances;
21
25
  readonly definition: GroupDefinition;
22
26
  readonly root: RootNode;
23
27
  readonly parent: GeneralParentNode;
24
28
  readonly currentState: GroupNodeState;
29
+ readonly validationState: AncestorNodeValidationState;
25
30
  }
@@ -0,0 +1,37 @@
1
+ import { LeafNodeDefinition } from '../model/LeafNodeDefinition.ts';
2
+ import { BaseNode, BaseNodeState } from './BaseNode.ts';
3
+ import { GeneralParentNode } from './hierarchy.ts';
4
+ import { RootNode } from './RootNode.ts';
5
+ import { LeafNodeValidationState } from './validation.ts';
6
+
7
+ export interface ModelValueNodeState extends BaseNodeState {
8
+ get label(): null;
9
+ get hint(): null;
10
+ get children(): null;
11
+ get valueOptions(): null;
12
+ /**
13
+ * Reflects the current value of a {@link ModelValueNode}. This value may be
14
+ * populated when a form is loaded, and it may be updated by certain
15
+ * computations defined by the form.
16
+ */
17
+ get value(): string;
18
+ }
19
+ export interface ModelValueDefinition extends LeafNodeDefinition {
20
+ readonly bodyElement: null;
21
+ }
22
+ /**
23
+ * A node which is:
24
+ *
25
+ * - model-only (i.e. it has no corresponding body element)
26
+ * - a leaf/value node (i.e. it has no element children; it may be defined in
27
+ * the form's `<model>` as either an {@link Element} or {@link Attr})
28
+ */
29
+ export interface ModelValueNode extends BaseNode {
30
+ readonly nodeType: 'model-value';
31
+ readonly appearances: null;
32
+ readonly definition: ModelValueDefinition;
33
+ readonly root: RootNode;
34
+ readonly parent: GeneralParentNode;
35
+ readonly currentState: ModelValueNodeState;
36
+ readonly validationState: LeafNodeValidationState;
37
+ }
@@ -0,0 +1,15 @@
1
+ import { ParsedTokenList } from '../lib/TokenListParser.ts';
2
+ import { NodeDefinition } from '../model/NodeDefinition.ts';
3
+
4
+ /**
5
+ * - Provides a means to distinguish between internal and client-facing names
6
+ * for the same {@link ParsedTokenList} types.
7
+ *
8
+ * - Anticipates some iteration on both parsed ("definition") types and
9
+ * client-facing node types, which may not happen in tandem.
10
+ */
11
+ export type NodeAppearances<Definition extends NodeDefinition<any>> = Definition extends {
12
+ readonly bodyElement: {
13
+ readonly appearances: infer Appearances extends ParsedTokenList<any>;
14
+ };
15
+ } ? Appearances : null;
@@ -0,0 +1,53 @@
1
+ import { InputDefinition } from '../body/control/InputDefinition.ts';
2
+ import { LeafNodeDefinition } from '../model/LeafNodeDefinition.ts';
3
+ import { BaseNode, BaseNodeState } from './BaseNode.ts';
4
+ import { GeneralParentNode } from './hierarchy.ts';
5
+ import { NodeAppearances } from './NodeAppearances.ts';
6
+ import { RootNode } from './RootNode.ts';
7
+ import { TextRange } from './TextRange.ts';
8
+ import { LeafNodeValidationState } from './validation.ts';
9
+
10
+ export interface NoteNodeState extends BaseNodeState {
11
+ /**
12
+ * Note-specific specialization: a note will always have a non-null value in
13
+ * at least one of:
14
+ *
15
+ * - {@link label}
16
+ * - {@link hint}
17
+ *
18
+ * This is an alias to whichever is present, with precedent to {@link label}
19
+ * if both are present.
20
+ */
21
+ get noteText(): NonNullable<this['label'] | this['hint']>;
22
+ /**
23
+ * A note will **always** be `readonly`.
24
+ */
25
+ readonly readonly: true;
26
+ get label(): TextRange<'label', 'form'> | null;
27
+ get hint(): TextRange<'hint', 'form'> | null;
28
+ get children(): null;
29
+ get valueOptions(): null;
30
+ /**
31
+ * Reflects the readonly value of a {@link NoteNode}, or `null` if blank.
32
+ */
33
+ get value(): string | null;
34
+ }
35
+ export interface NoteDefinition extends LeafNodeDefinition {
36
+ readonly bodyElement: InputDefinition;
37
+ }
38
+ export type NoteNodeAppearances = NodeAppearances<NoteDefinition>;
39
+ /**
40
+ * A node which is:
41
+ *
42
+ * - associated with an input, with at least one text element (label or hint)
43
+ * - guaranteed to be {@link NoteNodeState.readonly | readonly}
44
+ */
45
+ export interface NoteNode extends BaseNode {
46
+ readonly nodeType: 'note';
47
+ readonly appearances: NoteNodeAppearances;
48
+ readonly definition: NoteDefinition;
49
+ readonly root: RootNode;
50
+ readonly parent: GeneralParentNode;
51
+ readonly currentState: NoteNodeState;
52
+ readonly validationState: LeafNodeValidationState;
53
+ }
@@ -1,7 +1,9 @@
1
+ import { BodyClassList } from '../body/BodyDefinition.ts';
1
2
  import { RootDefinition } from '../model/RootDefinition.ts';
2
3
  import { BaseNode, BaseNodeState } from './BaseNode.ts';
3
4
  import { ActiveLanguage, FormLanguage, FormLanguages } from './FormLanguage.ts';
4
5
  import { GeneralChildNode } from './hierarchy.ts';
6
+ import { AncestorNodeValidationState } from './validation.ts';
5
7
 
6
8
  export interface RootNodeState extends BaseNodeState {
7
9
  /**
@@ -19,10 +21,29 @@ export interface RootNodeState extends BaseNodeState {
19
21
  }
20
22
  export interface RootNode extends BaseNode {
21
23
  readonly nodeType: 'root';
24
+ /**
25
+ * @todo this along with {@link classes} is... awkward.
26
+ */
27
+ readonly appearances: null;
28
+ /**
29
+ * @todo This is another odd deviation in {@link RootNode}. Unlike
30
+ * {@link languages}, it doesn't feel particularly **essential**. While it
31
+ * would deviate from XForms spec terminology, it seems like it _might be
32
+ * reasonable_ to instead convey `<h:body class="...">` as
33
+ * {@link RootNode.appearances} in the client interface. They do have slightly
34
+ * different spec semantics (i.e. a body class can be anything, to trigger
35
+ * styling in a form UI). But the **most likely anticipated** use case in Web
36
+ * Forms would be the "pages" class, and perhaps "theme-grid". The former is
37
+ * definitely conceptually similar to a XForms `appearance` (albeit
38
+ * form-global, which is not a spec concept). The latter does as well, and we
39
+ * already anticipate applying that concept in non-form-global ways.
40
+ */
41
+ readonly classes: BodyClassList;
22
42
  readonly definition: RootDefinition;
23
43
  readonly root: RootNode;
24
44
  readonly parent: null;
25
45
  readonly currentState: RootNodeState;
46
+ readonly validationState: AncestorNodeValidationState;
26
47
  /**
27
48
  * @todo as with {@link RootNodeState.activeLanguage}, this is the most
28
49
  * significant break in consistency across node types.
@@ -1,13 +1,15 @@
1
1
  import { AnySelectDefinition } from '../body/control/select/SelectDefinition.ts';
2
- import { ValueNodeDefinition } from '../model/ValueNodeDefinition.ts';
2
+ import { LeafNodeDefinition } from '../model/LeafNodeDefinition.ts';
3
3
  import { BaseNode, BaseNodeState } from './BaseNode.ts';
4
+ import { NodeAppearances } from './NodeAppearances.ts';
4
5
  import { RootNode } from './RootNode.ts';
5
6
  import { TextRange } from './TextRange.ts';
6
7
  import { GeneralParentNode } from './hierarchy.ts';
8
+ import { LeafNodeValidationState } from './validation.ts';
7
9
 
8
10
  export interface SelectItem {
9
11
  get value(): string;
10
- get label(): TextRange<'label'> | null;
12
+ get label(): TextRange<'item-label'> | null;
11
13
  }
12
14
  export interface SelectNodeState extends BaseNodeState {
13
15
  get children(): null;
@@ -29,15 +31,18 @@ export interface SelectNodeState extends BaseNodeState {
29
31
  */
30
32
  get value(): readonly SelectItem[];
31
33
  }
32
- export interface SelectDefinition extends ValueNodeDefinition {
34
+ export interface SelectDefinition extends LeafNodeDefinition {
33
35
  readonly bodyElement: AnySelectDefinition;
34
36
  }
37
+ export type SelectNodeAppearances = NodeAppearances<SelectDefinition>;
35
38
  export interface SelectNode extends BaseNode {
36
39
  readonly nodeType: 'select';
40
+ readonly appearances: SelectNodeAppearances;
37
41
  readonly definition: SelectDefinition;
38
42
  readonly root: RootNode;
39
43
  readonly parent: GeneralParentNode;
40
44
  readonly currentState: SelectNodeState;
45
+ readonly validationState: LeafNodeValidationState;
41
46
  /**
42
47
  * For use by a client to update the selection of a select node where:
43
48
  *