@getodk/xforms-engine 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/BaseItem.d.ts +6 -0
- package/dist/client/GroupNode.d.ts +4 -4
- package/dist/client/MarkdownNode.d.ts +33 -0
- package/dist/client/RankNode.d.ts +2 -4
- package/dist/client/SelectNode.d.ts +2 -5
- package/dist/client/TextRange.d.ts +2 -2
- package/dist/client/hierarchy.d.ts +1 -2
- package/dist/client/index.d.ts +1 -1
- package/dist/client/node-types.d.ts +1 -1
- package/dist/index.js +10411 -327
- package/dist/index.js.map +1 -1
- package/dist/instance/hierarchy.d.ts +5 -6
- package/dist/instance/markdown/MarkdownNode.d.ts +75 -0
- package/dist/instance/text/TextChunk.d.ts +0 -1
- package/dist/instance/text/TextRange.d.ts +2 -1
- package/dist/instance/text/markdownFormat.d.ts +3 -0
- package/dist/lib/reactivity/createItemCollection.d.ts +5 -7
- package/dist/parse/body/BodyDefinition.d.ts +2 -8
- package/dist/parse/body/GroupElementDefinition.d.ts +22 -0
- package/dist/parse/body/control/ItemsetDefinition.d.ts +3 -0
- package/dist/parse/expression/ItemPropertyExpression.d.ts +6 -0
- package/dist/parse/model/{SubtreeDefinition.d.ts → GroupDefinition.d.ts} +4 -3
- package/dist/parse/model/NodeDefinition.d.ts +7 -8
- package/dist/parse/model/RepeatDefinition.d.ts +1 -1
- package/dist/parse/model/RootDefinition.d.ts +1 -1
- package/dist/parse/text/LabelDefinition.d.ts +4 -5
- package/dist/solid.js +10411 -327
- package/dist/solid.js.map +1 -1
- package/package.json +3 -2
- package/src/client/BaseItem.ts +7 -0
- package/src/client/GroupNode.ts +4 -10
- package/src/client/MarkdownNode.ts +53 -0
- package/src/client/RankNode.ts +2 -5
- package/src/client/SelectNode.ts +2 -6
- package/src/client/TextRange.ts +2 -2
- package/src/client/hierarchy.ts +0 -2
- package/src/client/index.ts +1 -1
- package/src/client/node-types.ts +0 -1
- package/src/instance/Group.ts +1 -1
- package/src/instance/children/buildChildren.ts +1 -17
- package/src/instance/children/normalizeChildInitOptions.ts +44 -59
- package/src/instance/hierarchy.ts +0 -6
- package/src/instance/markdown/MarkdownNode.ts +115 -0
- package/src/instance/text/TextChunk.ts +0 -5
- package/src/instance/text/TextRange.ts +5 -3
- package/src/instance/text/markdownFormat.ts +214 -0
- package/src/integration/xpath/adapter/names.ts +0 -1
- package/src/lib/reactivity/createItemCollection.ts +25 -9
- package/src/parse/body/BodyDefinition.ts +7 -34
- package/src/parse/body/GroupElementDefinition.ts +47 -0
- package/src/parse/body/control/ItemsetDefinition.ts +7 -0
- package/src/parse/expression/ItemPropertyExpression.ts +12 -0
- package/src/parse/model/{SubtreeDefinition.ts → GroupDefinition.ts} +6 -8
- package/src/parse/model/NodeDefinition.ts +8 -9
- package/src/parse/model/RepeatDefinition.ts +2 -2
- package/src/parse/model/RootDefinition.ts +2 -2
- package/src/parse/text/LabelDefinition.ts +4 -9
- package/dist/client/SubtreeNode.d.ts +0 -56
- package/dist/instance/Subtree.d.ts +0 -38
- package/dist/instance/text/FormattedTextStub.d.ts +0 -1
- package/dist/parse/body/group/BaseGroupDefinition.d.ts +0 -40
- package/dist/parse/body/group/LogicalGroupDefinition.d.ts +0 -6
- package/dist/parse/body/group/PresentationGroupDefinition.d.ts +0 -11
- package/dist/parse/body/group/StructuralGroupDefinition.d.ts +0 -6
- package/src/client/SubtreeNode.ts +0 -61
- package/src/instance/Subtree.ts +0 -102
- package/src/instance/text/FormattedTextStub.ts +0 -8
- package/src/parse/body/group/BaseGroupDefinition.ts +0 -89
- package/src/parse/body/group/LogicalGroupDefinition.ts +0 -11
- package/src/parse/body/group/PresentationGroupDefinition.ts +0 -28
- package/src/parse/body/group/StructuralGroupDefinition.ts +0 -11
|
@@ -7,10 +7,10 @@ import type { QualifiedName } from '../../lib/names/QualifiedName.ts';
|
|
|
7
7
|
import type { AnyBodyElementDefinition } from '../body/BodyDefinition.ts';
|
|
8
8
|
import type { RepeatElementDefinition } from '../body/RepeatElementDefinition.ts';
|
|
9
9
|
import type { BindDefinition } from './BindDefinition.ts';
|
|
10
|
+
import type { GroupDefinition } from './GroupDefinition.ts';
|
|
10
11
|
import type { LeafNodeDefinition } from './LeafNodeDefinition.ts';
|
|
11
12
|
import type { AnyRepeatDefinition } from './RepeatDefinition.ts';
|
|
12
13
|
import type { RootDefinition } from './RootDefinition.ts';
|
|
13
|
-
import type { SubtreeDefinition } from './SubtreeDefinition.ts';
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Corresponds to a model instance root node, i.e.:
|
|
@@ -33,10 +33,9 @@ export type RepeatType = 'repeat';
|
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
35
|
* Corresponds to a model instance subtree which **does not** correspond to a
|
|
36
|
-
* <repeat> in the form definition.
|
|
37
|
-
* but this is not strictly necessary per spec (hence the distinct name).
|
|
36
|
+
* <repeat> in the form definition.
|
|
38
37
|
*/
|
|
39
|
-
export type
|
|
38
|
+
export type GroupNodeType = 'group';
|
|
40
39
|
|
|
41
40
|
/**
|
|
42
41
|
* Corresponds to a model instance leaf node, i.e. one of:
|
|
@@ -51,7 +50,7 @@ export type NodeDefinitionType =
|
|
|
51
50
|
// eslint-disable-next-line @typescript-eslint/sort-type-constituents
|
|
52
51
|
| RootNodeType
|
|
53
52
|
| RepeatType
|
|
54
|
-
|
|
|
53
|
+
| GroupNodeType
|
|
55
54
|
| LeafNodeType;
|
|
56
55
|
|
|
57
56
|
// prettier-ignore
|
|
@@ -59,13 +58,13 @@ export type ParentNodeDefinition =
|
|
|
59
58
|
// eslint-disable-next-line @typescript-eslint/sort-type-constituents
|
|
60
59
|
| RootDefinition
|
|
61
60
|
| AnyRepeatDefinition
|
|
62
|
-
|
|
|
61
|
+
| GroupDefinition;
|
|
63
62
|
|
|
64
63
|
// prettier-ignore
|
|
65
64
|
export type ChildNodeDefinition =
|
|
66
65
|
| AnyRepeatDefinition
|
|
67
|
-
|
|
|
68
|
-
|
|
|
66
|
+
| GroupDefinition
|
|
67
|
+
| LeafNodeDefinition;
|
|
69
68
|
|
|
70
69
|
export abstract class NodeDefinition<Type extends NodeDefinitionType>
|
|
71
70
|
implements NamedSubtreeDefinition
|
|
@@ -92,5 +91,5 @@ export type AnyNodeDefinition =
|
|
|
92
91
|
// eslint-disable-next-line @typescript-eslint/sort-type-constituents
|
|
93
92
|
| RootDefinition
|
|
94
93
|
| AnyRepeatDefinition
|
|
95
|
-
|
|
|
94
|
+
| GroupDefinition
|
|
96
95
|
| LeafNodeDefinition;
|
|
@@ -21,9 +21,9 @@ import type { RepeatElementDefinition } from '../body/RepeatElementDefinition.ts
|
|
|
21
21
|
import { RepeatCountControlExpression } from '../expression/RepeatCountControlExpression.ts';
|
|
22
22
|
import type { BindDefinition } from './BindDefinition.ts';
|
|
23
23
|
import { DescendentNodeDefinition } from './DescendentNodeDefinition.ts';
|
|
24
|
+
import type { GroupDefinition } from './GroupDefinition.ts';
|
|
24
25
|
import type { ChildNodeDefinition, ParentNodeDefinition } from './NodeDefinition.ts';
|
|
25
26
|
import type { RootDefinition } from './RootDefinition.ts';
|
|
26
|
-
import type { SubtreeDefinition } from './SubtreeDefinition.ts';
|
|
27
27
|
|
|
28
28
|
interface JavaRosaNamespaceURI extends NamespaceURL {
|
|
29
29
|
readonly href: JAVAROSA_NAMESPACE_URI;
|
|
@@ -284,7 +284,7 @@ export interface UncontrolledRepeatDefinition extends RepeatDefinition {
|
|
|
284
284
|
* "repeat", as defined by a form, where those concepts include:
|
|
285
285
|
*
|
|
286
286
|
* - 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
|
|
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 GroupDefinition}).
|
|
288
288
|
*
|
|
289
289
|
* - A "repeat template", defined by a form either
|
|
290
290
|
* explicitly,
|
|
@@ -3,6 +3,7 @@ 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 { GroupDefinition } from './GroupDefinition.ts';
|
|
6
7
|
import { LeafNodeDefinition } from './LeafNodeDefinition.ts';
|
|
7
8
|
import type { ModelDefinition } from './ModelDefinition.ts';
|
|
8
9
|
import type { ChildNodeDefinition, ParentNodeDefinition } from './NodeDefinition.ts';
|
|
@@ -12,7 +13,6 @@ import { RangeNodeDefinition } from './RangeNodeDefinition.ts';
|
|
|
12
13
|
import { RepeatDefinition } from './RepeatDefinition.ts';
|
|
13
14
|
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';
|
|
@@ -107,7 +107,7 @@ export class RootDefinition extends NodeDefinition<'root'> {
|
|
|
107
107
|
);
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
return new
|
|
110
|
+
return new GroupDefinition(parent, bind, bodyElement, element);
|
|
111
111
|
});
|
|
112
112
|
}
|
|
113
113
|
|
|
@@ -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 {
|
|
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
|
-
|
|
|
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,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,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
|
-
}
|
package/src/instance/Subtree.ts
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import { XPathNodeKindKey } from '@getodk/xpath';
|
|
2
|
-
import type { Accessor } from 'solid-js';
|
|
3
|
-
import type { FormNodeID } from '../client/identity.ts';
|
|
4
|
-
import type { InstanceState } from '../client/serialization/InstanceState.ts';
|
|
5
|
-
import type { SubtreeDefinition, SubtreeNode } from '../client/SubtreeNode.ts';
|
|
6
|
-
import type { AncestorNodeValidationState } from '../client/validation.ts';
|
|
7
|
-
import type { XFormsXPathElement } from '../integration/xpath/adapter/XFormsXPathNode.ts';
|
|
8
|
-
import type { StaticElement } from '../integration/xpath/static-dom/StaticElement.ts';
|
|
9
|
-
import { createParentNodeInstanceState } from '../lib/client-reactivity/instance-state/createParentNodeInstanceState.ts';
|
|
10
|
-
import type { ChildrenState } from '../lib/reactivity/createChildrenState.ts';
|
|
11
|
-
import { createChildrenState } from '../lib/reactivity/createChildrenState.ts';
|
|
12
|
-
import type { MaterializedChildren } from '../lib/reactivity/materializeCurrentStateChildren.ts';
|
|
13
|
-
import { materializeCurrentStateChildren } from '../lib/reactivity/materializeCurrentStateChildren.ts';
|
|
14
|
-
import type { CurrentState } from '../lib/reactivity/node-state/createCurrentState.ts';
|
|
15
|
-
import type { EngineState } from '../lib/reactivity/node-state/createEngineState.ts';
|
|
16
|
-
import type { SharedNodeState } from '../lib/reactivity/node-state/createSharedNodeState.ts';
|
|
17
|
-
import { createSharedNodeState } from '../lib/reactivity/node-state/createSharedNodeState.ts';
|
|
18
|
-
import { createAggregatedViolations } from '../lib/reactivity/validation/createAggregatedViolations.ts';
|
|
19
|
-
import type { DescendantNodeSharedStateSpec } from './abstract/DescendantNode.ts';
|
|
20
|
-
import { DescendantNode } from './abstract/DescendantNode.ts';
|
|
21
|
-
import { buildChildren } from './children/buildChildren.ts';
|
|
22
|
-
import type { GeneralChildNode, GeneralParentNode } from './hierarchy.ts';
|
|
23
|
-
import type { EvaluationContext } from './internal-api/EvaluationContext.ts';
|
|
24
|
-
import type { ClientReactiveSerializableParentNode } from './internal-api/serialization/ClientReactiveSerializableParentNode.ts';
|
|
25
|
-
|
|
26
|
-
interface SubtreeStateSpec extends DescendantNodeSharedStateSpec {
|
|
27
|
-
readonly label: null;
|
|
28
|
-
readonly hint: null;
|
|
29
|
-
readonly children: Accessor<readonly FormNodeID[]>;
|
|
30
|
-
readonly valueOptions: null;
|
|
31
|
-
readonly value: null;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export class Subtree
|
|
35
|
-
extends DescendantNode<SubtreeDefinition, SubtreeStateSpec, GeneralParentNode, GeneralChildNode>
|
|
36
|
-
implements
|
|
37
|
-
SubtreeNode,
|
|
38
|
-
XFormsXPathElement,
|
|
39
|
-
EvaluationContext,
|
|
40
|
-
ClientReactiveSerializableParentNode<GeneralChildNode>
|
|
41
|
-
{
|
|
42
|
-
private readonly childrenState: ChildrenState<GeneralChildNode>;
|
|
43
|
-
|
|
44
|
-
override readonly [XPathNodeKindKey] = 'element';
|
|
45
|
-
|
|
46
|
-
// InstanceNode
|
|
47
|
-
protected readonly state: SharedNodeState<SubtreeStateSpec>;
|
|
48
|
-
protected readonly engineState: EngineState<SubtreeStateSpec>;
|
|
49
|
-
|
|
50
|
-
// SubtreeNode
|
|
51
|
-
readonly nodeType = 'subtree';
|
|
52
|
-
readonly appearances = null;
|
|
53
|
-
readonly nodeOptions = null;
|
|
54
|
-
readonly currentState: MaterializedChildren<CurrentState<SubtreeStateSpec>, GeneralChildNode>;
|
|
55
|
-
readonly validationState: AncestorNodeValidationState;
|
|
56
|
-
readonly instanceState: InstanceState;
|
|
57
|
-
|
|
58
|
-
constructor(
|
|
59
|
-
parent: GeneralParentNode,
|
|
60
|
-
instanceNode: StaticElement | null,
|
|
61
|
-
definition: SubtreeDefinition
|
|
62
|
-
) {
|
|
63
|
-
super(parent, instanceNode, definition);
|
|
64
|
-
|
|
65
|
-
const childrenState = createChildrenState<Subtree, GeneralChildNode>(this);
|
|
66
|
-
|
|
67
|
-
this.childrenState = childrenState;
|
|
68
|
-
|
|
69
|
-
const state = createSharedNodeState(
|
|
70
|
-
this.scope,
|
|
71
|
-
{
|
|
72
|
-
reference: this.contextReference,
|
|
73
|
-
readonly: this.isReadonly,
|
|
74
|
-
relevant: this.isRelevant,
|
|
75
|
-
required: this.isRequired,
|
|
76
|
-
|
|
77
|
-
label: null,
|
|
78
|
-
hint: null,
|
|
79
|
-
children: childrenState.childIds,
|
|
80
|
-
valueOptions: null,
|
|
81
|
-
value: null,
|
|
82
|
-
},
|
|
83
|
-
this.instanceConfig
|
|
84
|
-
);
|
|
85
|
-
|
|
86
|
-
this.state = state;
|
|
87
|
-
this.engineState = state.engineState;
|
|
88
|
-
this.currentState = materializeCurrentStateChildren(
|
|
89
|
-
this.scope,
|
|
90
|
-
state.currentState,
|
|
91
|
-
childrenState
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
childrenState.setChildren(buildChildren(this));
|
|
95
|
-
this.validationState = createAggregatedViolations(this, this.instanceConfig);
|
|
96
|
-
this.instanceState = createParentNodeInstanceState(this);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
getChildren(): readonly GeneralChildNode[] {
|
|
100
|
-
return this.childrenState.getChildren();
|
|
101
|
-
}
|
|
102
|
-
}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { UpsertableMap } from '@getodk/common/lib/collections/UpsertableMap.ts';
|
|
2
|
-
import { getLabelElement } from '../../../lib/dom/query.ts';
|
|
3
|
-
import { LabelDefinition } from '../../text/LabelDefinition.ts';
|
|
4
|
-
import type { XFormDefinition } from '../../XFormDefinition.ts';
|
|
5
|
-
import { parseNodesetReference } from '../../xpath/reference-parsing.ts';
|
|
6
|
-
import type { StructureElementAppearanceDefinition } from '../appearance/structureElementAppearanceParser.ts';
|
|
7
|
-
import { structureElementAppearanceParser } from '../appearance/structureElementAppearanceParser.ts';
|
|
8
|
-
import {
|
|
9
|
-
type BodyElementDefinitionArray,
|
|
10
|
-
type BodyElementParentContext,
|
|
11
|
-
} from '../BodyDefinition.ts';
|
|
12
|
-
import { BodyElementDefinition } from '../BodyElementDefinition.ts';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* These type names are derived from **and expand upon** the language used in
|
|
16
|
-
* the ODK XForms spec to describe various group usage. Whereas the spec
|
|
17
|
-
* language allows for a group to be described as more than one case, the intent
|
|
18
|
-
* here is to establish exclusive naming which may or may not compound. As such:
|
|
19
|
-
*
|
|
20
|
-
* - `logical-group`, per spec language, is a group with a `ref`; its usage here
|
|
21
|
-
* differs from the spec language in that it _may_ have a `<label>` child but
|
|
22
|
-
* is not also treated as a `presentation-group` (which is only used for
|
|
23
|
-
* groups which do not have a `ref`)
|
|
24
|
-
* - `presentation-group` is a group with a `<label>` child; its usage here
|
|
25
|
-
* differs from the spec language in that `presentation-group` does **not**
|
|
26
|
-
* have a `ref`
|
|
27
|
-
* - `structural-group` is any `<group>` element which does not satisfy any of
|
|
28
|
-
* the other usage scenarios; this isn't exactly the terminology used, but is
|
|
29
|
-
* the most closely fitting name for the concept where the other sceanarios
|
|
30
|
-
* do not apply
|
|
31
|
-
*
|
|
32
|
-
* A more succinct decision tree:
|
|
33
|
-
*
|
|
34
|
-
* - `<group ref="$ref">` -> `logical-group`, else
|
|
35
|
-
* - `<group><label>` -> `presentation-group`, else
|
|
36
|
-
* - `<group>` -> `structural-group`
|
|
37
|
-
*/
|
|
38
|
-
export type GroupType = 'logical-group' | 'presentation-group' | 'structural-group';
|
|
39
|
-
|
|
40
|
-
export abstract class BaseGroupDefinition<
|
|
41
|
-
Type extends GroupType,
|
|
42
|
-
> extends BodyElementDefinition<Type> {
|
|
43
|
-
// TODO: does this really accomplish anything? It seems highly unlikely it
|
|
44
|
-
// has enough performance benefit to outweigh its memory and lookup costs.
|
|
45
|
-
private static groupTypes = new UpsertableMap<Element, GroupType | null>();
|
|
46
|
-
|
|
47
|
-
protected static getGroupType(localName: string, element: Element): GroupType | null {
|
|
48
|
-
return this.groupTypes.upsert(element, () => {
|
|
49
|
-
if (localName !== 'group') {
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (element.hasAttribute('ref')) {
|
|
54
|
-
return 'logical-group';
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const label = getLabelElement(element);
|
|
58
|
-
|
|
59
|
-
if (label == null) {
|
|
60
|
-
return 'structural-group';
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return 'presentation-group';
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
override readonly category = 'structure';
|
|
68
|
-
|
|
69
|
-
readonly children: BodyElementDefinitionArray;
|
|
70
|
-
|
|
71
|
-
override readonly reference: string | null;
|
|
72
|
-
readonly appearances: StructureElementAppearanceDefinition;
|
|
73
|
-
override readonly label: LabelDefinition | null;
|
|
74
|
-
|
|
75
|
-
constructor(form: XFormDefinition, parent: BodyElementParentContext, element: Element) {
|
|
76
|
-
super(form, parent, element);
|
|
77
|
-
|
|
78
|
-
const childElements = Array.from(element.children).filter((child) => {
|
|
79
|
-
const childName = child.localName;
|
|
80
|
-
|
|
81
|
-
return childName !== 'label';
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
this.children = this.body.getChildElementDefinitions(form, this, element, childElements);
|
|
85
|
-
this.reference = parseNodesetReference(parent, element, 'ref');
|
|
86
|
-
this.appearances = structureElementAppearanceParser.parseFrom(element, 'appearance');
|
|
87
|
-
this.label = LabelDefinition.forGroup(form, this);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { BaseGroupDefinition } from './BaseGroupDefinition.ts';
|
|
2
|
-
|
|
3
|
-
export class LogicalGroupDefinition extends BaseGroupDefinition<'logical-group'> {
|
|
4
|
-
static override isCompatible(localName: string, element: Element): boolean {
|
|
5
|
-
return this.getGroupType(localName, element) === 'logical-group';
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
readonly type = 'logical-group';
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export type LogicalGroupDefinitionClass = typeof LogicalGroupDefinition;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { LabelDefinition } from '../../text/LabelDefinition.ts';
|
|
2
|
-
import type { XFormDefinition } from '../../XFormDefinition.ts';
|
|
3
|
-
import type { BodyElementParentContext } from '../BodyDefinition.ts';
|
|
4
|
-
import { BaseGroupDefinition } from './BaseGroupDefinition.ts';
|
|
5
|
-
|
|
6
|
-
export class PresentationGroupDefinition extends BaseGroupDefinition<'presentation-group'> {
|
|
7
|
-
static override isCompatible(localName: string, element: Element): boolean {
|
|
8
|
-
return this.getGroupType(localName, element) === 'presentation-group';
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
readonly type = 'presentation-group';
|
|
12
|
-
|
|
13
|
-
override readonly label: LabelDefinition;
|
|
14
|
-
|
|
15
|
-
constructor(form: XFormDefinition, parent: BodyElementParentContext, element: Element) {
|
|
16
|
-
super(form, parent, element);
|
|
17
|
-
|
|
18
|
-
const label = LabelDefinition.forGroup(form, this);
|
|
19
|
-
|
|
20
|
-
if (label == null) {
|
|
21
|
-
throw new Error('Invalid presentation-group: missing label');
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
this.label = label;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export type PresentationGroupDefinitionClass = typeof PresentationGroupDefinition;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { BaseGroupDefinition } from './BaseGroupDefinition.ts';
|
|
2
|
-
|
|
3
|
-
export class StructuralGroupDefinition extends BaseGroupDefinition<'structural-group'> {
|
|
4
|
-
static override isCompatible(localName: string, element: Element): boolean {
|
|
5
|
-
return this.getGroupType(localName, element) === 'structural-group';
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
readonly type = 'structural-group';
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export type StructuralGroupDefinitionClass = typeof StructuralGroupDefinition;
|