@getodk/xpath 0.2.1 → 0.3.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 (100) hide show
  1. package/dist/.vite/manifest.json +4 -4
  2. package/dist/adapter/WHAT/WHATNode.d.ts +30 -0
  3. package/dist/adapter/WHAT/kind.d.ts +11 -0
  4. package/dist/adapter/WHAT/names.d.ts +6 -0
  5. package/dist/adapter/WHAT/optimizations.d.ts +37 -0
  6. package/dist/adapter/WHAT/platform.d.ts +6 -0
  7. package/dist/adapter/WHAT/traversal.d.ts +14 -0
  8. package/dist/adapter/WHAT/values.d.ts +2 -0
  9. package/dist/adapter/WHAT/whatDOMAdapter.d.ts +5 -0
  10. package/dist/adapter/defaults.d.ts +26 -0
  11. package/dist/adapter/interface/XPathCustomUnwrappableNode.d.ts +55 -0
  12. package/dist/adapter/interface/XPathDOMAdapter.d.ts +16 -0
  13. package/dist/adapter/interface/XPathDOMOptimizableOperations.d.ts +13 -0
  14. package/dist/adapter/interface/XPathNameAdapter.d.ts +23 -0
  15. package/dist/adapter/interface/XPathNode.d.ts +164 -0
  16. package/dist/adapter/interface/XPathNodeKindAdapter.d.ts +15 -0
  17. package/dist/adapter/interface/XPathTraversalAdapter.d.ts +38 -0
  18. package/dist/adapter/interface/XPathValueAdapter.d.ts +9 -0
  19. package/dist/adapter/xpathDOMProvider.d.ts +80 -0
  20. package/dist/context/Context.d.ts +12 -9
  21. package/dist/context/EvaluationContext.d.ts +18 -28
  22. package/dist/error/IncompatibleRuntimeEnvironmentError.d.ts +2 -0
  23. package/dist/evaluations/BooleanEvaluation.d.ts +4 -3
  24. package/dist/evaluations/DateTimeLikeEvaluation.d.ts +4 -3
  25. package/dist/evaluations/Evaluation.d.ts +12 -11
  26. package/dist/evaluations/EvaluationType.d.ts +5 -3
  27. package/dist/evaluations/LocationPathEvaluation.d.ts +44 -67
  28. package/dist/evaluations/NodeEvaluation.d.ts +6 -5
  29. package/dist/evaluations/NumberEvaluation.d.ts +4 -3
  30. package/dist/evaluations/StringEvaluation.d.ts +4 -3
  31. package/dist/evaluations/ValueEvaluation.d.ts +11 -10
  32. package/dist/evaluator/DefaultEvaluator.d.ts +16 -0
  33. package/dist/evaluator/Evaluator.d.ts +32 -25
  34. package/dist/evaluator/NamespaceResolver.d.ts +16 -9
  35. package/dist/evaluator/expression/BinaryExpressionEvaluator.d.ts +2 -1
  36. package/dist/evaluator/expression/BooleanBinaryExpressionEvaluator.d.ts +5 -4
  37. package/dist/evaluator/expression/ExpressionEvaluator.d.ts +2 -1
  38. package/dist/evaluator/expression/FilterPathExpressionEvaluator.d.ts +2 -1
  39. package/dist/evaluator/expression/FunctionCallExpressionEvaluator.d.ts +2 -1
  40. package/dist/evaluator/expression/LocationPathEvaluator.d.ts +2 -1
  41. package/dist/evaluator/expression/LocationPathExpressionEvaluator.d.ts +3 -2
  42. package/dist/evaluator/expression/NumberExpressionEvaluator.d.ts +3 -2
  43. package/dist/evaluator/expression/NumericBinaryExpressionEvaluator.d.ts +2 -1
  44. package/dist/evaluator/expression/StringExpressionEvaluator.d.ts +3 -2
  45. package/dist/evaluator/expression/UnaryExpressionEvaluator.d.ts +2 -1
  46. package/dist/evaluator/expression/UnionExpressionEvaluator.d.ts +2 -1
  47. package/dist/evaluator/functions/BooleanFunction.d.ts +2 -2
  48. package/dist/evaluator/functions/FunctionAlias.d.ts +2 -2
  49. package/dist/evaluator/functions/FunctionImplementation.d.ts +14 -13
  50. package/dist/evaluator/functions/FunctionLibrary.d.ts +6 -5
  51. package/dist/evaluator/functions/FunctionLibraryCollection.d.ts +3 -2
  52. package/dist/evaluator/functions/NodeSetFunction.d.ts +4 -3
  53. package/dist/evaluator/functions/NumberFunction.d.ts +2 -2
  54. package/dist/evaluator/functions/StringFunction.d.ts +2 -2
  55. package/dist/evaluator/functions/TypedFunctionImplementation.d.ts +5 -3
  56. package/dist/evaluator/result/BaseResult.d.ts +13 -9
  57. package/dist/evaluator/result/BooleanResult.d.ts +5 -5
  58. package/dist/evaluator/result/NodeSetResult.d.ts +28 -32
  59. package/dist/evaluator/result/NumberResult.d.ts +5 -5
  60. package/dist/evaluator/result/PrimitiveResult.d.ts +7 -7
  61. package/dist/evaluator/result/StringResult.d.ts +5 -5
  62. package/dist/evaluator/result/XPathEvaluationResult.d.ts +61 -0
  63. package/dist/evaluator/result/toXPathEvaluationResult.d.ts +5 -0
  64. package/dist/evaluator/step/Step.d.ts +1 -1
  65. package/dist/{expressionParser-BVz9yCmv.js → expressionParser-DpqfmhIO.js} +1 -4
  66. package/dist/{expressionParser-BVz9yCmv.js.map → expressionParser-DpqfmhIO.js.map} +1 -1
  67. package/dist/expressionParser.js +1 -1
  68. package/dist/functions/_shared/number.d.ts +5 -4
  69. package/dist/functions/_shared/string.d.ts +2 -1
  70. package/dist/functions/fn/boolean.d.ts +5 -5
  71. package/dist/functions/fn/node-set.d.ts +8 -8
  72. package/dist/functions/fn/number.d.ts +5 -5
  73. package/dist/functions/fn/string.d.ts +10 -10
  74. package/dist/functions/javarosa/string.d.ts +8 -1
  75. package/dist/functions/xforms/boolean.d.ts +4 -4
  76. package/dist/functions/xforms/datetime.d.ts +7 -7
  77. package/dist/functions/xforms/geo.d.ts +2 -2
  78. package/dist/functions/xforms/node-set.d.ts +16 -6
  79. package/dist/functions/xforms/number.d.ts +21 -21
  80. package/dist/functions/xforms/select.d.ts +3 -3
  81. package/dist/functions/xforms/string.d.ts +8 -8
  82. package/dist/index.d.ts +44 -1
  83. package/dist/index.js +1310 -879
  84. package/dist/index.js.map +1 -1
  85. package/dist/xforms/XFormsElementRepresentation.d.ts +15 -0
  86. package/dist/xforms/XFormsItextTranslations.d.ts +75 -23
  87. package/dist/xforms/XFormsSecondaryInstances.d.ts +4 -0
  88. package/dist/xforms/XFormsXPathEvaluator.d.ts +35 -14
  89. package/package.json +5 -3
  90. package/dist/evaluator/result/ResultType.d.ts +0 -13
  91. package/dist/evaluator/result/index.d.ts +0 -7
  92. package/dist/lib/dom/assertions.d.ts +0 -4
  93. package/dist/lib/dom/predicates.d.ts +0 -11
  94. package/dist/lib/dom/sort.d.ts +0 -1
  95. package/dist/lib/dom/traversal.d.ts +0 -21
  96. package/dist/lib/dom/types.d.ts +0 -21
  97. package/dist/lib/dom/xml.d.ts +0 -1
  98. package/dist/shared/constants.d.ts +0 -13
  99. package/dist/shared/index.d.ts +0 -2
  100. package/dist/shared/interface.d.ts +0 -33
package/dist/index.js CHANGED
@@ -1,21 +1,21 @@
1
- import { c as commonjsGlobal, U as UpsertableMap, e as expressionParser, g as getAugmentedNamespace, a as getDefaultExportFromCjs } from './expressionParser-BVz9yCmv.js';
1
+ import { c as commonjsGlobal, U as UpsertableMap, e as expressionParser, g as getAugmentedNamespace, a as getDefaultExportFromCjs } from './expressionParser-DpqfmhIO.js';
2
2
 
3
3
  function _mergeNamespaces(n, m) {
4
- for (var i = 0; i < m.length; i++) {
5
- const e = m[i];
6
- if (typeof e !== 'string' && !Array.isArray(e)) { for (const k in e) {
7
- if (k !== 'default' && !(k in n)) {
8
- const d = Object.getOwnPropertyDescriptor(e, k);
9
- if (d) {
10
- Object.defineProperty(n, k, d.get ? d : {
11
- enumerable: true,
12
- get: () => e[k]
13
- });
14
- }
15
- }
16
- } }
17
- }
18
- return Object.freeze(Object.defineProperty(n, Symbol.toStringTag, { value: 'Module' }));
4
+ for (var i = 0; i < m.length; i++) {
5
+ const e = m[i];
6
+ if (typeof e !== 'string' && !Array.isArray(e)) { for (const k in e) {
7
+ if (k !== 'default' && !(k in n)) {
8
+ const d = Object.getOwnPropertyDescriptor(e, k);
9
+ if (d) {
10
+ Object.defineProperty(n, k, d.get ? d : {
11
+ enumerable: true,
12
+ get: () => e[k]
13
+ });
14
+ }
15
+ }
16
+ } }
17
+ }
18
+ return Object.freeze(Object.defineProperty(n, Symbol.toStringTag, { value: 'Module' }));
19
19
  }
20
20
 
21
21
  const t = {};
@@ -7952,35 +7952,6 @@ for (const e of Zt) {
7952
7952
  (t.configurable || t.enumerable || t.writable) && (t.configurable = !1, t.enumerable = !1, t.writable = !1, Object.defineProperty(e, "prototype", t));
7953
7953
  }
7954
7954
 
7955
- class UnreachableError extends Error {
7956
- constructor(unrechable, additionalDetail) {
7957
- let message = `Unreachable value: ${JSON.stringify(unrechable)}`;
7958
- if (additionalDetail != null) {
7959
- message = `${message} (${additionalDetail})`;
7960
- }
7961
- super(message);
7962
- }
7963
- }
7964
-
7965
- const identity = (value) => value;
7966
-
7967
- const {
7968
- ATTRIBUTE_NODE,
7969
- CDATA_SECTION_NODE,
7970
- COMMENT_NODE,
7971
- DOCUMENT_NODE,
7972
- DOCUMENT_FRAGMENT_NODE,
7973
- ELEMENT_NODE,
7974
- PROCESSING_INSTRUCTION_NODE,
7975
- TEXT_NODE
7976
- } = Node;
7977
- const isAttributeNode = (node) => node.nodeType === ATTRIBUTE_NODE;
7978
- const isNamespaceAttribute = (attr) => attr.name === "xmlns" || attr.prefix === "xmlns";
7979
- const isNamespaceNode = (node) => isAttributeNode(node) && (node.name === "xmlns" || node.prefix === "xmlns");
7980
- const isDocumentNode = (node) => node.nodeType === DOCUMENT_NODE;
7981
- const isElementNode = (node) => node.nodeType === ELEMENT_NODE;
7982
- const isProcessingInstructionNode = (node) => node.nodeType === PROCESSING_INSTRUCTION_NODE;
7983
-
7984
7955
  var transform = {};
7985
7956
 
7986
7957
  var exceptions = {};
@@ -21440,14 +21411,6 @@ function* toIterableIterator(iter) {
21440
21411
  }
21441
21412
  }
21442
21413
  }
21443
- const map$1 = (fn) => (
21444
- // eslint-disable-next-line @typescript-eslint/no-shadow -- naming the function is helpful in stack traces/debugging
21445
- function* map2(iterable) {
21446
- for (const item of toIterableIterator(iterable)) {
21447
- yield fn(item);
21448
- }
21449
- }
21450
- );
21451
21414
  const filter = (guard) => (
21452
21415
  // eslint-disable-next-line @typescript-eslint/no-shadow -- naming the function is helpful in stack traces/debugging
21453
21416
  function* filter2(iterable) {
@@ -21472,6 +21435,228 @@ const tee = (input) => {
21472
21435
  return transformExports.tee(input, 2);
21473
21436
  };
21474
21437
 
21438
+ const extendNodeKindGuards = (base) => {
21439
+ const assertXPathNode = (value, message = "Invalid context node") => {
21440
+ if (!base.isXPathNode(value)) {
21441
+ throw new Error(message);
21442
+ }
21443
+ };
21444
+ const isParentNode = (value) => {
21445
+ const kind = base.getNodeKind(value);
21446
+ return kind === "document" || kind === "element";
21447
+ };
21448
+ const extensions = {
21449
+ assertXPathNode,
21450
+ assertParentNode: (value, message = "Invalid parent node") => {
21451
+ assertXPathNode(value);
21452
+ if (!isParentNode(value)) {
21453
+ throw new Error(message);
21454
+ }
21455
+ },
21456
+ isDocument: (node) => {
21457
+ return base.getNodeKind(node) === "document";
21458
+ },
21459
+ isElement: (node) => {
21460
+ return base.getNodeKind(node) === "element";
21461
+ },
21462
+ isNamespaceDeclaration: (node) => {
21463
+ return base.getNodeKind(node) === "namespace_declaration";
21464
+ },
21465
+ isAttribute: (node) => {
21466
+ return base.getNodeKind(node) === "attribute";
21467
+ },
21468
+ isText: (node) => {
21469
+ return base.getNodeKind(node) === "text";
21470
+ },
21471
+ isComment: (node) => {
21472
+ return base.getNodeKind(node) === "comment";
21473
+ },
21474
+ isProcessingInstruction: (node) => {
21475
+ return base.getNodeKind(node) === "processing_instruction";
21476
+ },
21477
+ isParentNode,
21478
+ isQualifiedNamedNode: (node) => {
21479
+ const kind = base.getNodeKind(node);
21480
+ return kind === "element" || kind === "attribute";
21481
+ }
21482
+ };
21483
+ return Object.assign(base, extensions);
21484
+ };
21485
+ const extendIterableOperations = (base) => {
21486
+ const extensions = {
21487
+ filterAttributes: filter(base.isAttribute),
21488
+ filterQualifiedNamedNodes: filter(base.isQualifiedNamedNode),
21489
+ filterComments: filter(base.isComment),
21490
+ filterNamespaceDeclarations: filter(base.isNamespaceDeclaration),
21491
+ filterProcessingInstructions: filter(base.isProcessingInstruction),
21492
+ filterTextNodes: filter(base.isText),
21493
+ sortInDocumentOrder: (nodes) => {
21494
+ return Array.from(nodes).sort((a, b) => base.compareDocumentOrder(a, b));
21495
+ }
21496
+ };
21497
+ return Object.assign(base, extensions);
21498
+ };
21499
+ const getElementByUniqueIdFactory = (adapter, getNamedAttributeValue) => {
21500
+ const adapterImplementation = adapter.getElementByUniqueId?.bind(adapter);
21501
+ if (adapterImplementation != null) {
21502
+ return adapterImplementation;
21503
+ }
21504
+ function* getElementDescendants(node) {
21505
+ if (adapter.isElement(node)) {
21506
+ yield node;
21507
+ }
21508
+ for (const element of adapter.getChildElements(node)) {
21509
+ yield element;
21510
+ yield* getElementDescendants(element);
21511
+ }
21512
+ }
21513
+ return (node, id) => {
21514
+ const containingDocument = adapter.getContainingDocument(node);
21515
+ for (const element of getElementDescendants(containingDocument)) {
21516
+ if (getNamedAttributeValue(element, "id") === id) {
21517
+ return element;
21518
+ }
21519
+ }
21520
+ return null;
21521
+ };
21522
+ };
21523
+ const getQualifiedNamedAttributeValueFactory = (adapter) => {
21524
+ const adapterImplementation = adapter.getQualifiedNamedAttributeValue?.bind(adapter);
21525
+ if (adapterImplementation != null) {
21526
+ return adapterImplementation;
21527
+ }
21528
+ return (node, namespaceURI, localName) => {
21529
+ const attributes = adapter.getAttributes(node);
21530
+ for (const attribute of attributes) {
21531
+ if (adapter.getNamespaceURI(attribute) === namespaceURI && adapter.getLocalName(attribute) === localName) {
21532
+ return adapter.getNodeValue(attribute);
21533
+ }
21534
+ }
21535
+ return null;
21536
+ };
21537
+ };
21538
+ const getLocalNamedAttributeValueFactory = (adapter) => {
21539
+ const adapterImplementation = adapter.getLocalNamedAttributeValue?.bind(adapter);
21540
+ if (adapterImplementation != null) {
21541
+ return adapterImplementation;
21542
+ }
21543
+ return (node, localName) => {
21544
+ const attributes = adapter.getAttributes(node);
21545
+ for (const attribute of attributes) {
21546
+ if (adapter.getLocalName(attribute) === localName) {
21547
+ return adapter.getNodeValue(attribute);
21548
+ }
21549
+ }
21550
+ return null;
21551
+ };
21552
+ };
21553
+ const hasLocalNamedAttributeFactory = (adapter, lookup) => {
21554
+ const adapterImplementation = adapter.hasLocalNamedAttribute?.bind(adapter);
21555
+ if (adapterImplementation != null) {
21556
+ return adapterImplementation;
21557
+ }
21558
+ return (node, localName) => {
21559
+ return lookup(node, localName) != null;
21560
+ };
21561
+ };
21562
+ const getChildrenByLocalNameFactory = (adapter) => {
21563
+ const adapterImplementation = adapter.getChildrenByLocalName?.bind(adapter);
21564
+ if (adapterImplementation != null) {
21565
+ return adapterImplementation;
21566
+ }
21567
+ return (node, localName) => {
21568
+ return Array.from(adapter.getChildElements(node)).filter((element) => {
21569
+ return adapter.getLocalName(element) === localName;
21570
+ });
21571
+ };
21572
+ };
21573
+ const getFirstChildNodeFactory = (adapter) => {
21574
+ const adapterImplementation = adapter.getFirstChildNode?.bind(adapter);
21575
+ if (adapterImplementation != null) {
21576
+ return adapterImplementation;
21577
+ }
21578
+ return (node) => {
21579
+ const [childNode] = adapter.getChildNodes(node);
21580
+ return childNode ?? null;
21581
+ };
21582
+ };
21583
+ const getLastChildNodeFactory = (adapter) => {
21584
+ const adapterImplementation = adapter.getLastChildNode?.bind(adapter);
21585
+ if (adapterImplementation != null) {
21586
+ return adapterImplementation;
21587
+ }
21588
+ return (node) => {
21589
+ return Array.from(adapter.getChildNodes(node)).at(-1) ?? null;
21590
+ };
21591
+ };
21592
+ const getFirstChildElementFactory = (adapter) => {
21593
+ const adapterImplementation = adapter.getFirstChildElement?.bind(adapter);
21594
+ if (adapterImplementation != null) {
21595
+ return adapterImplementation;
21596
+ }
21597
+ return (node) => {
21598
+ const [childElement] = adapter.getChildElements(node);
21599
+ return childElement ?? null;
21600
+ };
21601
+ };
21602
+ const getLastChildElementFactory = (adapter) => {
21603
+ const adapterImplementation = adapter.getLastChildElement?.bind(adapter);
21604
+ if (adapterImplementation != null) {
21605
+ return adapterImplementation;
21606
+ }
21607
+ return (node) => {
21608
+ return Array.from(adapter.getChildElements(node)).at(-1) ?? null;
21609
+ };
21610
+ };
21611
+ const extendOptimizableOperations = (base) => {
21612
+ const getLocalNamedAttributeValue = getLocalNamedAttributeValueFactory(base);
21613
+ const extensions = {
21614
+ getElementByUniqueId: getElementByUniqueIdFactory(base, getLocalNamedAttributeValue),
21615
+ getQualifiedNamedAttributeValue: getQualifiedNamedAttributeValueFactory(base),
21616
+ getLocalNamedAttributeValue,
21617
+ hasLocalNamedAttribute: hasLocalNamedAttributeFactory(base, getLocalNamedAttributeValue),
21618
+ getChildrenByLocalName: getChildrenByLocalNameFactory(base),
21619
+ getFirstChildNode: getFirstChildNodeFactory(base),
21620
+ getFirstChildElement: getFirstChildElementFactory(base),
21621
+ getLastChildNode: getLastChildNodeFactory(base),
21622
+ getLastChildElement: getLastChildElementFactory(base)
21623
+ };
21624
+ return Object.assign(base, extensions);
21625
+ };
21626
+ const DERIVED_DOM_PROVIDER = Symbol("DERIVED_DOM_PROVIDER");
21627
+ const derivedDOMProvider = (base) => {
21628
+ return Object.assign({}, base, {
21629
+ [DERIVED_DOM_PROVIDER]: true
21630
+ });
21631
+ };
21632
+ const isXPathDOMProvider = (adapter) => {
21633
+ return DERIVED_DOM_PROVIDER in adapter && adapter[DERIVED_DOM_PROVIDER] === true;
21634
+ };
21635
+ const xpathDOMProvider = (adapter) => {
21636
+ if (isXPathDOMProvider(adapter)) {
21637
+ console.warn(
21638
+ "Repeat call to xpathDOMProvider: provider has already been derived from provided adapter"
21639
+ );
21640
+ return adapter;
21641
+ }
21642
+ const extendedGuards = extendNodeKindGuards(adapter);
21643
+ const extendedIterableOperations = extendIterableOperations(extendedGuards);
21644
+ const exended = extendOptimizableOperations(extendedIterableOperations);
21645
+ return derivedDOMProvider(exended);
21646
+ };
21647
+
21648
+ class UnreachableError extends Error {
21649
+ constructor(unrechable, additionalDetail) {
21650
+ let message = `Unreachable value: ${JSON.stringify(unrechable)}`;
21651
+ if (additionalDetail != null) {
21652
+ message = `${message} (${additionalDetail})`;
21653
+ }
21654
+ super(message);
21655
+ }
21656
+ }
21657
+
21658
+ const identity = (value) => value;
21659
+
21475
21660
  class Reiterable {
21476
21661
  constructor(source) {
21477
21662
  this.source = source;
@@ -21691,7 +21876,7 @@ class NodeEvaluation extends ValueEvaluation {
21691
21876
  let { computedValues } = this;
21692
21877
  if (computedValues == null) {
21693
21878
  const { context, value: node } = this;
21694
- const stringValue = node.textContent ?? "";
21879
+ const stringValue = context.domProvider.getNodeValue(node);
21695
21880
  const isEmpty = trimXMLXPathWhitespace(stringValue) === "";
21696
21881
  const booleanValue = !isEmpty;
21697
21882
  const numberFunction = context.functions.getDefaultImplementation("number");
@@ -21720,32 +21905,244 @@ class NodeEvaluation extends ValueEvaluation {
21720
21905
  }
21721
21906
  }
21722
21907
 
21908
+ function* concat$2(...iterables) {
21909
+ for (const iterable of iterables) {
21910
+ yield* iterable;
21911
+ }
21912
+ }
21913
+ function* flatMapNodeSets(contextNodes, fn) {
21914
+ for (const contextNode of contextNodes) {
21915
+ yield* fn(contextNode);
21916
+ }
21917
+ }
21723
21918
  function* toNodeEvaluations(context, nodes) {
21724
21919
  for (const node of nodes) {
21725
21920
  yield new NodeEvaluation(context, node);
21726
21921
  }
21727
21922
  }
21728
- const filterNamespace = filter(isNamespaceAttribute);
21729
- const filterNonNamespace = filter((attr) => !isNamespaceAttribute(attr));
21730
- const filterNonAttribute = filter((node) => !isAttributeNode(node));
21731
- const axisNameToMethod = {
21732
- ["ancestor" /* ANCESTOR */]: "ancestor",
21733
- ["ancestor-or-self" /* ANCESTOR_OR_SELF */]: "ancestorOrSelf",
21734
- ["attribute" /* ATTRIBUTE */]: "attribute",
21735
- ["child" /* CHILD */]: "child",
21736
- ["descendant" /* DESCENDANT */]: "descendant",
21737
- ["descendant-or-self" /* DESCENDANT_OR_SELF */]: "descendantOrSelf",
21738
- ["following" /* FOLLOWING */]: "following",
21739
- ["following-sibling" /* FOLLOWING_SIBLING */]: "followingSibling",
21740
- ["namespace" /* NAMESPACE */]: "namespace",
21741
- ["parent" /* PARENT */]: "parent",
21742
- ["preceding" /* PRECEDING */]: "preceding",
21743
- ["preceding-sibling" /* PRECEDING_SIBLING */]: "precedingSibling",
21744
- ["self" /* SELF */]: "self"
21923
+ const getNodeTypeFilter = (domProvider, step) => {
21924
+ switch (step.axisType) {
21925
+ case "attribute":
21926
+ return domProvider.filterAttributes;
21927
+ case "namespace":
21928
+ return domProvider.filterNamespaceDeclarations;
21929
+ }
21930
+ switch (step.nodeType) {
21931
+ case "__NAMED__":
21932
+ return domProvider.filterQualifiedNamedNodes;
21933
+ case "processing-instruction":
21934
+ return domProvider.filterProcessingInstructions;
21935
+ case "comment":
21936
+ return domProvider.filterComments;
21937
+ case "node":
21938
+ return identity;
21939
+ case "text":
21940
+ return domProvider.filterTextNodes;
21941
+ default:
21942
+ throw new UnreachableError(step);
21943
+ }
21944
+ };
21945
+ const axisEvaluationContext = (currentContext, contextNode) => {
21946
+ const { domProvider, contextDocument, rootNode, visited } = currentContext;
21947
+ return {
21948
+ domProvider,
21949
+ contextDocument,
21950
+ rootNode,
21951
+ contextNode,
21952
+ visited
21953
+ };
21954
+ };
21955
+ function* siblings(context, methodName) {
21956
+ const method = context.domProvider[methodName];
21957
+ let currentNode = context.contextNode;
21958
+ while (currentNode != null) {
21959
+ currentNode = method(currentNode);
21960
+ if (currentNode != null) {
21961
+ yield currentNode;
21962
+ }
21963
+ }
21964
+ }
21965
+ const getDocumentOrderTraversalContextNode = (domProvider, contextNode) => {
21966
+ if (domProvider.isAttribute(contextNode) || domProvider.isNamespaceDeclaration(contextNode)) {
21967
+ const parentElement = domProvider.getParentNode(contextNode);
21968
+ domProvider.assertParentNode(parentElement);
21969
+ return parentElement;
21970
+ }
21971
+ return contextNode;
21972
+ };
21973
+ function* filterValues(iter) {
21974
+ for (const item of iter) {
21975
+ if (item != null) {
21976
+ yield item;
21977
+ }
21978
+ }
21979
+ }
21980
+ function* documentRootPrecedingSiblings(domAdapter, precedingContext, documentRoot, step) {
21981
+ const documentRootContext = axisEvaluationContext(precedingContext, documentRoot);
21982
+ const precedingSiblings = axisEvaluators["preceding-sibling"](documentRootContext, step);
21983
+ for (const node of precedingSiblings) {
21984
+ try {
21985
+ if (domAdapter.getNodeKind(node) != null) {
21986
+ yield node;
21987
+ }
21988
+ } catch {
21989
+ }
21990
+ }
21991
+ }
21992
+ const axisEvaluators = {
21993
+ ancestor: function* ancestor(context, step) {
21994
+ const { rootNode } = context;
21995
+ const parentNodes = axisEvaluators.parent(context, step);
21996
+ for (const parentNode of parentNodes) {
21997
+ if (parentNode !== rootNode) {
21998
+ const parentContext = axisEvaluationContext(context, parentNode);
21999
+ yield* axisEvaluators.ancestor(parentContext, step);
22000
+ }
22001
+ yield parentNode;
22002
+ }
22003
+ },
22004
+ "ancestor-or-self": function* ancestorOrSelf(context, step) {
22005
+ const { contextNode } = context;
22006
+ const isNamedStep = step.stepType !== "NodeTypeTest";
22007
+ const currentContext = axisEvaluationContext(context, contextNode);
22008
+ yield* axisEvaluators.ancestor(currentContext, step);
22009
+ if (!isNamedStep || context.domProvider.isElement(contextNode)) {
22010
+ yield contextNode;
22011
+ }
22012
+ },
22013
+ attribute: (context) => {
22014
+ return context.domProvider.getAttributes(context.contextNode);
22015
+ },
22016
+ child: (context, step) => {
22017
+ const { contextNode, domProvider } = context;
22018
+ if (step.nodeType === "__NAMED__") {
22019
+ return domProvider.getChildElements(contextNode);
22020
+ }
22021
+ return domProvider.getChildNodes(contextNode);
22022
+ },
22023
+ descendant: function* descendant(context, step) {
22024
+ for (const childNode of axisEvaluators.child(context, step)) {
22025
+ yield childNode;
22026
+ const childContext = axisEvaluationContext(context, childNode);
22027
+ yield* axisEvaluators.descendant(childContext, step);
22028
+ }
22029
+ },
22030
+ "descendant-or-self": function* descendantOrSelf(context, step) {
22031
+ const { contextNode } = context;
22032
+ yield contextNode;
22033
+ const selfContext = axisEvaluationContext(context, contextNode);
22034
+ yield* axisEvaluators.descendant(selfContext, step);
22035
+ },
22036
+ following: function* following(context, step) {
22037
+ const { domProvider, contextDocument, rootNode } = context;
22038
+ const contextNode = getDocumentOrderTraversalContextNode(domProvider, context.contextNode);
22039
+ if (context.visited.has(contextNode)) {
22040
+ return;
22041
+ }
22042
+ context.visited.add(contextNode);
22043
+ const parentNode = domProvider.getParentNode(contextNode);
22044
+ if (contextNode === rootNode || parentNode === contextDocument) {
22045
+ return;
22046
+ }
22047
+ let firstChild;
22048
+ let nextSibling = null;
22049
+ if (step.nodeType === "__NAMED__") {
22050
+ firstChild = domProvider.getFirstChildElement(contextNode);
22051
+ nextSibling = domProvider.getNextSiblingElement(contextNode);
22052
+ } else {
22053
+ firstChild = domProvider.getFirstChildNode(contextNode);
22054
+ nextSibling = domProvider.getNextSiblingNode(contextNode);
22055
+ }
22056
+ let currentNodes = filterValues([firstChild, nextSibling]);
22057
+ if (parentNode != null && parentNode !== rootNode) {
22058
+ const followingParentSiblingsContext = axisEvaluationContext(context, parentNode);
22059
+ const followingParentSiblings = axisEvaluators["following-sibling"](
22060
+ followingParentSiblingsContext,
22061
+ step
22062
+ );
22063
+ currentNodes = concat$2(currentNodes, followingParentSiblings);
22064
+ }
22065
+ for (const currentNode of currentNodes) {
22066
+ yield currentNode;
22067
+ const currentContext = axisEvaluationContext(context, currentNode);
22068
+ yield* axisEvaluators.following(currentContext, step);
22069
+ }
22070
+ },
22071
+ "following-sibling": (context, step) => {
22072
+ if (step.nodeType === "__NAMED__") {
22073
+ return siblings(context, "getNextSiblingElement");
22074
+ }
22075
+ return siblings(context, "getNextSiblingNode");
22076
+ },
22077
+ namespace: (context) => {
22078
+ return context.domProvider.getNamespaceDeclarations(context.contextNode);
22079
+ },
22080
+ parent: function* parent(context) {
22081
+ const { rootNode, contextNode } = context;
22082
+ if (contextNode === rootNode) {
22083
+ return;
22084
+ }
22085
+ const parentNode = context.domProvider.getParentNode(contextNode);
22086
+ if (parentNode != null) {
22087
+ yield parentNode;
22088
+ }
22089
+ },
22090
+ preceding: function* preceding(context, step) {
22091
+ const { domProvider, rootNode, contextDocument, visited } = context;
22092
+ const contextNode = getDocumentOrderTraversalContextNode(domProvider, context.contextNode);
22093
+ if (visited.has(contextNode)) {
22094
+ return;
22095
+ }
22096
+ visited.add(contextNode);
22097
+ if (contextNode === rootNode) {
22098
+ return;
22099
+ }
22100
+ const parentNode = domProvider.getParentNode(contextNode);
22101
+ if (parentNode === contextDocument) {
22102
+ yield* documentRootPrecedingSiblings(domProvider, context, contextNode, step);
22103
+ return;
22104
+ }
22105
+ let lastChild;
22106
+ let previousSibling;
22107
+ if (step.nodeType === "__NAMED__") {
22108
+ previousSibling = domProvider.getPreviousSiblingElement(contextNode);
22109
+ lastChild = domProvider.getLastChildElement(contextNode);
22110
+ } else {
22111
+ previousSibling = domProvider.getPreviousSiblingNode(contextNode);
22112
+ lastChild = domProvider.getLastChildNode(contextNode);
22113
+ }
22114
+ if (lastChild === contextNode) {
22115
+ lastChild = null;
22116
+ }
22117
+ let currentNodes = filterValues([lastChild, previousSibling]);
22118
+ if (contextNode !== rootNode && parentNode != null && parentNode !== rootNode) {
22119
+ const precedingParentSiblingsContext = axisEvaluationContext(context, parentNode);
22120
+ const precedingParentSiblings = axisEvaluators["preceding-sibling"](
22121
+ precedingParentSiblingsContext,
22122
+ step
22123
+ );
22124
+ currentNodes = concat$2(currentNodes, precedingParentSiblings);
22125
+ }
22126
+ for (const currentNode of currentNodes) {
22127
+ yield currentNode;
22128
+ const currentContext = axisEvaluationContext(context, currentNode);
22129
+ yield* preceding(currentContext, step);
22130
+ }
22131
+ },
22132
+ "preceding-sibling": (context, step) => {
22133
+ if (step.nodeType === "__NAMED__") {
22134
+ return siblings(context, "getPreviousSiblingElement");
22135
+ }
22136
+ return siblings(context, "getPreviousSiblingNode");
22137
+ },
22138
+ self: function* self(context) {
22139
+ yield context.contextNode;
22140
+ }
21745
22141
  };
21746
22142
  class LocationPathEvaluation {
21747
22143
  constructor(parentContext, contextNodes, options = {}) {
21748
22144
  this.parentContext = parentContext;
22145
+ this.domProvider = parentContext.domProvider;
21749
22146
  const {
21750
22147
  evaluator,
21751
22148
  contextDocument,
@@ -21753,8 +22150,7 @@ class LocationPathEvaluation {
21753
22150
  functions,
21754
22151
  namespaceResolver,
21755
22152
  rootNode,
21756
- timeZone,
21757
- treeWalkers
22153
+ timeZone
21758
22154
  } = parentContext;
21759
22155
  this.evaluator = evaluator;
21760
22156
  this.contextDocument = contextDocument;
@@ -21763,9 +22159,8 @@ class LocationPathEvaluation {
21763
22159
  this.namespaceResolver = namespaceResolver;
21764
22160
  this.rootNode = rootNode;
21765
22161
  this.timeZone = timeZone;
21766
- this.treeWalkers = treeWalkers;
21767
- const [nodes] = tee(distinct(contextNodes));
21768
- this.nodes = nodes;
22162
+ const nodes = distinct(contextNodes);
22163
+ this._nodes = nodes;
21769
22164
  this.nodeEvaluations = Reiterable.from(toNodeEvaluations(this, contextNodes));
21770
22165
  if (options.contextSize != null) {
21771
22166
  this.optionsContextSize = options.contextSize;
@@ -21774,6 +22169,16 @@ class LocationPathEvaluation {
21774
22169
  }
21775
22170
  this.initializedContextPosition = options.contextPosition ?? 1;
21776
22171
  }
22172
+ static isInstance(context, value) {
22173
+ return value instanceof LocationPathEvaluation && value.domProvider === context.domProvider;
22174
+ }
22175
+ static assertInstance = (context, value, message) => {
22176
+ if (!this.isInstance(context, value)) {
22177
+ throw new Error(message ?? "Expected a node-set result");
22178
+ }
22179
+ };
22180
+ // --- DOM adapter/provider ---
22181
+ domProvider;
21777
22182
  // --- Evaluation ---
21778
22183
  type = "NODE";
21779
22184
  nodeEvaluations;
@@ -21786,10 +22191,13 @@ class LocationPathEvaluation {
21786
22191
  evaluationContextNode;
21787
22192
  contextDocument;
21788
22193
  rootNode;
21789
- nodes;
22194
+ _nodes;
22195
+ get nodes() {
22196
+ return this._nodes;
22197
+ }
21790
22198
  get contextNodes() {
21791
- const [nodes, contextNodes] = tee(this.nodes);
21792
- this.nodes = nodes;
22199
+ const [nodes, contextNodes] = tee(this._nodes);
22200
+ this._nodes = nodes;
21793
22201
  return contextNodes;
21794
22202
  }
21795
22203
  computedContextSize = null;
@@ -21797,7 +22205,6 @@ class LocationPathEvaluation {
21797
22205
  initializedContextPosition;
21798
22206
  functions;
21799
22207
  namespaceResolver;
21800
- treeWalkers;
21801
22208
  timeZone;
21802
22209
  /**
21803
22210
  * TODO: this is a temporary accommodation for these cases which are presently
@@ -21939,257 +22346,68 @@ class LocationPathEvaluation {
21939
22346
  gte(operand) {
21940
22347
  return this.compare((lhs, rhs) => lhs.gte(rhs), operand);
21941
22348
  }
21942
- getTreeWalker(step) {
21943
- const { treeWalkers } = this;
21944
- switch (step.nodeType) {
21945
- case "__NAMED__":
21946
- return treeWalkers.ELEMENT;
21947
- case "comment":
21948
- return treeWalkers.COMMENT;
21949
- case "node":
21950
- return treeWalkers.ANY;
21951
- case "processing-instruction":
21952
- return treeWalkers.PROCESSING_INSTRUCTION;
21953
- case "text":
21954
- return treeWalkers.TEXT;
21955
- default:
21956
- throw new UnreachableError(step);
21957
- }
21958
- }
21959
- *ancestor(step) {
21960
- const { rootNode } = this;
21961
- const parents = this.parent(step);
21962
- for (const parent of parents) {
21963
- if (parent !== rootNode) {
21964
- const parentContext = new LocationPathEvaluation(this, [parent]);
21965
- yield* parentContext.ancestor(step);
21966
- }
21967
- yield parent;
21968
- }
21969
- }
21970
- *ancestorOrSelf(step) {
21971
- const isNamedStep = step.stepType !== "NodeTypeTest";
21972
- for (const self of this) {
21973
- yield* self.ancestor(step);
21974
- for (const node of self.contextNodes) {
21975
- if (!isNamedStep || isElementNode(node)) {
21976
- yield node;
21977
- }
21978
- }
21979
- }
21980
- }
21981
- *attribute() {
21982
- for (const node of this.contextNodes) {
21983
- yield* filterNonNamespace(node.attributes ?? []);
21984
- }
21985
- }
21986
- *child(step) {
21987
- const treeWalker = this.getTreeWalker(step);
21988
- for (const node of this.contextNodes) {
21989
- let currentNode = node;
21990
- treeWalker.currentNode = currentNode;
21991
- treeWalker.firstChild();
21992
- do {
21993
- currentNode = treeWalker.currentNode;
21994
- if (currentNode.parentNode === node) {
21995
- yield currentNode;
21996
- treeWalker.currentNode = currentNode;
21997
- }
21998
- } while (treeWalker.nextSibling() != null);
21999
- }
22000
- }
22001
- *descendant(step) {
22002
- const treeWalker = this.getTreeWalker(step);
22003
- for (const node of this.contextNodes) {
22004
- treeWalker.currentNode = node;
22005
- if (treeWalker.firstChild() == null) {
22006
- continue;
22007
- }
22008
- do {
22009
- const { currentNode } = treeWalker;
22010
- if (!node.contains(currentNode)) {
22011
- break;
22012
- }
22013
- yield currentNode;
22014
- treeWalker.currentNode = currentNode;
22015
- } while (treeWalker.nextNode() != null);
22016
- }
22017
- }
22018
- *descendantOrSelf(step) {
22019
- for (const self of this) {
22020
- yield* self.contextNodes;
22021
- yield* self.descendant(step);
22022
- }
22023
- }
22024
- *following(step) {
22025
- const contextNodes = map$1((node) => node.ownerElement ?? node)(
22026
- this.contextNodes
22027
- );
22028
- const treeWalker = this.getTreeWalker(step);
22029
- const visited = /* @__PURE__ */ new WeakSet();
22030
- for (const node of contextNodes) {
22031
- const { nextSibling } = node;
22032
- if (nextSibling == null) {
22033
- continue;
22034
- }
22035
- treeWalker.currentNode = nextSibling;
22036
- do {
22037
- const { currentNode } = treeWalker;
22038
- if (visited.has(currentNode)) {
22039
- continue;
22040
- }
22041
- visited.add(currentNode);
22042
- yield currentNode;
22043
- treeWalker.currentNode = currentNode;
22044
- } while (treeWalker.nextNode() != null);
22045
- }
22046
- }
22047
- *followingSibling(step) {
22048
- const visited = /* @__PURE__ */ new WeakSet();
22049
- const treeWalker = this.getTreeWalker(step);
22050
- for (const node of this.contextNodes) {
22051
- const { nextSibling } = node;
22052
- if (nextSibling == null) {
22053
- continue;
22054
- }
22055
- const { parentNode } = node;
22056
- treeWalker.currentNode = nextSibling;
22057
- do {
22058
- const { currentNode } = treeWalker;
22059
- if (visited.has(currentNode) || currentNode.parentNode !== parentNode) {
22060
- continue;
22061
- }
22062
- visited.add(currentNode);
22063
- yield currentNode;
22064
- treeWalker.currentNode = currentNode;
22065
- } while (treeWalker.nextSibling() != null);
22066
- }
22067
- }
22068
- *namespace() {
22069
- for (const node of this.contextNodes) {
22070
- yield* filterNamespace(node.attributes ?? []);
22071
- }
22072
- }
22073
- *parent(step) {
22074
- const { contextNodes, rootNode } = this;
22075
- const treeWalker = this.getTreeWalker(step);
22076
- for (const node of contextNodes) {
22077
- const contextNode = node.ownerElement ?? node;
22078
- if (contextNode === rootNode) {
22079
- continue;
22080
- }
22081
- if (contextNode !== node) {
22082
- yield contextNode;
22083
- continue;
22084
- }
22085
- treeWalker.currentNode = contextNode;
22086
- const parentNode = treeWalker.parentNode();
22087
- if (parentNode != null) {
22088
- yield parentNode;
22089
- treeWalker.currentNode = parentNode;
22090
- }
22091
- }
22092
- }
22093
- *preceding(step) {
22094
- const { rootNode } = this;
22095
- const { nodeType = null } = step;
22096
- const treeWalker = this.getTreeWalker(step);
22097
- treeWalker.currentNode = rootNode;
22098
- if (nodeType != null && nodeType !== "node") {
22099
- treeWalker.nextNode();
22100
- treeWalker.previousNode();
22101
- }
22102
- for (const node of this.contextNodes) {
22103
- const contextNode = node.ownerElement ?? node;
22104
- do {
22105
- const { currentNode } = treeWalker;
22106
- if (currentNode.contains(contextNode)) {
22107
- continue;
22108
- }
22109
- if (currentNode === contextNode || (contextNode.compareDocumentPosition(currentNode) & Node.DOCUMENT_POSITION_PRECEDING) === 0) {
22110
- break;
22111
- }
22112
- yield currentNode;
22113
- treeWalker.currentNode = currentNode;
22114
- } while (treeWalker.nextNode() != null);
22115
- }
22116
- }
22117
- *precedingSibling(step) {
22118
- const { nodeType = null } = step;
22119
- const treeWalker = this.getTreeWalker(step);
22120
- let parentNode = null;
22121
- for (const node of filterNonAttribute(this.contextNodes)) {
22122
- const currentParentNode = node.parentNode;
22123
- if (currentParentNode == null) {
22124
- continue;
22125
- }
22126
- if (currentParentNode !== parentNode) {
22127
- parentNode = currentParentNode;
22128
- treeWalker.currentNode = parentNode.firstChild;
22129
- if (nodeType != null && nodeType !== "node") {
22130
- treeWalker.nextSibling();
22131
- treeWalker.previousSibling();
22132
- }
22133
- }
22134
- do {
22135
- const { currentNode } = treeWalker;
22136
- if (currentNode === node) {
22137
- break;
22138
- }
22139
- yield currentNode;
22140
- treeWalker.currentNode = currentNode;
22141
- } while (treeWalker.nextSibling() != null);
22142
- }
22143
- }
22144
- *self() {
22145
- yield* this.contextNodes;
22146
- }
22147
22349
  step(step) {
22148
- let nodesFilter = identity;
22149
- const { namespaceResolver } = this;
22350
+ const { domProvider, namespaceResolver } = this;
22351
+ let nodesFilter;
22150
22352
  switch (step.stepType) {
22151
22353
  case "NodeTypeTest":
22354
+ case "UnqualifiedWildcardTest":
22355
+ nodesFilter = getNodeTypeFilter(domProvider, step);
22152
22356
  break;
22153
22357
  case "NodeNameTest": {
22154
22358
  const { nodeName } = step;
22155
22359
  const nullNamespaceURI = namespaceResolver.lookupNamespaceURI(null);
22156
22360
  nodesFilter = filter((node) => {
22157
- const { namespaceURI } = node;
22158
- return node.localName === nodeName && (namespaceURI == null || namespaceURI === nullNamespaceURI);
22361
+ if (!domProvider.isQualifiedNamedNode(node)) {
22362
+ return false;
22363
+ }
22364
+ const namespaceURI = domProvider.getNamespaceURI(node);
22365
+ return domProvider.getLocalName(node) === nodeName && (namespaceURI == null || namespaceURI === nullNamespaceURI);
22159
22366
  });
22160
22367
  break;
22161
22368
  }
22162
22369
  case "ProcessingInstructionNameTest": {
22163
22370
  const { processingInstructionName } = step;
22164
22371
  nodesFilter = filter((node) => {
22165
- return node.nodeName === processingInstructionName;
22372
+ return domProvider.isProcessingInstruction(node) && domProvider.getProcessingInstructionName(node) === processingInstructionName;
22166
22373
  });
22167
22374
  break;
22168
22375
  }
22169
22376
  case "QualifiedNameTest": {
22170
22377
  const { prefix, localName } = step;
22171
22378
  const namespaceURI = namespaceResolver.lookupNamespaceURI(prefix);
22172
- nodesFilter = filter(
22173
- (node) => node.localName === localName && node.namespaceURI === namespaceURI
22174
- );
22379
+ nodesFilter = filter((node) => {
22380
+ return domProvider.isQualifiedNamedNode(node) && domProvider.getLocalName(node) === localName && domProvider.getNamespaceURI(node) === namespaceURI;
22381
+ });
22175
22382
  break;
22176
22383
  }
22177
22384
  case "QualifiedWildcardTest": {
22178
22385
  const { prefix } = step;
22179
22386
  const namespaceURI = namespaceResolver.lookupNamespaceURI(prefix);
22180
- nodesFilter = filter(
22181
- (node) => node.namespaceURI === namespaceURI
22182
- );
22387
+ nodesFilter = filter((node) => {
22388
+ return domProvider.isQualifiedNamedNode(node) && domProvider.getNamespaceURI(node) === namespaceURI;
22389
+ });
22183
22390
  break;
22184
22391
  }
22185
- case "UnqualifiedWildcardTest":
22186
- break;
22187
22392
  default:
22188
22393
  throw new UnreachableError(step);
22189
22394
  }
22190
22395
  const { axisType } = step;
22191
- const axisMethod = axisNameToMethod[axisType];
22192
- const nodes = nodesFilter(this[axisMethod](step));
22396
+ const axisEvaluator = axisEvaluators[axisType];
22397
+ const context = {
22398
+ domProvider: this.domProvider,
22399
+ rootNode: this.rootNode,
22400
+ contextDocument: this.contextDocument,
22401
+ visited: /* @__PURE__ */ new WeakSet()
22402
+ };
22403
+ let nodes = flatMapNodeSets(this.contextNodes, function* (contextNode) {
22404
+ const currentContext = axisEvaluationContext(context, contextNode);
22405
+ const axisNodes = axisEvaluator(currentContext, step);
22406
+ yield* nodesFilter(axisNodes);
22407
+ });
22408
+ if (axisType === "preceding" || axisType === "preceding-sibling") {
22409
+ nodes = this.domProvider.sortInDocumentOrder(nodes);
22410
+ }
22193
22411
  return new LocationPathEvaluation(this, nodes);
22194
22412
  }
22195
22413
  evaluateLocationPathExpression(expression) {
@@ -22241,18 +22459,36 @@ const staticNamespaces = new StaticNamespaces("xf", XFORMS_NAMESPACE_URI, {
22241
22459
  });
22242
22460
  const namespaceURIs = new UpsertableMap();
22243
22461
  class NamespaceResolver {
22244
- constructor(rootNode, referenceNode) {
22462
+ constructor(domProvider, rootNode, referenceNode, contextResolver) {
22463
+ this.domProvider = domProvider;
22245
22464
  this.rootNode = rootNode;
22246
22465
  this.referenceNode = referenceNode;
22247
- this.contextResolver = referenceNode ?? rootNode;
22466
+ const contextResolverNode = referenceNode ?? rootNode;
22467
+ if (contextResolver == null) {
22468
+ this.contextResolver = (prefix) => {
22469
+ return domProvider.resolveNamespaceURI(contextResolverNode, prefix);
22470
+ };
22471
+ } else if (typeof contextResolver === "function") {
22472
+ this.contextResolver = contextResolver;
22473
+ } else {
22474
+ this.contextResolver = (prefix) => contextResolver.lookupNamespaceURI(prefix);
22475
+ }
22476
+ }
22477
+ static isInstance(rootNode, value) {
22478
+ return value instanceof NamespaceResolver && value.rootNode === rootNode;
22479
+ }
22480
+ static from(domProvider, rootNode, referenceNode, contextResolver) {
22481
+ if (this.isInstance(rootNode, contextResolver)) {
22482
+ return contextResolver;
22483
+ }
22484
+ return new this(
22485
+ domProvider,
22486
+ rootNode,
22487
+ referenceNode ?? null,
22488
+ contextResolver
22489
+ );
22248
22490
  }
22249
22491
  contextResolver;
22250
- lookupNodeNamespaceURI = (node, prefix) => {
22251
- return node.lookupNamespaceURI(prefix);
22252
- };
22253
- lookupStaticNamespaceURI = (prefix) => {
22254
- return staticNamespaces.get(prefix) ?? null;
22255
- };
22256
22492
  /**
22257
22493
  * Note: while it is likely consistent with the **spec** to resolve a `null`
22258
22494
  * prefix, it's not typical in a browser environment for the resolver to be
@@ -22263,102 +22499,33 @@ class NamespaceResolver {
22263
22499
  */
22264
22500
  lookupNamespaceURI(prefix) {
22265
22501
  return namespaceURIs.upsert(this.contextResolver, () => new UpsertableMap()).upsert(prefix, () => {
22266
- return this.contextResolver.lookupNamespaceURI(prefix) ?? staticNamespaces.get(prefix) ?? null;
22502
+ return this.contextResolver(prefix) ?? staticNamespaces.get(prefix) ?? null;
22267
22503
  });
22268
22504
  }
22269
22505
  }
22270
22506
 
22271
- const assertParentNode = (node) => {
22272
- if (node.children == null) {
22273
- throw "todo assertParentNode";
22274
- }
22275
- };
22276
-
22277
- const getDocument = (node) => node.nodeType === Node.DOCUMENT_NODE ? node : node.ownerDocument;
22278
- const getRootNode = (node) => {
22279
- if (isDocumentNode(node)) {
22280
- return node;
22281
- }
22282
- if (isElementNode(node)) {
22283
- const rootNode = node.getRootNode();
22284
- assertParentNode(rootNode);
22285
- return rootNode;
22286
- }
22287
- if (isAttributeNode(node)) {
22288
- const { ownerElement } = node;
22289
- if (ownerElement == null) {
22290
- throw "todo";
22291
- }
22292
- return getRootNode(ownerElement);
22293
- }
22294
- const { parentElement } = node;
22295
- if (parentElement == null) {
22296
- throw "todo getRootNode COMMENT | PROCESSING_INSTRUCTION | TEXT";
22297
- }
22298
- return getRootNode(parentElement);
22299
- };
22300
- const {
22301
- SHOW_ELEMENT,
22302
- SHOW_ATTRIBUTE,
22303
- SHOW_TEXT,
22304
- SHOW_CDATA_SECTION,
22305
- SHOW_PROCESSING_INSTRUCTION,
22306
- SHOW_COMMENT,
22307
- SHOW_DOCUMENT,
22308
- SHOW_DOCUMENT_TYPE
22309
- } = NodeFilter;
22310
- const SHOW_ANY = 0 | SHOW_ELEMENT | SHOW_ATTRIBUTE | SHOW_TEXT | SHOW_CDATA_SECTION | SHOW_PROCESSING_INSTRUCTION | SHOW_COMMENT | SHOW_DOCUMENT | SHOW_DOCUMENT_TYPE;
22311
- const SHOW_ANY_TEXT = 0 | SHOW_TEXT | SHOW_CDATA_SECTION;
22312
- const TreeWalkerFilter = {
22313
- ANY: SHOW_ANY,
22314
- ELEMENT: SHOW_ELEMENT,
22315
- TEXT: SHOW_ANY_TEXT,
22316
- COMMENT: SHOW_COMMENT,
22317
- PROCESSING_INSTRUCTION: SHOW_PROCESSING_INSTRUCTION
22318
- };
22319
- const getTreeWalker = (contextDocument, contextNode = contextDocument, filter = "ANY") => {
22320
- const flag = TreeWalkerFilter[filter];
22321
- return contextDocument.createTreeWalker(contextNode, flag);
22322
- };
22323
-
22324
- class EvaluationContextTreeWalkers {
22325
- ANY;
22326
- COMMENT;
22327
- ELEMENT;
22328
- PROCESSING_INSTRUCTION;
22329
- TEXT;
22330
- constructor(contextDocument, rootNode) {
22331
- this.ANY = getTreeWalker(contextDocument, rootNode, "ANY");
22332
- this.COMMENT = getTreeWalker(contextDocument, rootNode, "COMMENT");
22333
- this.ELEMENT = getTreeWalker(contextDocument, rootNode, "ELEMENT");
22334
- this.PROCESSING_INSTRUCTION = getTreeWalker(
22335
- contextDocument,
22336
- rootNode,
22337
- "PROCESSING_INSTRUCTION"
22338
- );
22339
- this.TEXT = getTreeWalker(contextDocument, rootNode, "TEXT");
22340
- }
22341
- }
22342
22507
  class EvaluationContext {
22343
22508
  constructor(evaluator, contextNode, options = {}) {
22344
22509
  this.evaluator = evaluator;
22345
- const {
22346
- rootNode = getRootNode(contextNode),
22347
- document = getDocument(rootNode),
22348
- functions = evaluator.functions,
22349
- namespaceResolver = new NamespaceResolver(document, contextNode),
22350
- treeWalkers = new EvaluationContextTreeWalkers(document, rootNode),
22351
- timeZone = evaluator.timeZone
22352
- } = options;
22353
- this.contextDocument = document;
22510
+ const { domProvider } = evaluator;
22511
+ this.domProvider = domProvider;
22512
+ const { namespaceResolver } = options;
22513
+ const rootNode = options.rootNode ?? domProvider.getContainingDocument(contextNode);
22514
+ const contextDocument = domProvider.getContainingDocument(rootNode);
22515
+ this.contextDocument = contextDocument;
22354
22516
  this.evaluationContextNode = contextNode;
22355
22517
  this.contextNodes = [contextNode];
22356
22518
  this.rootNode = rootNode;
22357
- this.functions = functions;
22358
- this.namespaceResolver = namespaceResolver;
22359
- this.treeWalkers = treeWalkers;
22360
- this.timeZone = timeZone;
22519
+ this.functions = options.functions ?? evaluator.functions;
22520
+ this.namespaceResolver = NamespaceResolver.from(
22521
+ domProvider,
22522
+ contextDocument,
22523
+ contextDocument,
22524
+ namespaceResolver
22525
+ );
22526
+ this.timeZone = options.timeZone ?? evaluator.timeZone;
22361
22527
  }
22528
+ domProvider;
22362
22529
  /**
22363
22530
  * @see {@link Context.evaluationContextNode}
22364
22531
  */
@@ -22369,7 +22536,6 @@ class EvaluationContext {
22369
22536
  functions;
22370
22537
  namespaceResolver;
22371
22538
  timeZone;
22372
- treeWalkers;
22373
22539
  contextPosition() {
22374
22540
  return 1;
22375
22541
  }
@@ -22517,21 +22683,19 @@ class BooleanEvaluation extends ValueEvaluation {
22517
22683
  }
22518
22684
 
22519
22685
  class TypedFunctionImplementation extends FunctionImplementation {
22520
- constructor(localName, TypedResult, signature, call) {
22521
- super(
22522
- localName,
22523
- signature,
22524
- (context, args) => {
22525
- const runtimeResult = call(context, args);
22526
- return new TypedResult(context, runtimeResult);
22527
- }
22528
- );
22686
+ constructor(localName, signature, call, resultFactory) {
22687
+ super(localName, signature, (context, args) => {
22688
+ const result = call(context, args);
22689
+ return resultFactory(context, result);
22690
+ });
22529
22691
  }
22530
22692
  }
22531
22693
 
22532
22694
  class BooleanFunction extends TypedFunctionImplementation {
22533
22695
  constructor(localName, signature, call) {
22534
- super(localName, BooleanEvaluation, signature, call);
22696
+ super(localName, signature, call, (context, value) => {
22697
+ return new BooleanEvaluation(context, value);
22698
+ });
22535
22699
  }
22536
22700
  }
22537
22701
 
@@ -22556,15 +22720,19 @@ const lang = new BooleanFunction(
22556
22720
  if (contextNode == null) {
22557
22721
  return false;
22558
22722
  }
22559
- let contextElement = isElementNode(contextNode) ? contextNode : contextNode.parentElement;
22560
- if (contextElement == null) {
22723
+ const { domProvider } = context;
22724
+ let currentContextNode = domProvider.isElement(contextNode) ? contextNode : domProvider.getParentNode(contextNode);
22725
+ if (currentContextNode == null) {
22561
22726
  return false;
22562
22727
  }
22563
- let langValue = contextElement.getAttributeNS(XML_NAMESPACE_URI, "lang");
22728
+ let langValue = null;
22564
22729
  do {
22565
- langValue = contextElement?.getAttributeNS(XML_NAMESPACE_URI, "lang")?.toLowerCase() ?? null;
22566
- contextElement = contextElement.parentElement;
22567
- } while (langValue == null && contextElement != null);
22730
+ if (currentContextNode == null || !domProvider.isElement(currentContextNode)) {
22731
+ break;
22732
+ }
22733
+ langValue = domProvider.getQualifiedNamedAttributeValue(currentContextNode, XML_NAMESPACE_URI, "lang")?.toLowerCase() ?? null;
22734
+ currentContextNode = domProvider.getParentNode(currentContextNode);
22735
+ } while (langValue == null && currentContextNode != null);
22568
22736
  return langValue != null && (langValue === language || langValue.startsWith(`${language}-`));
22569
22737
  }
22570
22738
  );
@@ -22577,12 +22745,12 @@ const not = new BooleanFunction(
22577
22745
  );
22578
22746
 
22579
22747
  const boolean$2 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
22580
- __proto__: null,
22581
- boolean: boolean$1,
22582
- false: falseFn,
22583
- lang,
22584
- not,
22585
- true: trueFn
22748
+ __proto__: null,
22749
+ boolean: boolean$1,
22750
+ false: falseFn,
22751
+ lang,
22752
+ not,
22753
+ true: trueFn
22586
22754
  }, Symbol.toStringTag, { value: 'Module' }));
22587
22755
 
22588
22756
  class InvalidArgumentError extends Error {}
@@ -23591,11 +23759,7 @@ class NodeSetFunction extends FunctionImplementation {
23591
23759
  constructor(localName, signature, call) {
23592
23760
  super(localName, signature, (context, args) => {
23593
23761
  const nodes = call(context, args);
23594
- return LocationPathEvaluation.fromArbitraryNodes(
23595
- context,
23596
- nodes,
23597
- this
23598
- );
23762
+ return LocationPathEvaluation.fromArbitraryNodes(context, nodes, this);
23599
23763
  });
23600
23764
  }
23601
23765
  }
@@ -23618,42 +23782,20 @@ class NumberEvaluation extends ValueEvaluation {
23618
23782
 
23619
23783
  class NumberFunction extends TypedFunctionImplementation {
23620
23784
  constructor(localName, signature, call) {
23621
- super(localName, NumberEvaluation, signature, call);
23785
+ super(localName, signature, call, (context, value) => {
23786
+ return new NumberEvaluation(context, value);
23787
+ });
23622
23788
  }
23623
23789
  }
23624
23790
 
23625
23791
  class StringFunction extends TypedFunctionImplementation {
23626
23792
  constructor(localName, signature, call) {
23627
- super(localName, StringEvaluation, signature, call);
23793
+ super(localName, signature, call, (context, value) => {
23794
+ return new StringEvaluation(context, value);
23795
+ });
23628
23796
  }
23629
23797
  }
23630
23798
 
23631
- const { DOCUMENT_POSITION_FOLLOWING, DOCUMENT_POSITION_PRECEDING } = Node;
23632
- const sortDocumentOrder = (nodes) => {
23633
- const array = Array.from(nodes);
23634
- if (array.length < 2) {
23635
- return array;
23636
- }
23637
- return array.sort((a, b) => {
23638
- const compared = b.compareDocumentPosition(a);
23639
- if (compared === 0 && a !== b) {
23640
- if (a.ownerElement === b) {
23641
- return 1;
23642
- }
23643
- if (a === b.ownerElement) {
23644
- return -1;
23645
- }
23646
- }
23647
- if (compared & DOCUMENT_POSITION_FOLLOWING) {
23648
- return 1;
23649
- }
23650
- if (compared & DOCUMENT_POSITION_PRECEDING) {
23651
- return -1;
23652
- }
23653
- return 0;
23654
- });
23655
- };
23656
-
23657
23799
  const { toCount } = reduce;
23658
23800
  const count = new NumberFunction(
23659
23801
  "count",
@@ -23685,15 +23827,15 @@ const id = new NodeSetFunction(
23685
23827
  if (elementIds.length === 0) {
23686
23828
  return [];
23687
23829
  }
23688
- const { contextDocument } = context;
23830
+ const { contextDocument, domProvider } = context;
23689
23831
  const elements = elementIds.flatMap((elementId) => {
23690
- const element = contextDocument.getElementById(elementId);
23832
+ const element = domProvider.getElementByUniqueId(contextDocument, elementId);
23691
23833
  if (element == null) {
23692
23834
  return [];
23693
23835
  }
23694
23836
  return element;
23695
23837
  });
23696
- return sortDocumentOrder(elements);
23838
+ return context.domProvider.sortInDocumentOrder(elements);
23697
23839
  }
23698
23840
  );
23699
23841
  const last = new NumberFunction("last", [], (context) => context.contextSize());
@@ -23709,11 +23851,14 @@ const localName = new StringFunction(
23709
23851
  if (node == null) {
23710
23852
  return "";
23711
23853
  }
23712
- if (node.nodeType !== Node.ELEMENT_NODE && node.nodeType !== Node.ATTRIBUTE_NODE && node.nodeType !== Node.PROCESSING_INSTRUCTION_NODE) {
23713
- return "";
23854
+ const { domProvider } = context;
23855
+ if (domProvider.isQualifiedNamedNode(node)) {
23856
+ return domProvider.getLocalName(node);
23857
+ }
23858
+ if (domProvider.isProcessingInstruction(node)) {
23859
+ return domProvider.getProcessingInstructionName(node);
23714
23860
  }
23715
- const name2 = isNamespaceNode(node) ? "" : isProcessingInstructionNode(node) ? node.nodeName : node.localName ?? "";
23716
- return name2;
23861
+ return "";
23717
23862
  }
23718
23863
  );
23719
23864
  const name = new StringFunction(
@@ -23728,13 +23873,14 @@ const name = new StringFunction(
23728
23873
  if (node == null) {
23729
23874
  return "";
23730
23875
  }
23731
- if (node.nodeType !== Node.ELEMENT_NODE && node.nodeType !== Node.ATTRIBUTE_NODE && node.nodeType !== Node.PROCESSING_INSTRUCTION_NODE) {
23732
- return "";
23876
+ const { domProvider } = context;
23877
+ if (domProvider.isQualifiedNamedNode(node)) {
23878
+ return domProvider.getQualifiedName(node);
23733
23879
  }
23734
- if (isNamespaceNode(node)) {
23735
- return "";
23880
+ if (domProvider.isProcessingInstruction(node)) {
23881
+ return domProvider.getProcessingInstructionName(node);
23736
23882
  }
23737
- return node.nodeName ?? "";
23883
+ return "";
23738
23884
  }
23739
23885
  );
23740
23886
  const namespaceURI = new StringFunction(
@@ -23749,10 +23895,11 @@ const namespaceURI = new StringFunction(
23749
23895
  if (node == null) {
23750
23896
  return "";
23751
23897
  }
23752
- if (isNamespaceNode(node)) {
23753
- return "";
23898
+ const { domProvider } = context;
23899
+ if (domProvider.isQualifiedNamedNode(node)) {
23900
+ return domProvider.getNamespaceURI(node) ?? "";
23754
23901
  }
23755
- return node.namespaceURI ?? "";
23902
+ return "";
23756
23903
  }
23757
23904
  );
23758
23905
  const position$1 = new NumberFunction(
@@ -23762,15 +23909,15 @@ const position$1 = new NumberFunction(
23762
23909
  );
23763
23910
 
23764
23911
  const nodeset$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
23765
- __proto__: null,
23766
- count,
23767
- current,
23768
- id,
23769
- last,
23770
- localName,
23771
- name,
23772
- namespaceURI,
23773
- position: position$1
23912
+ __proto__: null,
23913
+ count,
23914
+ current,
23915
+ id,
23916
+ last,
23917
+ localName,
23918
+ name,
23919
+ namespaceURI,
23920
+ position: position$1
23774
23921
  }, Symbol.toStringTag, { value: 'Module' }));
23775
23922
 
23776
23923
  class FunctionAlias extends FunctionImplementation {
@@ -23869,12 +24016,12 @@ const sum$1 = new NumberFunction(
23869
24016
  );
23870
24017
 
23871
24018
  const number$3 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
23872
- __proto__: null,
23873
- ceiling,
23874
- floor,
23875
- number: number$2,
23876
- round: round$1,
23877
- sum: sum$1
24019
+ __proto__: null,
24020
+ ceiling,
24021
+ floor,
24022
+ number: number$2,
24023
+ round: round$1,
24024
+ sum: sum$1
23878
24025
  }, Symbol.toStringTag, { value: 'Module' }));
23879
24026
 
23880
24027
  const escapeRegExp = (value) => value.replace(/[\\^$*+?.()|[\]{}]/g, "\\$&");
@@ -24020,17 +24167,17 @@ const translate = new StringFunction(
24020
24167
  );
24021
24168
 
24022
24169
  const string$3 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
24023
- __proto__: null,
24024
- concat: concat$1,
24025
- contains,
24026
- normalizeSpace,
24027
- startsWith,
24028
- string: string$2,
24029
- stringLength,
24030
- substring,
24031
- substringAfter,
24032
- substringBefore,
24033
- translate
24170
+ __proto__: null,
24171
+ concat: concat$1,
24172
+ contains,
24173
+ normalizeSpace,
24174
+ startsWith,
24175
+ string: string$2,
24176
+ stringLength,
24177
+ substring,
24178
+ substringAfter,
24179
+ substringBefore,
24180
+ translate
24034
24181
  }, Symbol.toStringTag, { value: 'Module' }));
24035
24182
 
24036
24183
  const fn = new FunctionLibrary(FN_NAMESPACE_URI, [
@@ -24452,9 +24599,7 @@ class FilterPathExpressionEvaluator extends LocationPathEvaluator {
24452
24599
  evaluateNodes(context) {
24453
24600
  if (this.hasSteps) {
24454
24601
  const filterContextResults = this.filterExpression.evaluate(context);
24455
- if (!(filterContextResults instanceof LocationPathEvaluation)) {
24456
- throw "todo not a node-set context";
24457
- }
24602
+ LocationPathEvaluation.assertInstance(context, filterContextResults);
24458
24603
  return super.evaluateNodes(filterContextResults);
24459
24604
  }
24460
24605
  return this.filterExpression.evaluateNodes(context);
@@ -24625,7 +24770,7 @@ class UnionExpressionEvaluator extends LocationPathExpressionEvaluator {
24625
24770
  if (!(rhs instanceof LocationPathEvaluation)) {
24626
24771
  throw "todo rhs not node-set result";
24627
24772
  }
24628
- return sortDocumentOrder(distinct(multiExports.chain(lhs.nodes, rhs.nodes)));
24773
+ return context.domProvider.sortInDocumentOrder(distinct(multiExports.chain(lhs.nodes, rhs.nodes)));
24629
24774
  }
24630
24775
  }
24631
24776
 
@@ -24748,19 +24893,29 @@ class FunctionLibraryCollection {
24748
24893
  }
24749
24894
  }
24750
24895
 
24751
- const ResultTypes = {
24752
- BOOLEAN_TYPE: XPathResult.BOOLEAN_TYPE,
24753
- NUMBER_TYPE: XPathResult.NUMBER_TYPE,
24754
- STRING_TYPE: XPathResult.STRING_TYPE,
24755
- UNORDERED_NODE_ITERATOR_TYPE: XPathResult.UNORDERED_NODE_ITERATOR_TYPE,
24756
- ORDERED_NODE_ITERATOR_TYPE: XPathResult.ORDERED_NODE_ITERATOR_TYPE,
24757
- UNORDERED_NODE_SNAPSHOT_TYPE: XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
24758
- ORDERED_NODE_SNAPSHOT_TYPE: XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
24759
- ANY_UNORDERED_NODE_TYPE: XPathResult.ANY_UNORDERED_NODE_TYPE,
24760
- FIRST_ORDERED_NODE_TYPE: XPathResult.FIRST_ORDERED_NODE_TYPE
24896
+ const ANY_TYPE$2 = 0;
24897
+ const NUMBER_TYPE$2 = 1;
24898
+ const STRING_TYPE$2 = 2;
24899
+ const BOOLEAN_TYPE$2 = 3;
24900
+ const UNORDERED_NODE_ITERATOR_TYPE$2 = 4;
24901
+ const ORDERED_NODE_ITERATOR_TYPE$2 = 5;
24902
+ const UNORDERED_NODE_SNAPSHOT_TYPE$2 = 6;
24903
+ const ORDERED_NODE_SNAPSHOT_TYPE$2 = 7;
24904
+ const ANY_UNORDERED_NODE_TYPE$2 = 8;
24905
+ const FIRST_ORDERED_NODE_TYPE$2 = 9;
24906
+ const XPATH_EVALUATION_RESULT = {
24907
+ ANY_TYPE: ANY_TYPE$2,
24908
+ ANY_UNORDERED_NODE_TYPE: ANY_UNORDERED_NODE_TYPE$2,
24909
+ BOOLEAN_TYPE: BOOLEAN_TYPE$2,
24910
+ FIRST_ORDERED_NODE_TYPE: FIRST_ORDERED_NODE_TYPE$2,
24911
+ NUMBER_TYPE: NUMBER_TYPE$2,
24912
+ ORDERED_NODE_ITERATOR_TYPE: ORDERED_NODE_ITERATOR_TYPE$2,
24913
+ ORDERED_NODE_SNAPSHOT_TYPE: ORDERED_NODE_SNAPSHOT_TYPE$2,
24914
+ STRING_TYPE: STRING_TYPE$2,
24915
+ UNORDERED_NODE_ITERATOR_TYPE: UNORDERED_NODE_ITERATOR_TYPE$2,
24916
+ UNORDERED_NODE_SNAPSHOT_TYPE: UNORDERED_NODE_SNAPSHOT_TYPE$2
24761
24917
  };
24762
24918
 
24763
- const NODE_SET_RESULT_TYPE = -1;
24764
24919
  const {
24765
24920
  ANY_TYPE: ANY_TYPE$1,
24766
24921
  NUMBER_TYPE: NUMBER_TYPE$1,
@@ -24772,7 +24927,7 @@ const {
24772
24927
  ORDERED_NODE_SNAPSHOT_TYPE: ORDERED_NODE_SNAPSHOT_TYPE$1,
24773
24928
  ANY_UNORDERED_NODE_TYPE: ANY_UNORDERED_NODE_TYPE$1,
24774
24929
  FIRST_ORDERED_NODE_TYPE: FIRST_ORDERED_NODE_TYPE$1
24775
- } = XPathResult;
24930
+ } = XPATH_EVALUATION_RESULT;
24776
24931
  class BaseResult {
24777
24932
  static ANY_TYPE = ANY_TYPE$1;
24778
24933
  static NUMBER_TYPE = NUMBER_TYPE$1;
@@ -24794,7 +24949,6 @@ class BaseResult {
24794
24949
  ORDERED_NODE_SNAPSHOT_TYPE = ORDERED_NODE_SNAPSHOT_TYPE$1;
24795
24950
  ANY_UNORDERED_NODE_TYPE = ANY_UNORDERED_NODE_TYPE$1;
24796
24951
  FIRST_ORDERED_NODE_TYPE = FIRST_ORDERED_NODE_TYPE$1;
24797
- static NODE_SET_RESULT_TYPE = NODE_SET_RESULT_TYPE;
24798
24952
  }
24799
24953
 
24800
24954
  class InvalidNodeSetResultError extends Error {
@@ -24803,9 +24957,6 @@ class InvalidNodeSetResultError extends Error {
24803
24957
  }
24804
24958
  }
24805
24959
  class PrimitiveResult extends BaseResult {
24806
- get resultType() {
24807
- return this.type;
24808
- }
24809
24960
  get singleNodeValue() {
24810
24961
  throw new InvalidNodeSetResultError();
24811
24962
  }
@@ -24822,9 +24973,8 @@ class PrimitiveResult extends BaseResult {
24822
24973
  }
24823
24974
 
24824
24975
  class BooleanResult extends PrimitiveResult {
24825
- isIntermediateResult = false;
24826
- type = PrimitiveResult.BOOLEAN_TYPE;
24827
24976
  nodes = null;
24977
+ resultType = PrimitiveResult.BOOLEAN_TYPE;
24828
24978
  booleanValue;
24829
24979
  numberValue;
24830
24980
  stringValue;
@@ -24837,13 +24987,12 @@ class BooleanResult extends PrimitiveResult {
24837
24987
  }
24838
24988
 
24839
24989
  class NodeSetResult extends BaseResult {
24840
- constructor(value) {
24990
+ constructor(domProvider, value) {
24841
24991
  super();
24992
+ this.domProvider = domProvider;
24842
24993
  this.value = value;
24843
24994
  this.nodes = value;
24844
24995
  }
24845
- isIntermediateResult = false;
24846
- type = BaseResult.NODE_SET_RESULT_TYPE;
24847
24996
  nodes;
24848
24997
  computedBooleanValue = null;
24849
24998
  computedNumberValue = null;
@@ -24864,7 +25013,12 @@ class NodeSetResult extends BaseResult {
24864
25013
  compute() {
24865
25014
  let { computedBooleanValue, computedNumberValue, computedStringValue } = this;
24866
25015
  if (computedBooleanValue == null || computedNumberValue == null || computedStringValue == null) {
24867
- computedStringValue = this.singleNodeValue?.textContent ?? "";
25016
+ const { singleNodeValue } = this;
25017
+ if (singleNodeValue == null) {
25018
+ computedStringValue = "";
25019
+ } else {
25020
+ computedStringValue = this.domProvider.getNodeValue(singleNodeValue);
25021
+ }
24868
25022
  const isBlank = computedStringValue === "";
24869
25023
  computedBooleanValue = !isBlank;
24870
25024
  computedNumberValue = isBlank ? NaN : Number(computedStringValue);
@@ -24877,9 +25031,9 @@ class NodeSetResult extends BaseResult {
24877
25031
  }
24878
25032
  }
24879
25033
  class NodeSetSnapshotResult extends NodeSetResult {
24880
- constructor(resultType, nodes) {
25034
+ constructor(domProvider, resultType, nodes) {
24881
25035
  const snapshot = [...Reiterable.from(nodes)];
24882
- super(snapshot);
25036
+ super(domProvider, snapshot);
24883
25037
  this.resultType = resultType;
24884
25038
  const snapshotIterator = snapshot.values();
24885
25039
  this.snapshot = snapshot;
@@ -24912,8 +25066,8 @@ class InvalidSnapshotError extends Error {
24912
25066
  }
24913
25067
  }
24914
25068
  class NodeSetIteratorResult extends NodeSetResult {
24915
- constructor(resultType, nodes) {
24916
- super(nodes);
25069
+ constructor(domProvider, resultType, nodes) {
25070
+ super(domProvider, nodes);
24917
25071
  this.resultType = resultType;
24918
25072
  this.nodes = Reiterable.from(nodes);
24919
25073
  }
@@ -24959,9 +25113,8 @@ class NodeSetIteratorResult extends NodeSetResult {
24959
25113
  }
24960
25114
 
24961
25115
  class NumberResult extends PrimitiveResult {
24962
- isIntermediateResult = false;
24963
- type = PrimitiveResult.NUMBER_TYPE;
24964
25116
  nodes = null;
25117
+ resultType = PrimitiveResult.NUMBER_TYPE;
24965
25118
  booleanValue;
24966
25119
  numberValue;
24967
25120
  stringValue;
@@ -24974,9 +25127,8 @@ class NumberResult extends PrimitiveResult {
24974
25127
  }
24975
25128
 
24976
25129
  class StringResult extends PrimitiveResult {
24977
- isIntermediateResult = false;
24978
- type = PrimitiveResult.STRING_TYPE;
24979
25130
  nodes = null;
25131
+ resultType = PrimitiveResult.STRING_TYPE;
24980
25132
  booleanValue;
24981
25133
  numberValue;
24982
25134
  stringValue;
@@ -24999,8 +25151,8 @@ const {
24999
25151
  ORDERED_NODE_SNAPSHOT_TYPE,
25000
25152
  ANY_UNORDERED_NODE_TYPE,
25001
25153
  FIRST_ORDERED_NODE_TYPE
25002
- } = globalThis.XPathResult;
25003
- const toXPathResult = (resultType, evaluation) => {
25154
+ } = XPATH_EVALUATION_RESULT;
25155
+ const toXPathEvaluationResult = (domProvider, resultType, evaluation) => {
25004
25156
  const { nodes } = evaluation;
25005
25157
  switch (resultType) {
25006
25158
  case ANY_TYPE:
@@ -25011,8 +25163,13 @@ const toXPathResult = (resultType, evaluation) => {
25011
25163
  return new NumberResult(evaluation);
25012
25164
  case "STRING":
25013
25165
  return new StringResult(evaluation);
25014
- case "NODE":
25015
- return new NodeSetIteratorResult(UNORDERED_NODE_ITERATOR_TYPE, evaluation.nodes);
25166
+ case "NODE": {
25167
+ return new NodeSetIteratorResult(
25168
+ domProvider,
25169
+ UNORDERED_NODE_ITERATOR_TYPE,
25170
+ evaluation.nodes ?? []
25171
+ );
25172
+ }
25016
25173
  default:
25017
25174
  throw new UnreachableError(evaluation.type);
25018
25175
  }
@@ -25029,59 +25186,63 @@ const toXPathResult = (resultType, evaluation) => {
25029
25186
  if (nodes == null) {
25030
25187
  throw "todo not a node-set";
25031
25188
  }
25032
- return new NodeSetIteratorResult(resultType, nodes);
25189
+ return new NodeSetIteratorResult(domProvider, resultType, nodes);
25033
25190
  case UNORDERED_NODE_SNAPSHOT_TYPE:
25034
25191
  case ORDERED_NODE_SNAPSHOT_TYPE:
25035
25192
  if (nodes == null) {
25036
25193
  throw "todo not a node-set";
25037
25194
  }
25038
- return new NodeSetSnapshotResult(resultType, nodes);
25195
+ return new NodeSetSnapshotResult(domProvider, resultType, nodes);
25039
25196
  default:
25040
25197
  throw new UnreachableError(resultType);
25041
25198
  }
25042
25199
  };
25043
25200
 
25044
25201
  const functions$1 = new FunctionLibraryCollection([fn]);
25045
- const isNonNullEntry = (entry) => entry[1] != null;
25046
- const partialOmitNullish = (object) => Object.fromEntries(Object.entries(object).filter(isNonNullEntry));
25047
25202
  class Evaluator {
25203
+ domProvider;
25048
25204
  // TODO: see notes on cache in `ExpressionParser.ts`, update or remove those
25049
25205
  // if this usage changes in a way that addresses concerns expressed there.
25050
25206
  parser;
25051
25207
  functions;
25052
25208
  parseOptions;
25053
- resultTypes = ResultTypes;
25054
- rootNodeDocument = null;
25055
25209
  rootNode;
25056
- sharedContextOptions;
25057
25210
  timeZone;
25058
- constructor(options = {}) {
25059
- const { parseOptions = {}, rootNode, timeZoneId } = options;
25211
+ constructor(options) {
25212
+ const rootNode = options.rootNode ?? null;
25213
+ const { domAdapter, parseOptions = {}, timeZoneId } = options;
25214
+ const domProvider = xpathDOMProvider(domAdapter);
25215
+ if (rootNode != null) {
25216
+ domProvider.assertParentNode(rootNode, "Invalid root node");
25217
+ }
25218
+ this.domProvider = domProvider;
25219
+ this.rootNode = rootNode;
25060
25220
  this.functions = options.functions ?? functions$1;
25061
25221
  this.parseOptions = parseOptions;
25062
25222
  this.parser = expressionParser;
25063
- this.rootNode = rootNode ?? null;
25064
- if (rootNode != null) {
25065
- this.rootNodeDocument = rootNode.ownerDocument ?? rootNode;
25066
- }
25067
- this.sharedContextOptions = partialOmitNullish({
25068
- rootNode
25069
- });
25070
25223
  this.timeZone = new Pt.TimeZone(timeZoneId ?? Pt.Now.timeZoneId());
25071
25224
  }
25225
+ /**
25226
+ * @package - exposed for testing
25227
+ */
25228
+ getEvaluationContext(contextNode, namespaceResolver) {
25229
+ const contextOptions = {
25230
+ rootNode: this.rootNode,
25231
+ namespaceResolver
25232
+ };
25233
+ this.domProvider.assertXPathNode(contextNode);
25234
+ return new EvaluationContext(this, contextNode, contextOptions);
25235
+ }
25072
25236
  evaluate(expression, contextNode, namespaceResolver, resultType) {
25073
25237
  const tree = this.parser.parse(expression, this.parseOptions);
25074
- const evaluationContextNamespaceResolver = typeof namespaceResolver === "function" ? {
25075
- lookupNamespaceURI: namespaceResolver
25076
- } : namespaceResolver;
25077
- const contextOptions = partialOmitNullish({
25078
- ...this.sharedContextOptions,
25079
- namespaceResolver: evaluationContextNamespaceResolver
25080
- });
25081
25238
  const expr = createExpression(tree.rootNode);
25082
- const context = new EvaluationContext(this, contextNode, contextOptions);
25083
- const results = expr.evaluate(context);
25084
- return toXPathResult(resultType ?? XPathResult.ANY_TYPE, results);
25239
+ const evaluationContext = this.getEvaluationContext(contextNode, namespaceResolver);
25240
+ const results = expr.evaluate(evaluationContext);
25241
+ return toXPathEvaluationResult(
25242
+ this.domProvider,
25243
+ resultType ?? XPATH_EVALUATION_RESULT.ANY_TYPE,
25244
+ results
25245
+ );
25085
25246
  }
25086
25247
  getContextNode(options) {
25087
25248
  const contextNode = options.contextNode ?? this.rootNode;
@@ -25094,19 +25255,24 @@ class Evaluator {
25094
25255
  }
25095
25256
  evaluateBoolean(expression, options = {}) {
25096
25257
  const contextNode = this.getContextNode(options);
25097
- return this.evaluate(expression, contextNode, null, XPathResult.BOOLEAN_TYPE).booleanValue;
25258
+ return this.evaluate(expression, contextNode, null, XPATH_EVALUATION_RESULT.BOOLEAN_TYPE).booleanValue;
25098
25259
  }
25099
25260
  evaluateNumber(expression, options = {}) {
25100
25261
  const contextNode = this.getContextNode(options);
25101
- return this.evaluate(expression, contextNode, null, XPathResult.NUMBER_TYPE).numberValue;
25262
+ return this.evaluate(expression, contextNode, null, XPATH_EVALUATION_RESULT.NUMBER_TYPE).numberValue;
25102
25263
  }
25103
25264
  evaluateString(expression, options = {}) {
25104
25265
  const contextNode = this.getContextNode(options);
25105
- return this.evaluate(expression, contextNode, null, XPathResult.STRING_TYPE).stringValue;
25266
+ return this.evaluate(expression, contextNode, null, XPATH_EVALUATION_RESULT.STRING_TYPE).stringValue;
25106
25267
  }
25107
25268
  evaluateNode(expression, options = {}) {
25108
25269
  const contextNode = this.getContextNode(options);
25109
- const node = this.evaluate(expression, contextNode, null, XPathResult.FIRST_ORDERED_NODE_TYPE).singleNodeValue;
25270
+ const node = this.evaluate(
25271
+ expression,
25272
+ contextNode,
25273
+ null,
25274
+ XPATH_EVALUATION_RESULT.FIRST_ORDERED_NODE_TYPE
25275
+ ).singleNodeValue;
25110
25276
  if (!options.assertExists) {
25111
25277
  return node;
25112
25278
  }
@@ -25130,7 +25296,7 @@ class Evaluator {
25130
25296
  expression,
25131
25297
  contextNode,
25132
25298
  null,
25133
- XPathResult.ORDERED_NODE_SNAPSHOT_TYPE
25299
+ XPATH_EVALUATION_RESULT.ORDERED_NODE_SNAPSHOT_TYPE
25134
25300
  );
25135
25301
  const { snapshotLength } = snapshotResult;
25136
25302
  const nodes = [];
@@ -25144,6 +25310,287 @@ class Evaluator {
25144
25310
  }
25145
25311
  }
25146
25312
 
25313
+ class IncompatibleRuntimeEnvironmentError extends Error {
25314
+ }
25315
+
25316
+ let didAssertNodeConstructor = false;
25317
+ const assertNodeConstructor = (NodeConstructor) => {
25318
+ if (didAssertNodeConstructor) {
25319
+ return;
25320
+ }
25321
+ const isExpectedFunctionSignature = typeof NodeConstructor === "function" && NodeConstructor.name === "Node" && NodeConstructor.length === 0;
25322
+ if (!isExpectedFunctionSignature || !(globalThis.document instanceof NodeConstructor)) {
25323
+ throw new IncompatibleRuntimeEnvironmentError();
25324
+ }
25325
+ didAssertNodeConstructor = true;
25326
+ };
25327
+ const getNodeConstructor = () => {
25328
+ const { Node } = globalThis;
25329
+ assertNodeConstructor(Node);
25330
+ return Node;
25331
+ };
25332
+
25333
+ const DOCUMENT_NODE = 9;
25334
+ const ELEMENT_NODE = 1;
25335
+ const ATTRIBUTE_NODE = 2;
25336
+ const TEXT_NODE = 3;
25337
+ const CDATA_SECTION_NODE = 4;
25338
+ const COMMENT_NODE = 8;
25339
+ const PROCESSING_INSTRUCTION_NODE = 7;
25340
+ const DOCUMENT_TYPE_NODE = 10;
25341
+ const isUnknownWHATNode = (value) => {
25342
+ return value instanceof getNodeConstructor();
25343
+ };
25344
+ const getOptionalNodeKind = (value) => {
25345
+ if (!isUnknownWHATNode(value)) {
25346
+ return null;
25347
+ }
25348
+ const node = value;
25349
+ switch (node.nodeType) {
25350
+ case DOCUMENT_NODE:
25351
+ return "document";
25352
+ case DOCUMENT_TYPE_NODE:
25353
+ return "UNSPECIFIED_NON_XPATH_NODE";
25354
+ case ELEMENT_NODE:
25355
+ return "element";
25356
+ case ATTRIBUTE_NODE:
25357
+ if (node.namespaceURI === XMLNS_NAMESPACE_URI) {
25358
+ return "namespace_declaration";
25359
+ }
25360
+ return "attribute";
25361
+ case TEXT_NODE:
25362
+ case CDATA_SECTION_NODE:
25363
+ return "text";
25364
+ case COMMENT_NODE:
25365
+ return "comment";
25366
+ case PROCESSING_INSTRUCTION_NODE:
25367
+ return "processing_instruction";
25368
+ default:
25369
+ return null;
25370
+ }
25371
+ };
25372
+ const getWHATNodeKind = (node) => {
25373
+ const nodeKind = getOptionalNodeKind(node);
25374
+ if (nodeKind == null) {
25375
+ throw new Error(`Unsupported WHAT node type: ${node.nodeType}`);
25376
+ }
25377
+ return nodeKind;
25378
+ };
25379
+ const isWHATNode = (value) => {
25380
+ const nodeKind = getOptionalNodeKind(value);
25381
+ return nodeKind != null && nodeKind !== "UNSPECIFIED_NON_XPATH_NODE";
25382
+ };
25383
+ const isWHATDocument = (node) => {
25384
+ return node.nodeType === DOCUMENT_NODE;
25385
+ };
25386
+ const isWHATElement = (node) => {
25387
+ return node.nodeType === ELEMENT_NODE;
25388
+ };
25389
+ const isWHATNamespaceDeclaration = (node) => {
25390
+ return node.nodeType === ATTRIBUTE_NODE && node.namespaceURI === XMLNS_NAMESPACE_URI;
25391
+ };
25392
+ const isWHATAttribute = (node) => {
25393
+ return node.nodeType === ATTRIBUTE_NODE && node.namespaceURI !== XMLNS_NAMESPACE_URI;
25394
+ };
25395
+ const isWHATParentNode = (node) => {
25396
+ return isWHATDocument(node) || isWHATElement(node);
25397
+ };
25398
+
25399
+ const getWHATNamespaceURI = (node) => {
25400
+ return node.namespaceURI;
25401
+ };
25402
+ const getWHATQualifiedName = (node) => {
25403
+ return node.nodeName;
25404
+ };
25405
+ const getWHATLocalName = (node) => {
25406
+ return node.localName;
25407
+ };
25408
+ const getWHATProcessingInstructionName = (node) => {
25409
+ return node.nodeName;
25410
+ };
25411
+ const resolveWHATNamespaceURI = (node, prefix) => {
25412
+ return node.lookupNamespaceURI(prefix);
25413
+ };
25414
+
25415
+ const getContainingWHATDocument = (node) => {
25416
+ if (isWHATDocument(node)) {
25417
+ return node;
25418
+ }
25419
+ return node.ownerDocument;
25420
+ };
25421
+ const getOwnerWHATElement = (node) => {
25422
+ const ownerElement = node.ownerElement ?? null;
25423
+ return ownerElement;
25424
+ };
25425
+ const getAttrs = (node) => {
25426
+ if (isWHATElement(node)) {
25427
+ return Array.from(node.attributes);
25428
+ }
25429
+ return [];
25430
+ };
25431
+ const getWHATNamespaceDeclarations = (node) => {
25432
+ return getAttrs(node).filter(isWHATNamespaceDeclaration);
25433
+ };
25434
+ const getWHATAttributes = (node) => {
25435
+ return getAttrs(node).filter(isWHATAttribute);
25436
+ };
25437
+ const getWHATParentNode = (node) => {
25438
+ let parentNode = getOwnerWHATElement(node);
25439
+ if (parentNode == null) {
25440
+ parentNode = node.parentNode;
25441
+ }
25442
+ return parentNode;
25443
+ };
25444
+ const getWHATChildNodes = (node) => {
25445
+ if (!isWHATParentNode(node)) {
25446
+ return [];
25447
+ }
25448
+ return Array.from(node.childNodes);
25449
+ };
25450
+ const getChildWHATElements = (node) => {
25451
+ if (!isWHATParentNode(node)) {
25452
+ return [];
25453
+ }
25454
+ return Array.from(node.children);
25455
+ };
25456
+ const getPreviousSiblingWHATNode = (node) => {
25457
+ const previousSibling = node.previousSibling;
25458
+ return previousSibling;
25459
+ };
25460
+ const getPreviousSiblingWHATElement = (node) => {
25461
+ const previousElementSibling = node.previousElementSibling ?? null;
25462
+ return previousElementSibling;
25463
+ };
25464
+ const getNextSiblingWHATNode = (node) => {
25465
+ return node.nextSibling;
25466
+ };
25467
+ const getNextSiblingWHATElement = (node) => {
25468
+ const nextElementSibling = node.nextElementSibling ?? null;
25469
+ return nextElementSibling;
25470
+ };
25471
+ const isDescendantWHATNode = (ancestor, other) => {
25472
+ return ancestor.contains(other);
25473
+ };
25474
+ const getWHATDocumentPositionComparableNode = (node) => {
25475
+ return getOwnerWHATElement(node) ?? node;
25476
+ };
25477
+ const DOCUMENT_POSITION_PRECEDING = 2;
25478
+ const DOCUMENT_POSITION_FOLLOWING = 4;
25479
+ const compareWHATDocumentOrder = (a, b) => {
25480
+ if (a === b) {
25481
+ return 0;
25482
+ }
25483
+ const compared = b.compareDocumentPosition(a);
25484
+ if (compared === 0) {
25485
+ if (getWHATDocumentPositionComparableNode(a) === b) {
25486
+ return 1;
25487
+ }
25488
+ if (a === getWHATDocumentPositionComparableNode(b)) {
25489
+ return -1;
25490
+ }
25491
+ }
25492
+ if (compared & DOCUMENT_POSITION_FOLLOWING) {
25493
+ return 1;
25494
+ }
25495
+ if (compared & DOCUMENT_POSITION_PRECEDING) {
25496
+ return -1;
25497
+ }
25498
+ throw new Error("Failed to compare document position");
25499
+ };
25500
+
25501
+ const getQualifiedNamedWHATAttributeValue = (node, namespaceURI, localName) => {
25502
+ return node.getAttributeNS(namespaceURI, localName);
25503
+ };
25504
+ const getLocalNamedWHATAttributeValue = (node, localName) => {
25505
+ return node.getAttribute(localName);
25506
+ };
25507
+ const hasLocalNamedWHATAttribute = (node, localName) => {
25508
+ return node.hasAttribute(localName);
25509
+ };
25510
+ const getWHATElementByUniqueId = (node, id) => {
25511
+ const element = getContainingWHATDocument(node).getElementById(id);
25512
+ return element;
25513
+ };
25514
+ const getWHATChildrenByLocalName = (node, localName) => {
25515
+ return getChildWHATElements(node).filter((element) => {
25516
+ return element.localName === localName;
25517
+ });
25518
+ };
25519
+ const getFirstWHATChildNode = (node) => {
25520
+ const firstChild = node.firstChild;
25521
+ return firstChild;
25522
+ };
25523
+ const getLastWHATChildNode = (node) => {
25524
+ const lastChild = node.lastChild;
25525
+ return lastChild;
25526
+ };
25527
+ const getFirstChildWHATElement = (node) => {
25528
+ const firstElementChild = node.firstElementChild ?? null;
25529
+ return firstElementChild;
25530
+ };
25531
+ const getLastChildWHATElement = (node) => {
25532
+ const lastElementChild = node.lastElementChild ?? null;
25533
+ return lastElementChild;
25534
+ };
25535
+
25536
+ const getWHATNodeValue = (node) => {
25537
+ return node.textContent ?? "";
25538
+ };
25539
+
25540
+ const whatDOMAdapter = {
25541
+ // XPathNodeKindAdapter
25542
+ getNodeKind: getWHATNodeKind,
25543
+ isXPathNode: isWHATNode,
25544
+ // XPathNameAdapter
25545
+ getLocalName: getWHATLocalName,
25546
+ getNamespaceURI: getWHATNamespaceURI,
25547
+ getQualifiedName: getWHATQualifiedName,
25548
+ getProcessingInstructionName: getWHATProcessingInstructionName,
25549
+ resolveNamespaceURI: resolveWHATNamespaceURI,
25550
+ // XPathValueAdapter
25551
+ getNodeValue: getWHATNodeValue,
25552
+ // XPathTraversalAdapter
25553
+ compareDocumentOrder: compareWHATDocumentOrder,
25554
+ getAttributes: getWHATAttributes,
25555
+ getChildElements: getChildWHATElements,
25556
+ getChildNodes: getWHATChildNodes,
25557
+ getContainingDocument: getContainingWHATDocument,
25558
+ getNamespaceDeclarations: getWHATNamespaceDeclarations,
25559
+ getNextSiblingElement: getNextSiblingWHATElement,
25560
+ getNextSiblingNode: getNextSiblingWHATNode,
25561
+ getParentNode: getWHATParentNode,
25562
+ getPreviousSiblingElement: getPreviousSiblingWHATElement,
25563
+ getPreviousSiblingNode: getPreviousSiblingWHATNode,
25564
+ isDescendantNode: isDescendantWHATNode,
25565
+ // XPathDOMOptimizableOperations
25566
+ getElementByUniqueId: getWHATElementByUniqueId,
25567
+ getChildrenByLocalName: getWHATChildrenByLocalName,
25568
+ getQualifiedNamedAttributeValue: getQualifiedNamedWHATAttributeValue,
25569
+ getLocalNamedAttributeValue: getLocalNamedWHATAttributeValue,
25570
+ hasLocalNamedAttribute: hasLocalNamedWHATAttribute,
25571
+ getFirstChildElement: getFirstChildWHATElement,
25572
+ getFirstChildNode: getFirstWHATChildNode,
25573
+ getLastChildElement: getLastChildWHATElement,
25574
+ getLastChildNode: getLastWHATChildNode
25575
+ };
25576
+
25577
+ const DEFAULT_DOM_ADAPTER = whatDOMAdapter;
25578
+ const DEFAULT_DOM_PROVIDER = xpathDOMProvider(DEFAULT_DOM_ADAPTER);
25579
+
25580
+ const XPathNodeKindKey = Symbol("XPathNodeKindKey");
25581
+
25582
+ class DefaultEvaluator extends Evaluator {
25583
+ constructor(options) {
25584
+ super({
25585
+ ...options,
25586
+ domAdapter: DEFAULT_DOM_ADAPTER
25587
+ });
25588
+ }
25589
+ }
25590
+
25591
+ const XFORMS_LOCAL_NAME = Symbol("XFORMS_LOCAL_NAME");
25592
+ const XFORMS_KNOWN_ATTRIBUTE = Symbol("XFORMS_KNOWN_ATTRIBUTE");
25593
+
25147
25594
  const DAY_MILLISECONDS = 1e3 * 60 * 60 * 24;
25148
25595
  const MILLISECOND_NANOSECONDS = BigInt(1e6);
25149
25596
  const ISO_DATE_LIKE_SUBPATTERN = "\\d{4}-\\d{2}-\\d{2}";
@@ -25510,14 +25957,14 @@ const decimalTime = new NumberFunction(
25510
25957
  );
25511
25958
 
25512
25959
  const datetime = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
25513
- __proto__: null,
25514
- date,
25515
- decimalDateTime,
25516
- decimalTime,
25517
- formatDate,
25518
- formatDateTime,
25519
- today,
25520
- xfNow
25960
+ __proto__: null,
25961
+ date,
25962
+ decimalDateTime,
25963
+ decimalTime,
25964
+ formatDate,
25965
+ formatDateTime,
25966
+ today,
25967
+ xfNow
25521
25968
  }, Symbol.toStringTag, { value: 'Module' }));
25522
25969
 
25523
25970
  const enk = new FunctionLibrary(ENKETO_NAMESPACE_URI, [
@@ -25525,209 +25972,18 @@ const enk = new FunctionLibrary(ENKETO_NAMESPACE_URI, [
25525
25972
  new FunctionAlias("format-date", formatDateTime)
25526
25973
  ]);
25527
25974
 
25528
- class UpsertableWeakMap extends WeakMap {
25529
- upsert(key, produce) {
25530
- if (this.has(key)) {
25531
- return this.get(key);
25532
- }
25533
- const value = produce(key);
25534
- this.set(key, value);
25535
- return value;
25536
- }
25537
- }
25538
-
25539
- const SUPPORTS_SCOPE_CHILD_SELECTOR = (() => {
25540
- const parent = document.createElement("parent");
25541
- const child1 = document.createElement("child1");
25542
- const child2 = document.createElement("child2");
25543
- child2.append(child1);
25544
- parent.append(child2);
25545
- return parent.querySelector(":scope > child1") === child1 && parent.querySelector(":scope > child2") !== child2;
25546
- })();
25547
- const getScopedElement = (() => {
25548
- if (SUPPORTS_SCOPE_CHILD_SELECTOR) {
25549
- return (lookup, contextNode) => {
25550
- return contextNode.querySelector(lookup.scopedSelector);
25551
- };
25552
- }
25553
- return (lookup, contextNode) => {
25554
- const { unscopedSelector } = lookup;
25555
- for (const child of contextNode.children) {
25556
- if (child.matches(unscopedSelector)) {
25557
- return child;
25558
- }
25559
- }
25560
- return null;
25561
- };
25562
- })();
25563
- const getScopedElements = (() => {
25564
- if (SUPPORTS_SCOPE_CHILD_SELECTOR) {
25565
- return (lookup, contextNode) => {
25566
- return contextNode.querySelectorAll(lookup.scopedSelector);
25567
- };
25568
- }
25569
- return (lookup, contextNode) => {
25570
- const { unscopedSelector } = lookup;
25571
- return Array.from(contextNode.children).filter((child) => {
25572
- return child.matches(unscopedSelector);
25573
- });
25574
- };
25575
- })();
25576
- class ScopedElementLookup {
25577
- constructor(scopedSelector, unscopedSelector) {
25578
- this.scopedSelector = scopedSelector;
25579
- this.unscopedSelector = unscopedSelector;
25580
- }
25581
- /**
25582
- * WARNING: `T` is unchecked at runtime, use with caution!
25583
- */
25584
- getElement(contextNode) {
25585
- return getScopedElement(this, contextNode);
25586
- }
25587
- /**
25588
- * WARNING: `T` is unchecked at runtime, use with caution!
25589
- */
25590
- getElements(contextNode) {
25591
- return getScopedElements(this, contextNode);
25592
- }
25593
- }
25594
-
25595
- const itextRootLookup = new ScopedElementLookup(":scope > itext", "itext");
25596
- const getItextRoot = (modelElement) => {
25597
- return itextRootLookup.getElement(modelElement);
25598
- };
25599
- const translationLookup = new ScopedElementLookup(
25600
- ":scope > translation[lang]",
25601
- "translation[lang]"
25602
- );
25603
- const translationElementsCache = new UpsertableWeakMap();
25604
- const getTranslationElementMap = (modelElement) => {
25605
- return translationElementsCache.upsert(modelElement, () => {
25606
- const itextRoot = getItextRoot(modelElement);
25607
- if (itextRoot == null) {
25608
- return /* @__PURE__ */ new Map();
25609
- }
25610
- const translationElements = Array.from(
25611
- translationLookup.getElements(itextRoot)
25612
- );
25613
- return new Map(
25614
- translationElements.map((element) => {
25615
- return [element.getAttribute("lang"), element];
25616
- })
25617
- );
25618
- });
25619
- };
25620
- const getTranslationElement = (modelElement, translationLanguage) => {
25621
- const translationElementMap = getTranslationElementMap(modelElement);
25622
- return translationElementMap.get(translationLanguage) ?? null;
25623
- };
25624
- const translationTextLookup = new ScopedElementLookup(":scope > text[id]", "text[id]");
25625
- const translationsCache = new UpsertableWeakMap();
25626
- const getTranslationTextByLanguage = (modelElement, language, itextID) => {
25627
- const translationElement = getTranslationElement(modelElement, language);
25628
- if (translationElement == null) {
25629
- return null;
25630
- }
25631
- const textMaps = translationsCache.upsert(modelElement, () => {
25632
- return new UpsertableWeakMap();
25633
- });
25634
- const textMap = textMaps.upsert(translationElement, () => {
25635
- const textElements = Array.from(
25636
- translationTextLookup.getElements(translationElement)
25637
- );
25638
- return new Map(
25639
- textElements.map((element) => {
25640
- return [element.getAttribute("id"), element];
25641
- })
25642
- );
25643
- });
25644
- return textMap.get(itextID) ?? null;
25645
- };
25646
- const defaultTextValueLookup = new ScopedElementLookup(
25647
- ":scope > value:not([form])",
25648
- "value:not([form])"
25649
- );
25650
- const getDefaultTextValueElement = (textElement) => {
25651
- return defaultTextValueLookup.getElement(textElement);
25652
- };
25653
- const getTranslationMetadata = (modelElement) => {
25654
- const languages = [];
25655
- let defaultLanguage = null;
25656
- if (modelElement == null) {
25657
- return {
25658
- defaultLanguage,
25659
- languages
25660
- };
25661
- }
25662
- const translationElementMap = getTranslationElementMap(modelElement);
25663
- for (const [language, element] of translationElementMap) {
25664
- if (defaultLanguage == null && element.hasAttribute("default")) {
25665
- defaultLanguage = language;
25666
- languages.unshift(language);
25667
- } else {
25668
- languages.push(language);
25669
- }
25670
- }
25671
- if (defaultLanguage == null) {
25672
- defaultLanguage = languages[0] ?? null;
25673
- }
25674
- return {
25675
- defaultLanguage,
25676
- languages
25677
- };
25678
- };
25679
- class XFormsItextTranslations {
25680
- constructor(evaluator) {
25681
- this.evaluator = evaluator;
25682
- const { defaultLanguage, languages } = getTranslationMetadata(evaluator.modelElement);
25683
- this.defaultLanguage = defaultLanguage;
25684
- this.activeLanguage = defaultLanguage;
25685
- this.languages = languages;
25686
- }
25687
- defaultLanguage;
25688
- languages;
25689
- activeLanguage;
25690
- getLanguages() {
25691
- return this.languages;
25692
- }
25693
- getActiveLanguage() {
25694
- return this.activeLanguage;
25695
- }
25696
- setActiveLanguage(language) {
25697
- this.activeLanguage = language ?? this.defaultLanguage;
25698
- return this.activeLanguage;
25699
- }
25700
- }
25701
-
25702
25975
  const itext = new StringFunction(
25703
25976
  "itext",
25704
25977
  [{ arityType: "required", typeHint: "string" }],
25705
25978
  (context, [itextIDExpression]) => {
25706
- const { evaluator } = context;
25707
- if (!(evaluator instanceof XFormsXPathEvaluator)) {
25708
- throw new Error("itext not available");
25709
- }
25710
- const { modelElement } = evaluator;
25711
- if (modelElement == null) {
25712
- return "";
25713
- }
25714
- const activeLanguage = evaluator.translations.getActiveLanguage();
25715
- if (activeLanguage == null) {
25716
- return "";
25717
- }
25718
25979
  const itextID = itextIDExpression.evaluate(context).toString();
25719
- const textElement = getTranslationTextByLanguage(modelElement, activeLanguage, itextID);
25720
- if (textElement == null) {
25721
- return "";
25722
- }
25723
- const defaultTextValue = getDefaultTextValueElement(textElement);
25724
- return defaultTextValue?.textContent ?? "";
25980
+ return XFormsXPathEvaluator.getDefaultTranslationText(context, itextID);
25725
25981
  }
25726
25982
  );
25727
25983
 
25728
25984
  const string$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
25729
- __proto__: null,
25730
- itext
25985
+ __proto__: null,
25986
+ itext
25731
25987
  }, Symbol.toStringTag, { value: 'Module' }));
25732
25988
 
25733
25989
  const jr = new FunctionLibrary(JAVAROSA_NAMESPACE_URI, [...Object.values(string$1)]);
@@ -25823,11 +26079,11 @@ const xfIf = new FunctionImplementation(
25823
26079
  );
25824
26080
 
25825
26081
  const boolean = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
25826
- __proto__: null,
25827
- booleanFromString,
25828
- checklist,
25829
- weightedChecklist,
25830
- xfIf
26082
+ __proto__: null,
26083
+ booleanFromString,
26084
+ checklist,
26085
+ weightedChecklist,
26086
+ xfIf
25831
26087
  }, Symbol.toStringTag, { value: 'Module' }));
25832
26088
 
25833
26089
  const DEGREES_MAX = {
@@ -25977,9 +26233,9 @@ const distance = new NumberFunction(
25977
26233
  );
25978
26234
 
25979
26235
  const geo = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
25980
- __proto__: null,
25981
- area,
25982
- distance
26236
+ __proto__: null,
26237
+ area,
26238
+ distance
25983
26239
  }, Symbol.toStringTag, { value: 'Module' }));
25984
26240
 
25985
26241
  const MAX_INT_32 = 2147483647;
@@ -26051,23 +26307,18 @@ const assertArgument = (index, arg) => {
26051
26307
  throw new Error(`Argument ${index + 1} expected`);
26052
26308
  }
26053
26309
  };
26054
- const assertIsLocationPathEvaluation = (evaluation) => {
26055
- if (!(evaluation instanceof LocationPathEvaluation)) {
26056
- throw new Error("Expected a node-set result");
26057
- }
26058
- };
26059
26310
  const evaluateArgumentToFilterableNodes = (context, arg) => {
26060
26311
  const evaluation = arg.evaluate(context);
26061
- assertIsLocationPathEvaluation(evaluation);
26312
+ LocationPathEvaluation.assertInstance(context, evaluation);
26062
26313
  return Array.from(evaluation.contextNodes);
26063
26314
  };
26064
- const compareContainmentDepth = ({ repeats: a }, { repeats: b }) => {
26315
+ const compareContainmentDepth = (domProvider, { repeats: a }, { repeats: b }) => {
26065
26316
  for (const repeatA of a) {
26066
26317
  for (const repeatB of b) {
26067
- if (repeatA.contains(repeatB)) {
26318
+ if (domProvider.isDescendantNode(repeatA, repeatB)) {
26068
26319
  return -1;
26069
26320
  }
26070
- if (repeatB.contains(repeatA)) {
26321
+ if (domProvider.isDescendantNode(repeatB, repeatA)) {
26071
26322
  return 1;
26072
26323
  }
26073
26324
  }
@@ -26118,14 +26369,15 @@ const indexedRepeat = new NodeSetFunction(
26118
26369
  position: position2
26119
26370
  });
26120
26371
  }
26121
- pairs = pairs.sort(compareContainmentDepth);
26372
+ const { domProvider } = context;
26373
+ pairs = pairs.sort((pairA, pairB) => compareContainmentDepth(domProvider, pairA, pairB));
26122
26374
  let repeatContextNode;
26123
26375
  for (const [index, pair] of pairs.entries()) {
26124
26376
  const { position: position2 } = pair;
26125
26377
  let { repeats } = pair;
26126
26378
  if (index > 0) {
26127
26379
  repeats = pair.repeats.filter((repeat) => {
26128
- return repeatContextNode.contains(repeat);
26380
+ return domProvider.isDescendantNode(repeatContextNode, repeat);
26129
26381
  });
26130
26382
  }
26131
26383
  const positionedRepeat = repeats[position2 - 1];
@@ -26136,40 +26388,20 @@ const indexedRepeat = new NodeSetFunction(
26136
26388
  }
26137
26389
  const targetNodes = evaluateArgumentToFilterableNodes(context, target);
26138
26390
  return targetNodes.filter((targetNode) => {
26139
- return repeatContextNode.contains(targetNode);
26391
+ return domProvider.isDescendantNode(repeatContextNode, targetNode);
26140
26392
  });
26141
26393
  }
26142
26394
  );
26143
- const identifiedInstanceLookup = new ScopedElementLookup(":scope > instance[id]", "instance[id]");
26144
- const instancesCache = new UpsertableWeakMap();
26145
- const getInstanceElementByID = (modelElement, id) => {
26146
- const instances = instancesCache.upsert(modelElement, () => {
26147
- const instanceElements = Array.from(
26148
- identifiedInstanceLookup.getElements(modelElement)
26149
- );
26150
- return new Map(
26151
- instanceElements.map((element) => {
26152
- return [element.getAttribute("id"), element];
26153
- })
26154
- );
26155
- });
26156
- return instances.get(id) ?? null;
26157
- };
26158
26395
  const instance = new NodeSetFunction(
26159
26396
  "instance",
26160
26397
  [{ arityType: "required" }],
26161
26398
  (context, [idExpression]) => {
26162
26399
  const id = idExpression.evaluate(context).toString();
26163
- const { evaluator } = context;
26164
- if (!(evaluator instanceof XFormsXPathEvaluator)) {
26165
- throw new Error("itext not available");
26166
- }
26167
- const { modelElement } = evaluator;
26168
- if (modelElement == null) {
26400
+ const instanceElement = XFormsXPathEvaluator.getSecondaryInstance(context, id);
26401
+ if (instanceElement == null) {
26169
26402
  return [];
26170
26403
  }
26171
- const instanceElement = getInstanceElementByID(modelElement, id);
26172
- return instanceElement == null ? [] : [instanceElement];
26404
+ return [instanceElement];
26173
26405
  }
26174
26406
  );
26175
26407
  const once = new StringFunction(
@@ -26180,13 +26412,17 @@ const once = new StringFunction(
26180
26412
  if (contextNode == null) {
26181
26413
  throw "todo once no context";
26182
26414
  }
26183
- const string = contextNode.textContent ?? "";
26415
+ const string = context.domProvider.getNodeValue(contextNode);
26184
26416
  if (string === "") {
26185
26417
  return expression.evaluate(context).toString();
26186
26418
  }
26187
26419
  return string;
26188
26420
  }
26189
26421
  );
26422
+ const isLikelyRepeatRangeEvaluationContextCommentMarkerNode = (context, node) => {
26423
+ const { evaluationContextNode } = context;
26424
+ return context.domProvider.isComment(node) && node === evaluationContextNode;
26425
+ };
26190
26426
  const position = new NumberFunction(
26191
26427
  "position",
26192
26428
  [{ arityType: "optional" }],
@@ -26195,9 +26431,7 @@ const position = new NumberFunction(
26195
26431
  return context.contextPosition();
26196
26432
  }
26197
26433
  const results = expression.evaluate(context);
26198
- if (!(results instanceof LocationPathEvaluation)) {
26199
- throw "todo not a node-set";
26200
- }
26434
+ LocationPathEvaluation.assertInstance(context, results);
26201
26435
  const [first, next] = results.values();
26202
26436
  if (first == null) {
26203
26437
  return NaN;
@@ -26205,15 +26439,27 @@ const position = new NumberFunction(
26205
26439
  if (next != null) {
26206
26440
  throw "todo enforce single node(?)";
26207
26441
  }
26442
+ const { domProvider } = context;
26208
26443
  const { value } = first;
26209
- const { nodeName } = value;
26210
- let currentNode = value;
26211
- let result = 1;
26212
- while ((currentNode = currentNode.previousSibling) != null) {
26213
- if (currentNode.nodeName === nodeName) {
26214
- result += 1;
26444
+ if (!domProvider.isQualifiedNamedNode(value)) {
26445
+ if (isLikelyRepeatRangeEvaluationContextCommentMarkerNode(context, value)) {
26446
+ return context.contextPosition();
26215
26447
  }
26448
+ throw new Error(
26449
+ "Cannot get position among contiguous nodes with same name: not a named node."
26450
+ );
26216
26451
  }
26452
+ const nodeName = domProvider.getQualifiedName(value);
26453
+ let currentNode = value;
26454
+ let result = 0;
26455
+ do {
26456
+ result += 1;
26457
+ const previousNode = domProvider.getPreviousSiblingElement(currentNode);
26458
+ if (previousNode == null) {
26459
+ break;
26460
+ }
26461
+ currentNode = previousNode;
26462
+ } while (domProvider.getQualifiedName(currentNode) === nodeName);
26217
26463
  return result;
26218
26464
  }
26219
26465
  );
@@ -26225,9 +26471,7 @@ const randomize = new NodeSetFunction(
26225
26471
  ],
26226
26472
  (context, [expression, seedExpression]) => {
26227
26473
  const results = expression.evaluate(context);
26228
- if (!(results instanceof LocationPathEvaluation)) {
26229
- throw "todo (not a node-set)";
26230
- }
26474
+ LocationPathEvaluation.assertInstance(context, results);
26231
26475
  const nodeResults = Array.from(results.values());
26232
26476
  const nodes = nodeResults.map(({ value }) => value);
26233
26477
  const seed = seedExpression?.evaluate(context).toNumber();
@@ -26236,13 +26480,13 @@ const randomize = new NodeSetFunction(
26236
26480
  );
26237
26481
 
26238
26482
  const nodeset = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
26239
- __proto__: null,
26240
- countNonEmpty,
26241
- indexedRepeat,
26242
- instance,
26243
- once,
26244
- position,
26245
- randomize
26483
+ __proto__: null,
26484
+ countNonEmpty,
26485
+ indexedRepeat,
26486
+ instance,
26487
+ once,
26488
+ position,
26489
+ randomize
26246
26490
  }, Symbol.toStringTag, { value: 'Module' }));
26247
26491
 
26248
26492
  const abs = mathAlias("abs");
@@ -26327,28 +26571,28 @@ const sqrt = mathAlias("sqrt");
26327
26571
  const tan = mathAlias("tan");
26328
26572
 
26329
26573
  const number$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
26330
- __proto__: null,
26331
- abs,
26332
- acos,
26333
- asin,
26334
- atan,
26335
- atan2,
26336
- cos,
26337
- exp,
26338
- exp10,
26339
- int,
26340
- log,
26341
- log10,
26342
- max,
26343
- min,
26344
- number,
26345
- pi,
26346
- pow,
26347
- random,
26348
- round,
26349
- sin,
26350
- sqrt,
26351
- tan
26574
+ __proto__: null,
26575
+ abs,
26576
+ acos,
26577
+ asin,
26578
+ atan,
26579
+ atan2,
26580
+ cos,
26581
+ exp,
26582
+ exp10,
26583
+ int,
26584
+ log,
26585
+ log10,
26586
+ max,
26587
+ min,
26588
+ number,
26589
+ pi,
26590
+ pow,
26591
+ random,
26592
+ round,
26593
+ sin,
26594
+ sqrt,
26595
+ tan
26352
26596
  }, Symbol.toStringTag, { value: 'Module' }));
26353
26597
 
26354
26598
  const countSelected = new NumberFunction(
@@ -26385,10 +26629,10 @@ const selectedAt = new StringFunction(
26385
26629
  );
26386
26630
 
26387
26631
  const select = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
26388
- __proto__: null,
26389
- countSelected,
26390
- selected,
26391
- selectedAt
26632
+ __proto__: null,
26633
+ countSelected,
26634
+ selected,
26635
+ selectedAt
26392
26636
  }, Symbol.toStringTag, { value: 'Module' }));
26393
26637
 
26394
26638
  var cryptoJs = {exports: {}};
@@ -26402,8 +26646,8 @@ var core = {exports: {}};
26402
26646
  const __viteBrowserExternal = {};
26403
26647
 
26404
26648
  const __viteBrowserExternal$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
26405
- __proto__: null,
26406
- default: __viteBrowserExternal
26649
+ __proto__: null,
26650
+ default: __viteBrowserExternal
26407
26651
  }, Symbol.toStringTag, { value: 'Module' }));
26408
26652
 
26409
26653
  const require$$0 = /*@__PURE__*/getAugmentedNamespace(__viteBrowserExternal$1);
@@ -27798,8 +28042,8 @@ var encBase64Exports = encBase64$1.exports;
27798
28042
  const encBase64 = /*@__PURE__*/getDefaultExportFromCjs(encBase64Exports);
27799
28043
 
27800
28044
  const base64 = /*#__PURE__*/_mergeNamespaces({
27801
- __proto__: null,
27802
- default: encBase64
28045
+ __proto__: null,
28046
+ default: encBase64
27803
28047
  }, [encBase64Exports]);
27804
28048
 
27805
28049
  var encBase64url = {exports: {}};
@@ -32947,8 +33191,8 @@ var encHexExports = encHex$1.exports;
32947
33191
  const encHex = /*@__PURE__*/getDefaultExportFromCjs(encHexExports);
32948
33192
 
32949
33193
  const hex = /*#__PURE__*/_mergeNamespaces({
32950
- __proto__: null,
32951
- default: encHex
33194
+ __proto__: null,
33195
+ default: encHex
32952
33196
  }, [encHexExports]);
32953
33197
 
32954
33198
  const toStrings = (context, expressions) => {
@@ -32979,11 +33223,11 @@ const coalesce = new StringFunction(
32979
33223
  const concat = new StringFunction(
32980
33224
  "concat",
32981
33225
  [{ arityType: "variadic", typeHint: "string" }],
32982
- (context, expressions) => {
32983
- if (expressions.length === 0) {
33226
+ (context, args) => {
33227
+ if (args.length === 0) {
32984
33228
  return "";
32985
33229
  }
32986
- return expressions.flatMap((expression) => {
33230
+ return args.flatMap((expression) => {
32987
33231
  const results = expression.evaluate(context);
32988
33232
  return Array.from(results).map((result) => result.toString());
32989
33233
  }).join("");
@@ -33089,10 +33333,29 @@ const substr = new StringFunction(
33089
33333
  return start <= end ? string.substring(start, end) : "";
33090
33334
  }
33091
33335
  );
33336
+ let didAssertCrypto = false;
33337
+ const assertCrypto = (crypto) => {
33338
+ if (didAssertCrypto) {
33339
+ return;
33340
+ }
33341
+ if (typeof crypto !== "object" || crypto == null) {
33342
+ throw new IncompatibleRuntimeEnvironmentError();
33343
+ }
33344
+ if (typeof crypto.randomUUID !== "function" || crypto.randomUUID.length !== 0) {
33345
+ throw new IncompatibleRuntimeEnvironmentError();
33346
+ }
33347
+ didAssertCrypto = true;
33348
+ };
33349
+ const getGlobalCrypto = () => {
33350
+ const { crypto } = globalThis;
33351
+ assertCrypto(crypto);
33352
+ return crypto;
33353
+ };
33092
33354
  const uuid = new StringFunction(
33093
33355
  "uuid",
33094
33356
  [{ arityType: "optional", typeHint: "number" }],
33095
33357
  (context, [lengthExpression]) => {
33358
+ const crypto = getGlobalCrypto();
33096
33359
  let result = crypto.randomUUID();
33097
33360
  if (lengthExpression == null) {
33098
33361
  return result;
@@ -33109,15 +33372,15 @@ const uuid = new StringFunction(
33109
33372
  );
33110
33373
 
33111
33374
  const string = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
33112
- __proto__: null,
33113
- coalesce,
33114
- concat,
33115
- digest,
33116
- endsWith,
33117
- join,
33118
- regex,
33119
- substr,
33120
- uuid
33375
+ __proto__: null,
33376
+ coalesce,
33377
+ concat,
33378
+ digest,
33379
+ endsWith,
33380
+ join,
33381
+ regex,
33382
+ substr,
33383
+ uuid
33121
33384
  }, Symbol.toStringTag, { value: 'Module' }));
33122
33385
 
33123
33386
  const xf = new FunctionLibrary(XFORMS_NAMESPACE_URI, [
@@ -33130,29 +33393,197 @@ const xf = new FunctionLibrary(XFORMS_NAMESPACE_URI, [
33130
33393
  ...Object.values(string)
33131
33394
  ]);
33132
33395
 
33396
+ class UpsertableWeakMap extends WeakMap {
33397
+ upsert(key, produce) {
33398
+ if (this.has(key)) {
33399
+ return this.get(key);
33400
+ }
33401
+ const value = produce(key);
33402
+ this.set(key, value);
33403
+ return value;
33404
+ }
33405
+ }
33406
+
33407
+ class XFormsItextTranslations {
33408
+ constructor(domProvider, translationElementMap) {
33409
+ this.domProvider = domProvider;
33410
+ this.translationElementMap = translationElementMap;
33411
+ this.domProvider = domProvider;
33412
+ this.translationElementMap = translationElementMap;
33413
+ const { defaultLanguage, languages } = this.getTranslationMetadata(
33414
+ domProvider,
33415
+ translationElementMap
33416
+ );
33417
+ this.defaultLanguage = defaultLanguage;
33418
+ this.activeLanguage = defaultLanguage;
33419
+ this.languages = languages;
33420
+ }
33421
+ defaultLanguage = null;
33422
+ languages = [];
33423
+ activeLanguage = null;
33424
+ translationsCache = new UpsertableWeakMap();
33425
+ getTranslationMetadata(domProvider, translationElementMap) {
33426
+ const languages = [];
33427
+ let defaultLanguage = null;
33428
+ for (const [language, element] of translationElementMap) {
33429
+ if (defaultLanguage == null && domProvider.hasLocalNamedAttribute(element, "default")) {
33430
+ defaultLanguage = language;
33431
+ languages.unshift(language);
33432
+ } else {
33433
+ languages.push(language);
33434
+ }
33435
+ }
33436
+ if (defaultLanguage == null) {
33437
+ defaultLanguage = languages[0] ?? null;
33438
+ }
33439
+ return {
33440
+ defaultLanguage,
33441
+ languages
33442
+ };
33443
+ }
33444
+ getTranslationTextElement(itextID) {
33445
+ const activeLanguage = this.getActiveLanguage();
33446
+ if (activeLanguage == null) {
33447
+ return null;
33448
+ }
33449
+ const { domProvider, translationElementMap, translationsCache } = this;
33450
+ const translationElement = translationElementMap.get(activeLanguage);
33451
+ if (translationElement == null) {
33452
+ return null;
33453
+ }
33454
+ const textMap = translationsCache.upsert(translationElement, () => {
33455
+ const textElements = Array.from(
33456
+ domProvider.getChildrenByLocalName(translationElement, "text")
33457
+ );
33458
+ return new Map(
33459
+ textElements.flatMap((element) => {
33460
+ const id = domProvider.getLocalNamedAttributeValue(element, "id");
33461
+ if (id == null) {
33462
+ return [];
33463
+ }
33464
+ return [[id, element]];
33465
+ })
33466
+ );
33467
+ });
33468
+ return textMap.get(itextID) ?? null;
33469
+ }
33470
+ /**
33471
+ * @package
33472
+ *
33473
+ * Here, "default" is meant as more precise language than "regular" as
33474
+ * {@link https://getodk.github.io/xforms-spec/#languages | specified by ODK XForms}. In other words, this is equivalent to the following hypothetical XPath pseudo-code (whitespace added to improve structural clarity):
33475
+ *
33476
+ * ```xpath
33477
+ * string(
33478
+ * imaginary:itext-translation(
33479
+ * xpath3-fn:environment-variable('activeLanguage')
33480
+ * )
33481
+ * /text[@id = $itextID]
33482
+ * /value[not(@form)]
33483
+ * )
33484
+ * ```
33485
+ *
33486
+ * Or alternately:
33487
+ *
33488
+ * ```xpath
33489
+ * string(
33490
+ * imaginary:itext-root()
33491
+ * /translation[@lang = xpath3-fn:environment-variable('activeLanguage')]
33492
+ * /text[@id = $itextID]
33493
+ * /value[not(@form)]
33494
+ * )
33495
+ * ```
33496
+ *
33497
+ * @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
33498
+ */
33499
+ getDefaultTranslationText(itextID) {
33500
+ const textElement = this.getTranslationTextElement(itextID);
33501
+ if (textElement == null) {
33502
+ return "";
33503
+ }
33504
+ const { domProvider } = this;
33505
+ for (const valueElement of domProvider.getChildrenByLocalName(textElement, "value")) {
33506
+ if (!domProvider.hasLocalNamedAttribute(valueElement, "form")) {
33507
+ return domProvider.getNodeValue(valueElement);
33508
+ }
33509
+ }
33510
+ return "";
33511
+ }
33512
+ getLanguages() {
33513
+ return this.languages;
33514
+ }
33515
+ getActiveLanguage() {
33516
+ return this.activeLanguage;
33517
+ }
33518
+ setActiveLanguage(language) {
33519
+ this.activeLanguage = language ?? this.defaultLanguage;
33520
+ return this.activeLanguage;
33521
+ }
33522
+ }
33523
+
33133
33524
  const functions = new FunctionLibraryCollection([enk, xf, fn, jr], {
33134
33525
  defaultNamespaceURIs: [enk.namespaceURI, xf.namespaceURI, fn.namespaceURI]
33135
33526
  });
33527
+ const assertInternalXFormsXPathEvaluatorContext = (context) => {
33528
+ const { evaluator } = context;
33529
+ if (evaluator instanceof XFormsXPathEvaluator && /**
33530
+ * This check ensures that we apply consistent DOM adapter access where an
33531
+ * (ODK XForms) XPath expression crosses tree boundaries (e.g. any two of
33532
+ * primary instance, secondary instance, itext translations).
33533
+ *
33534
+ * It's not totally clear whether this check is strictly necessary! Even if
33535
+ * not, it should be cheap enough not to bother finding out.
33536
+ */
33537
+ evaluator.domProvider === context.domProvider) {
33538
+ return;
33539
+ }
33540
+ throw new Error("Expected evaluation context initiated by XFormsXPathEvaluator");
33541
+ };
33136
33542
  class XFormsXPathEvaluator extends Evaluator {
33543
+ static getSecondaryInstance(context, id) {
33544
+ assertInternalXFormsXPathEvaluatorContext(context);
33545
+ return context.evaluator.secondaryInstancesById.get(id) ?? null;
33546
+ }
33547
+ static getDefaultTranslationText(context, itextID) {
33548
+ assertInternalXFormsXPathEvaluatorContext(context);
33549
+ return context.evaluator.itextTranslations.getDefaultTranslationText(itextID);
33550
+ }
33137
33551
  rootNode;
33138
- rootNodeDocument;
33139
- modelElement;
33140
- translations;
33552
+ /**
33553
+ * @package
33554
+ * @see {@link InternalXFormsXPathEvaluator}
33555
+ */
33556
+ itextTranslations;
33557
+ /**
33558
+ * @package
33559
+ * @see {@link InternalXFormsXPathEvaluator}
33560
+ */
33561
+ secondaryInstancesById;
33141
33562
  constructor(options) {
33142
33563
  super({
33143
33564
  functions,
33144
33565
  ...options
33145
33566
  });
33146
- const { rootNode } = options;
33147
- const rootNodeDocument = rootNode.ownerDocument ?? rootNode;
33148
- this.modelElement = this.evaluateNode("./h:html/h:head/xf:model", {
33149
- contextNode: rootNodeDocument
33150
- });
33567
+ this.secondaryInstancesById = options.secondaryInstancesById;
33151
33568
  this.rootNode = options.rootNode;
33152
- this.rootNodeDocument = rootNodeDocument;
33153
- this.translations = new XFormsItextTranslations(this);
33569
+ this.itextTranslations = new XFormsItextTranslations(
33570
+ this.domProvider,
33571
+ options.itextTranslationsByLanguage
33572
+ );
33573
+ }
33574
+ getLanguages() {
33575
+ return this.itextTranslations.getLanguages();
33576
+ }
33577
+ getActiveLanguage() {
33578
+ return this.itextTranslations.getActiveLanguage();
33579
+ }
33580
+ setActiveLanguage(language) {
33581
+ return this.itextTranslations.setActiveLanguage(language);
33582
+ }
33583
+ getSecondaryInstance(id) {
33584
+ return this.secondaryInstancesById.get(id);
33154
33585
  }
33155
33586
  }
33156
33587
 
33157
- export { Evaluator, XFormsXPathEvaluator };
33588
+ export { DEFAULT_DOM_ADAPTER, DEFAULT_DOM_PROVIDER, DefaultEvaluator, Evaluator, XFORMS_KNOWN_ATTRIBUTE, XFORMS_LOCAL_NAME, XFormsXPathEvaluator, XPathNodeKindKey };
33158
33589
  //# sourceMappingURL=index.js.map