dom_util.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.NodeType = void 0;
  4. exports.toArray = toArray;
  5. exports.parseInput = parseInput;
  6. exports.replaceNode = replaceNode;
  7. exports.createElement = createElement;
  8. exports.createElementNS = createElementNS;
  9. exports.createTextNode = createTextNode;
  10. exports.formatXml = formatXml;
  11. exports.querySelectorAllByAttr = querySelectorAllByAttr;
  12. exports.querySelectorAllByAttrValue = querySelectorAllByAttrValue;
  13. exports.querySelectorAll = querySelectorAll;
  14. exports.tagName = tagName;
  15. exports.cloneNode = cloneNode;
  16. exports.serializeXml = serializeXml;
  17. const engine_js_1 = require("./engine.js");
  18. const EngineConst = require("../common/engine_const.js");
  19. const system_external_js_1 = require("./system_external.js");
  20. const XpathUtil = require("./xpath_util.js");
  21. function toArray(nodeList) {
  22. const nodeArray = [];
  23. for (let i = 0, m = nodeList.length; i < m; i++) {
  24. nodeArray.push(nodeList[i]);
  25. }
  26. return nodeArray;
  27. }
  28. function trimInput(input) {
  29. input = input.replace(/&nbsp;/g, ' ');
  30. return input.replace(/>[ \f\n\r\t\v\u200b]+</g, '><').trim();
  31. }
  32. function parseInput(input) {
  33. const dp = new system_external_js_1.SystemExternal.xmldom.DOMParser();
  34. const clean_input = trimInput(input);
  35. const allValues = clean_input.match(/&(?!lt|gt|amp|quot|apos)\w+;/g);
  36. const html = !!allValues;
  37. if (!clean_input) {
  38. throw new Error('Empty input!');
  39. }
  40. try {
  41. const doc = dp.parseFromString(clean_input, html ? 'text/html' : 'text/xml');
  42. if (engine_js_1.Engine.getInstance().mode === EngineConst.Mode.HTTP) {
  43. XpathUtil.xpath.currentDocument = doc;
  44. return html ? doc.body.childNodes[0] : doc.documentElement;
  45. }
  46. return doc.documentElement;
  47. }
  48. catch (err) {
  49. throw new engine_js_1.SREError('Illegal input: ' + err.message);
  50. }
  51. }
  52. var NodeType;
  53. (function (NodeType) {
  54. NodeType[NodeType["ELEMENT_NODE"] = 1] = "ELEMENT_NODE";
  55. NodeType[NodeType["ATTRIBUTE_NODE"] = 2] = "ATTRIBUTE_NODE";
  56. NodeType[NodeType["TEXT_NODE"] = 3] = "TEXT_NODE";
  57. NodeType[NodeType["CDATA_SECTION_NODE"] = 4] = "CDATA_SECTION_NODE";
  58. NodeType[NodeType["ENTITY_REFERENCE_NODE"] = 5] = "ENTITY_REFERENCE_NODE";
  59. NodeType[NodeType["ENTITY_NODE"] = 6] = "ENTITY_NODE";
  60. NodeType[NodeType["PROCESSING_INSTRUCTION_NODE"] = 7] = "PROCESSING_INSTRUCTION_NODE";
  61. NodeType[NodeType["COMMENT_NODE"] = 8] = "COMMENT_NODE";
  62. NodeType[NodeType["DOCUMENT_NODE"] = 9] = "DOCUMENT_NODE";
  63. NodeType[NodeType["DOCUMENT_TYPE_NODE"] = 10] = "DOCUMENT_TYPE_NODE";
  64. NodeType[NodeType["DOCUMENT_FRAGMENT_NODE"] = 11] = "DOCUMENT_FRAGMENT_NODE";
  65. NodeType[NodeType["NOTATION_NODE"] = 12] = "NOTATION_NODE";
  66. })(NodeType || (exports.NodeType = NodeType = {}));
  67. function replaceNode(oldNode, newNode) {
  68. if (!oldNode.parentNode) {
  69. return;
  70. }
  71. oldNode.parentNode.insertBefore(newNode, oldNode);
  72. oldNode.parentNode.removeChild(oldNode);
  73. }
  74. function createElement(tag) {
  75. return system_external_js_1.SystemExternal.document.createElement(tag);
  76. }
  77. function createElementNS(url, tag) {
  78. return system_external_js_1.SystemExternal.document.createElementNS(url, tag);
  79. }
  80. function createTextNode(content) {
  81. return system_external_js_1.SystemExternal.document.createTextNode(content);
  82. }
  83. function formatXml(xml) {
  84. let formatted = '';
  85. let reg = /(>)(<)(\/*)/g;
  86. xml = xml.replace(reg, '$1\r\n$2$3');
  87. let pad = 0;
  88. let split = xml.split('\r\n');
  89. reg = /(\.)*(<)(\/*)/g;
  90. split = split
  91. .map((x) => x.replace(reg, '$1\r\n$2$3').split('\r\n'))
  92. .reduce((x, y) => x.concat(y), []);
  93. while (split.length) {
  94. let node = split.shift();
  95. if (!node) {
  96. continue;
  97. }
  98. let indent = 0;
  99. if (node.match(/^<\w[^>/]*>[^>]+$/)) {
  100. const match = matchingStartEnd(node, split[0]);
  101. if (match[0]) {
  102. if (match[1]) {
  103. node = node + split.shift().slice(0, -match[1].length);
  104. if (match[1].trim()) {
  105. split.unshift(match[1]);
  106. }
  107. }
  108. else {
  109. node = node + split.shift();
  110. }
  111. }
  112. else {
  113. indent = 1;
  114. }
  115. }
  116. else if (node.match(/^<\/\w/)) {
  117. if (pad !== 0) {
  118. pad -= 1;
  119. }
  120. }
  121. else if (node.match(/^<\w[^>]*[^/]>.*$/)) {
  122. indent = 1;
  123. }
  124. else if (node.match(/^<\w[^>]*\/>.+$/)) {
  125. const position = node.indexOf('>') + 1;
  126. const rest = node.slice(position);
  127. if (rest.trim()) {
  128. split.unshift();
  129. }
  130. node = node.slice(0, position) + rest;
  131. }
  132. else {
  133. indent = 0;
  134. }
  135. formatted += new Array(pad + 1).join(' ') + node + '\r\n';
  136. pad += indent;
  137. }
  138. return formatted;
  139. }
  140. function matchingStartEnd(start, end) {
  141. if (!end) {
  142. return [false, ''];
  143. }
  144. const tag1 = start.match(/^<([^> ]+).*>/);
  145. const tag2 = end.match(/^<\/([^>]+)>(.*)/);
  146. return tag1 && tag2 && tag1[1] === tag2[1] ? [true, tag2[2]] : [false, ''];
  147. }
  148. function querySelectorAllByAttr(node, attr) {
  149. return node.querySelectorAll
  150. ? toArray(node.querySelectorAll(`[${attr}]`))
  151. : XpathUtil.evalXPath(`.//*[@${attr}]`, node);
  152. }
  153. function querySelectorAllByAttrValue(node, attr, value) {
  154. return node.querySelectorAll
  155. ? toArray(node.querySelectorAll(`[${attr}="${value}"]`))
  156. : XpathUtil.evalXPath(`.//*[@${attr}="${value}"]`, node);
  157. }
  158. function querySelectorAll(node, tag) {
  159. return node.querySelectorAll
  160. ? toArray(node.querySelectorAll(tag))
  161. : XpathUtil.evalXPath(`.//${tag}`, node);
  162. }
  163. function tagName(node) {
  164. return node.tagName.toUpperCase();
  165. }
  166. function cloneNode(node) {
  167. return node.cloneNode(true);
  168. }
  169. function serializeXml(node) {
  170. const xmls = new system_external_js_1.SystemExternal.xmldom.XMLSerializer();
  171. return xmls.serializeToString(node);
  172. }