@getodk/xforms-engine 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/dist/client/AttributeNode.d.ts +53 -0
  2. package/dist/client/BaseItem.d.ts +6 -0
  3. package/dist/client/GroupNode.d.ts +4 -4
  4. package/dist/client/MarkdownNode.d.ts +33 -0
  5. package/dist/client/RankNode.d.ts +2 -4
  6. package/dist/client/SelectNode.d.ts +2 -5
  7. package/dist/client/TextRange.d.ts +2 -2
  8. package/dist/client/hierarchy.d.ts +1 -2
  9. package/dist/client/index.d.ts +2 -1
  10. package/dist/client/node-types.d.ts +2 -2
  11. package/dist/client/validation.d.ts +7 -1
  12. package/dist/index.js +10758 -402
  13. package/dist/index.js.map +1 -1
  14. package/dist/instance/Attribute.d.ts +58 -0
  15. package/dist/instance/Group.d.ts +4 -0
  16. package/dist/instance/PrimaryInstance.d.ts +4 -0
  17. package/dist/instance/Root.d.ts +4 -0
  18. package/dist/instance/UploadControl.d.ts +4 -0
  19. package/dist/instance/abstract/InstanceNode.d.ts +7 -4
  20. package/dist/instance/abstract/ValueNode.d.ts +1 -0
  21. package/dist/instance/attachments/buildAttributes.d.ts +3 -0
  22. package/dist/instance/hierarchy.d.ts +6 -6
  23. package/dist/instance/internal-api/AttributeContext.d.ts +29 -0
  24. package/dist/instance/internal-api/serialization/ClientReactiveSerializableAttributeNode.d.ts +16 -0
  25. package/dist/instance/internal-api/serialization/ClientReactiveSerializableParentNode.d.ts +2 -0
  26. package/dist/instance/internal-api/serialization/ClientReactiveSerializableTemplatedNode.d.ts +2 -2
  27. package/dist/instance/markdown/MarkdownNode.d.ts +75 -0
  28. package/dist/instance/repeat/BaseRepeatRange.d.ts +5 -0
  29. package/dist/instance/repeat/RepeatInstance.d.ts +4 -2
  30. package/dist/instance/text/TextChunk.d.ts +0 -1
  31. package/dist/instance/text/TextRange.d.ts +2 -1
  32. package/dist/instance/text/markdownFormat.d.ts +3 -0
  33. package/dist/integration/xpath/adapter/XFormsXPathNode.d.ts +2 -2
  34. package/dist/lib/client-reactivity/instance-state/createAttributeNodeInstanceState.d.ts +3 -0
  35. package/dist/lib/client-reactivity/instance-state/createTemplatedNodeInstanceState.d.ts +0 -3
  36. package/dist/lib/names/NamespaceDeclarationMap.d.ts +1 -1
  37. package/dist/lib/reactivity/createAttributeState.d.ts +16 -0
  38. package/dist/lib/reactivity/createAttributeValueState.d.ts +15 -0
  39. package/dist/lib/reactivity/createItemCollection.d.ts +5 -7
  40. package/dist/lib/xml-serialization.d.ts +5 -9
  41. package/dist/parse/XFormDOM.d.ts +1 -1
  42. package/dist/parse/body/BodyDefinition.d.ts +2 -8
  43. package/dist/parse/body/GroupElementDefinition.d.ts +22 -0
  44. package/dist/parse/body/control/ItemsetDefinition.d.ts +3 -0
  45. package/dist/parse/expression/ItemPropertyExpression.d.ts +6 -0
  46. package/dist/parse/model/AttributeDefinition.d.ts +22 -0
  47. package/dist/parse/model/{RootAttributeMap.d.ts → AttributeDefinitionMap.d.ts} +4 -10
  48. package/dist/parse/model/{SubtreeDefinition.d.ts → GroupDefinition.d.ts} +8 -4
  49. package/dist/parse/model/LeafNodeDefinition.d.ts +1 -0
  50. package/dist/parse/model/NodeDefinition.d.ts +13 -9
  51. package/dist/parse/model/RepeatDefinition.d.ts +5 -2
  52. package/dist/parse/model/RootDefinition.d.ts +3 -3
  53. package/dist/parse/text/LabelDefinition.d.ts +4 -5
  54. package/dist/solid.js +10758 -402
  55. package/dist/solid.js.map +1 -1
  56. package/package.json +6 -5
  57. package/src/client/AttributeNode.ts +62 -0
  58. package/src/client/BaseItem.ts +7 -0
  59. package/src/client/GroupNode.ts +4 -10
  60. package/src/client/MarkdownNode.ts +53 -0
  61. package/src/client/RankNode.ts +2 -5
  62. package/src/client/SelectNode.ts +2 -6
  63. package/src/client/TextRange.ts +2 -2
  64. package/src/client/hierarchy.ts +0 -2
  65. package/src/client/index.ts +2 -1
  66. package/src/client/node-types.ts +1 -1
  67. package/src/client/validation.ts +9 -1
  68. package/src/instance/Attribute.ts +164 -0
  69. package/src/instance/Group.ts +17 -1
  70. package/src/instance/InputControl.ts +1 -0
  71. package/src/instance/ModelValue.ts +1 -0
  72. package/src/instance/Note.ts +1 -0
  73. package/src/instance/PrimaryInstance.ts +17 -0
  74. package/src/instance/RangeControl.ts +1 -0
  75. package/src/instance/RankControl.ts +1 -0
  76. package/src/instance/Root.ts +16 -0
  77. package/src/instance/SelectControl.ts +1 -0
  78. package/src/instance/TriggerControl.ts +1 -0
  79. package/src/instance/UploadControl.ts +14 -0
  80. package/src/instance/abstract/DescendantNode.ts +5 -1
  81. package/src/instance/abstract/InstanceNode.ts +6 -3
  82. package/src/instance/abstract/ValueNode.ts +1 -0
  83. package/src/instance/attachments/buildAttributes.ts +8 -0
  84. package/src/instance/children/buildChildren.ts +1 -17
  85. package/src/instance/children/normalizeChildInitOptions.ts +44 -59
  86. package/src/instance/hierarchy.ts +3 -7
  87. package/src/instance/internal-api/AttributeContext.ts +34 -0
  88. package/src/instance/internal-api/serialization/ClientReactiveSerializableAttributeNode.ts +19 -0
  89. package/src/instance/internal-api/serialization/ClientReactiveSerializableParentNode.ts +2 -0
  90. package/src/instance/internal-api/serialization/ClientReactiveSerializableTemplatedNode.ts +2 -3
  91. package/src/instance/markdown/MarkdownNode.ts +115 -0
  92. package/src/instance/repeat/BaseRepeatRange.ts +14 -0
  93. package/src/instance/repeat/RepeatInstance.ts +14 -5
  94. package/src/instance/text/TextChunk.ts +0 -5
  95. package/src/instance/text/TextRange.ts +5 -3
  96. package/src/instance/text/markdownFormat.ts +214 -0
  97. package/src/integration/xpath/adapter/XFormsXPathNode.ts +3 -1
  98. package/src/integration/xpath/adapter/names.ts +0 -1
  99. package/src/lib/client-reactivity/instance-state/createAttributeNodeInstanceState.ts +16 -0
  100. package/src/lib/client-reactivity/instance-state/createParentNodeInstanceState.ts +5 -5
  101. package/src/lib/client-reactivity/instance-state/createRootInstanceState.ts +6 -9
  102. package/src/lib/client-reactivity/instance-state/createTemplatedNodeInstanceState.ts +5 -15
  103. package/src/lib/names/NamespaceDeclarationMap.ts +1 -1
  104. package/src/lib/reactivity/createAttributeState.ts +51 -0
  105. package/src/lib/reactivity/createAttributeValueState.ts +189 -0
  106. package/src/lib/reactivity/createItemCollection.ts +25 -9
  107. package/src/lib/xml-serialization.ts +30 -34
  108. package/src/parse/body/BodyDefinition.ts +7 -34
  109. package/src/parse/body/GroupElementDefinition.ts +47 -0
  110. package/src/parse/body/control/ItemsetDefinition.ts +7 -0
  111. package/src/parse/expression/ItemPropertyExpression.ts +12 -0
  112. package/src/parse/model/AttributeDefinition.ts +58 -0
  113. package/src/parse/model/{RootAttributeMap.ts → AttributeDefinitionMap.ts} +7 -13
  114. package/src/parse/model/{SubtreeDefinition.ts → GroupDefinition.ts} +12 -8
  115. package/src/parse/model/LeafNodeDefinition.ts +1 -0
  116. package/src/parse/model/NodeDefinition.ts +19 -12
  117. package/src/parse/model/RepeatDefinition.ts +10 -3
  118. package/src/parse/model/RootDefinition.ts +6 -6
  119. package/src/parse/model/nodeDefinitionMap.ts +1 -1
  120. package/src/parse/text/LabelDefinition.ts +4 -9
  121. package/dist/client/SubtreeNode.d.ts +0 -56
  122. package/dist/error/TemplatedNodeAttributeSerializationError.d.ts +0 -22
  123. package/dist/instance/Subtree.d.ts +0 -38
  124. package/dist/instance/text/FormattedTextStub.d.ts +0 -1
  125. package/dist/parse/body/group/BaseGroupDefinition.d.ts +0 -40
  126. package/dist/parse/body/group/LogicalGroupDefinition.d.ts +0 -6
  127. package/dist/parse/body/group/PresentationGroupDefinition.d.ts +0 -11
  128. package/dist/parse/body/group/StructuralGroupDefinition.d.ts +0 -6
  129. package/dist/parse/model/RootAttributeDefinition.d.ts +0 -21
  130. package/src/client/SubtreeNode.ts +0 -61
  131. package/src/error/TemplatedNodeAttributeSerializationError.ts +0 -24
  132. package/src/instance/Subtree.ts +0 -102
  133. package/src/instance/text/FormattedTextStub.ts +0 -8
  134. package/src/parse/body/group/BaseGroupDefinition.ts +0 -89
  135. package/src/parse/body/group/LogicalGroupDefinition.ts +0 -11
  136. package/src/parse/body/group/PresentationGroupDefinition.ts +0 -28
  137. package/src/parse/body/group/StructuralGroupDefinition.ts +0 -11
  138. package/src/parse/model/RootAttributeDefinition.ts +0 -44
@@ -2,8 +2,8 @@ import { XMLNS_NAMESPACE_URI } from '@getodk/common/constants/xmlns.ts';
2
2
  import type { StaticAttribute } from '../../integration/xpath/static-dom/StaticAttribute.ts';
3
3
  import type { StaticElement } from '../../integration/xpath/static-dom/StaticElement.ts';
4
4
  import type { QualifiedName } from '../../lib/names/QualifiedName.ts';
5
- import { RootAttributeDefinition } from './RootAttributeDefinition.ts';
6
- import type { RootDefinition } from './RootDefinition.ts';
5
+ import { AttributeDefinition } from './AttributeDefinition.ts';
6
+ import type { ModelDefinition } from './ModelDefinition.ts';
7
7
 
8
8
  /**
9
9
  * @todo We should probably just distinguish these as separate `StaticNode`
@@ -14,12 +14,6 @@ const isNonNamespaceAttribute = (attribute: StaticAttribute) => {
14
14
  };
15
15
 
16
16
  /**
17
- * @todo This can be trivially expanded to a narrowly general case when we
18
- * prioritize work to
19
- * {@link https://github.com/getodk/web-forms/issues/285 | support attributes}
20
- * (as modeled form nodes on par with elements). It's been deferred here to
21
- * avoid expanding scope of an already fairly large yak shave.
22
- *
23
17
  * @todo There's a **much more expansive** general case just waiting for a good
24
18
  * opportuntity to prioritize it. E.g. a `NamedNodeMap<T>`, where T is any
25
19
  * generalized concept of a named node. This expansive generalization would have
@@ -29,17 +23,17 @@ const isNonNamespaceAttribute = (attribute: StaticAttribute) => {
29
23
  *
30
24
  * @see {@link QualifiedName} for more detail.
31
25
  */
32
- export class RootAttributeMap extends Map<QualifiedName, RootAttributeDefinition> {
33
- static from(root: RootDefinition, instanceNode: StaticElement) {
26
+ export class AttributeDefinitionMap extends Map<QualifiedName, AttributeDefinition> {
27
+ static from(model: ModelDefinition, instanceNode: StaticElement) {
34
28
  const nonNamespaceAttributes = instanceNode.attributes.filter(isNonNamespaceAttribute);
35
29
  const definitions = nonNamespaceAttributes.map((attribute) => {
36
- return new RootAttributeDefinition(root, attribute);
30
+ const bind = model.binds.getOrCreateBindDefinition(attribute.nodeset);
31
+ return new AttributeDefinition(model.root, bind, attribute);
37
32
  });
38
-
39
33
  return new this(definitions);
40
34
  }
41
35
 
42
- private constructor(definitions: readonly RootAttributeDefinition[]) {
36
+ private constructor(definitions: readonly AttributeDefinition[]) {
43
37
  super(
44
38
  definitions.map((attribute) => {
45
39
  return [attribute.qualifiedName, attribute];
@@ -1,25 +1,27 @@
1
1
  import type { StaticElement } from '../../integration/xpath/static-dom/StaticElement.ts';
2
2
  import { NamespaceDeclarationMap } from '../../lib/names/NamespaceDeclarationMap.ts';
3
3
  import { QualifiedName } from '../../lib/names/QualifiedName.ts';
4
- import type {
5
- AnyBodyElementDefinition,
6
- AnyGroupElementDefinition,
7
- } from '../body/BodyDefinition.ts';
4
+ import type { AnyBodyElementDefinition } from '../body/BodyDefinition.ts';
5
+ import type { GroupElementDefinition } from '../body/GroupElementDefinition.ts';
6
+ import { AttributeDefinitionMap } from './AttributeDefinitionMap.ts';
8
7
  import type { BindDefinition } from './BindDefinition.ts';
9
8
  import { DescendentNodeDefinition } from './DescendentNodeDefinition.ts';
9
+ import type { ModelDefinition } from './ModelDefinition.ts';
10
10
  import type { ChildNodeDefinition, ParentNodeDefinition } from './NodeDefinition.ts';
11
11
 
12
- export class SubtreeDefinition extends DescendentNodeDefinition<
13
- 'subtree',
14
- AnyGroupElementDefinition | null
12
+ export class GroupDefinition extends DescendentNodeDefinition<
13
+ 'group',
14
+ GroupElementDefinition | null
15
15
  > {
16
- readonly type = 'subtree';
16
+ readonly type = 'group';
17
17
 
18
18
  readonly namespaceDeclarations: NamespaceDeclarationMap;
19
19
  readonly qualifiedName: QualifiedName;
20
20
  readonly children: readonly ChildNodeDefinition[];
21
+ readonly attributes: AttributeDefinitionMap;
21
22
 
22
23
  constructor(
24
+ model: ModelDefinition,
23
25
  parent: ParentNodeDefinition,
24
26
  bind: BindDefinition,
25
27
  bodyElement: AnyBodyElementDefinition | null,
@@ -39,6 +41,8 @@ export class SubtreeDefinition extends DescendentNodeDefinition<
39
41
  this.qualifiedName = template.qualifiedName;
40
42
  this.namespaceDeclarations = new NamespaceDeclarationMap(this);
41
43
  this.children = root.buildSubtree(this, template);
44
+
45
+ this.attributes = AttributeDefinitionMap.from(model, template);
42
46
  }
43
47
 
44
48
  toJSON() {
@@ -20,6 +20,7 @@ export class LeafNodeDefinition<V extends ValueType = ValueType>
20
20
  readonly namespaceDeclarations: NamespaceDeclarationMap;
21
21
  readonly qualifiedName: QualifiedName;
22
22
  readonly children = null;
23
+ readonly attributes = null;
23
24
 
24
25
  constructor(
25
26
  parent: ParentNodeDefinition,
@@ -1,3 +1,4 @@
1
+ import type { StaticAttribute } from '../../integration/xpath/static-dom/StaticAttribute.ts';
1
2
  import type { StaticElement } from '../../integration/xpath/static-dom/StaticElement.ts';
2
3
  import type {
3
4
  NamedSubtreeDefinition,
@@ -6,11 +7,13 @@ import type {
6
7
  import type { QualifiedName } from '../../lib/names/QualifiedName.ts';
7
8
  import type { AnyBodyElementDefinition } from '../body/BodyDefinition.ts';
8
9
  import type { RepeatElementDefinition } from '../body/RepeatElementDefinition.ts';
10
+ import type { AttributeDefinition } from './AttributeDefinition.ts';
11
+ import type { AttributeDefinitionMap } from './AttributeDefinitionMap.ts';
9
12
  import type { BindDefinition } from './BindDefinition.ts';
13
+ import type { GroupDefinition } from './GroupDefinition.ts';
10
14
  import type { LeafNodeDefinition } from './LeafNodeDefinition.ts';
11
15
  import type { AnyRepeatDefinition } from './RepeatDefinition.ts';
12
16
  import type { RootDefinition } from './RootDefinition.ts';
13
- import type { SubtreeDefinition } from './SubtreeDefinition.ts';
14
17
 
15
18
  /**
16
19
  * Corresponds to a model instance root node, i.e.:
@@ -33,10 +36,9 @@ export type RepeatType = 'repeat';
33
36
 
34
37
  /**
35
38
  * Corresponds to a model instance subtree which **does not** correspond to a
36
- * <repeat> in the form definition. This will typically correspond to a <group>,
37
- * but this is not strictly necessary per spec (hence the distinct name).
39
+ * <repeat> in the form definition.
38
40
  */
39
- export type SubtreeNodeType = 'subtree';
41
+ export type GroupNodeType = 'group';
40
42
 
41
43
  /**
42
44
  * Corresponds to a model instance leaf node, i.e. one of:
@@ -46,26 +48,29 @@ export type SubtreeNodeType = 'subtree';
46
48
  */
47
49
  export type LeafNodeType = 'leaf-node';
48
50
 
51
+ export type AttributeNodeType = 'attribute';
52
+
49
53
  // prettier-ignore
50
54
  export type NodeDefinitionType =
51
55
  // eslint-disable-next-line @typescript-eslint/sort-type-constituents
52
56
  | RootNodeType
53
57
  | RepeatType
54
- | SubtreeNodeType
55
- | LeafNodeType;
58
+ | GroupNodeType
59
+ | LeafNodeType
60
+ | AttributeNodeType;
56
61
 
57
62
  // prettier-ignore
58
63
  export type ParentNodeDefinition =
59
64
  // eslint-disable-next-line @typescript-eslint/sort-type-constituents
60
65
  | RootDefinition
61
66
  | AnyRepeatDefinition
62
- | SubtreeDefinition;
67
+ | GroupDefinition;
63
68
 
64
69
  // prettier-ignore
65
70
  export type ChildNodeDefinition =
66
71
  | AnyRepeatDefinition
67
- | LeafNodeDefinition
68
- | SubtreeDefinition;
72
+ | GroupDefinition
73
+ | LeafNodeDefinition;
69
74
 
70
75
  export abstract class NodeDefinition<Type extends NodeDefinitionType>
71
76
  implements NamedSubtreeDefinition
@@ -77,8 +82,9 @@ export abstract class NodeDefinition<Type extends NodeDefinitionType>
77
82
  abstract readonly isTranslated: boolean;
78
83
  abstract readonly root: RootDefinition;
79
84
  abstract readonly parent: ParentNodeDefinition | null;
80
- abstract readonly template: StaticElement;
85
+ abstract readonly template: StaticAttribute | StaticElement;
81
86
  abstract readonly children: readonly ChildNodeDefinition[] | null;
87
+ abstract readonly attributes: AttributeDefinitionMap | null;
82
88
 
83
89
  readonly nodeset: string;
84
90
 
@@ -92,5 +98,6 @@ export type AnyNodeDefinition =
92
98
  // eslint-disable-next-line @typescript-eslint/sort-type-constituents
93
99
  | RootDefinition
94
100
  | AnyRepeatDefinition
95
- | SubtreeDefinition
96
- | LeafNodeDefinition;
101
+ | GroupDefinition
102
+ | LeafNodeDefinition
103
+ | AttributeDefinition;
@@ -19,11 +19,13 @@ import type { NamespaceURL } from '../../lib/names/NamespaceURL.ts';
19
19
  import type { QualifiedName, QualifiedNameSource } from '../../lib/names/QualifiedName.ts';
20
20
  import type { RepeatElementDefinition } from '../body/RepeatElementDefinition.ts';
21
21
  import { RepeatCountControlExpression } from '../expression/RepeatCountControlExpression.ts';
22
+ import { AttributeDefinitionMap } from './AttributeDefinitionMap.ts';
22
23
  import type { BindDefinition } from './BindDefinition.ts';
23
24
  import { DescendentNodeDefinition } from './DescendentNodeDefinition.ts';
25
+ import type { GroupDefinition } from './GroupDefinition.ts';
26
+ import type { ModelDefinition } from './ModelDefinition.ts';
24
27
  import type { ChildNodeDefinition, ParentNodeDefinition } from './NodeDefinition.ts';
25
28
  import type { RootDefinition } from './RootDefinition.ts';
26
- import type { SubtreeDefinition } from './SubtreeDefinition.ts';
27
29
 
28
30
  interface JavaRosaNamespaceURI extends NamespaceURL {
29
31
  readonly href: JAVAROSA_NAMESPACE_URI;
@@ -284,7 +286,7 @@ export interface UncontrolledRepeatDefinition extends RepeatDefinition {
284
286
  * "repeat", as defined by a form, where those concepts include:
285
287
  *
286
288
  * - A {@link RepeatElementDefinition}—corresponding to a `<repeat>` {@link https://getodk.github.io/xforms-spec/#body-elements | body element}—which is associated with the nodeset referencing the "repeat template" and
287
- * all "repeat instances" (see below points describing both concepts in more detail). The presence of such a body element determines whether to produce a repeat definition (rather than e.g. a {@link SubtreeDefinition}).
289
+ * all "repeat instances" (see below points describing both concepts in more detail). The presence of such a body element determines whether to produce a repeat definition (rather than e.g. a {@link GroupDefinition}).
288
290
  *
289
291
  * - A "repeat template", defined by a form either
290
292
  * explicitly,
@@ -313,18 +315,20 @@ export interface UncontrolledRepeatDefinition extends RepeatDefinition {
313
315
  */
314
316
  export class RepeatDefinition extends DescendentNodeDefinition<'repeat', RepeatElementDefinition> {
315
317
  static from(
318
+ model: ModelDefinition,
316
319
  parent: ParentNodeDefinition,
317
320
  bind: BindDefinition,
318
321
  bodyElement: RepeatElementDefinition,
319
322
  instanceNodes: RepeatInstanceNodes
320
323
  ): AnyRepeatDefinition;
321
324
  static from(
325
+ model: ModelDefinition,
322
326
  parent: ParentNodeDefinition,
323
327
  bind: BindDefinition,
324
328
  bodyElement: RepeatElementDefinition,
325
329
  instanceNodes: RepeatInstanceNodes
326
330
  ): RepeatDefinition {
327
- return new this(parent, bind, bodyElement, instanceNodes);
331
+ return new this(model, parent, bind, bodyElement, instanceNodes);
328
332
  }
329
333
 
330
334
  readonly type = 'repeat';
@@ -333,8 +337,10 @@ export class RepeatDefinition extends DescendentNodeDefinition<'repeat', RepeatE
333
337
  readonly template: StaticElement;
334
338
  readonly namespaceDeclarations: NamespaceDeclarationMap;
335
339
  readonly qualifiedName: QualifiedName;
340
+ readonly attributes: AttributeDefinitionMap;
336
341
 
337
342
  private constructor(
343
+ model: ModelDefinition,
338
344
  parent: ParentNodeDefinition,
339
345
  bind: BindDefinition,
340
346
  bodyElement: RepeatElementDefinition,
@@ -353,6 +359,7 @@ export class RepeatDefinition extends DescendentNodeDefinition<'repeat', RepeatE
353
359
  this.children = root.buildSubtree(self, template);
354
360
 
355
361
  const initialCount = this.omitTemplate(instanceNodes).length;
362
+ this.attributes = AttributeDefinitionMap.from(model, template);
356
363
 
357
364
  this.count = RepeatCountControlExpression.from(bodyElement, initialCount);
358
365
  }
@@ -3,6 +3,8 @@ import { NamespaceDeclarationMap } from '../../lib/names/NamespaceDeclarationMap
3
3
  import { QualifiedName } from '../../lib/names/QualifiedName.ts';
4
4
  import type { BodyClassList } from '../body/BodyDefinition.ts';
5
5
  import type { XFormDefinition } from '../XFormDefinition.ts';
6
+ import { AttributeDefinitionMap } from './AttributeDefinitionMap.ts';
7
+ import { GroupDefinition } from './GroupDefinition.ts';
6
8
  import { LeafNodeDefinition } from './LeafNodeDefinition.ts';
7
9
  import type { ModelDefinition } from './ModelDefinition.ts';
8
10
  import type { ChildNodeDefinition, ParentNodeDefinition } from './NodeDefinition.ts';
@@ -10,9 +12,7 @@ import { NodeDefinition } from './NodeDefinition.ts';
10
12
  import { NoteNodeDefinition } from './NoteNodeDefinition.ts';
11
13
  import { RangeNodeDefinition } from './RangeNodeDefinition.ts';
12
14
  import { RepeatDefinition } from './RepeatDefinition.ts';
13
- import { RootAttributeMap } from './RootAttributeMap.ts';
14
15
  import type { SubmissionDefinition } from './SubmissionDefinition.ts';
15
- import { SubtreeDefinition } from './SubtreeDefinition.ts';
16
16
 
17
17
  export class RootDefinition extends NodeDefinition<'root'> {
18
18
  readonly type = 'root';
@@ -22,7 +22,7 @@ export class RootDefinition extends NodeDefinition<'root'> {
22
22
  readonly parent = null;
23
23
  readonly template: StaticElement;
24
24
  readonly namespaceDeclarations: NamespaceDeclarationMap;
25
- readonly attributes: RootAttributeMap;
25
+ readonly attributes: AttributeDefinitionMap;
26
26
  readonly children: readonly ChildNodeDefinition[];
27
27
 
28
28
  readonly isTranslated = false;
@@ -51,7 +51,7 @@ export class RootDefinition extends NodeDefinition<'root'> {
51
51
 
52
52
  this.qualifiedName = qualifiedName;
53
53
  this.template = template;
54
- this.attributes = RootAttributeMap.from(this, template);
54
+ this.attributes = AttributeDefinitionMap.from(model, template);
55
55
  this.namespaceDeclarations = new NamespaceDeclarationMap(this);
56
56
  this.children = this.buildSubtree(this, template);
57
57
  }
@@ -87,7 +87,7 @@ export class RootDefinition extends NodeDefinition<'root'> {
87
87
  const [firstChild, ...restChildren] = children;
88
88
 
89
89
  if (bodyElement?.type === 'repeat') {
90
- return RepeatDefinition.from(parent, bind, bodyElement, children);
90
+ return RepeatDefinition.from(model, parent, bind, bodyElement, children);
91
91
  }
92
92
 
93
93
  if (restChildren.length) {
@@ -107,7 +107,7 @@ export class RootDefinition extends NodeDefinition<'root'> {
107
107
  );
108
108
  }
109
109
 
110
- return new SubtreeDefinition(parent, bind, bodyElement, element);
110
+ return new GroupDefinition(model, parent, bind, bodyElement, element);
111
111
  });
112
112
  }
113
113
 
@@ -16,7 +16,7 @@ const collectDefinitions = (
16
16
 
17
17
  result.set(nodeset, definition);
18
18
 
19
- if (definition.type === 'leaf-node') {
19
+ if (definition.type === 'leaf-node' || definition.type === 'attribute') {
20
20
  return result;
21
21
  }
22
22
 
@@ -1,16 +1,15 @@
1
1
  import type { LocalNamedElement } from '@getodk/common/types/dom.ts';
2
2
  import { getLabelElement, getRepeatGroupLabelElement } from '../../lib/dom/query.ts';
3
3
  import type { XFormDefinition } from '../../parse/XFormDefinition.ts';
4
- import type { AnyGroupElementDefinition } from '../../parse/body/BodyDefinition.ts';
5
- import type { RepeatElementDefinition } from '../body/RepeatElementDefinition.ts';
6
4
  import type { AnyControlDefinition } from '../body/control/ControlDefinition.ts';
7
- import type { BaseGroupDefinition } from '../body/group/BaseGroupDefinition.ts';
5
+ import type { GroupElementDefinition } from '../body/GroupElementDefinition.ts';
6
+ import type { RepeatElementDefinition } from '../body/RepeatElementDefinition.ts';
8
7
  import { TextElementDefinition } from './abstract/TextElementDefinition.ts';
9
8
 
10
9
  // prettier-ignore
11
10
  export type LabelOwner =
12
11
  | AnyControlDefinition
13
- | AnyGroupElementDefinition
12
+ | GroupElementDefinition
14
13
  | RepeatElementDefinition;
15
14
 
16
15
  interface LabelElement extends LocalNamedElement<'label'> {}
@@ -39,11 +38,7 @@ export class LabelDefinition extends TextElementDefinition<'label'> {
39
38
  return new this(form, repeat, repeatGroupLabel);
40
39
  }
41
40
 
42
- static forGroup(
43
- form: XFormDefinition,
44
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
- group: BaseGroupDefinition<any>
46
- ): LabelDefinition | null {
41
+ static forGroup(form: XFormDefinition, group: GroupElementDefinition): LabelDefinition | null {
47
42
  const labelElement = getLabelElement(group.element);
48
43
 
49
44
  if (labelElement == null) {
@@ -1,56 +0,0 @@
1
- import { SubtreeDefinition as BaseSubtreeDefinition } from '../parse/model/SubtreeDefinition.ts';
2
- import { BaseNode, BaseNodeState } from './BaseNode.ts';
3
- import { RootNode } from './RootNode.ts';
4
- import { GeneralChildNode, GeneralParentNode } from './hierarchy.ts';
5
- import { AncestorNodeValidationState } from './validation.ts';
6
- export interface SubtreeNodeState extends BaseNodeState {
7
- get label(): null;
8
- get hint(): null;
9
- get children(): readonly GeneralChildNode[];
10
- get valueOptions(): null;
11
- get value(): null;
12
- }
13
- export interface SubtreeDefinition extends BaseSubtreeDefinition {
14
- readonly bodyElement: null;
15
- }
16
- /**
17
- * A non-root node which has children, but **no** corresponding XForms
18
- * `<group>`. A subtree node does not have any direct implications for
19
- * presentation to users, but its descendants may specify presentational details
20
- * in their own {@link BaseNode.definition | definition}s.
21
- *
22
- * @example
23
- *
24
- * A common `SubtreeNode` case will be a form's `<meta>` element:
25
- *
26
- * ```xml
27
- * <!-- /h:html/h:head/model -->
28
- * <instance>
29
- * <data>
30
- * <some-group>
31
- * <some-field />
32
- * </some-group>
33
- * <!-- Note that `meta` does not have a corresponding group body element -->
34
- * <!-- SubtreeNode(/data/meta): { ... -->
35
- * <meta>
36
- * <instanceID/>
37
- * </meta>
38
- * <!-- } -->
39
- * </data>
40
- * </instance>
41
- * <!-- /h:html/h:body -->
42
- * <group ref="/data/some-group">
43
- * <input ref="/data/some-group/some-field" />
44
- * </group>
45
- * ```
46
- */
47
- export interface SubtreeNode extends BaseNode {
48
- readonly nodeType: 'subtree';
49
- readonly appearances: null;
50
- readonly nodeOptions: null;
51
- readonly definition: SubtreeDefinition;
52
- readonly root: RootNode;
53
- readonly parent: GeneralParentNode;
54
- readonly currentState: SubtreeNodeState;
55
- readonly validationState: AncestorNodeValidationState;
56
- }
@@ -1,22 +0,0 @@
1
- /**
2
- * This error class is intended as a common point of reference for all of the
3
- * related interfaces and implementation where we've deferred two concerns:
4
- *
5
- * 1. Support for attributes on instance nodes (which may be bound in a form's
6
- * model and/or may be expected to preserve model-defined defaults)
7
- * 2. Present lack of logic to treat a `jr:template` attribute as a special
8
- * case: whereas in the general case we would expect to pass through a
9
- * form/model-defined attribute, we expect to specifically **omit**
10
- * `jr:template` from repeat instances derived from any of form's
11
- * explicitly-defined repeat templates
12
- *
13
- * Addressing #1 is (now) a prerequisite to addressing #2, and it is also a
14
- * prerequisite for #2's unaddressed status to _become meaningfully observable
15
- * and problematic_.
16
- *
17
- * By introducing this error at a point where a change in #1's status is likely
18
- * to be implicated, we're also likely to be reminded to address #2 in tandem.
19
- */
20
- export declare class TemplatedNodeAttributeSerializationError extends Error {
21
- constructor();
22
- }
@@ -1,38 +0,0 @@
1
- import { XPathNodeKindKey } from '@getodk/xpath';
2
- import { Accessor } from 'solid-js';
3
- import { FormNodeID } from '../client/identity.ts';
4
- import { InstanceState } from '../client/serialization/InstanceState.ts';
5
- import { SubtreeDefinition, SubtreeNode } from '../client/SubtreeNode.ts';
6
- import { AncestorNodeValidationState } from '../client/validation.ts';
7
- import { XFormsXPathElement } from '../integration/xpath/adapter/XFormsXPathNode.ts';
8
- import { StaticElement } from '../integration/xpath/static-dom/StaticElement.ts';
9
- import { MaterializedChildren } from '../lib/reactivity/materializeCurrentStateChildren.ts';
10
- import { CurrentState } from '../lib/reactivity/node-state/createCurrentState.ts';
11
- import { EngineState } from '../lib/reactivity/node-state/createEngineState.ts';
12
- import { SharedNodeState } from '../lib/reactivity/node-state/createSharedNodeState.ts';
13
- import { DescendantNodeSharedStateSpec, DescendantNode } from './abstract/DescendantNode.ts';
14
- import { GeneralChildNode, GeneralParentNode } from './hierarchy.ts';
15
- import { EvaluationContext } from './internal-api/EvaluationContext.ts';
16
- import { ClientReactiveSerializableParentNode } from './internal-api/serialization/ClientReactiveSerializableParentNode.ts';
17
- interface SubtreeStateSpec extends DescendantNodeSharedStateSpec {
18
- readonly label: null;
19
- readonly hint: null;
20
- readonly children: Accessor<readonly FormNodeID[]>;
21
- readonly valueOptions: null;
22
- readonly value: null;
23
- }
24
- export declare class Subtree extends DescendantNode<SubtreeDefinition, SubtreeStateSpec, GeneralParentNode, GeneralChildNode> implements SubtreeNode, XFormsXPathElement, EvaluationContext, ClientReactiveSerializableParentNode<GeneralChildNode> {
25
- private readonly childrenState;
26
- readonly [XPathNodeKindKey] = "element";
27
- protected readonly state: SharedNodeState<SubtreeStateSpec>;
28
- protected readonly engineState: EngineState<SubtreeStateSpec>;
29
- readonly nodeType = "subtree";
30
- readonly appearances: null;
31
- readonly nodeOptions: null;
32
- readonly currentState: MaterializedChildren<CurrentState<SubtreeStateSpec>, GeneralChildNode>;
33
- readonly validationState: AncestorNodeValidationState;
34
- readonly instanceState: InstanceState;
35
- constructor(parent: GeneralParentNode, instanceNode: StaticElement | null, definition: SubtreeDefinition);
36
- getChildren(): readonly GeneralChildNode[];
37
- }
38
- export {};
@@ -1 +0,0 @@
1
- export declare const FormattedTextStub: Record<PropertyKey, unknown>;
@@ -1,40 +0,0 @@
1
- import { LabelDefinition } from '../../text/LabelDefinition.ts';
2
- import { XFormDefinition } from '../../XFormDefinition.ts';
3
- import { StructureElementAppearanceDefinition } from '../appearance/structureElementAppearanceParser.ts';
4
- import { BodyElementDefinitionArray, BodyElementParentContext } from '../BodyDefinition.ts';
5
- import { BodyElementDefinition } from '../BodyElementDefinition.ts';
6
- /**
7
- * These type names are derived from **and expand upon** the language used in
8
- * the ODK XForms spec to describe various group usage. Whereas the spec
9
- * language allows for a group to be described as more than one case, the intent
10
- * here is to establish exclusive naming which may or may not compound. As such:
11
- *
12
- * - `logical-group`, per spec language, is a group with a `ref`; its usage here
13
- * differs from the spec language in that it _may_ have a `<label>` child but
14
- * is not also treated as a `presentation-group` (which is only used for
15
- * groups which do not have a `ref`)
16
- * - `presentation-group` is a group with a `<label>` child; its usage here
17
- * differs from the spec language in that `presentation-group` does **not**
18
- * have a `ref`
19
- * - `structural-group` is any `<group>` element which does not satisfy any of
20
- * the other usage scenarios; this isn't exactly the terminology used, but is
21
- * the most closely fitting name for the concept where the other sceanarios
22
- * do not apply
23
- *
24
- * A more succinct decision tree:
25
- *
26
- * - `<group ref="$ref">` -> `logical-group`, else
27
- * - `<group><label>` -> `presentation-group`, else
28
- * - `<group>` -> `structural-group`
29
- */
30
- export type GroupType = 'logical-group' | 'presentation-group' | 'structural-group';
31
- export declare abstract class BaseGroupDefinition<Type extends GroupType> extends BodyElementDefinition<Type> {
32
- private static groupTypes;
33
- protected static getGroupType(localName: string, element: Element): GroupType | null;
34
- readonly category = "structure";
35
- readonly children: BodyElementDefinitionArray;
36
- readonly reference: string | null;
37
- readonly appearances: StructureElementAppearanceDefinition;
38
- readonly label: LabelDefinition | null;
39
- constructor(form: XFormDefinition, parent: BodyElementParentContext, element: Element);
40
- }
@@ -1,6 +0,0 @@
1
- import { BaseGroupDefinition } from './BaseGroupDefinition.ts';
2
- export declare class LogicalGroupDefinition extends BaseGroupDefinition<'logical-group'> {
3
- static isCompatible(localName: string, element: Element): boolean;
4
- readonly type = "logical-group";
5
- }
6
- export type LogicalGroupDefinitionClass = typeof LogicalGroupDefinition;
@@ -1,11 +0,0 @@
1
- import { LabelDefinition } from '../../text/LabelDefinition.ts';
2
- import { XFormDefinition } from '../../XFormDefinition.ts';
3
- import { BodyElementParentContext } from '../BodyDefinition.ts';
4
- import { BaseGroupDefinition } from './BaseGroupDefinition.ts';
5
- export declare class PresentationGroupDefinition extends BaseGroupDefinition<'presentation-group'> {
6
- static isCompatible(localName: string, element: Element): boolean;
7
- readonly type = "presentation-group";
8
- readonly label: LabelDefinition;
9
- constructor(form: XFormDefinition, parent: BodyElementParentContext, element: Element);
10
- }
11
- export type PresentationGroupDefinitionClass = typeof PresentationGroupDefinition;
@@ -1,6 +0,0 @@
1
- import { BaseGroupDefinition } from './BaseGroupDefinition.ts';
2
- export declare class StructuralGroupDefinition extends BaseGroupDefinition<'structural-group'> {
3
- static isCompatible(localName: string, element: Element): boolean;
4
- readonly type = "structural-group";
5
- }
6
- export type StructuralGroupDefinitionClass = typeof StructuralGroupDefinition;
@@ -1,21 +0,0 @@
1
- import { NamedNodeDefinition } from '../../lib/names/NamespaceDeclarationMap.ts';
2
- import { QualifiedName } from '../../lib/names/QualifiedName.ts';
3
- import { RootDefinition } from './RootDefinition.ts';
4
- interface RootAttributeSource {
5
- readonly qualifiedName: QualifiedName;
6
- readonly value: string;
7
- }
8
- /**
9
- * @todo This class is named and typed to emphasize its intentionally narrow
10
- * usage and purpose. It **intentionally** avoids addressing the much broader
11
- * set of concerns around modeling attributes in primary instance/submissions.
12
- */
13
- export declare class RootAttributeDefinition implements NamedNodeDefinition {
14
- private readonly serializedXML;
15
- readonly parent: RootDefinition;
16
- readonly qualifiedName: QualifiedName;
17
- readonly value: string;
18
- constructor(root: RootDefinition, source: RootAttributeSource);
19
- serializeAttributeXML(): string;
20
- }
21
- export {};
@@ -1,61 +0,0 @@
1
- import type { SubtreeDefinition as BaseSubtreeDefinition } from '../parse/model/SubtreeDefinition.ts';
2
- import type { BaseNode, BaseNodeState } from './BaseNode.ts';
3
- import type { RootNode } from './RootNode.ts';
4
- import type { GeneralChildNode, GeneralParentNode } from './hierarchy.ts';
5
- import type { AncestorNodeValidationState } from './validation.ts';
6
-
7
- export interface SubtreeNodeState extends BaseNodeState {
8
- get label(): null;
9
- get hint(): null;
10
- get children(): readonly GeneralChildNode[];
11
- get valueOptions(): null;
12
- get value(): null;
13
- }
14
-
15
- // TODO: obviously there is a naming inconsistency emerging here.
16
- export interface SubtreeDefinition extends BaseSubtreeDefinition {
17
- readonly bodyElement: null;
18
- }
19
-
20
- /**
21
- * A non-root node which has children, but **no** corresponding XForms
22
- * `<group>`. A subtree node does not have any direct implications for
23
- * presentation to users, but its descendants may specify presentational details
24
- * in their own {@link BaseNode.definition | definition}s.
25
- *
26
- * @example
27
- *
28
- * A common `SubtreeNode` case will be a form's `<meta>` element:
29
- *
30
- * ```xml
31
- * <!-- /h:html/h:head/model -->
32
- * <instance>
33
- * <data>
34
- * <some-group>
35
- * <some-field />
36
- * </some-group>
37
- * <!-- Note that `meta` does not have a corresponding group body element -->
38
- * <!-- SubtreeNode(/data/meta): { ... -->
39
- * <meta>
40
- * <instanceID/>
41
- * </meta>
42
- * <!-- } -->
43
- * </data>
44
- * </instance>
45
- * <!-- /h:html/h:body -->
46
- * <group ref="/data/some-group">
47
- * <input ref="/data/some-group/some-field" />
48
- * </group>
49
- * ```
50
- */
51
- // TODO: directly test presentation of non-group subtree children/descendants
52
- export interface SubtreeNode extends BaseNode {
53
- readonly nodeType: 'subtree';
54
- readonly appearances: null;
55
- readonly nodeOptions: null;
56
- readonly definition: SubtreeDefinition;
57
- readonly root: RootNode;
58
- readonly parent: GeneralParentNode;
59
- readonly currentState: SubtreeNodeState;
60
- readonly validationState: AncestorNodeValidationState;
61
- }
@@ -1,24 +0,0 @@
1
- /**
2
- * This error class is intended as a common point of reference for all of the
3
- * related interfaces and implementation where we've deferred two concerns:
4
- *
5
- * 1. Support for attributes on instance nodes (which may be bound in a form's
6
- * model and/or may be expected to preserve model-defined defaults)
7
- * 2. Present lack of logic to treat a `jr:template` attribute as a special
8
- * case: whereas in the general case we would expect to pass through a
9
- * form/model-defined attribute, we expect to specifically **omit**
10
- * `jr:template` from repeat instances derived from any of form's
11
- * explicitly-defined repeat templates
12
- *
13
- * Addressing #1 is (now) a prerequisite to addressing #2, and it is also a
14
- * prerequisite for #2's unaddressed status to _become meaningfully observable
15
- * and problematic_.
16
- *
17
- * By introducing this error at a point where a change in #1's status is likely
18
- * to be implicated, we're also likely to be reminded to address #2 in tandem.
19
- */
20
- export class TemplatedNodeAttributeSerializationError extends Error {
21
- constructor() {
22
- super('Template attribute omission not implemented');
23
- }
24
- }