xpath_util.js 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import { Engine } from './engine.js';
  2. import * as EngineConst from '../common/engine_const.js';
  3. import { SystemExternal } from './system_external.js';
  4. function xpathSupported() {
  5. if (typeof XPathResult === 'undefined') {
  6. return false;
  7. }
  8. return true;
  9. }
  10. export const xpath = {
  11. currentDocument: null,
  12. evaluate: xpathSupported()
  13. ? document.evaluate
  14. : SystemExternal.xpath.evaluate,
  15. result: xpathSupported() ? XPathResult : SystemExternal.xpath.XPathResult,
  16. createNSResolver: xpathSupported()
  17. ? document.createNSResolver
  18. : SystemExternal.xpath.createNSResolver
  19. };
  20. const nameSpaces = {
  21. xhtml: 'http://www.w3.org/1999/xhtml',
  22. mathml: 'http://www.w3.org/1998/Math/MathML',
  23. mml: 'http://www.w3.org/1998/Math/MathML',
  24. svg: 'http://www.w3.org/2000/svg'
  25. };
  26. export function resolveNameSpace(prefix) {
  27. return nameSpaces[prefix] || null;
  28. }
  29. class Resolver {
  30. constructor() {
  31. this.lookupNamespaceURI = resolveNameSpace;
  32. }
  33. }
  34. function evaluateXpath(expression, rootNode, type) {
  35. return Engine.getInstance().mode === EngineConst.Mode.HTTP &&
  36. !Engine.getInstance().isIE &&
  37. !Engine.getInstance().isEdge
  38. ? xpath.currentDocument.evaluate(expression, rootNode, resolveNameSpace, type, null)
  39. : xpath.evaluate(expression, rootNode, new Resolver(), type, null);
  40. }
  41. export function evalXPath(expression, rootNode) {
  42. let iterator;
  43. try {
  44. iterator = evaluateXpath(expression, rootNode, xpath.result.ORDERED_NODE_ITERATOR_TYPE);
  45. }
  46. catch (_err) {
  47. return [];
  48. }
  49. const results = [];
  50. for (let xpathNode = iterator.iterateNext(); xpathNode; xpathNode = iterator.iterateNext()) {
  51. results.push(xpathNode);
  52. }
  53. return results;
  54. }
  55. export function evaluateBoolean(expression, rootNode) {
  56. let result;
  57. try {
  58. result = evaluateXpath(expression, rootNode, xpath.result.BOOLEAN_TYPE);
  59. }
  60. catch (_err) {
  61. return false;
  62. }
  63. return result.booleanValue;
  64. }
  65. export function evaluateString(expression, rootNode) {
  66. let result;
  67. try {
  68. result = evaluateXpath(expression, rootNode, xpath.result.STRING_TYPE);
  69. }
  70. catch (_err) {
  71. return '';
  72. }
  73. return result.stringValue;
  74. }
  75. export function updateEvaluator(node) {
  76. if (Engine.getInstance().mode !== EngineConst.Mode.HTTP)
  77. return;
  78. let parent = node;
  79. while (parent && !parent.evaluate) {
  80. parent = parent.parentNode;
  81. }
  82. if (parent && parent.evaluate) {
  83. xpath.currentDocument = parent;
  84. }
  85. else if (node.ownerDocument) {
  86. xpath.currentDocument = node.ownerDocument;
  87. }
  88. }