@getodk/xforms-engine 0.9.0 → 0.10.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/SelectNode.d.ts +1 -0
- package/dist/client/TextRange.d.ts +4 -0
- package/dist/index.js +125 -133
- package/dist/index.js.map +1 -1
- package/dist/instance/SelectControl.d.ts +1 -0
- package/dist/instance/text/TextRange.d.ts +11 -1
- package/dist/lib/reactivity/text/createTextRange.d.ts +1 -2
- package/dist/parse/expression/TextChunkExpression.d.ts +16 -0
- package/dist/parse/text/ItemsetLabelDefinition.d.ts +2 -4
- package/dist/parse/text/MessageDefinition.d.ts +3 -7
- package/dist/parse/text/abstract/TextElementDefinition.d.ts +2 -8
- package/dist/parse/text/abstract/TextRangeDefinition.d.ts +2 -2
- package/dist/solid.js +125 -133
- package/dist/solid.js.map +1 -1
- package/package.json +2 -2
- package/src/client/SelectNode.ts +2 -0
- package/src/client/TextRange.ts +5 -1
- package/src/instance/SelectControl.ts +6 -0
- package/src/instance/text/TextRange.ts +21 -1
- package/src/lib/reactivity/text/createTextRange.ts +56 -43
- package/src/lib/reactivity/validation/createValidation.ts +1 -3
- package/src/parse/expression/TextChunkExpression.ts +78 -0
- package/src/parse/text/ItemsetLabelDefinition.ts +8 -12
- package/src/parse/text/MessageDefinition.ts +9 -16
- package/src/parse/text/abstract/TextElementDefinition.ts +10 -26
- package/src/parse/text/abstract/TextRangeDefinition.ts +2 -2
- package/src/parse/xpath/semantic-analysis.ts +7 -2
- package/dist/parse/expression/TextLiteralExpression.d.ts +0 -9
- package/dist/parse/expression/TextOutputExpression.d.ts +0 -7
- package/dist/parse/expression/TextReferenceExpression.d.ts +0 -7
- package/dist/parse/expression/TextTranslationExpression.d.ts +0 -8
- package/dist/parse/expression/abstract/TextChunkExpression.d.ts +0 -17
- package/src/parse/expression/TextLiteralExpression.ts +0 -19
- package/src/parse/expression/TextOutputExpression.ts +0 -25
- package/src/parse/expression/TextReferenceExpression.ts +0 -14
- package/src/parse/expression/TextTranslationExpression.ts +0 -38
- package/src/parse/expression/abstract/TextChunkExpression.ts +0 -38
|
@@ -22,6 +22,7 @@ interface SelectControlStateSpec extends ValueNodeStateSpec<readonly string[]> {
|
|
|
22
22
|
readonly label: Accessor<TextRange<'label'> | null>;
|
|
23
23
|
readonly hint: Accessor<TextRange<'hint'> | null>;
|
|
24
24
|
readonly valueOptions: Accessor<SelectValueOptions>;
|
|
25
|
+
readonly isSelectWithImages: Accessor<boolean>;
|
|
25
26
|
}
|
|
26
27
|
export declare class SelectControl extends ValueNode<'string', SelectDefinition<'string'>, readonly string[], readonly string[]> implements SelectNode, XFormsXPathElement, EvaluationContext, ValidationContext, ClientReactiveSerializableValueNode {
|
|
27
28
|
static from(parent: GeneralParentNode, instanceNode: StaticLeafElement | null, definition: SelectDefinition): SelectControl;
|
|
@@ -1,10 +1,20 @@
|
|
|
1
|
+
import { JRResourceURL } from '../../../../common/src/jr-resources/JRResourceURL.ts';
|
|
1
2
|
import { TextRange as ClientTextRange, TextChunk, TextOrigin, TextRole } from '../../client/TextRange.ts';
|
|
3
|
+
export interface MediaSources {
|
|
4
|
+
image?: JRResourceURL;
|
|
5
|
+
video?: JRResourceURL;
|
|
6
|
+
audio?: JRResourceURL;
|
|
7
|
+
}
|
|
2
8
|
export declare class TextRange<Role extends TextRole, Origin extends TextOrigin> implements ClientTextRange<Role, Origin> {
|
|
3
9
|
readonly origin: Origin;
|
|
4
10
|
readonly role: Role;
|
|
5
11
|
protected readonly chunks: readonly TextChunk[];
|
|
12
|
+
protected readonly mediaSources?: MediaSources | undefined;
|
|
6
13
|
[Symbol.iterator](): Generator<TextChunk, void, unknown>;
|
|
7
14
|
get formatted(): Record<PropertyKey, unknown>;
|
|
8
15
|
get asString(): string;
|
|
9
|
-
|
|
16
|
+
get imageSource(): JRResourceURL | undefined;
|
|
17
|
+
get audioSource(): JRResourceURL | undefined;
|
|
18
|
+
get videoSource(): JRResourceURL | undefined;
|
|
19
|
+
constructor(origin: Origin, role: Role, chunks: readonly TextChunk[], mediaSources?: MediaSources | undefined);
|
|
10
20
|
}
|
|
@@ -5,8 +5,7 @@ import { TextRange } from '../../../instance/text/TextRange.ts';
|
|
|
5
5
|
import { TextRangeDefinition } from '../../../parse/text/abstract/TextRangeDefinition.ts';
|
|
6
6
|
type ComputedFormTextRange<Role extends TextRole> = Accessor<TextRange<Role, 'form'>>;
|
|
7
7
|
/**
|
|
8
|
-
* Creates a text range (e.g. label or hint) from the provided definition,
|
|
9
|
-
* reactive to:
|
|
8
|
+
* Creates a text range (e.g. label or hint) from the provided definition, reactive to:
|
|
10
9
|
*
|
|
11
10
|
* - The form's current language (e.g. `<label ref="jr:itext('text-id')" />`)
|
|
12
11
|
* - Direct `<output>` references within the label's children
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { TextChunkSource } from '../../client/TextRange.ts';
|
|
2
|
+
import { AnyTextRangeDefinition } from '../text/abstract/TextRangeDefinition.ts';
|
|
3
|
+
import { DependentExpression } from './abstract/DependentExpression.ts';
|
|
4
|
+
interface TextChunkExpressionOptions {
|
|
5
|
+
readonly isTranslated?: true;
|
|
6
|
+
}
|
|
7
|
+
export declare class TextChunkExpression<T extends 'nodes' | 'string'> extends DependentExpression<T> {
|
|
8
|
+
readonly source: TextChunkSource;
|
|
9
|
+
readonly stringValue: string;
|
|
10
|
+
constructor(context: AnyTextRangeDefinition, resultType: T, expression: string, source: TextChunkSource, options?: TextChunkExpressionOptions, literalValue?: string);
|
|
11
|
+
static fromLiteral(context: AnyTextRangeDefinition, stringValue: string): TextChunkExpression<'string'>;
|
|
12
|
+
static fromReference(context: AnyTextRangeDefinition, ref: string): TextChunkExpression<'string'>;
|
|
13
|
+
static fromOutput(context: AnyTextRangeDefinition, element: Element): TextChunkExpression<'string'> | null;
|
|
14
|
+
static fromTranslation(context: AnyTextRangeDefinition, maybeExpression: string): TextChunkExpression<'nodes'> | null;
|
|
15
|
+
}
|
|
16
|
+
export {};
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { XFormDefinition } from '../../parse/XFormDefinition.ts';
|
|
2
|
-
import { ItemDefinition } from '../body/control/ItemDefinition.ts';
|
|
3
2
|
import { ItemsetDefinition } from '../body/control/ItemsetDefinition.ts';
|
|
4
|
-
import {
|
|
3
|
+
import { TextChunkExpression } from '../expression/TextChunkExpression.ts';
|
|
5
4
|
import { TextRangeDefinition } from './abstract/TextRangeDefinition.ts';
|
|
6
|
-
export type ItemLabelOwner = ItemDefinition | ItemsetDefinition;
|
|
7
5
|
export declare class ItemsetLabelDefinition extends TextRangeDefinition<'item-label'> {
|
|
8
6
|
static from(form: XFormDefinition, owner: ItemsetDefinition): ItemsetLabelDefinition | null;
|
|
9
7
|
readonly role = "item-label";
|
|
10
|
-
readonly chunks:
|
|
8
|
+
readonly chunks: ReadonlyArray<TextChunkExpression<'nodes' | 'string'>>;
|
|
11
9
|
private constructor();
|
|
12
10
|
}
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { TextTranslationExpression } from '../expression/TextTranslationExpression.ts';
|
|
1
|
+
import { TextChunkExpression } from '../expression/TextChunkExpression.ts';
|
|
3
2
|
import { BindDefinition } from '../model/BindDefinition.ts';
|
|
4
|
-
import { TextBindAttributeLocalName,
|
|
5
|
-
export type MessageSourceNode = TextSourceNode<TextBindAttributeLocalName>;
|
|
6
|
-
type MessageChunk = TextLiteralExpression | TextTranslationExpression;
|
|
3
|
+
import { TextBindAttributeLocalName, TextRangeDefinition } from './abstract/TextRangeDefinition.ts';
|
|
7
4
|
export declare class MessageDefinition<Type extends TextBindAttributeLocalName> extends TextRangeDefinition<Type> {
|
|
8
5
|
readonly role: Type;
|
|
9
6
|
static from<Type extends TextBindAttributeLocalName>(bind: BindDefinition, type: Type): MessageDefinition<Type> | null;
|
|
10
|
-
readonly chunks:
|
|
7
|
+
readonly chunks: ReadonlyArray<TextChunkExpression<'nodes' | 'string'>>;
|
|
11
8
|
private constructor();
|
|
12
9
|
}
|
|
13
10
|
export type AnyMessageDefinition = MessageDefinition<TextBindAttributeLocalName>;
|
|
14
|
-
export {};
|
|
@@ -1,21 +1,15 @@
|
|
|
1
1
|
import { ElementTextRole } from '../../../client/TextRange.ts';
|
|
2
2
|
import { XFormDefinition } from '../../../parse/XFormDefinition.ts';
|
|
3
3
|
import { ItemDefinition } from '../../body/control/ItemDefinition.ts';
|
|
4
|
-
import {
|
|
5
|
-
import { TextOutputExpression } from '../../expression/TextOutputExpression.ts';
|
|
6
|
-
import { TextReferenceExpression } from '../../expression/TextReferenceExpression.ts';
|
|
7
|
-
import { TextTranslationExpression } from '../../expression/TextTranslationExpression.ts';
|
|
4
|
+
import { TextChunkExpression } from '../../expression/TextChunkExpression.ts';
|
|
8
5
|
import { HintDefinition } from '../HintDefinition.ts';
|
|
9
6
|
import { ItemLabelDefinition } from '../ItemLabelDefinition.ts';
|
|
10
7
|
import { ItemsetLabelDefinition } from '../ItemsetLabelDefinition.ts';
|
|
11
8
|
import { LabelDefinition, LabelOwner } from '../LabelDefinition.ts';
|
|
12
9
|
import { TextSourceNode, TextRangeDefinition } from './TextRangeDefinition.ts';
|
|
13
|
-
export type RefAttributeChunk = TextReferenceExpression | TextTranslationExpression;
|
|
14
|
-
type TextElementChildChunk = TextLiteralExpression | TextOutputExpression;
|
|
15
|
-
type TextElementChunks = readonly [RefAttributeChunk] | readonly TextElementChildChunk[];
|
|
16
10
|
type TextElementOwner = ItemDefinition | LabelOwner;
|
|
17
11
|
export declare abstract class TextElementDefinition<Role extends ElementTextRole> extends TextRangeDefinition<Role> {
|
|
18
|
-
readonly chunks:
|
|
12
|
+
readonly chunks: ReadonlyArray<TextChunkExpression<'nodes' | 'string'>>;
|
|
19
13
|
constructor(form: XFormDefinition, owner: TextElementOwner, sourceNode: TextSourceNode<Role>);
|
|
20
14
|
}
|
|
21
15
|
export type AnyTextElementDefinition = HintDefinition | ItemLabelDefinition | ItemsetLabelDefinition | LabelDefinition;
|
|
@@ -2,7 +2,7 @@ import { LocalNamedElement } from '../../../../../common/types/dom.ts';
|
|
|
2
2
|
import { TextRole } from '../../../client/TextRange.ts';
|
|
3
3
|
import { XFormDefinition } from '../../../parse/XFormDefinition.ts';
|
|
4
4
|
import { DependencyContext } from '../../expression/abstract/DependencyContext.ts';
|
|
5
|
-
import {
|
|
5
|
+
import { TextChunkExpression } from '../../expression/TextChunkExpression.ts';
|
|
6
6
|
import { AnyMessageDefinition } from '../MessageDefinition.ts';
|
|
7
7
|
import { AnyTextElementDefinition } from './TextElementDefinition.ts';
|
|
8
8
|
export type TextBindAttributeLocalName = 'constraintMsg' | 'requiredMsg';
|
|
@@ -22,7 +22,7 @@ export declare abstract class TextRangeDefinition<Role extends TextRole> extends
|
|
|
22
22
|
abstract readonly role: Role;
|
|
23
23
|
readonly parentReference: string | null;
|
|
24
24
|
readonly reference: string | null;
|
|
25
|
-
abstract readonly chunks:
|
|
25
|
+
abstract readonly chunks: ReadonlyArray<TextChunkExpression<'nodes' | 'string'>>;
|
|
26
26
|
get isTranslated(): boolean;
|
|
27
27
|
set isTranslated(value: true);
|
|
28
28
|
protected constructor(form: XFormDefinition, ownerContext: DependencyContext, sourceNode: TextSourceNode<Role>);
|
package/dist/solid.js
CHANGED
|
@@ -9402,7 +9402,7 @@ const substring = new StringFunction(
|
|
|
9402
9402
|
return string2.substring(start, end);
|
|
9403
9403
|
}
|
|
9404
9404
|
);
|
|
9405
|
-
const string$
|
|
9405
|
+
const string$1 = new StringFunction(
|
|
9406
9406
|
"string",
|
|
9407
9407
|
[{ arityType: "optional" }],
|
|
9408
9408
|
(context, [expression]) => (expression?.evaluate(context) ?? context).toString()
|
|
@@ -9435,13 +9435,13 @@ const translate = new StringFunction(
|
|
|
9435
9435
|
}
|
|
9436
9436
|
);
|
|
9437
9437
|
|
|
9438
|
-
const string$
|
|
9438
|
+
const string$2 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
|
|
9439
9439
|
__proto__: null,
|
|
9440
9440
|
concat: concat$1,
|
|
9441
9441
|
contains,
|
|
9442
9442
|
normalizeSpace,
|
|
9443
9443
|
startsWith,
|
|
9444
|
-
string: string$
|
|
9444
|
+
string: string$1,
|
|
9445
9445
|
stringLength,
|
|
9446
9446
|
substring,
|
|
9447
9447
|
substringAfter,
|
|
@@ -9453,7 +9453,7 @@ const fn$2 = new FunctionLibrary(FN_NAMESPACE_URI, [
|
|
|
9453
9453
|
...Object.values(boolean$2),
|
|
9454
9454
|
...Object.values(nodeset$1),
|
|
9455
9455
|
...Object.values(number$3),
|
|
9456
|
-
...Object.values(string$
|
|
9456
|
+
...Object.values(string$2)
|
|
9457
9457
|
]);
|
|
9458
9458
|
|
|
9459
9459
|
class BaseStep {
|
|
@@ -11233,21 +11233,21 @@ const enk = new FunctionLibrary(ENKETO_NAMESPACE_URI, [
|
|
|
11233
11233
|
new FunctionAlias("format-date", formatDateTime)
|
|
11234
11234
|
]);
|
|
11235
11235
|
|
|
11236
|
-
const itext = new
|
|
11236
|
+
const itext = new NodeSetFunction(
|
|
11237
11237
|
"itext",
|
|
11238
11238
|
[{ arityType: "required", typeHint: "string" }],
|
|
11239
11239
|
(context, [itextIDExpression]) => {
|
|
11240
11240
|
const itextID = itextIDExpression.evaluate(context).toString();
|
|
11241
|
-
return XFormsXPathEvaluator.
|
|
11241
|
+
return XFormsXPathEvaluator.getTranslationValues(context, itextID) ?? [];
|
|
11242
11242
|
}
|
|
11243
11243
|
);
|
|
11244
11244
|
|
|
11245
|
-
const
|
|
11245
|
+
const nodeSet = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
|
|
11246
11246
|
__proto__: null,
|
|
11247
11247
|
itext
|
|
11248
11248
|
}, Symbol.toStringTag, { value: 'Module' }));
|
|
11249
11249
|
|
|
11250
|
-
const jr$2 = new FunctionLibrary(JAVAROSA_NAMESPACE_URI, [...Object.values(
|
|
11250
|
+
const jr$2 = new FunctionLibrary(JAVAROSA_NAMESPACE_URI, [...Object.values(nodeSet)]);
|
|
11251
11251
|
|
|
11252
11252
|
const booleanFromString = new BooleanFunction(
|
|
11253
11253
|
"boolean-from-string",
|
|
@@ -18950,46 +18950,39 @@ class XFormsItextTranslations {
|
|
|
18950
18950
|
return textMap.get(itextID) ?? null;
|
|
18951
18951
|
}
|
|
18952
18952
|
/**
|
|
18953
|
+
* Retrieves all translation value elements for a given Itext in the active language.
|
|
18954
|
+
*
|
|
18953
18955
|
* @package
|
|
18954
18956
|
*
|
|
18955
|
-
*
|
|
18956
|
-
*
|
|
18957
|
+
* This method fetches the `text` element matching `itextID` and returns its child `value` elements,
|
|
18958
|
+
* which may have an optional `@form` attribute.
|
|
18959
|
+
*
|
|
18960
|
+
* The operation is conceptually similar to the following XPath query:
|
|
18957
18961
|
*
|
|
18958
18962
|
* ```xpath
|
|
18959
|
-
*
|
|
18960
|
-
*
|
|
18961
|
-
* xpath3-fn:environment-variable('activeLanguage')
|
|
18962
|
-
* )
|
|
18963
|
-
* /text[@id = $itextID]
|
|
18964
|
-
* /value[not(@form)]
|
|
18963
|
+
* imaginary:itext-translation(
|
|
18964
|
+
* xpath3-fn:environment-variable('activeLanguage')
|
|
18965
18965
|
* )
|
|
18966
|
+
* /text[@id = $itextID]
|
|
18967
|
+
* /value
|
|
18966
18968
|
* ```
|
|
18967
18969
|
*
|
|
18968
18970
|
* Or alternately:
|
|
18969
18971
|
*
|
|
18970
18972
|
* ```xpath
|
|
18971
|
-
*
|
|
18972
|
-
*
|
|
18973
|
-
* /
|
|
18974
|
-
* /
|
|
18975
|
-
* /value[not(@form)]
|
|
18976
|
-
* )
|
|
18973
|
+
* imaginary:itext-root()
|
|
18974
|
+
* /translation[@lang = xpath3-fn:environment-variable('activeLanguage')]
|
|
18975
|
+
* /text[@id = $itextID]
|
|
18976
|
+
* /value
|
|
18977
18977
|
* ```
|
|
18978
|
-
*
|
|
18979
|
-
* @todo The above really feels like it adds some helpful clarity to how `jr:itext()` is designed to work, and the kinds of structures, state and input involved. Since there's already some discomfort around that API as specified, it's worth considering
|
|
18978
|
+
* Returns an array of `XFormsItextTranslationValueElement<T>`
|
|
18980
18979
|
*/
|
|
18981
|
-
|
|
18980
|
+
getTranslationValues(itextID) {
|
|
18982
18981
|
const textElement = this.getTranslationTextElement(itextID);
|
|
18983
18982
|
if (textElement == null) {
|
|
18984
|
-
return
|
|
18985
|
-
}
|
|
18986
|
-
const { domProvider } = this;
|
|
18987
|
-
for (const valueElement of domProvider.getChildrenByLocalName(textElement, "value")) {
|
|
18988
|
-
if (!domProvider.hasLocalNamedAttribute(valueElement, "form")) {
|
|
18989
|
-
return domProvider.getNodeValue(valueElement);
|
|
18990
|
-
}
|
|
18983
|
+
return [];
|
|
18991
18984
|
}
|
|
18992
|
-
return "";
|
|
18985
|
+
return [...this.domProvider.getChildrenByLocalName(textElement, "value")];
|
|
18993
18986
|
}
|
|
18994
18987
|
getLanguages() {
|
|
18995
18988
|
return this.languages;
|
|
@@ -19026,9 +19019,9 @@ class XFormsXPathEvaluator extends Evaluator {
|
|
|
19026
19019
|
assertInternalXFormsXPathEvaluatorContext(context);
|
|
19027
19020
|
return context.evaluator.secondaryInstancesById.get(id) ?? null;
|
|
19028
19021
|
}
|
|
19029
|
-
static
|
|
19022
|
+
static getTranslationValues(context, itextID) {
|
|
19030
19023
|
assertInternalXFormsXPathEvaluatorContext(context);
|
|
19031
|
-
return context.evaluator.itextTranslations.
|
|
19024
|
+
return context.evaluator.itextTranslations.getTranslationValues(itextID);
|
|
19032
19025
|
}
|
|
19033
19026
|
rootNode;
|
|
19034
19027
|
/**
|
|
@@ -19582,8 +19575,13 @@ const isTranslationFunctionCall = (syntaxNode) => {
|
|
|
19582
19575
|
]);
|
|
19583
19576
|
};
|
|
19584
19577
|
const isTranslationExpression = (expression) => {
|
|
19585
|
-
|
|
19586
|
-
|
|
19578
|
+
let result;
|
|
19579
|
+
try {
|
|
19580
|
+
result = expressionParser.parse(expression);
|
|
19581
|
+
} catch {
|
|
19582
|
+
return false;
|
|
19583
|
+
}
|
|
19584
|
+
const functionCallNode = findTypedPrincipalExpressionNode(["function_call"], result.rootNode);
|
|
19587
19585
|
if (functionCallNode == null) {
|
|
19588
19586
|
return false;
|
|
19589
19587
|
}
|
|
@@ -19747,77 +19745,43 @@ class DependentExpression {
|
|
|
19747
19745
|
}
|
|
19748
19746
|
}
|
|
19749
19747
|
|
|
19748
|
+
const isOutputElement = (element) => {
|
|
19749
|
+
return element.localName === "output" && element.hasAttribute("value");
|
|
19750
|
+
};
|
|
19750
19751
|
class TextChunkExpression extends DependentExpression {
|
|
19752
|
+
source;
|
|
19753
|
+
// Set for the literal source, blank otherwise
|
|
19751
19754
|
stringValue;
|
|
19752
|
-
constructor(context, expression, options = {}) {
|
|
19753
|
-
super(context,
|
|
19755
|
+
constructor(context, resultType, expression, source, options = {}, literalValue = "") {
|
|
19756
|
+
super(context, resultType, expression, {
|
|
19754
19757
|
semanticDependencies: {
|
|
19755
19758
|
translations: options.isTranslated
|
|
19756
19759
|
},
|
|
19757
19760
|
ignoreContextReference: true
|
|
19758
19761
|
});
|
|
19762
|
+
this.source = source;
|
|
19763
|
+
this.stringValue = literalValue;
|
|
19759
19764
|
}
|
|
19760
|
-
|
|
19761
|
-
|
|
19762
|
-
class TextLiteralExpression extends TextChunkExpression {
|
|
19763
|
-
constructor(context, stringValue) {
|
|
19764
|
-
super(context, "null");
|
|
19765
|
-
this.stringValue = stringValue;
|
|
19766
|
-
}
|
|
19767
|
-
static from(context, stringValue) {
|
|
19768
|
-
return new this(context, stringValue);
|
|
19769
|
-
}
|
|
19770
|
-
source = "literal";
|
|
19771
|
-
}
|
|
19772
|
-
|
|
19773
|
-
const isOutputElement = (element) => {
|
|
19774
|
-
return element.localName === "output" && element.hasAttribute("value");
|
|
19775
|
-
};
|
|
19776
|
-
class TextOutputExpression extends TextChunkExpression {
|
|
19777
|
-
static from(context, element) {
|
|
19778
|
-
if (isOutputElement(element)) {
|
|
19779
|
-
return new this(context, element);
|
|
19780
|
-
}
|
|
19781
|
-
return null;
|
|
19782
|
-
}
|
|
19783
|
-
source = "output";
|
|
19784
|
-
constructor(context, element) {
|
|
19785
|
-
super(context, element.getAttribute("value"));
|
|
19786
|
-
}
|
|
19787
|
-
}
|
|
19788
|
-
|
|
19789
|
-
class TextReferenceExpression extends TextChunkExpression {
|
|
19790
|
-
static from(context, refExpression) {
|
|
19791
|
-
return new this(context, refExpression);
|
|
19765
|
+
static fromLiteral(context, stringValue) {
|
|
19766
|
+
return new TextChunkExpression(context, "string", "null", "literal", {}, stringValue);
|
|
19792
19767
|
}
|
|
19793
|
-
|
|
19794
|
-
|
|
19795
|
-
super(context, refExpression);
|
|
19768
|
+
static fromReference(context, ref) {
|
|
19769
|
+
return new TextChunkExpression(context, "string", ref, "reference");
|
|
19796
19770
|
}
|
|
19797
|
-
|
|
19798
|
-
|
|
19799
|
-
class TextTranslationExpression extends TextChunkExpression {
|
|
19800
|
-
static fromMessage(context, maybeExpression) {
|
|
19801
|
-
try {
|
|
19802
|
-
expressionParser.parse(maybeExpression);
|
|
19803
|
-
} catch {
|
|
19771
|
+
static fromOutput(context, element) {
|
|
19772
|
+
if (!isOutputElement(element)) {
|
|
19804
19773
|
return null;
|
|
19805
19774
|
}
|
|
19806
|
-
|
|
19807
|
-
return new this(context, maybeExpression);
|
|
19808
|
-
}
|
|
19809
|
-
return null;
|
|
19775
|
+
return new TextChunkExpression(context, "string", element.getAttribute("value"), "output");
|
|
19810
19776
|
}
|
|
19811
|
-
static
|
|
19777
|
+
static fromTranslation(context, maybeExpression) {
|
|
19812
19778
|
if (isTranslationExpression(maybeExpression)) {
|
|
19813
|
-
return new
|
|
19779
|
+
return new TextChunkExpression(context, "nodes", maybeExpression, "translation", {
|
|
19780
|
+
isTranslated: true
|
|
19781
|
+
});
|
|
19814
19782
|
}
|
|
19815
19783
|
return null;
|
|
19816
19784
|
}
|
|
19817
|
-
source = "translation";
|
|
19818
|
-
constructor(context, expression) {
|
|
19819
|
-
super(context, expression, { isTranslated: true });
|
|
19820
|
-
}
|
|
19821
19785
|
}
|
|
19822
19786
|
|
|
19823
19787
|
const absolutePathNodeList = (pathNode) => {
|
|
@@ -20066,16 +20030,20 @@ class TextElementDefinition extends TextRangeDefinition {
|
|
|
20066
20030
|
if (refExpression == null) {
|
|
20067
20031
|
this.chunks = Array.from(sourceNode.childNodes).flatMap((childNode) => {
|
|
20068
20032
|
if (isElementNode(childNode)) {
|
|
20069
|
-
return
|
|
20033
|
+
return TextChunkExpression.fromOutput(context, childNode) ?? [];
|
|
20070
20034
|
}
|
|
20071
20035
|
if (isTextNode(childNode)) {
|
|
20072
|
-
return
|
|
20036
|
+
return TextChunkExpression.fromLiteral(context, childNode.data);
|
|
20073
20037
|
}
|
|
20074
20038
|
return [];
|
|
20075
20039
|
});
|
|
20076
20040
|
} else {
|
|
20077
|
-
const
|
|
20078
|
-
|
|
20041
|
+
const expression = TextChunkExpression.fromTranslation(context, refExpression);
|
|
20042
|
+
if (expression != null) {
|
|
20043
|
+
this.chunks = [expression];
|
|
20044
|
+
} else {
|
|
20045
|
+
this.chunks = [TextChunkExpression.fromReference(context, refExpression)];
|
|
20046
|
+
}
|
|
20079
20047
|
}
|
|
20080
20048
|
}
|
|
20081
20049
|
}
|
|
@@ -20327,8 +20295,12 @@ class ItemsetLabelDefinition extends TextRangeDefinition {
|
|
|
20327
20295
|
if (refExpression == null) {
|
|
20328
20296
|
throw new Error("<itemset><label> missing ref attribute");
|
|
20329
20297
|
}
|
|
20330
|
-
const
|
|
20331
|
-
|
|
20298
|
+
const expression = TextChunkExpression.fromTranslation(this, refExpression);
|
|
20299
|
+
if (expression != null) {
|
|
20300
|
+
this.chunks = [expression];
|
|
20301
|
+
} else {
|
|
20302
|
+
this.chunks = [TextChunkExpression.fromReference(this, refExpression)];
|
|
20303
|
+
}
|
|
20332
20304
|
}
|
|
20333
20305
|
}
|
|
20334
20306
|
|
|
@@ -21236,8 +21208,12 @@ class MessageDefinition extends TextRangeDefinition {
|
|
|
21236
21208
|
constructor(bind, role, message) {
|
|
21237
21209
|
super(bind.form, bind, null);
|
|
21238
21210
|
this.role = role;
|
|
21239
|
-
const
|
|
21240
|
-
|
|
21211
|
+
const expression = TextChunkExpression.fromTranslation(this, message);
|
|
21212
|
+
if (expression != null) {
|
|
21213
|
+
this.chunks = [expression];
|
|
21214
|
+
} else {
|
|
21215
|
+
this.chunks = [TextChunkExpression.fromLiteral(this, message)];
|
|
21216
|
+
}
|
|
21241
21217
|
}
|
|
21242
21218
|
static from(bind, type) {
|
|
21243
21219
|
const message = bind.bindElement.getAttributeNS(JAVAROSA_NAMESPACE_URI$1, type);
|
|
@@ -29122,10 +29098,11 @@ class TextChunk {
|
|
|
29122
29098
|
}
|
|
29123
29099
|
|
|
29124
29100
|
class TextRange {
|
|
29125
|
-
constructor(origin, role, chunks) {
|
|
29101
|
+
constructor(origin, role, chunks, mediaSources) {
|
|
29126
29102
|
this.origin = origin;
|
|
29127
29103
|
this.role = role;
|
|
29128
29104
|
this.chunks = chunks;
|
|
29105
|
+
this.mediaSources = mediaSources;
|
|
29129
29106
|
}
|
|
29130
29107
|
*[Symbol.iterator]() {
|
|
29131
29108
|
yield* this.chunks;
|
|
@@ -29136,44 +29113,56 @@ class TextRange {
|
|
|
29136
29113
|
get asString() {
|
|
29137
29114
|
return this.chunks.map((chunk) => chunk.asString).join("");
|
|
29138
29115
|
}
|
|
29116
|
+
get imageSource() {
|
|
29117
|
+
return this.mediaSources?.image;
|
|
29118
|
+
}
|
|
29119
|
+
get audioSource() {
|
|
29120
|
+
return this.mediaSources?.audio;
|
|
29121
|
+
}
|
|
29122
|
+
get videoSource() {
|
|
29123
|
+
return this.mediaSources?.video;
|
|
29124
|
+
}
|
|
29139
29125
|
}
|
|
29140
29126
|
|
|
29141
|
-
const
|
|
29142
|
-
|
|
29143
|
-
|
|
29144
|
-
const
|
|
29145
|
-
|
|
29146
|
-
source
|
|
29147
|
-
|
|
29148
|
-
|
|
29149
|
-
|
|
29150
|
-
|
|
29151
|
-
|
|
29152
|
-
|
|
29153
|
-
|
|
29154
|
-
|
|
29155
|
-
|
|
29156
|
-
|
|
29157
|
-
|
|
29158
|
-
|
|
29159
|
-
|
|
29160
|
-
|
|
29161
|
-
|
|
29162
|
-
|
|
29163
|
-
|
|
29164
|
-
|
|
29165
|
-
|
|
29166
|
-
|
|
29167
|
-
|
|
29168
|
-
|
|
29127
|
+
const createTextChunks = (context, chunkExpressions) => {
|
|
29128
|
+
return createMemo(() => {
|
|
29129
|
+
const chunks = [];
|
|
29130
|
+
const mediaSources = {};
|
|
29131
|
+
chunkExpressions.forEach((chunkExpression) => {
|
|
29132
|
+
if (chunkExpression.source === "literal") {
|
|
29133
|
+
chunks.push(new TextChunk(context, chunkExpression.source, chunkExpression.stringValue));
|
|
29134
|
+
return;
|
|
29135
|
+
}
|
|
29136
|
+
const computed = createComputedExpression(context, chunkExpression)();
|
|
29137
|
+
if (typeof computed === "string") {
|
|
29138
|
+
chunks.push(new TextChunk(context, chunkExpression.source, computed));
|
|
29139
|
+
return;
|
|
29140
|
+
} else {
|
|
29141
|
+
computed.forEach((itextForm) => {
|
|
29142
|
+
if (isEngineXPathElement(itextForm) && itextForm instanceof StaticElement) {
|
|
29143
|
+
const formAttribute = itextForm.getAttributeValue("form");
|
|
29144
|
+
if (!formAttribute) {
|
|
29145
|
+
const defaultFormValue = itextForm.getXPathValue();
|
|
29146
|
+
chunks.push(new TextChunk(context, chunkExpression.source, defaultFormValue));
|
|
29147
|
+
} else if (["image", "video", "audio"].includes(formAttribute)) {
|
|
29148
|
+
const formValue = itextForm.getXPathValue();
|
|
29149
|
+
if (JRResourceURL.isJRResourceReference(formValue)) {
|
|
29150
|
+
mediaSources[formAttribute] = JRResourceURL.from(formValue);
|
|
29151
|
+
}
|
|
29152
|
+
}
|
|
29153
|
+
}
|
|
29154
|
+
});
|
|
29155
|
+
}
|
|
29169
29156
|
});
|
|
29157
|
+
return { chunks, mediaSources };
|
|
29170
29158
|
});
|
|
29171
29159
|
};
|
|
29172
29160
|
const createTextRange = (context, role, definition) => {
|
|
29173
29161
|
return context.scope.runTask(() => {
|
|
29174
|
-
const
|
|
29162
|
+
const textChunks = createTextChunks(context, definition.chunks);
|
|
29175
29163
|
return createMemo(() => {
|
|
29176
|
-
|
|
29164
|
+
const chunks = textChunks();
|
|
29165
|
+
return new TextRange("form", role, chunks.chunks, chunks.mediaSources);
|
|
29177
29166
|
});
|
|
29178
29167
|
});
|
|
29179
29168
|
};
|
|
@@ -29340,8 +29329,7 @@ const createInstanceValueState = (context) => {
|
|
|
29340
29329
|
const engineViolationMessage = (context, role) => {
|
|
29341
29330
|
const messageText = VALIDATION_TEXT[role];
|
|
29342
29331
|
const chunk = new TextChunk(context, "literal", messageText);
|
|
29343
|
-
|
|
29344
|
-
return () => message;
|
|
29332
|
+
return () => new TextRange("engine", role, [chunk]);
|
|
29345
29333
|
};
|
|
29346
29334
|
const createViolationMessage = (context, role, definition) => {
|
|
29347
29335
|
if (definition == null) {
|
|
@@ -30518,6 +30506,9 @@ class SelectControl extends ValueNode {
|
|
|
30518
30506
|
this.appearances = definition.bodyElement.appearances;
|
|
30519
30507
|
this.selectType = definition.bodyElement.type;
|
|
30520
30508
|
const valueOptions = createItemCollection(this);
|
|
30509
|
+
const isSelectWithImages = this.scope.runTask(() => {
|
|
30510
|
+
return createMemo(() => valueOptions().some((item) => !!item.label.imageSource));
|
|
30511
|
+
});
|
|
30521
30512
|
const mapOptionsByValue = this.scope.runTask(() => {
|
|
30522
30513
|
return createMemo(() => {
|
|
30523
30514
|
return new Map(valueOptions().map((item) => [item.value, item]));
|
|
@@ -30552,7 +30543,8 @@ class SelectControl extends ValueNode {
|
|
|
30552
30543
|
children: null,
|
|
30553
30544
|
valueOptions,
|
|
30554
30545
|
value: valueState,
|
|
30555
|
-
instanceValue: this.getInstanceValue
|
|
30546
|
+
instanceValue: this.getInstanceValue,
|
|
30547
|
+
isSelectWithImages
|
|
30556
30548
|
},
|
|
30557
30549
|
this.instanceConfig
|
|
30558
30550
|
);
|