@getodk/xforms-engine 0.1.1 → 0.2.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 (101) hide show
  1. package/dist/body/BodyDefinition.d.ts +24 -7
  2. package/dist/body/RepeatElementDefinition.d.ts +19 -0
  3. package/dist/body/appearance/inputAppearanceParser.d.ts +4 -0
  4. package/dist/body/appearance/selectAppearanceParser.d.ts +4 -0
  5. package/dist/body/appearance/structureElementAppearanceParser.d.ts +4 -0
  6. package/dist/body/control/ControlDefinition.d.ts +2 -0
  7. package/dist/body/control/InputDefinition.d.ts +5 -0
  8. package/dist/body/control/select/SelectDefinition.d.ts +11 -1
  9. package/dist/body/group/BaseGroupDefinition.d.ts +3 -8
  10. package/dist/body/text/LabelDefinition.d.ts +2 -0
  11. package/dist/body/text/TextElementDefinition.d.ts +3 -3
  12. package/dist/client/BaseNode.d.ts +6 -1
  13. package/dist/client/GroupNode.d.ts +5 -2
  14. package/dist/client/NodeAppearances.d.ts +15 -0
  15. package/dist/client/RepeatInstanceNode.d.ts +3 -0
  16. package/dist/client/RepeatRangeNode.d.ts +5 -2
  17. package/dist/client/RootNode.d.ts +19 -0
  18. package/dist/client/SelectNode.d.ts +3 -0
  19. package/dist/client/StringNode.d.ts +3 -0
  20. package/dist/client/SubtreeNode.d.ts +1 -0
  21. package/dist/index.js +624 -368
  22. package/dist/index.js.map +1 -1
  23. package/dist/instance/Group.d.ts +3 -3
  24. package/dist/instance/RepeatInstance.d.ts +26 -2
  25. package/dist/instance/RepeatRange.d.ts +84 -5
  26. package/dist/instance/Root.d.ts +8 -23
  27. package/dist/instance/SelectField.d.ts +2 -2
  28. package/dist/instance/StringField.d.ts +2 -2
  29. package/dist/instance/Subtree.d.ts +1 -1
  30. package/dist/instance/abstract/DescendantNode.d.ts +12 -4
  31. package/dist/instance/abstract/InstanceNode.d.ts +26 -29
  32. package/dist/instance/internal-api/EvaluationContext.d.ts +5 -4
  33. package/dist/instance/internal-api/ValueContext.d.ts +2 -2
  34. package/dist/lib/TokenListParser.d.ts +84 -0
  35. package/dist/lib/dom/query.d.ts +5 -0
  36. package/dist/lib/reactivity/materializeCurrentStateChildren.d.ts +2 -1
  37. package/dist/model/DescendentNodeDefinition.d.ts +1 -2
  38. package/dist/model/NodeDefinition.d.ts +12 -12
  39. package/dist/model/RepeatInstanceDefinition.d.ts +5 -6
  40. package/dist/model/{RepeatSequenceDefinition.d.ts → RepeatRangeDefinition.d.ts} +4 -4
  41. package/dist/model/RepeatTemplateDefinition.d.ts +6 -7
  42. package/dist/model/RootDefinition.d.ts +3 -1
  43. package/dist/model/SubtreeDefinition.d.ts +2 -2
  44. package/dist/model/ValueNodeDefinition.d.ts +2 -3
  45. package/dist/solid.js +625 -369
  46. package/dist/solid.js.map +1 -1
  47. package/package.json +2 -2
  48. package/src/XFormDOM.ts +81 -8
  49. package/src/body/BodyDefinition.ts +38 -23
  50. package/src/body/RepeatElementDefinition.ts +70 -0
  51. package/src/body/appearance/inputAppearanceParser.ts +39 -0
  52. package/src/body/appearance/selectAppearanceParser.ts +38 -0
  53. package/src/body/appearance/structureElementAppearanceParser.ts +7 -0
  54. package/src/body/control/ControlDefinition.ts +4 -0
  55. package/src/body/control/InputDefinition.ts +13 -0
  56. package/src/body/control/select/SelectDefinition.ts +14 -5
  57. package/src/body/group/BaseGroupDefinition.ts +11 -49
  58. package/src/body/text/LabelDefinition.ts +15 -1
  59. package/src/body/text/TextElementDefinition.ts +5 -5
  60. package/src/client/BaseNode.ts +9 -1
  61. package/src/client/GroupNode.ts +6 -2
  62. package/src/client/NodeAppearances.ts +22 -0
  63. package/src/client/RepeatInstanceNode.ts +4 -0
  64. package/src/client/RepeatRangeNode.ts +6 -2
  65. package/src/client/RootNode.ts +22 -0
  66. package/src/client/SelectNode.ts +4 -0
  67. package/src/client/StringNode.ts +4 -0
  68. package/src/client/SubtreeNode.ts +1 -0
  69. package/src/instance/Group.ts +14 -9
  70. package/src/instance/RepeatInstance.ts +59 -15
  71. package/src/instance/RepeatRange.ts +133 -15
  72. package/src/instance/Root.ts +20 -64
  73. package/src/instance/SelectField.ts +7 -7
  74. package/src/instance/StringField.ts +8 -7
  75. package/src/instance/Subtree.ts +10 -7
  76. package/src/instance/abstract/DescendantNode.ts +45 -43
  77. package/src/instance/abstract/InstanceNode.ts +69 -86
  78. package/src/instance/children.ts +17 -7
  79. package/src/instance/index.ts +1 -1
  80. package/src/instance/internal-api/EvaluationContext.ts +5 -6
  81. package/src/instance/internal-api/ValueContext.ts +2 -2
  82. package/src/lib/TokenListParser.ts +156 -0
  83. package/src/lib/dom/query.ts +13 -0
  84. package/src/lib/reactivity/createChildrenState.ts +51 -6
  85. package/src/lib/reactivity/createComputedExpression.ts +1 -1
  86. package/src/lib/reactivity/createSelectItems.ts +4 -6
  87. package/src/lib/reactivity/createValueState.ts +6 -6
  88. package/src/lib/reactivity/materializeCurrentStateChildren.ts +3 -1
  89. package/src/model/DescendentNodeDefinition.ts +1 -2
  90. package/src/model/ModelDefinition.ts +1 -1
  91. package/src/model/NodeDefinition.ts +12 -12
  92. package/src/model/RepeatInstanceDefinition.ts +8 -13
  93. package/src/model/{RepeatSequenceDefinition.ts → RepeatRangeDefinition.ts} +6 -6
  94. package/src/model/RepeatTemplateDefinition.ts +10 -15
  95. package/src/model/RootDefinition.ts +6 -12
  96. package/src/model/SubtreeDefinition.ts +3 -3
  97. package/src/model/ValueNodeDefinition.ts +2 -3
  98. package/dist/body/RepeatDefinition.d.ts +0 -16
  99. package/dist/body/group/RepeatGroupDefinition.d.ts +0 -13
  100. package/src/body/RepeatDefinition.ts +0 -54
  101. package/src/body/group/RepeatGroupDefinition.ts +0 -91
@@ -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 {};
@@ -0,0 +1,19 @@
1
+ import { XFormDefinition } from '../XFormDefinition.ts';
2
+ import { BodyElementDefinitionArray, BodyElementParentContext } from './BodyDefinition.ts';
3
+ import { BodyElementDefinition } from './BodyElementDefinition.ts';
4
+ import { StructureElementAppearanceDefinition } from './appearance/structureElementAppearanceParser.ts';
5
+ import { LabelDefinition } from './text/LabelDefinition.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 isFixedCount: boolean;
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,4 +1,5 @@
1
1
  import { XFormDefinition } from '../../XFormDefinition.ts';
2
+ import { ParsedTokenList } from '../../lib/TokenListParser.ts';
2
3
  import { BodyElementParentContext } from '../BodyDefinition.ts';
3
4
  import { BodyElementDefinition } from '../BodyElementDefinition.ts';
4
5
  import { HintDefinition } from '../text/HintDefinition.ts';
@@ -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
  }
@@ -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,6 +1,7 @@
1
1
  import { XFormDefinition } from '../../XFormDefinition.ts';
2
2
  import { BodyElementDefinitionArray, BodyElementParentContext } from '../BodyDefinition.ts';
3
3
  import { BodyElementDefinition } from '../BodyElementDefinition.ts';
4
+ import { StructureElementAppearanceDefinition } from '../appearance/structureElementAppearanceParser.ts';
4
5
  import { LabelDefinition } from '../text/LabelDefinition.ts';
5
6
 
6
7
  /**
@@ -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;
@@ -3,6 +3,7 @@ import { AnyControlDefinition } from '../control/ControlDefinition.ts';
3
3
  import { ItemDefinition } from '../control/select/ItemDefinition.ts';
4
4
  import { ItemsetDefinition } from '../control/select/ItemsetDefinition.ts';
5
5
  import { BaseGroupDefinition } from '../group/BaseGroupDefinition.ts';
6
+ import { RepeatElementDefinition } from '../RepeatElementDefinition.ts';
6
7
  import { TextElement, TextElementOwner, TextElementDefinition } from './TextElementDefinition.ts';
7
8
 
8
9
  export interface LabelElement extends TextElement {
@@ -12,6 +13,7 @@ type StaticLabelContext = Exclude<TextElementOwner, ItemsetDefinition>;
12
13
  export declare class LabelDefinition extends TextElementDefinition<'label'> {
13
14
  protected static staticDefinition(form: XFormDefinition, definition: StaticLabelContext): LabelDefinition | null;
14
15
  static forControl(form: XFormDefinition, control: AnyControlDefinition): LabelDefinition | null;
16
+ static forRepeatGroup(form: XFormDefinition, repeat: RepeatElementDefinition): LabelDefinition | null;
15
17
  static forGroup(form: XFormDefinition, group: BaseGroupDefinition<any>): LabelDefinition | null;
16
18
  static forItem(form: XFormDefinition, item: ItemDefinition): LabelDefinition | null;
17
19
  static forItemset(form: XFormDefinition, itemset: ItemsetDefinition): LabelDefinition | null;
@@ -2,10 +2,10 @@ import { XFormDefinition } from '../../XFormDefinition.ts';
2
2
  import { AnyDependentExpression } from '../../expression/DependentExpression.ts';
3
3
  import { AnyGroupElementDefinition } from '../BodyDefinition.ts';
4
4
  import { BodyElementDefinition } from '../BodyElementDefinition.ts';
5
- import { InputDefinition } from '../control/InputDefinition.ts';
5
+ import { RepeatElementDefinition } from '../RepeatElementDefinition.ts';
6
+ import { AnyControlDefinition } from '../control/ControlDefinition.ts';
6
7
  import { ItemDefinition } from '../control/select/ItemDefinition.ts';
7
8
  import { ItemsetDefinition } from '../control/select/ItemsetDefinition.ts';
8
- import { AnySelectDefinition } from '../control/select/SelectDefinition.ts';
9
9
  import { TextElementOutputPart } from './TextElementOutputPart.ts';
10
10
  import { TextElementReferencePart } from './TextElementReferencePart.ts';
11
11
  import { TextElementStaticPart } from './TextElementStaticPart.ts';
@@ -14,7 +14,7 @@ export type TextElementType = 'hint' | 'label';
14
14
  export interface TextElement extends Element {
15
15
  readonly localName: TextElementType;
16
16
  }
17
- export type TextElementOwner = AnyGroupElementDefinition | AnySelectDefinition | InputDefinition | ItemDefinition | ItemsetDefinition;
17
+ export type TextElementOwner = AnyControlDefinition | AnyGroupElementDefinition | ItemDefinition | ItemsetDefinition | RepeatElementDefinition;
18
18
  export type TextElementChild = TextElementOutputPart | TextElementStaticPart;
19
19
  export declare abstract class TextElementDefinition<Type extends TextElementType> extends BodyElementDefinition<Type> {
20
20
  readonly owner: TextElementOwner;
@@ -1,6 +1,7 @@
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';
4
5
 
5
6
  export interface BaseNodeState {
6
7
  /**
@@ -108,6 +109,10 @@ export interface BaseNode {
108
109
  * the lifetime of an active session filling a form.
109
110
  */
110
111
  readonly nodeId: FormNodeID;
112
+ /**
113
+ * @see {@link TokenListParser} for details.
114
+ */
115
+ readonly appearances: NodeAppearances<any> | null;
111
116
  /**
112
117
  * Each node has a definition which specifies aspects of the node defined in
113
118
  * the form. These aspects include (but are not limited to) the node's data
@@ -1,6 +1,7 @@
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';
6
7
 
@@ -11,13 +12,15 @@ export interface GroupNodeState extends BaseNodeState {
11
12
  get value(): null;
12
13
  }
13
14
  export interface GroupDefinition extends SubtreeDefinition {
14
- readonly bodyElement: NonRepeatGroupElementDefinition;
15
+ readonly bodyElement: AnyGroupElementDefinition;
15
16
  }
17
+ export type GroupNodeAppearances = NodeAppearances<GroupDefinition>;
16
18
  /**
17
19
  * A node corresponding to an XForms `<group>`.
18
20
  */
19
21
  export interface GroupNode extends BaseNode {
20
22
  readonly nodeType: 'group';
23
+ readonly appearances: GroupNodeAppearances;
21
24
  readonly definition: GroupDefinition;
22
25
  readonly root: RootNode;
23
26
  readonly parent: GeneralParentNode;
@@ -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;
@@ -1,6 +1,7 @@
1
1
  import { RepeatInstanceDefinition } from '../model/RepeatInstanceDefinition.ts';
2
2
  import { RepeatTemplateDefinition } from '../model/RepeatTemplateDefinition.ts';
3
3
  import { BaseNode, BaseNodeState } from './BaseNode.ts';
4
+ import { NodeAppearances } from './NodeAppearances.ts';
4
5
  import { RepeatRangeNode } from './RepeatRangeNode.ts';
5
6
  import { RootNode } from './RootNode.ts';
6
7
  import { GeneralChildNode } from './hierarchy.ts';
@@ -12,8 +13,10 @@ export interface RepeatInstanceNodeState extends BaseNodeState {
12
13
  get value(): null;
13
14
  }
14
15
  export type RepeatDefinition = RepeatInstanceDefinition | RepeatTemplateDefinition;
16
+ export type RepeatInstanceNodeAppearances = NodeAppearances<RepeatDefinition>;
15
17
  export interface RepeatInstanceNode extends BaseNode {
16
18
  readonly nodeType: 'repeat-instance';
19
+ readonly appearances: RepeatInstanceNodeAppearances;
17
20
  readonly definition: RepeatDefinition;
18
21
  readonly root: RootNode;
19
22
  /**
@@ -1,5 +1,6 @@
1
- import { RepeatSequenceDefinition } from '../model/RepeatSequenceDefinition.ts';
1
+ import { RepeatRangeDefinition } from '../model/RepeatRangeDefinition.ts';
2
2
  import { BaseNode, BaseNodeState } from './BaseNode.ts';
3
+ import { NodeAppearances } from './NodeAppearances.ts';
3
4
  import { RepeatInstanceNode } from './RepeatInstanceNode.ts';
4
5
  import { RootNode } from './RootNode.ts';
5
6
  import { TextRange } from './TextRange.ts';
@@ -20,6 +21,7 @@ export interface RepeatRangeNodeState extends BaseNodeState {
20
21
  get valueOptions(): null;
21
22
  get value(): null;
22
23
  }
24
+ export type RepeatRangeNodeAppearances = NodeAppearances<RepeatRangeDefinition>;
23
25
  /**
24
26
  * Represents a contiguous set of zero or more {@link RepeatInstanceNode}s
25
27
  * (accessed by its
@@ -86,7 +88,8 @@ export interface RepeatRangeNodeState extends BaseNodeState {
86
88
  */
87
89
  export interface RepeatRangeNode extends BaseNode {
88
90
  readonly nodeType: 'repeat-range';
89
- readonly definition: RepeatSequenceDefinition;
91
+ readonly appearances: RepeatRangeNodeAppearances;
92
+ readonly definition: RepeatRangeDefinition;
90
93
  readonly root: RootNode;
91
94
  readonly parent: GeneralParentNode;
92
95
  readonly currentState: RepeatRangeNodeState;
@@ -1,3 +1,4 @@
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';
@@ -19,6 +20,24 @@ export interface RootNodeState extends BaseNodeState {
19
20
  }
20
21
  export interface RootNode extends BaseNode {
21
22
  readonly nodeType: 'root';
23
+ /**
24
+ * @todo this along with {@link classes} is... awkward.
25
+ */
26
+ readonly appearances: null;
27
+ /**
28
+ * @todo This is another odd deviation in {@link RootNode}. Unlike
29
+ * {@link languages}, it doesn't feel particularly **essential**. While it
30
+ * would deviate from XForms spec terminology, it seems like it _might be
31
+ * reasonable_ to instead convey `<h:body class="...">` as
32
+ * {@link RootNode.appearances} in the client interface. They do have slightly
33
+ * different spec semantics (i.e. a body class can be anything, to trigger
34
+ * styling in a form UI). But the **most likely anticipated** use case in Web
35
+ * Forms would be the "pages" class, and perhaps "theme-grid". The former is
36
+ * definitely conceptually similar to a XForms `appearance` (albeit
37
+ * form-global, which is not a spec concept). The latter does as well, and we
38
+ * already anticipate applying that concept in non-form-global ways.
39
+ */
40
+ readonly classes: BodyClassList;
22
41
  readonly definition: RootDefinition;
23
42
  readonly root: RootNode;
24
43
  readonly parent: null;
@@ -1,6 +1,7 @@
1
1
  import { AnySelectDefinition } from '../body/control/select/SelectDefinition.ts';
2
2
  import { ValueNodeDefinition } from '../model/ValueNodeDefinition.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';
@@ -32,8 +33,10 @@ export interface SelectNodeState extends BaseNodeState {
32
33
  export interface SelectDefinition extends ValueNodeDefinition {
33
34
  readonly bodyElement: AnySelectDefinition;
34
35
  }
36
+ export type SelectNodeAppearances = NodeAppearances<SelectDefinition>;
35
37
  export interface SelectNode extends BaseNode {
36
38
  readonly nodeType: 'select';
39
+ readonly appearances: SelectNodeAppearances;
37
40
  readonly definition: SelectDefinition;
38
41
  readonly root: RootNode;
39
42
  readonly parent: GeneralParentNode;
@@ -1,6 +1,7 @@
1
1
  import { InputDefinition } from '../body/control/InputDefinition.ts';
2
2
  import { ValueNodeDefinition } from '../model/ValueNodeDefinition.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 { GeneralParentNode } from './hierarchy.ts';
6
7
 
@@ -18,6 +19,7 @@ export interface StringNodeState extends BaseNodeState {
18
19
  export interface StringDefinition extends ValueNodeDefinition {
19
20
  readonly bodyElement: InputDefinition | null;
20
21
  }
22
+ export type StringNodeAppearances = NodeAppearances<StringDefinition>;
21
23
  /**
22
24
  * A node which can be assigned a string/text value. A string node **MAY**
23
25
  * correspond to form field defined as an XForms `<input>`, which a user-facing
@@ -27,6 +29,7 @@ export interface StringDefinition extends ValueNodeDefinition {
27
29
  */
28
30
  export interface StringNode extends BaseNode {
29
31
  readonly nodeType: 'string';
32
+ readonly appearances: StringNodeAppearances;
30
33
  readonly definition: StringDefinition;
31
34
  readonly root: RootNode;
32
35
  readonly parent: GeneralParentNode;
@@ -46,6 +46,7 @@ export interface SubtreeDefinition extends BaseSubtreeDefinition {
46
46
  */
47
47
  export interface SubtreeNode extends BaseNode {
48
48
  readonly nodeType: 'subtree';
49
+ readonly appearances: null;
49
50
  readonly definition: SubtreeDefinition;
50
51
  readonly root: RootNode;
51
52
  readonly parent: GeneralParentNode;