@getodk/xforms-engine 0.12.0 → 0.13.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/TextRange.d.ts +0 -9
- package/dist/index.js +227 -100
- package/dist/index.js.map +1 -1
- package/dist/instance/RankControl.d.ts +3 -2
- package/dist/instance/SelectControl.d.ts +3 -2
- package/dist/parse/body/control/ItemsetDefinition.d.ts +1 -1
- package/dist/parse/expression/BindComputationExpression.d.ts +1 -1
- package/dist/parse/expression/ItemsetNodesetExpression.d.ts +1 -2
- package/dist/parse/expression/TextChunkExpression.d.ts +9 -7
- package/dist/parse/expression/abstract/DependentExpression.d.ts +1 -15
- package/dist/parse/model/ModelDefinition.d.ts +6 -1
- package/dist/parse/model/generateItextChunks.d.ts +5 -0
- package/dist/parse/xpath/semantic-analysis.d.ts +1 -0
- package/dist/solid.js +227 -100
- package/dist/solid.js.map +1 -1
- package/package.json +2 -2
- package/src/client/TextRange.ts +0 -9
- package/src/instance/RankControl.ts +8 -2
- package/src/instance/SelectControl.ts +8 -2
- package/src/lib/reactivity/text/createTextRange.ts +30 -30
- package/src/parse/body/control/ItemsetDefinition.ts +2 -2
- package/src/parse/expression/BindComputationExpression.ts +2 -7
- package/src/parse/expression/ItemsetNodesetExpression.ts +2 -3
- package/src/parse/expression/ItemsetValueExpression.ts +1 -1
- package/src/parse/expression/RepeatCountControlExpression.ts +4 -4
- package/src/parse/expression/TextChunkExpression.ts +25 -35
- package/src/parse/expression/abstract/DependentExpression.ts +2 -38
- package/src/parse/model/ModelDefinition.ts +13 -0
- package/src/parse/model/generateItextChunks.ts +61 -0
- package/src/parse/text/ItemsetLabelDefinition.ts +4 -4
- package/src/parse/text/MessageDefinition.ts +4 -4
- package/src/parse/text/abstract/TextElementDefinition.ts +6 -7
- package/src/parse/xpath/semantic-analysis.ts +37 -8
package/dist/solid.js
CHANGED
|
@@ -11233,7 +11233,45 @@ const nodeSet = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
|
|
|
11233
11233
|
itext
|
|
11234
11234
|
}, Symbol.toStringTag, { value: 'Module' }));
|
|
11235
11235
|
|
|
11236
|
-
const
|
|
11236
|
+
const choiceName = new StringFunction(
|
|
11237
|
+
"choice-name",
|
|
11238
|
+
[
|
|
11239
|
+
{ arityType: "required", typeHint: "string" },
|
|
11240
|
+
{ arityType: "required", typeHint: "string" }
|
|
11241
|
+
],
|
|
11242
|
+
(context, [nodeExpression, valueExpression]) => {
|
|
11243
|
+
const node = nodeExpression.evaluate(context).toString();
|
|
11244
|
+
const value = valueExpression.evaluate(context).toString();
|
|
11245
|
+
const [contextNode] = context.contextNodes;
|
|
11246
|
+
const { domProvider } = context;
|
|
11247
|
+
let nodes;
|
|
11248
|
+
if (contextNode && domProvider.isElement(contextNode)) {
|
|
11249
|
+
nodes = context.evaluator.evaluateNodes(value, { contextNode });
|
|
11250
|
+
} else {
|
|
11251
|
+
nodes = context.evaluator.evaluateNodes(value);
|
|
11252
|
+
}
|
|
11253
|
+
const firstNode = nodes?.[0];
|
|
11254
|
+
if (!firstNode) {
|
|
11255
|
+
return "";
|
|
11256
|
+
}
|
|
11257
|
+
if (!("getChoiceName" in firstNode)) {
|
|
11258
|
+
throw new Error(
|
|
11259
|
+
`Evaluating 'jr:choice-name' on element '${value}' which has no possible choices.`
|
|
11260
|
+
);
|
|
11261
|
+
}
|
|
11262
|
+
return firstNode.getChoiceName(node) ?? "";
|
|
11263
|
+
}
|
|
11264
|
+
);
|
|
11265
|
+
|
|
11266
|
+
const select$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
|
|
11267
|
+
__proto__: null,
|
|
11268
|
+
choiceName
|
|
11269
|
+
}, Symbol.toStringTag, { value: 'Module' }));
|
|
11270
|
+
|
|
11271
|
+
const jr$2 = new FunctionLibrary(JAVAROSA_NAMESPACE_URI, [
|
|
11272
|
+
...Object.values(nodeSet),
|
|
11273
|
+
...Object.values(select$1)
|
|
11274
|
+
]);
|
|
11237
11275
|
|
|
11238
11276
|
const booleanFromString = new BooleanFunction(
|
|
11239
11277
|
"boolean-from-string",
|
|
@@ -18664,6 +18702,10 @@ const hex = /*#__PURE__*/_mergeNamespaces({
|
|
|
18664
18702
|
default: encHex
|
|
18665
18703
|
}, [encHexExports]);
|
|
18666
18704
|
|
|
18705
|
+
const base64Decode$1 = (base64Input) => {
|
|
18706
|
+
return new TextDecoder().decode(Uint8Array.from(atob(base64Input), (m) => m.charCodeAt(0)));
|
|
18707
|
+
};
|
|
18708
|
+
|
|
18667
18709
|
const toStrings = (context, expressions) => {
|
|
18668
18710
|
return expressions.flatMap((arg) => {
|
|
18669
18711
|
const result = arg.evaluate(context);
|
|
@@ -18675,6 +18717,17 @@ const toStrings = (context, expressions) => {
|
|
|
18675
18717
|
});
|
|
18676
18718
|
};
|
|
18677
18719
|
|
|
18720
|
+
const base64Decode = new StringFunction(
|
|
18721
|
+
"base64-decode",
|
|
18722
|
+
[{ arityType: "required", typeHint: "string" }],
|
|
18723
|
+
(context, [base64Expression]) => {
|
|
18724
|
+
try {
|
|
18725
|
+
return base64Decode$1(base64Expression.evaluate(context).toString());
|
|
18726
|
+
} catch {
|
|
18727
|
+
return "";
|
|
18728
|
+
}
|
|
18729
|
+
}
|
|
18730
|
+
);
|
|
18678
18731
|
const coalesce = new StringFunction(
|
|
18679
18732
|
"coalesce",
|
|
18680
18733
|
[
|
|
@@ -18764,6 +18817,23 @@ const join = new StringFunction(
|
|
|
18764
18817
|
return strings.join(glue);
|
|
18765
18818
|
}
|
|
18766
18819
|
);
|
|
18820
|
+
const pulldata = new StringFunction(
|
|
18821
|
+
"pulldata",
|
|
18822
|
+
[
|
|
18823
|
+
{ arityType: "required", typeHint: "string" },
|
|
18824
|
+
{ arityType: "required", typeHint: "string" },
|
|
18825
|
+
{ arityType: "required", typeHint: "string" },
|
|
18826
|
+
{ arityType: "required", typeHint: "string" }
|
|
18827
|
+
],
|
|
18828
|
+
(context, [instanceExpression, desiredElementExpression, queryElementExpression, queryExpression]) => {
|
|
18829
|
+
const instanceId = instanceExpression.evaluate(context).toString();
|
|
18830
|
+
const desiredElement = desiredElementExpression.evaluate(context).toString();
|
|
18831
|
+
const queryElement = queryElementExpression.evaluate(context).toString();
|
|
18832
|
+
const query = queryExpression.evaluate(context).toString();
|
|
18833
|
+
const expr = `instance('${instanceId}')/root/item[${queryElement}='${query}']/${desiredElement}`;
|
|
18834
|
+
return context.evaluator.evaluateString(expr);
|
|
18835
|
+
}
|
|
18836
|
+
);
|
|
18767
18837
|
const regex = new BooleanFunction(
|
|
18768
18838
|
"regex",
|
|
18769
18839
|
[
|
|
@@ -18842,11 +18912,13 @@ const uuid = new StringFunction(
|
|
|
18842
18912
|
|
|
18843
18913
|
const string = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
|
|
18844
18914
|
__proto__: null,
|
|
18915
|
+
base64Decode,
|
|
18845
18916
|
coalesce,
|
|
18846
18917
|
concat,
|
|
18847
18918
|
digest,
|
|
18848
18919
|
endsWith,
|
|
18849
18920
|
join,
|
|
18921
|
+
pulldata,
|
|
18850
18922
|
regex,
|
|
18851
18923
|
substr,
|
|
18852
18924
|
uuid
|
|
@@ -19560,18 +19632,32 @@ const isTranslationFunctionCall = (syntaxNode) => {
|
|
|
19560
19632
|
ANY_ARGUMENT_TYPE
|
|
19561
19633
|
]);
|
|
19562
19634
|
};
|
|
19563
|
-
const
|
|
19635
|
+
const findFunctionPrincipalExpressionNode = (expression) => {
|
|
19564
19636
|
let result;
|
|
19565
19637
|
try {
|
|
19566
19638
|
result = expressionParser.parse(expression);
|
|
19567
19639
|
} catch {
|
|
19568
|
-
return
|
|
19640
|
+
return null;
|
|
19569
19641
|
}
|
|
19570
19642
|
const functionCallNode = findTypedPrincipalExpressionNode(["function_call"], result.rootNode);
|
|
19571
19643
|
if (functionCallNode == null) {
|
|
19572
|
-
return
|
|
19644
|
+
return null;
|
|
19573
19645
|
}
|
|
19574
|
-
return
|
|
19646
|
+
return functionCallNode;
|
|
19647
|
+
};
|
|
19648
|
+
const getTranslationExpression = (expression) => {
|
|
19649
|
+
const functionCallNode = findFunctionPrincipalExpressionNode(expression);
|
|
19650
|
+
if (!functionCallNode) {
|
|
19651
|
+
return null;
|
|
19652
|
+
}
|
|
19653
|
+
if (!isTranslationFunctionCall(functionCallNode)) {
|
|
19654
|
+
return null;
|
|
19655
|
+
}
|
|
19656
|
+
const arg = functionCallNode.children.find((child) => child.type === "argument");
|
|
19657
|
+
if (!arg) {
|
|
19658
|
+
return null;
|
|
19659
|
+
}
|
|
19660
|
+
return arg.text;
|
|
19575
19661
|
};
|
|
19576
19662
|
const isCurrentFunctionCall = (syntaxNode) => {
|
|
19577
19663
|
return isCallToLocalNamedFunction(syntaxNode, "current") && hasCallSignature(syntaxNode, []);
|
|
@@ -19691,7 +19777,7 @@ const evaluatorMethodsByResultType = {
|
|
|
19691
19777
|
string: "evaluateString"
|
|
19692
19778
|
};
|
|
19693
19779
|
class DependentExpression {
|
|
19694
|
-
constructor(
|
|
19780
|
+
constructor(resultType, expression) {
|
|
19695
19781
|
this.resultType = resultType;
|
|
19696
19782
|
this.expression = expression;
|
|
19697
19783
|
if (resultType === "boolean" && isConstantTruthyExpression(expression)) {
|
|
@@ -19705,16 +19791,6 @@ class DependentExpression {
|
|
|
19705
19791
|
this.constantExpression = null;
|
|
19706
19792
|
}
|
|
19707
19793
|
this.evaluatorMethod = evaluatorMethodsByResultType[resultType];
|
|
19708
|
-
const {
|
|
19709
|
-
semanticDependencies = {
|
|
19710
|
-
translations: false
|
|
19711
|
-
}
|
|
19712
|
-
} = options;
|
|
19713
|
-
const isTranslated = semanticDependencies.translations && isTranslationExpression(expression);
|
|
19714
|
-
if (isTranslated) {
|
|
19715
|
-
this.isTranslated = true;
|
|
19716
|
-
context.isTranslated = true;
|
|
19717
|
-
}
|
|
19718
19794
|
}
|
|
19719
19795
|
isTranslated = false;
|
|
19720
19796
|
evaluatorMethod;
|
|
@@ -19738,33 +19814,32 @@ class TextChunkExpression extends DependentExpression {
|
|
|
19738
19814
|
source;
|
|
19739
19815
|
// Set for the literal source, blank otherwise
|
|
19740
19816
|
stringValue;
|
|
19741
|
-
|
|
19742
|
-
|
|
19743
|
-
|
|
19744
|
-
|
|
19745
|
-
},
|
|
19746
|
-
ignoreContextReference: true
|
|
19747
|
-
});
|
|
19817
|
+
resourceType;
|
|
19818
|
+
constructor(resultType, expression, source, literalValue = "", options = {}) {
|
|
19819
|
+
super(resultType, expression);
|
|
19820
|
+
this.resourceType = options.type ?? null;
|
|
19748
19821
|
this.source = source;
|
|
19749
19822
|
this.stringValue = literalValue;
|
|
19750
19823
|
}
|
|
19751
|
-
static fromLiteral(
|
|
19752
|
-
return new TextChunkExpression(
|
|
19824
|
+
static fromLiteral(stringValue) {
|
|
19825
|
+
return new TextChunkExpression("string", "null", "literal", stringValue);
|
|
19753
19826
|
}
|
|
19754
|
-
static fromReference(
|
|
19755
|
-
return new TextChunkExpression(
|
|
19827
|
+
static fromReference(ref) {
|
|
19828
|
+
return new TextChunkExpression("string", ref, "reference");
|
|
19756
19829
|
}
|
|
19757
|
-
static fromOutput(
|
|
19830
|
+
static fromOutput(element) {
|
|
19758
19831
|
if (!isOutputElement(element)) {
|
|
19759
19832
|
return null;
|
|
19760
19833
|
}
|
|
19761
|
-
return new TextChunkExpression(
|
|
19834
|
+
return new TextChunkExpression("string", element.getAttribute("value"), "output");
|
|
19762
19835
|
}
|
|
19763
|
-
static
|
|
19764
|
-
|
|
19765
|
-
|
|
19766
|
-
|
|
19767
|
-
|
|
19836
|
+
static fromResource(url, type) {
|
|
19837
|
+
return new TextChunkExpression("string", "null", "literal", url, { type });
|
|
19838
|
+
}
|
|
19839
|
+
static fromTranslation(maybeExpression) {
|
|
19840
|
+
const translationExpression = getTranslationExpression(maybeExpression);
|
|
19841
|
+
if (translationExpression) {
|
|
19842
|
+
return new TextChunkExpression("nodes", translationExpression, "translation");
|
|
19768
19843
|
}
|
|
19769
19844
|
return null;
|
|
19770
19845
|
}
|
|
@@ -20011,24 +20086,23 @@ class TextElementDefinition extends TextRangeDefinition {
|
|
|
20011
20086
|
chunks;
|
|
20012
20087
|
constructor(form, owner, sourceNode) {
|
|
20013
20088
|
super(form, owner, sourceNode);
|
|
20014
|
-
const context = this;
|
|
20015
20089
|
const refExpression = parseNodesetReference(owner, sourceNode, "ref");
|
|
20016
20090
|
if (refExpression == null) {
|
|
20017
20091
|
this.chunks = Array.from(sourceNode.childNodes).flatMap((childNode) => {
|
|
20018
20092
|
if (isElementNode(childNode)) {
|
|
20019
|
-
return TextChunkExpression.fromOutput(
|
|
20093
|
+
return TextChunkExpression.fromOutput(childNode) ?? [];
|
|
20020
20094
|
}
|
|
20021
20095
|
if (isTextNode(childNode)) {
|
|
20022
|
-
return TextChunkExpression.fromLiteral(
|
|
20096
|
+
return TextChunkExpression.fromLiteral(childNode.data);
|
|
20023
20097
|
}
|
|
20024
20098
|
return [];
|
|
20025
20099
|
});
|
|
20026
20100
|
} else {
|
|
20027
|
-
const
|
|
20028
|
-
if (
|
|
20029
|
-
this.chunks = [
|
|
20101
|
+
const translationChunk = TextChunkExpression.fromTranslation(refExpression);
|
|
20102
|
+
if (translationChunk) {
|
|
20103
|
+
this.chunks = [translationChunk];
|
|
20030
20104
|
} else {
|
|
20031
|
-
this.chunks = [TextChunkExpression.fromReference(
|
|
20105
|
+
this.chunks = [TextChunkExpression.fromReference(refExpression)];
|
|
20032
20106
|
}
|
|
20033
20107
|
}
|
|
20034
20108
|
}
|
|
@@ -20253,14 +20327,14 @@ class RangeControlDefinition extends ControlDefinition {
|
|
|
20253
20327
|
}
|
|
20254
20328
|
|
|
20255
20329
|
class ItemsetNodesetExpression extends DependentExpression {
|
|
20256
|
-
constructor(
|
|
20257
|
-
super(
|
|
20330
|
+
constructor(nodesetExpression) {
|
|
20331
|
+
super("nodes", nodesetExpression);
|
|
20258
20332
|
}
|
|
20259
20333
|
}
|
|
20260
20334
|
|
|
20261
20335
|
class ItemsetValueExpression extends DependentExpression {
|
|
20262
20336
|
constructor(itemset, expression) {
|
|
20263
|
-
super(
|
|
20337
|
+
super("string", expression);
|
|
20264
20338
|
this.itemset = itemset;
|
|
20265
20339
|
}
|
|
20266
20340
|
}
|
|
@@ -20281,11 +20355,11 @@ class ItemsetLabelDefinition extends TextRangeDefinition {
|
|
|
20281
20355
|
if (refExpression == null) {
|
|
20282
20356
|
throw new Error("<itemset><label> missing ref attribute");
|
|
20283
20357
|
}
|
|
20284
|
-
const
|
|
20285
|
-
if (
|
|
20286
|
-
this.chunks = [
|
|
20358
|
+
const translationChunk = TextChunkExpression.fromTranslation(refExpression);
|
|
20359
|
+
if (translationChunk) {
|
|
20360
|
+
this.chunks = [translationChunk];
|
|
20287
20361
|
} else {
|
|
20288
|
-
this.chunks = [TextChunkExpression.fromReference(
|
|
20362
|
+
this.chunks = [TextChunkExpression.fromReference(refExpression)];
|
|
20289
20363
|
}
|
|
20290
20364
|
}
|
|
20291
20365
|
}
|
|
@@ -20295,7 +20369,7 @@ class ItemsetDefinition extends BodyElementDefinition {
|
|
|
20295
20369
|
super(form, parent, element);
|
|
20296
20370
|
this.parent = parent;
|
|
20297
20371
|
const nodesetExpression = parseNodesetReference(parent, element, "nodeset");
|
|
20298
|
-
this.nodes = new ItemsetNodesetExpression(
|
|
20372
|
+
this.nodes = new ItemsetNodesetExpression(nodesetExpression);
|
|
20299
20373
|
this.reference = nodesetExpression;
|
|
20300
20374
|
const valueElement = getValueElement(element);
|
|
20301
20375
|
if (valueElement == null) {
|
|
@@ -21114,6 +21188,64 @@ const parseStaticDocumentFromDOMSubtree = (subtreeRootElement, options = {}) =>
|
|
|
21114
21188
|
});
|
|
21115
21189
|
};
|
|
21116
21190
|
|
|
21191
|
+
const JR_RESOURCE_URL_PROTOCOL = "jr:";
|
|
21192
|
+
const ALL_RESOURCE_TYPES = ["image", "audio", "video"];
|
|
21193
|
+
const isResourceType = (string) => {
|
|
21194
|
+
return ALL_RESOURCE_TYPES.includes(string);
|
|
21195
|
+
};
|
|
21196
|
+
class JRResourceURL extends URL {
|
|
21197
|
+
static create(category, fileName) {
|
|
21198
|
+
return new this(`jr://${category}/${fileName}`);
|
|
21199
|
+
}
|
|
21200
|
+
static from(url) {
|
|
21201
|
+
return new this(url);
|
|
21202
|
+
}
|
|
21203
|
+
static isJRResourceReference(reference) {
|
|
21204
|
+
return reference?.startsWith(JR_RESOURCE_URL_PROTOCOL) ?? false;
|
|
21205
|
+
}
|
|
21206
|
+
constructor(url) {
|
|
21207
|
+
super(url);
|
|
21208
|
+
}
|
|
21209
|
+
}
|
|
21210
|
+
|
|
21211
|
+
const generateChunk = (node) => {
|
|
21212
|
+
if (isElementNode(node)) {
|
|
21213
|
+
return TextChunkExpression.fromOutput(node);
|
|
21214
|
+
}
|
|
21215
|
+
if (isTextNode(node)) {
|
|
21216
|
+
const formAttribute = node.parentElement.getAttribute("form");
|
|
21217
|
+
if (isResourceType(formAttribute)) {
|
|
21218
|
+
return TextChunkExpression.fromResource(node.data, formAttribute);
|
|
21219
|
+
}
|
|
21220
|
+
return TextChunkExpression.fromLiteral(node.data);
|
|
21221
|
+
}
|
|
21222
|
+
return null;
|
|
21223
|
+
};
|
|
21224
|
+
const generateChunksForValues = (valueElement) => {
|
|
21225
|
+
return Array.from(valueElement.childNodes).map((node) => generateChunk(node)).filter((chunk) => chunk !== null);
|
|
21226
|
+
};
|
|
21227
|
+
const generateChunksForTranslation = (textElement) => {
|
|
21228
|
+
return Array.from(textElement.childNodes).flatMap(
|
|
21229
|
+
(valueElement) => generateChunksForValues(valueElement)
|
|
21230
|
+
);
|
|
21231
|
+
};
|
|
21232
|
+
const generateChunksForLanguage = (translationElement) => {
|
|
21233
|
+
return new Map(
|
|
21234
|
+
Array.from(translationElement.children).map((textElement) => {
|
|
21235
|
+
const itextId = textElement.getAttribute("id");
|
|
21236
|
+
return [itextId, generateChunksForTranslation(textElement)];
|
|
21237
|
+
})
|
|
21238
|
+
);
|
|
21239
|
+
};
|
|
21240
|
+
const generateItextChunks = (translationElements) => {
|
|
21241
|
+
return new Map(
|
|
21242
|
+
translationElements.map((translationElement) => {
|
|
21243
|
+
const lang = translationElement.getAttribute("lang");
|
|
21244
|
+
return [lang, generateChunksForLanguage(translationElement)];
|
|
21245
|
+
})
|
|
21246
|
+
);
|
|
21247
|
+
};
|
|
21248
|
+
|
|
21117
21249
|
const assertItextTranslationsDefinitionEntry = ([
|
|
21118
21250
|
key,
|
|
21119
21251
|
root
|
|
@@ -21160,8 +21292,7 @@ const bindComputationResultTypes = {
|
|
|
21160
21292
|
saveIncomplete: "boolean"
|
|
21161
21293
|
};
|
|
21162
21294
|
class BindComputationExpression extends DependentExpression {
|
|
21163
|
-
constructor(
|
|
21164
|
-
const ignoreContextReference = computation === "constraint";
|
|
21295
|
+
constructor(computation, expression) {
|
|
21165
21296
|
let isDefaultExpression;
|
|
21166
21297
|
let resolvedExpression;
|
|
21167
21298
|
if (expression == null) {
|
|
@@ -21174,9 +21305,7 @@ class BindComputationExpression extends DependentExpression {
|
|
|
21174
21305
|
isDefaultExpression = false;
|
|
21175
21306
|
resolvedExpression = expression;
|
|
21176
21307
|
}
|
|
21177
|
-
super(
|
|
21178
|
-
ignoreContextReference
|
|
21179
|
-
});
|
|
21308
|
+
super(bindComputationResultTypes[computation], resolvedExpression);
|
|
21180
21309
|
this.computation = computation;
|
|
21181
21310
|
this.isDefaultExpression = isDefaultExpression;
|
|
21182
21311
|
}
|
|
@@ -21185,7 +21314,7 @@ class BindComputationExpression extends DependentExpression {
|
|
|
21185
21314
|
if (expression == null) {
|
|
21186
21315
|
return null;
|
|
21187
21316
|
}
|
|
21188
|
-
return new this(
|
|
21317
|
+
return new this(computation, expression);
|
|
21189
21318
|
}
|
|
21190
21319
|
isDefaultExpression;
|
|
21191
21320
|
}
|
|
@@ -21194,11 +21323,11 @@ class MessageDefinition extends TextRangeDefinition {
|
|
|
21194
21323
|
constructor(bind, role, message) {
|
|
21195
21324
|
super(bind.form, bind, null);
|
|
21196
21325
|
this.role = role;
|
|
21197
|
-
const
|
|
21198
|
-
if (
|
|
21199
|
-
this.chunks = [
|
|
21326
|
+
const translationChunk = TextChunkExpression.fromTranslation(message);
|
|
21327
|
+
if (translationChunk) {
|
|
21328
|
+
this.chunks = [translationChunk];
|
|
21200
21329
|
} else {
|
|
21201
|
-
this.chunks = [TextChunkExpression.fromLiteral(
|
|
21330
|
+
this.chunks = [TextChunkExpression.fromLiteral(message)];
|
|
21202
21331
|
}
|
|
21203
21332
|
}
|
|
21204
21333
|
static from(bind, type) {
|
|
@@ -26066,16 +26195,16 @@ class RepeatCountControlExpression extends DependentExpression {
|
|
|
26066
26195
|
static from(bodyElement, initialCount) {
|
|
26067
26196
|
const { countExpression, noAddRemoveExpression } = bodyElement;
|
|
26068
26197
|
if (countExpression != null) {
|
|
26069
|
-
return new this(
|
|
26198
|
+
return new this(countExpression);
|
|
26070
26199
|
}
|
|
26071
26200
|
if (noAddRemoveExpression != null && isConstantTruthyExpression(noAddRemoveExpression)) {
|
|
26072
26201
|
const fixedCountExpression = String(Math.max(initialCount, 1));
|
|
26073
|
-
return new this(
|
|
26202
|
+
return new this(fixedCountExpression);
|
|
26074
26203
|
}
|
|
26075
26204
|
return null;
|
|
26076
26205
|
}
|
|
26077
|
-
constructor(
|
|
26078
|
-
super(
|
|
26206
|
+
constructor(expression) {
|
|
26207
|
+
super("number", expression);
|
|
26079
26208
|
}
|
|
26080
26209
|
}
|
|
26081
26210
|
|
|
@@ -26342,12 +26471,14 @@ class ModelDefinition {
|
|
|
26342
26471
|
this.root = new RootDefinition(form, this, submission, form.body.classes);
|
|
26343
26472
|
this.nodes = nodeDefinitionMap(this.root);
|
|
26344
26473
|
this.itextTranslations = ItextTranslationsDefinition.from(form.xformDOM);
|
|
26474
|
+
this.itextChunks = generateItextChunks(form.xformDOM.itextTranslationElements);
|
|
26345
26475
|
}
|
|
26346
26476
|
binds;
|
|
26347
26477
|
root;
|
|
26348
26478
|
nodes;
|
|
26349
26479
|
instance;
|
|
26350
26480
|
itextTranslations;
|
|
26481
|
+
itextChunks;
|
|
26351
26482
|
getNodeDefinition(nodeset) {
|
|
26352
26483
|
const definition = this.nodes.get(nodeset);
|
|
26353
26484
|
if (definition == null) {
|
|
@@ -26366,6 +26497,10 @@ class ModelDefinition {
|
|
|
26366
26497
|
const { form, ...rest } = this;
|
|
26367
26498
|
return rest;
|
|
26368
26499
|
}
|
|
26500
|
+
getTranslationChunks(itextId, activeLanguage) {
|
|
26501
|
+
const languageMap = this.itextChunks.get(activeLanguage.language);
|
|
26502
|
+
return languageMap?.get(itextId) ?? [];
|
|
26503
|
+
}
|
|
26369
26504
|
}
|
|
26370
26505
|
|
|
26371
26506
|
class XFormDefinition {
|
|
@@ -26391,22 +26526,6 @@ class XFormDefinition {
|
|
|
26391
26526
|
model;
|
|
26392
26527
|
}
|
|
26393
26528
|
|
|
26394
|
-
const JR_RESOURCE_URL_PROTOCOL = "jr:";
|
|
26395
|
-
class JRResourceURL extends URL {
|
|
26396
|
-
static create(category, fileName) {
|
|
26397
|
-
return new this(`jr://${category}/${fileName}`);
|
|
26398
|
-
}
|
|
26399
|
-
static from(url) {
|
|
26400
|
-
return new this(url);
|
|
26401
|
-
}
|
|
26402
|
-
static isJRResourceReference(reference) {
|
|
26403
|
-
return reference?.startsWith(JR_RESOURCE_URL_PROTOCOL) ?? false;
|
|
26404
|
-
}
|
|
26405
|
-
constructor(url) {
|
|
26406
|
-
super(url);
|
|
26407
|
-
}
|
|
26408
|
-
}
|
|
26409
|
-
|
|
26410
26529
|
const assertSecondaryInstanceDefinition = ({ root }) => {
|
|
26411
26530
|
const id = root.getAttributeValue("id");
|
|
26412
26531
|
if (id == null) {
|
|
@@ -29111,42 +29230,42 @@ class TextRange {
|
|
|
29111
29230
|
}
|
|
29112
29231
|
}
|
|
29113
29232
|
|
|
29114
|
-
const createTextChunks = (context,
|
|
29233
|
+
const createTextChunks = (context, definition) => {
|
|
29115
29234
|
return createMemo(() => {
|
|
29116
29235
|
const chunks = [];
|
|
29117
29236
|
const mediaSources = {};
|
|
29237
|
+
let chunkExpressions;
|
|
29238
|
+
if (definition.chunks[0]?.source === "translation") {
|
|
29239
|
+
const itextId = context.evaluator.evaluateString(definition.chunks[0].toString(), {
|
|
29240
|
+
contextNode: context.contextNode
|
|
29241
|
+
});
|
|
29242
|
+
chunkExpressions = definition.form.model.getTranslationChunks(
|
|
29243
|
+
itextId,
|
|
29244
|
+
context.getActiveLanguage()
|
|
29245
|
+
);
|
|
29246
|
+
} else {
|
|
29247
|
+
chunkExpressions = definition.chunks;
|
|
29248
|
+
}
|
|
29118
29249
|
chunkExpressions.forEach((chunkExpression) => {
|
|
29250
|
+
if (chunkExpression.resourceType) {
|
|
29251
|
+
mediaSources[chunkExpression.resourceType] = JRResourceURL.from(
|
|
29252
|
+
chunkExpression.stringValue
|
|
29253
|
+
);
|
|
29254
|
+
return;
|
|
29255
|
+
}
|
|
29119
29256
|
if (chunkExpression.source === "literal") {
|
|
29120
29257
|
chunks.push(new TextChunk(context, chunkExpression.source, chunkExpression.stringValue));
|
|
29121
29258
|
return;
|
|
29122
29259
|
}
|
|
29123
29260
|
const computed = createComputedExpression(context, chunkExpression)();
|
|
29124
|
-
|
|
29125
|
-
chunks.push(new TextChunk(context, chunkExpression.source, computed));
|
|
29126
|
-
return;
|
|
29127
|
-
} else {
|
|
29128
|
-
computed.forEach((itextForm) => {
|
|
29129
|
-
if (isEngineXPathElement(itextForm) && itextForm instanceof StaticElement) {
|
|
29130
|
-
const formAttribute = itextForm.getAttributeValue("form");
|
|
29131
|
-
if (!formAttribute) {
|
|
29132
|
-
const defaultFormValue = itextForm.getXPathValue();
|
|
29133
|
-
chunks.push(new TextChunk(context, chunkExpression.source, defaultFormValue));
|
|
29134
|
-
} else if (["image", "video", "audio"].includes(formAttribute)) {
|
|
29135
|
-
const formValue = itextForm.getXPathValue();
|
|
29136
|
-
if (JRResourceURL.isJRResourceReference(formValue)) {
|
|
29137
|
-
mediaSources[formAttribute] = JRResourceURL.from(formValue);
|
|
29138
|
-
}
|
|
29139
|
-
}
|
|
29140
|
-
}
|
|
29141
|
-
});
|
|
29142
|
-
}
|
|
29261
|
+
chunks.push(new TextChunk(context, chunkExpression.source, computed));
|
|
29143
29262
|
});
|
|
29144
29263
|
return { chunks, mediaSources };
|
|
29145
29264
|
});
|
|
29146
29265
|
};
|
|
29147
29266
|
const createTextRange = (context, role, definition) => {
|
|
29148
29267
|
return context.scope.runTask(() => {
|
|
29149
|
-
const textChunks = createTextChunks(context, definition
|
|
29268
|
+
const textChunks = createTextChunks(context, definition);
|
|
29150
29269
|
return createMemo(() => {
|
|
29151
29270
|
const chunks = textChunks();
|
|
29152
29271
|
return new TextRange("form", role, chunks.chunks, chunks.mediaSources);
|
|
@@ -30025,6 +30144,10 @@ class RankControl extends ValueNode {
|
|
|
30025
30144
|
this.setValueState(valuesInOrder);
|
|
30026
30145
|
return this.root;
|
|
30027
30146
|
}
|
|
30147
|
+
getChoiceName(value) {
|
|
30148
|
+
const option = this.mapOptionsByValue().get(value);
|
|
30149
|
+
return option?.label?.asString ?? null;
|
|
30150
|
+
}
|
|
30028
30151
|
}
|
|
30029
30152
|
|
|
30030
30153
|
const insertAtIndex = (currentValues, insertionIndex, newValues) => {
|
|
@@ -30589,6 +30712,10 @@ class SelectControl extends ValueNode {
|
|
|
30589
30712
|
this.setValueState(effectiveValues);
|
|
30590
30713
|
return this.root;
|
|
30591
30714
|
}
|
|
30715
|
+
getChoiceName(value) {
|
|
30716
|
+
const option = this.mapOptionsByValue().get(value);
|
|
30717
|
+
return option?.label?.asString ?? null;
|
|
30718
|
+
}
|
|
30592
30719
|
}
|
|
30593
30720
|
|
|
30594
30721
|
class Subtree extends DescendantNode {
|