@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.
Files changed (33) hide show
  1. package/dist/client/TextRange.d.ts +0 -9
  2. package/dist/index.js +227 -100
  3. package/dist/index.js.map +1 -1
  4. package/dist/instance/RankControl.d.ts +3 -2
  5. package/dist/instance/SelectControl.d.ts +3 -2
  6. package/dist/parse/body/control/ItemsetDefinition.d.ts +1 -1
  7. package/dist/parse/expression/BindComputationExpression.d.ts +1 -1
  8. package/dist/parse/expression/ItemsetNodesetExpression.d.ts +1 -2
  9. package/dist/parse/expression/TextChunkExpression.d.ts +9 -7
  10. package/dist/parse/expression/abstract/DependentExpression.d.ts +1 -15
  11. package/dist/parse/model/ModelDefinition.d.ts +6 -1
  12. package/dist/parse/model/generateItextChunks.d.ts +5 -0
  13. package/dist/parse/xpath/semantic-analysis.d.ts +1 -0
  14. package/dist/solid.js +227 -100
  15. package/dist/solid.js.map +1 -1
  16. package/package.json +2 -2
  17. package/src/client/TextRange.ts +0 -9
  18. package/src/instance/RankControl.ts +8 -2
  19. package/src/instance/SelectControl.ts +8 -2
  20. package/src/lib/reactivity/text/createTextRange.ts +30 -30
  21. package/src/parse/body/control/ItemsetDefinition.ts +2 -2
  22. package/src/parse/expression/BindComputationExpression.ts +2 -7
  23. package/src/parse/expression/ItemsetNodesetExpression.ts +2 -3
  24. package/src/parse/expression/ItemsetValueExpression.ts +1 -1
  25. package/src/parse/expression/RepeatCountControlExpression.ts +4 -4
  26. package/src/parse/expression/TextChunkExpression.ts +25 -35
  27. package/src/parse/expression/abstract/DependentExpression.ts +2 -38
  28. package/src/parse/model/ModelDefinition.ts +13 -0
  29. package/src/parse/model/generateItextChunks.ts +61 -0
  30. package/src/parse/text/ItemsetLabelDefinition.ts +4 -4
  31. package/src/parse/text/MessageDefinition.ts +4 -4
  32. package/src/parse/text/abstract/TextElementDefinition.ts +6 -7
  33. 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 jr$2 = new FunctionLibrary(JAVAROSA_NAMESPACE_URI, [...Object.values(nodeSet)]);
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 isTranslationExpression = (expression) => {
19635
+ const findFunctionPrincipalExpressionNode = (expression) => {
19564
19636
  let result;
19565
19637
  try {
19566
19638
  result = expressionParser.parse(expression);
19567
19639
  } catch {
19568
- return false;
19640
+ return null;
19569
19641
  }
19570
19642
  const functionCallNode = findTypedPrincipalExpressionNode(["function_call"], result.rootNode);
19571
19643
  if (functionCallNode == null) {
19572
- return false;
19644
+ return null;
19573
19645
  }
19574
- return isTranslationFunctionCall(functionCallNode);
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(context, resultType, expression, options = {}) {
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
- constructor(context, resultType, expression, source, options = {}, literalValue = "") {
19742
- super(context, resultType, expression, {
19743
- semanticDependencies: {
19744
- translations: options.isTranslated
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(context, stringValue) {
19752
- return new TextChunkExpression(context, "string", "null", "literal", {}, stringValue);
19824
+ static fromLiteral(stringValue) {
19825
+ return new TextChunkExpression("string", "null", "literal", stringValue);
19753
19826
  }
19754
- static fromReference(context, ref) {
19755
- return new TextChunkExpression(context, "string", ref, "reference");
19827
+ static fromReference(ref) {
19828
+ return new TextChunkExpression("string", ref, "reference");
19756
19829
  }
19757
- static fromOutput(context, element) {
19830
+ static fromOutput(element) {
19758
19831
  if (!isOutputElement(element)) {
19759
19832
  return null;
19760
19833
  }
19761
- return new TextChunkExpression(context, "string", element.getAttribute("value"), "output");
19834
+ return new TextChunkExpression("string", element.getAttribute("value"), "output");
19762
19835
  }
19763
- static fromTranslation(context, maybeExpression) {
19764
- if (isTranslationExpression(maybeExpression)) {
19765
- return new TextChunkExpression(context, "nodes", maybeExpression, "translation", {
19766
- isTranslated: true
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(context, childNode) ?? [];
20093
+ return TextChunkExpression.fromOutput(childNode) ?? [];
20020
20094
  }
20021
20095
  if (isTextNode(childNode)) {
20022
- return TextChunkExpression.fromLiteral(context, childNode.data);
20096
+ return TextChunkExpression.fromLiteral(childNode.data);
20023
20097
  }
20024
20098
  return [];
20025
20099
  });
20026
20100
  } else {
20027
- const expression = TextChunkExpression.fromTranslation(context, refExpression);
20028
- if (expression != null) {
20029
- this.chunks = [expression];
20101
+ const translationChunk = TextChunkExpression.fromTranslation(refExpression);
20102
+ if (translationChunk) {
20103
+ this.chunks = [translationChunk];
20030
20104
  } else {
20031
- this.chunks = [TextChunkExpression.fromReference(context, refExpression)];
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(itemset, nodesetExpression) {
20257
- super(itemset.parent, "nodes", nodesetExpression);
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(itemset, "string", expression);
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 expression = TextChunkExpression.fromTranslation(this, refExpression);
20285
- if (expression != null) {
20286
- this.chunks = [expression];
20358
+ const translationChunk = TextChunkExpression.fromTranslation(refExpression);
20359
+ if (translationChunk) {
20360
+ this.chunks = [translationChunk];
20287
20361
  } else {
20288
- this.chunks = [TextChunkExpression.fromReference(this, refExpression)];
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(this, nodesetExpression);
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(bind, computation, expression) {
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(bind, bindComputationResultTypes[computation], resolvedExpression, {
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(bind, computation, expression);
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 expression = TextChunkExpression.fromTranslation(this, message);
21198
- if (expression != null) {
21199
- this.chunks = [expression];
21326
+ const translationChunk = TextChunkExpression.fromTranslation(message);
21327
+ if (translationChunk) {
21328
+ this.chunks = [translationChunk];
21200
21329
  } else {
21201
- this.chunks = [TextChunkExpression.fromLiteral(this, message)];
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(bodyElement, countExpression);
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(bodyElement, fixedCountExpression);
26202
+ return new this(fixedCountExpression);
26074
26203
  }
26075
26204
  return null;
26076
26205
  }
26077
- constructor(context, expression) {
26078
- super(context, "number", expression);
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, chunkExpressions) => {
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
- if (typeof computed === "string") {
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.chunks);
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 {