You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1252 lines
48 KiB

  1. var __extends = (this && this.__extends) || (function () {
  2. var extendStatics = function (d, b) {
  3. extendStatics = Object.setPrototypeOf ||
  4. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  5. function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
  6. return extendStatics(d, b);
  7. };
  8. return function (d, b) {
  9. extendStatics(d, b);
  10. function __() { this.constructor = d; }
  11. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  12. };
  13. })();
  14. var __importDefault = (this && this.__importDefault) || function (mod) {
  15. return (mod && mod.__esModule) ? mod : { "default": mod };
  16. };
  17. var __spreadArrays = (this && this.__spreadArrays) || function () {
  18. for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
  19. for (var r = Array(s), k = 0, i = 0; i < il; i++)
  20. for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
  21. r[k] = a[j];
  22. return r;
  23. };
  24. define("back", ["require", "exports"], function (require, exports) {
  25. "use strict";
  26. Object.defineProperty(exports, "__esModule", { value: true });
  27. function arr_back(arr) {
  28. return arr[arr.length - 1];
  29. }
  30. exports.default = arr_back;
  31. });
  32. define("nodes/type", ["require", "exports"], function (require, exports) {
  33. "use strict";
  34. Object.defineProperty(exports, "__esModule", { value: true });
  35. var NodeType;
  36. (function (NodeType) {
  37. NodeType[NodeType["ELEMENT_NODE"] = 1] = "ELEMENT_NODE";
  38. NodeType[NodeType["TEXT_NODE"] = 3] = "TEXT_NODE";
  39. NodeType[NodeType["COMMENT_NODE"] = 8] = "COMMENT_NODE";
  40. })(NodeType || (NodeType = {}));
  41. exports.default = NodeType;
  42. });
  43. define("nodes/node", ["require", "exports"], function (require, exports) {
  44. "use strict";
  45. Object.defineProperty(exports, "__esModule", { value: true });
  46. /**
  47. * Node Class as base class for TextNode and HTMLElement.
  48. */
  49. var Node = /** @class */ (function () {
  50. function Node() {
  51. this.childNodes = [];
  52. }
  53. Object.defineProperty(Node.prototype, "innerText", {
  54. get: function () {
  55. return this.rawText;
  56. },
  57. enumerable: false,
  58. configurable: true
  59. });
  60. return Node;
  61. }());
  62. exports.default = Node;
  63. });
  64. define("nodes/comment", ["require", "exports", "nodes/node", "nodes/type"], function (require, exports, node_1, type_1) {
  65. "use strict";
  66. Object.defineProperty(exports, "__esModule", { value: true });
  67. node_1 = __importDefault(node_1);
  68. type_1 = __importDefault(type_1);
  69. var CommentNode = /** @class */ (function (_super) {
  70. __extends(CommentNode, _super);
  71. function CommentNode(rawText) {
  72. var _this = _super.call(this) || this;
  73. _this.rawText = rawText;
  74. /**
  75. * Node Type declaration.
  76. * @type {Number}
  77. */
  78. _this.nodeType = type_1.default.COMMENT_NODE;
  79. return _this;
  80. }
  81. Object.defineProperty(CommentNode.prototype, "text", {
  82. /**
  83. * Get unescaped text value of current node and its children.
  84. * @return {string} text content
  85. */
  86. get: function () {
  87. return this.rawText;
  88. },
  89. enumerable: false,
  90. configurable: true
  91. });
  92. CommentNode.prototype.toString = function () {
  93. return "<!--" + this.rawText + "-->";
  94. };
  95. return CommentNode;
  96. }(node_1.default));
  97. exports.default = CommentNode;
  98. });
  99. define("nodes/text", ["require", "exports", "nodes/type", "nodes/node"], function (require, exports, type_2, node_2) {
  100. "use strict";
  101. Object.defineProperty(exports, "__esModule", { value: true });
  102. type_2 = __importDefault(type_2);
  103. node_2 = __importDefault(node_2);
  104. /**
  105. * TextNode to contain a text element in DOM tree.
  106. * @param {string} value [description]
  107. */
  108. var TextNode = /** @class */ (function (_super) {
  109. __extends(TextNode, _super);
  110. function TextNode(rawText) {
  111. var _this = _super.call(this) || this;
  112. _this.rawText = rawText;
  113. /**
  114. * Node Type declaration.
  115. * @type {Number}
  116. */
  117. _this.nodeType = type_2.default.TEXT_NODE;
  118. return _this;
  119. }
  120. Object.defineProperty(TextNode.prototype, "text", {
  121. /**
  122. * Get unescaped text value of current node and its children.
  123. * @return {string} text content
  124. */
  125. get: function () {
  126. return this.rawText;
  127. },
  128. enumerable: false,
  129. configurable: true
  130. });
  131. Object.defineProperty(TextNode.prototype, "isWhitespace", {
  132. /**
  133. * Detect if the node contains only white space.
  134. * @return {bool}
  135. */
  136. get: function () {
  137. return /^(\s|&nbsp;)*$/.test(this.rawText);
  138. },
  139. enumerable: false,
  140. configurable: true
  141. });
  142. TextNode.prototype.toString = function () {
  143. return this.text;
  144. };
  145. return TextNode;
  146. }(node_2.default));
  147. exports.default = TextNode;
  148. });
  149. define("matcher", ["require", "exports"], function (require, exports) {
  150. "use strict";
  151. Object.defineProperty(exports, "__esModule", { value: true });
  152. /**
  153. * Cache to store generated match functions
  154. * @type {Object}
  155. */
  156. var pMatchFunctionCache = {};
  157. function compare_tagname(tag1, tag2) {
  158. if (!tag1) {
  159. return !tag2;
  160. }
  161. if (!tag2) {
  162. return !tag1;
  163. }
  164. return tag1.toLowerCase() === tag2.toLowerCase();
  165. }
  166. /**
  167. * Function cache
  168. */
  169. var functionCache = {
  170. f145: function (el, tagName, classes) {
  171. 'use strict';
  172. tagName = tagName || '';
  173. classes = classes || [];
  174. if (el.id !== tagName.substr(1)) {
  175. return false;
  176. }
  177. for (var cls = classes, i = 0; i < cls.length; i++) {
  178. if (el.classNames.indexOf(cls[i]) === -1) {
  179. return false;
  180. }
  181. }
  182. return true;
  183. },
  184. f45: function (el, tagName, classes) {
  185. 'use strict';
  186. tagName = tagName || '';
  187. classes = classes || [];
  188. for (var cls = classes, i = 0; i < cls.length; i++) {
  189. if (el.classNames.indexOf(cls[i]) === -1) {
  190. return false;
  191. }
  192. }
  193. return true;
  194. },
  195. f15: function (el, tagName) {
  196. 'use strict';
  197. tagName = tagName || '';
  198. if (el.id !== tagName.substr(1)) {
  199. return false;
  200. }
  201. return true;
  202. },
  203. f1: function (el, tagName) {
  204. 'use strict';
  205. tagName = tagName || '';
  206. if (el.id !== tagName.substr(1)) {
  207. return false;
  208. }
  209. },
  210. f5: function () {
  211. 'use strict';
  212. return true;
  213. },
  214. f55: function (el, tagName, classes, attr_key) {
  215. 'use strict';
  216. tagName = tagName || '';
  217. classes = classes || [];
  218. attr_key = attr_key || '';
  219. var attrs = el.attributes;
  220. return attrs.hasOwnProperty(attr_key);
  221. },
  222. f245: function (el, tagName, classes, attr_key, value) {
  223. 'use strict';
  224. tagName = tagName || '';
  225. classes = classes || [];
  226. attr_key = attr_key || '';
  227. value = value || '';
  228. var attrs = el.attributes;
  229. return Object.keys(attrs).some(function (key) {
  230. var val = attrs[key];
  231. return key === attr_key && val === value;
  232. });
  233. // for (let cls = classes, i = 0; i < cls.length; i++) {if (el.classNames.indexOf(cls[i]) === -1){ return false;}}
  234. // return true;
  235. },
  236. f25: function (el, tagName, classes, attr_key, value) {
  237. 'use strict';
  238. tagName = tagName || '';
  239. classes = classes || [];
  240. attr_key = attr_key || '';
  241. value = value || '';
  242. var attrs = el.attributes;
  243. return Object.keys(attrs).some(function (key) {
  244. var val = attrs[key];
  245. return key === attr_key && val === value;
  246. });
  247. // return true;
  248. },
  249. f2: function (el, tagName, classes, attr_key, value) {
  250. 'use strict';
  251. tagName = tagName || '';
  252. classes = classes || [];
  253. attr_key = attr_key || '';
  254. value = value || '';
  255. var attrs = el.attributes;
  256. return Object.keys(attrs).some(function (key) {
  257. var val = attrs[key];
  258. return key === attr_key && val === value;
  259. });
  260. },
  261. f345: function (el, tagName, classes) {
  262. 'use strict';
  263. tagName = tagName || '';
  264. classes = classes || [];
  265. if (!compare_tagname(el.tagName, tagName)) {
  266. return false;
  267. }
  268. for (var cls = classes, i = 0; i < cls.length; i++) {
  269. if (el.classNames.indexOf(cls[i]) === -1) {
  270. return false;
  271. }
  272. }
  273. return true;
  274. },
  275. f35: function (el, tagName) {
  276. 'use strict';
  277. tagName = tagName || '';
  278. return compare_tagname(el.tagName, tagName);
  279. },
  280. f3: function (el, tagName) {
  281. 'use strict';
  282. tagName = tagName || '';
  283. // if (el.tagName !== tagName) {
  284. // return false;
  285. // }
  286. return compare_tagname(el.tagName, tagName);
  287. }
  288. };
  289. /**
  290. * Matcher class to make CSS match
  291. *
  292. * @class Matcher
  293. */
  294. var Matcher = /** @class */ (function () {
  295. /**
  296. * Creates an instance of Matcher.
  297. * @param {string} selector
  298. *
  299. * @memberof Matcher
  300. */
  301. function Matcher(selector) {
  302. this.nextMatch = 0;
  303. this.matchers = selector.split(' ').map(function (matcher) {
  304. if (pMatchFunctionCache[matcher]) {
  305. return pMatchFunctionCache[matcher];
  306. }
  307. var parts = matcher.split('.');
  308. var tagName = parts[0];
  309. var classes = parts.slice(1).sort();
  310. // let source = '"use strict";';
  311. var function_name = 'f';
  312. var attr_key = '';
  313. var value = '';
  314. if (tagName && tagName !== '*') {
  315. var reg = void 0;
  316. if (tagName.startsWith('#')) {
  317. // source += 'if (el.id != ' + JSON.stringify(tagName.substr(1)) + ') return false;';// 1
  318. function_name += '1';
  319. }
  320. else {
  321. reg = /^\[\s*(\S+)\s*(=|!=)\s*((((["'])([^\6]*)\6))|(\S*?))\]\s*/.exec(tagName);
  322. if (reg) {
  323. attr_key = reg[1];
  324. var method = reg[2];
  325. if (method !== '=' && method !== '!=') {
  326. // eslint-disable-next-line no-template-curly-in-string
  327. throw new Error('Selector not supported, Expect [key${op}value].op must be =,!=');
  328. }
  329. if (method === '=') {
  330. method = '==';
  331. }
  332. value = reg[7] || reg[8];
  333. // source += `let attrs = el.attributes;for (let key in attrs){const val = attrs[key]; if (key == "${attr_key}" && val == "${value}"){return true;}} return false;`;// 2
  334. function_name += '2';
  335. }
  336. else if ((reg = /^\[(.*?)\]/.exec(tagName))) {
  337. attr_key = reg[1];
  338. function_name += '5';
  339. }
  340. else {
  341. // source += 'if (el.tagName != ' + JSON.stringify(tagName) + ') return false;';// 3
  342. function_name += '3';
  343. }
  344. }
  345. }
  346. if (classes.length > 0) {
  347. // source += 'for (let cls = ' + JSON.stringify(classes) + ', i = 0; i < cls.length; i++) if (el.classNames.indexOf(cls[i]) === -1) return false;';// 4
  348. function_name += '4';
  349. }
  350. // source += 'return true;';// 5
  351. function_name += '5';
  352. var obj = {
  353. func: functionCache[function_name],
  354. tagName: tagName || '',
  355. classes: classes || '',
  356. attr_key: attr_key || '',
  357. value: value || ''
  358. };
  359. // source = source || '';
  360. return (pMatchFunctionCache[matcher] = obj);
  361. });
  362. }
  363. /**
  364. * Trying to advance match pointer
  365. * @param {HTMLElement} el element to make the match
  366. * @return {bool} true when pointer advanced.
  367. */
  368. Matcher.prototype.advance = function (el) {
  369. if (this.nextMatch < this.matchers.length &&
  370. this.matchers[this.nextMatch].func(el, this.matchers[this.nextMatch].tagName, this.matchers[this.nextMatch].classes, this.matchers[this.nextMatch].attr_key, this.matchers[this.nextMatch].value)) {
  371. this.nextMatch++;
  372. return true;
  373. }
  374. return false;
  375. };
  376. /**
  377. * Rewind the match pointer
  378. */
  379. Matcher.prototype.rewind = function () {
  380. this.nextMatch--;
  381. };
  382. Object.defineProperty(Matcher.prototype, "matched", {
  383. /**
  384. * Trying to determine if match made.
  385. * @return {bool} true when the match is made
  386. */
  387. get: function () {
  388. return this.nextMatch === this.matchers.length;
  389. },
  390. enumerable: false,
  391. configurable: true
  392. });
  393. /**
  394. * Rest match pointer.
  395. * @return {[type]} [description]
  396. */
  397. Matcher.prototype.reset = function () {
  398. this.nextMatch = 0;
  399. };
  400. /**
  401. * flush cache to free memory
  402. */
  403. Matcher.prototype.flushCache = function () {
  404. pMatchFunctionCache = {};
  405. };
  406. return Matcher;
  407. }());
  408. exports.default = Matcher;
  409. });
  410. define("nodes/html", ["require", "exports", "he", "nodes/node", "nodes/type", "nodes/text", "matcher", "back", "nodes/comment"], function (require, exports, he_1, node_3, type_3, text_1, matcher_1, back_1, comment_1) {
  411. "use strict";
  412. Object.defineProperty(exports, "__esModule", { value: true });
  413. exports.parse = void 0;
  414. node_3 = __importDefault(node_3);
  415. type_3 = __importDefault(type_3);
  416. text_1 = __importDefault(text_1);
  417. matcher_1 = __importDefault(matcher_1);
  418. back_1 = __importDefault(back_1);
  419. comment_1 = __importDefault(comment_1);
  420. var kBlockElements = {
  421. DIV: true,
  422. P: true,
  423. // ul: true,
  424. // ol: true,
  425. LI: true,
  426. // table: true,
  427. // tr: true,
  428. TD: true,
  429. SECTION: true,
  430. BR: true
  431. };
  432. /**
  433. * HTMLElement, which contains a set of children.
  434. *
  435. * Note: this is a minimalist implementation, no complete tree
  436. * structure provided (no parentNode, nextSibling,
  437. * previousSibling etc).
  438. * @class HTMLElement
  439. * @extends {Node}
  440. */
  441. var HTMLElement = /** @class */ (function (_super) {
  442. __extends(HTMLElement, _super);
  443. /**
  444. * Creates an instance of HTMLElement.
  445. * @param keyAttrs id and class attribute
  446. * @param [rawAttrs] attributes in string
  447. *
  448. * @memberof HTMLElement
  449. */
  450. function HTMLElement(tagName, keyAttrs, rawAttrs, parentNode) {
  451. if (rawAttrs === void 0) { rawAttrs = ''; }
  452. if (parentNode === void 0) { parentNode = null; }
  453. var _this = _super.call(this) || this;
  454. _this.rawAttrs = rawAttrs;
  455. _this.parentNode = parentNode;
  456. _this.classNames = [];
  457. /**
  458. * Node Type declaration.
  459. */
  460. _this.nodeType = type_3.default.ELEMENT_NODE;
  461. _this._tag_name = tagName;
  462. _this.rawAttrs = rawAttrs || '';
  463. _this.parentNode = parentNode || null;
  464. _this.childNodes = [];
  465. if (keyAttrs.id) {
  466. _this.id = keyAttrs.id;
  467. if (!rawAttrs) {
  468. _this.rawAttrs = "id=\"" + keyAttrs.id + "\"";
  469. }
  470. }
  471. if (keyAttrs.class) {
  472. _this.classNames = keyAttrs.class.split(/\s+/);
  473. if (!rawAttrs) {
  474. var cls = "class=\"" + _this.classNames.join(' ') + "\"";
  475. if (_this.rawAttrs) {
  476. _this.rawAttrs += " " + cls;
  477. }
  478. else {
  479. _this.rawAttrs = cls;
  480. }
  481. }
  482. }
  483. return _this;
  484. }
  485. /**
  486. * Remove Child element from childNodes array
  487. * @param {HTMLElement} node node to remove
  488. */
  489. HTMLElement.prototype.removeChild = function (node) {
  490. this.childNodes = this.childNodes.filter(function (child) {
  491. return (child !== node);
  492. });
  493. };
  494. /**
  495. * Exchanges given child with new child
  496. * @param {HTMLElement} oldNode node to exchange
  497. * @param {HTMLElement} newNode new node
  498. */
  499. HTMLElement.prototype.exchangeChild = function (oldNode, newNode) {
  500. var idx = -1;
  501. for (var i = 0; i < this.childNodes.length; i++) {
  502. if (this.childNodes[i] === oldNode) {
  503. idx = i;
  504. break;
  505. }
  506. }
  507. this.childNodes[idx] = newNode;
  508. };
  509. Object.defineProperty(HTMLElement.prototype, "tagName", {
  510. get: function () {
  511. return this._tag_name ? this._tag_name.toUpperCase() : this._tag_name;
  512. },
  513. enumerable: false,
  514. configurable: true
  515. });
  516. Object.defineProperty(HTMLElement.prototype, "rawText", {
  517. /**
  518. * Get escpaed (as-it) text value of current node and its children.
  519. * @return {string} text content
  520. */
  521. get: function () {
  522. return this.childNodes.reduce(function (pre, cur) {
  523. return (pre += cur.rawText);
  524. }, '');
  525. },
  526. enumerable: false,
  527. configurable: true
  528. });
  529. Object.defineProperty(HTMLElement.prototype, "text", {
  530. /**
  531. * Get unescaped text value of current node and its children.
  532. * @return {string} text content
  533. */
  534. get: function () {
  535. return he_1.decode(this.rawText);
  536. },
  537. enumerable: false,
  538. configurable: true
  539. });
  540. Object.defineProperty(HTMLElement.prototype, "structuredText", {
  541. /**
  542. * Get structured Text (with '\n' etc.)
  543. * @return {string} structured text
  544. */
  545. get: function () {
  546. var currentBlock = [];
  547. var blocks = [currentBlock];
  548. function dfs(node) {
  549. if (node.nodeType === type_3.default.ELEMENT_NODE) {
  550. if (kBlockElements[node.tagName]) {
  551. if (currentBlock.length > 0) {
  552. blocks.push(currentBlock = []);
  553. }
  554. node.childNodes.forEach(dfs);
  555. if (currentBlock.length > 0) {
  556. blocks.push(currentBlock = []);
  557. }
  558. }
  559. else {
  560. node.childNodes.forEach(dfs);
  561. }
  562. }
  563. else if (node.nodeType === type_3.default.TEXT_NODE) {
  564. if (node.isWhitespace) {
  565. // Whitespace node, postponed output
  566. currentBlock.prependWhitespace = true;
  567. }
  568. else {
  569. var text = node.text;
  570. if (currentBlock.prependWhitespace) {
  571. text = " " + text;
  572. currentBlock.prependWhitespace = false;
  573. }
  574. currentBlock.push(text);
  575. }
  576. }
  577. }
  578. dfs(this);
  579. return blocks.map(function (block) {
  580. // Normalize each line's whitespace
  581. return block.join('').trim().replace(/\s{2,}/g, ' ');
  582. })
  583. .join('\n').replace(/\s+$/, ''); // trimRight;
  584. },
  585. enumerable: false,
  586. configurable: true
  587. });
  588. HTMLElement.prototype.toString = function () {
  589. var tag = this._tag_name;
  590. if (tag) {
  591. var is_void = /^(area|base|br|col|embed|hr|img|input|link|meta|param|source|track|wbr)$/i.test(tag);
  592. var attrs = this.rawAttrs ? " " + this.rawAttrs : '';
  593. if (is_void) {
  594. return "<" + tag + attrs + ">";
  595. }
  596. return "<" + tag + attrs + ">" + this.innerHTML + "</" + tag + ">";
  597. }
  598. return this.innerHTML;
  599. };
  600. Object.defineProperty(HTMLElement.prototype, "innerHTML", {
  601. get: function () {
  602. return this.childNodes.map(function (child) {
  603. return child.toString();
  604. }).join('');
  605. },
  606. enumerable: false,
  607. configurable: true
  608. });
  609. HTMLElement.prototype.set_content = function (content, options) {
  610. if (options === void 0) { options = {}; }
  611. if (content instanceof node_3.default) {
  612. content = [content];
  613. }
  614. else if (typeof content == 'string') {
  615. var r = parse(content, options);
  616. content = r.childNodes.length ? r.childNodes : [new text_1.default(content)];
  617. }
  618. this.childNodes = content;
  619. };
  620. Object.defineProperty(HTMLElement.prototype, "outerHTML", {
  621. get: function () {
  622. return this.toString();
  623. },
  624. enumerable: false,
  625. configurable: true
  626. });
  627. /**
  628. * Trim element from right (in block) after seeing pattern in a TextNode.
  629. * @param {RegExp} pattern pattern to find
  630. * @return {HTMLElement} reference to current node
  631. */
  632. HTMLElement.prototype.trimRight = function (pattern) {
  633. for (var i = 0; i < this.childNodes.length; i++) {
  634. var childNode = this.childNodes[i];
  635. if (childNode.nodeType === type_3.default.ELEMENT_NODE) {
  636. childNode.trimRight(pattern);
  637. }
  638. else {
  639. var index = childNode.rawText.search(pattern);
  640. if (index > -1) {
  641. childNode.rawText = childNode.rawText.substr(0, index);
  642. // trim all following nodes.
  643. this.childNodes.length = i + 1;
  644. }
  645. }
  646. }
  647. return this;
  648. };
  649. Object.defineProperty(HTMLElement.prototype, "structure", {
  650. /**
  651. * Get DOM structure
  652. * @return {string} strucutre
  653. */
  654. get: function () {
  655. var res = [];
  656. var indention = 0;
  657. function write(str) {
  658. res.push(' '.repeat(indention) + str);
  659. }
  660. function dfs(node) {
  661. var idStr = node.id ? ("#" + node.id) : '';
  662. var classStr = node.classNames.length ? ("." + node.classNames.join('.')) : '';
  663. write(node._tag_name + idStr + classStr);
  664. indention++;
  665. node.childNodes.forEach(function (childNode) {
  666. if (childNode.nodeType === type_3.default.ELEMENT_NODE) {
  667. dfs(childNode);
  668. }
  669. else if (childNode.nodeType === type_3.default.TEXT_NODE) {
  670. if (!childNode.isWhitespace) {
  671. write('#text');
  672. }
  673. }
  674. });
  675. indention--;
  676. }
  677. dfs(this);
  678. return res.join('\n');
  679. },
  680. enumerable: false,
  681. configurable: true
  682. });
  683. /**
  684. * Remove whitespaces in this sub tree.
  685. * @return {HTMLElement} pointer to this
  686. */
  687. HTMLElement.prototype.removeWhitespace = function () {
  688. var _this = this;
  689. var o = 0;
  690. this.childNodes.forEach(function (node) {
  691. if (node.nodeType === type_3.default.TEXT_NODE) {
  692. if (node.isWhitespace) {
  693. return;
  694. }
  695. node.rawText = node.rawText.trim();
  696. }
  697. else if (node.nodeType === type_3.default.ELEMENT_NODE) {
  698. node.removeWhitespace();
  699. }
  700. _this.childNodes[o++] = node;
  701. });
  702. this.childNodes.length = o;
  703. return this;
  704. };
  705. /**
  706. * Query CSS selector to find matching nodes.
  707. * @param {string} selector Simplified CSS selector
  708. * @param {Matcher} selector A Matcher instance
  709. * @return {HTMLElement[]} matching elements
  710. */
  711. HTMLElement.prototype.querySelectorAll = function (selector) {
  712. var _this = this;
  713. var matcher;
  714. if (selector instanceof matcher_1.default) {
  715. matcher = selector;
  716. matcher.reset();
  717. }
  718. else {
  719. if (selector.includes(',')) {
  720. var selectors = selector.split(',');
  721. return Array.from(selectors.reduce(function (pre, cur) {
  722. var result = _this.querySelectorAll(cur.trim());
  723. return result.reduce(function (p, c) {
  724. return p.add(c);
  725. }, pre);
  726. }, new Set()));
  727. }
  728. matcher = new matcher_1.default(selector);
  729. }
  730. var stack = [];
  731. return this.childNodes.reduce(function (res, cur) {
  732. stack.push([cur, 0, false]);
  733. while (stack.length) {
  734. var state = back_1.default(stack); // get last element
  735. var el = state[0];
  736. if (state[1] === 0) {
  737. // Seen for first time.
  738. if (el.nodeType !== type_3.default.ELEMENT_NODE) {
  739. stack.pop();
  740. continue;
  741. }
  742. var html_el = el;
  743. state[2] = matcher.advance(html_el);
  744. if (state[2]) {
  745. if (matcher.matched) {
  746. res.push(html_el);
  747. res.push.apply(res, (html_el.querySelectorAll(selector)));
  748. // no need to go further.
  749. matcher.rewind();
  750. stack.pop();
  751. continue;
  752. }
  753. }
  754. }
  755. if (state[1] < el.childNodes.length) {
  756. stack.push([el.childNodes[state[1]++], 0, false]);
  757. }
  758. else {
  759. if (state[2]) {
  760. matcher.rewind();
  761. }
  762. stack.pop();
  763. }
  764. }
  765. return res;
  766. }, []);
  767. };
  768. /**
  769. * Query CSS Selector to find matching node.
  770. * @param {string} selector Simplified CSS selector
  771. * @param {Matcher} selector A Matcher instance
  772. * @return {HTMLElement} matching node
  773. */
  774. HTMLElement.prototype.querySelector = function (selector) {
  775. var matcher;
  776. if (selector instanceof matcher_1.default) {
  777. matcher = selector;
  778. matcher.reset();
  779. }
  780. else {
  781. matcher = new matcher_1.default(selector);
  782. }
  783. var stack = [];
  784. for (var _i = 0, _a = this.childNodes; _i < _a.length; _i++) {
  785. var node = _a[_i];
  786. stack.push([node, 0, false]);
  787. while (stack.length) {
  788. var state = back_1.default(stack);
  789. var el = state[0];
  790. if (state[1] === 0) {
  791. // Seen for first time.
  792. if (el.nodeType !== type_3.default.ELEMENT_NODE) {
  793. stack.pop();
  794. continue;
  795. }
  796. state[2] = matcher.advance(el);
  797. if (state[2]) {
  798. if (matcher.matched) {
  799. return el;
  800. }
  801. }
  802. }
  803. if (state[1] < el.childNodes.length) {
  804. stack.push([el.childNodes[state[1]++], 0, false]);
  805. }
  806. else {
  807. if (state[2]) {
  808. matcher.rewind();
  809. }
  810. stack.pop();
  811. }
  812. }
  813. }
  814. return null;
  815. };
  816. /**
  817. * Append a child node to childNodes
  818. * @param {Node} node node to append
  819. * @return {Node} node appended
  820. */
  821. HTMLElement.prototype.appendChild = function (node) {
  822. // node.parentNode = this;
  823. this.childNodes.push(node);
  824. if (node instanceof HTMLElement) {
  825. node.parentNode = this;
  826. }
  827. return node;
  828. };
  829. Object.defineProperty(HTMLElement.prototype, "firstChild", {
  830. /**
  831. * Get first child node
  832. * @return {Node} first child node
  833. */
  834. get: function () {
  835. return this.childNodes[0];
  836. },
  837. enumerable: false,
  838. configurable: true
  839. });
  840. Object.defineProperty(HTMLElement.prototype, "lastChild", {
  841. /**
  842. * Get last child node
  843. * @return {Node} last child node
  844. */
  845. get: function () {
  846. return back_1.default(this.childNodes);
  847. },
  848. enumerable: false,
  849. configurable: true
  850. });
  851. Object.defineProperty(HTMLElement.prototype, "attributes", {
  852. /**
  853. * Get attributes
  854. * @return {Object} parsed and unescaped attributes
  855. */
  856. get: function () {
  857. if (this._attrs) {
  858. return this._attrs;
  859. }
  860. this._attrs = {};
  861. var attrs = this.rawAttributes;
  862. for (var key in attrs) {
  863. var val = attrs[key] || '';
  864. this._attrs[key] = he_1.decode(val);
  865. }
  866. return this._attrs;
  867. },
  868. enumerable: false,
  869. configurable: true
  870. });
  871. Object.defineProperty(HTMLElement.prototype, "rawAttributes", {
  872. /**
  873. * Get escaped (as-it) attributes
  874. * @return {Object} parsed attributes
  875. */
  876. get: function () {
  877. if (this._rawAttrs) {
  878. return this._rawAttrs;
  879. }
  880. var attrs = {};
  881. if (this.rawAttrs) {
  882. var re = /\b([a-z][a-z0-9-]*)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|(\S+)))?/ig;
  883. var match = void 0;
  884. while ((match = re.exec(this.rawAttrs))) {
  885. attrs[match[1]] = match[2] || match[3] || match[4] || null;
  886. }
  887. }
  888. this._rawAttrs = attrs;
  889. return attrs;
  890. },
  891. enumerable: false,
  892. configurable: true
  893. });
  894. HTMLElement.prototype.removeAttribute = function (key) {
  895. var attrs = this.rawAttributes;
  896. delete attrs[key];
  897. // Update this.attribute
  898. if (this._attrs) {
  899. delete this._attrs[key];
  900. }
  901. // Update rawString
  902. this.rawAttrs = Object.keys(attrs).map(function (name) {
  903. var val = JSON.stringify(attrs[name]);
  904. if (val === undefined || val === 'null') {
  905. return name;
  906. }
  907. return name + "=" + val;
  908. }).join(' ');
  909. };
  910. HTMLElement.prototype.hasAttribute = function (key) {
  911. return key in this.attributes;
  912. };
  913. /**
  914. * Get an attribute
  915. * @return {string} value of the attribute
  916. */
  917. HTMLElement.prototype.getAttribute = function (key) {
  918. return this.attributes[key];
  919. };
  920. /**
  921. * Set an attribute value to the HTMLElement
  922. * @param {string} key The attribute name
  923. * @param {string} value The value to set, or null / undefined to remove an attribute
  924. */
  925. HTMLElement.prototype.setAttribute = function (key, value) {
  926. if (arguments.length < 2) {
  927. throw new Error('Failed to execute \'setAttribute\' on \'Element\'');
  928. }
  929. var attrs = this.rawAttributes;
  930. attrs[key] = String(value);
  931. if (this._attrs) {
  932. this._attrs[key] = he_1.decode(attrs[key]);
  933. }
  934. // Update rawString
  935. this.rawAttrs = Object.keys(attrs).map(function (name) {
  936. var val = JSON.stringify(attrs[name]);
  937. if (val === 'null' || val === '""') {
  938. return name;
  939. }
  940. return name + "=" + val;
  941. }).join(' ');
  942. };
  943. /**
  944. * Replace all the attributes of the HTMLElement by the provided attributes
  945. * @param {Attributes} attributes the new attribute set
  946. */
  947. HTMLElement.prototype.setAttributes = function (attributes) {
  948. // Invalidate current this.attributes
  949. if (this._attrs) {
  950. delete this._attrs;
  951. }
  952. // Invalidate current this.rawAttributes
  953. if (this._rawAttrs) {
  954. delete this._rawAttrs;
  955. }
  956. // Update rawString
  957. this.rawAttrs = Object.keys(attributes).map(function (name) {
  958. var val = attributes[name];
  959. if (val === 'null' || val === '""') {
  960. return name;
  961. }
  962. return name + "=" + JSON.stringify(String(val));
  963. }).join(' ');
  964. };
  965. HTMLElement.prototype.insertAdjacentHTML = function (where, html) {
  966. var _a, _b, _c;
  967. var _this = this;
  968. if (arguments.length < 2) {
  969. throw new Error('2 arguments required');
  970. }
  971. var p = parse(html);
  972. if (where === 'afterend') {
  973. var idx = this.parentNode.childNodes.findIndex(function (child) {
  974. return child === _this;
  975. });
  976. (_a = this.parentNode.childNodes).splice.apply(_a, __spreadArrays([idx + 1, 0], p.childNodes));
  977. p.childNodes.forEach(function (n) {
  978. if (n instanceof HTMLElement) {
  979. n.parentNode = _this.parentNode;
  980. }
  981. });
  982. }
  983. else if (where === 'afterbegin') {
  984. (_b = this.childNodes).unshift.apply(_b, p.childNodes);
  985. }
  986. else if (where === 'beforeend') {
  987. p.childNodes.forEach(function (n) {
  988. _this.appendChild(n);
  989. });
  990. }
  991. else if (where === 'beforebegin') {
  992. var idx = this.parentNode.childNodes.findIndex(function (child) {
  993. return child === _this;
  994. });
  995. (_c = this.parentNode.childNodes).splice.apply(_c, __spreadArrays([idx, 0], p.childNodes));
  996. p.childNodes.forEach(function (n) {
  997. if (n instanceof HTMLElement) {
  998. n.parentNode = _this.parentNode;
  999. }
  1000. });
  1001. }
  1002. else {
  1003. throw new Error("The value provided ('" + where + "') is not one of 'beforebegin', 'afterbegin', 'beforeend', or 'afterend'");
  1004. }
  1005. // if (!where || html === undefined || html === null) {
  1006. // return;
  1007. // }
  1008. };
  1009. return HTMLElement;
  1010. }(node_3.default));
  1011. exports.default = HTMLElement;
  1012. // https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name
  1013. var kMarkupPattern = /<!--[^]*?(?=-->)-->|<(\/?)([a-z][-.:0-9_a-z]*)\s*([^>]*?)(\/?)>/ig;
  1014. var kAttributePattern = /(^|\s)(id|class)\s*=\s*("([^"]+)"|'([^']+)'|(\S+))/ig;
  1015. var kSelfClosingElements = {
  1016. area: true,
  1017. AREA: true,
  1018. base: true,
  1019. BASE: true,
  1020. br: true,
  1021. BR: true,
  1022. col: true,
  1023. COL: true,
  1024. hr: true,
  1025. HR: true,
  1026. img: true,
  1027. IMG: true,
  1028. input: true,
  1029. INPUT: true,
  1030. link: true,
  1031. LINK: true,
  1032. meta: true,
  1033. META: true,
  1034. source: true,
  1035. SOURCE: true
  1036. };
  1037. var kElementsClosedByOpening = {
  1038. li: { li: true, LI: true },
  1039. LI: { li: true, LI: true },
  1040. p: { p: true, div: true, P: true, DIV: true },
  1041. P: { p: true, div: true, P: true, DIV: true },
  1042. b: { div: true, DIV: true },
  1043. B: { div: true, DIV: true },
  1044. td: { td: true, th: true, TD: true, TH: true },
  1045. TD: { td: true, th: true, TD: true, TH: true },
  1046. th: { td: true, th: true, TD: true, TH: true },
  1047. TH: { td: true, th: true, TD: true, TH: true },
  1048. h1: { h1: true, H1: true },
  1049. H1: { h1: true, H1: true },
  1050. h2: { h2: true, H2: true },
  1051. H2: { h2: true, H2: true },
  1052. h3: { h3: true, H3: true },
  1053. H3: { h3: true, H3: true },
  1054. h4: { h4: true, H4: true },
  1055. H4: { h4: true, H4: true },
  1056. h5: { h5: true, H5: true },
  1057. H5: { h5: true, H5: true },
  1058. h6: { h6: true, H6: true },
  1059. H6: { h6: true, H6: true }
  1060. };
  1061. var kElementsClosedByClosing = {
  1062. li: { ul: true, ol: true, UL: true, OL: true },
  1063. LI: { ul: true, ol: true, UL: true, OL: true },
  1064. a: { div: true, DIV: true },
  1065. A: { div: true, DIV: true },
  1066. b: { div: true, DIV: true },
  1067. B: { div: true, DIV: true },
  1068. i: { div: true, DIV: true },
  1069. I: { div: true, DIV: true },
  1070. p: { div: true, DIV: true },
  1071. P: { div: true, DIV: true },
  1072. td: { tr: true, table: true, TR: true, TABLE: true },
  1073. TD: { tr: true, table: true, TR: true, TABLE: true },
  1074. th: { tr: true, table: true, TR: true, TABLE: true },
  1075. TH: { tr: true, table: true, TR: true, TABLE: true }
  1076. };
  1077. var kBlockTextElements = {
  1078. script: true,
  1079. SCRIPT: true,
  1080. noscript: true,
  1081. NOSCRIPT: true,
  1082. style: true,
  1083. STYLE: true,
  1084. pre: true,
  1085. PRE: true
  1086. };
  1087. var frameflag = 'documentfragmentcontainer';
  1088. function parse(data, options) {
  1089. if (options === void 0) { options = {}; }
  1090. var root = new HTMLElement(null, {});
  1091. var currentParent = root;
  1092. var stack = [root];
  1093. var lastTextPos = -1;
  1094. var match;
  1095. // https://github.com/taoqf/node-html-parser/issues/38
  1096. data = "<" + frameflag + ">" + data + "</" + frameflag + ">";
  1097. var _loop_1 = function () {
  1098. if (lastTextPos > -1) {
  1099. if (lastTextPos + match[0].length < kMarkupPattern.lastIndex) {
  1100. // if has content
  1101. var text = data.substring(lastTextPos, kMarkupPattern.lastIndex - match[0].length);
  1102. currentParent.appendChild(new text_1.default(text));
  1103. }
  1104. }
  1105. lastTextPos = kMarkupPattern.lastIndex;
  1106. if (match[2] === frameflag) {
  1107. return "continue";
  1108. }
  1109. if (match[0][1] === '!') {
  1110. // this is a comment
  1111. if (options.comment) {
  1112. // Only keep what is in between <!-- and -->
  1113. var text = data.substring(lastTextPos - 3, lastTextPos - match[0].length + 4);
  1114. currentParent.appendChild(new comment_1.default(text));
  1115. }
  1116. return "continue";
  1117. }
  1118. if (options.lowerCaseTagName) {
  1119. match[2] = match[2].toLowerCase();
  1120. }
  1121. if (!match[1]) {
  1122. // not </ tags
  1123. var attrs = {};
  1124. for (var attMatch = void 0; (attMatch = kAttributePattern.exec(match[3]));) {
  1125. attrs[attMatch[2]] = attMatch[4] || attMatch[5] || attMatch[6];
  1126. }
  1127. var tagName = currentParent.tagName;
  1128. if (!match[4] && kElementsClosedByOpening[tagName]) {
  1129. if (kElementsClosedByOpening[tagName][match[2]]) {
  1130. stack.pop();
  1131. currentParent = back_1.default(stack);
  1132. }
  1133. }
  1134. // ignore container tag we add above
  1135. // https://github.com/taoqf/node-html-parser/issues/38
  1136. currentParent = currentParent.appendChild(new HTMLElement(match[2], attrs, match[3]));
  1137. stack.push(currentParent);
  1138. if (kBlockTextElements[match[2]]) {
  1139. // a little test to find next </script> or </style> ...
  1140. var closeMarkup_1 = "</" + match[2] + ">";
  1141. var index = (function () {
  1142. if (options.lowerCaseTagName) {
  1143. return data.toLocaleLowerCase().indexOf(closeMarkup_1, kMarkupPattern.lastIndex);
  1144. }
  1145. return data.indexOf(closeMarkup_1, kMarkupPattern.lastIndex);
  1146. })();
  1147. if (options[match[2]]) {
  1148. var text = void 0;
  1149. if (index === -1) {
  1150. // there is no matching ending for the text element.
  1151. text = data.substr(kMarkupPattern.lastIndex);
  1152. }
  1153. else {
  1154. text = data.substring(kMarkupPattern.lastIndex, index);
  1155. }
  1156. if (text.length > 0) {
  1157. currentParent.appendChild(new text_1.default(text));
  1158. }
  1159. }
  1160. if (index === -1) {
  1161. lastTextPos = kMarkupPattern.lastIndex = data.length + 1;
  1162. }
  1163. else {
  1164. lastTextPos = kMarkupPattern.lastIndex = index + closeMarkup_1.length;
  1165. match[1] = 'true';
  1166. }
  1167. }
  1168. }
  1169. if (match[1] || match[4] || kSelfClosingElements[match[2]]) {
  1170. // </ or /> or <br> etc.
  1171. while (true) {
  1172. if (currentParent.tagName === match[2].toUpperCase()) {
  1173. stack.pop();
  1174. currentParent = back_1.default(stack);
  1175. break;
  1176. }
  1177. else {
  1178. var tagName = currentParent.tagName;
  1179. // Trying to close current tag, and move on
  1180. if (kElementsClosedByClosing[tagName]) {
  1181. if (kElementsClosedByClosing[tagName][match[2]]) {
  1182. stack.pop();
  1183. currentParent = back_1.default(stack);
  1184. continue;
  1185. }
  1186. }
  1187. // Use aggressive strategy to handle unmatching markups.
  1188. break;
  1189. }
  1190. }
  1191. }
  1192. };
  1193. while ((match = kMarkupPattern.exec(data))) {
  1194. _loop_1();
  1195. }
  1196. var valid = Boolean(stack.length === 1);
  1197. if (!options.noFix) {
  1198. var response_1 = root;
  1199. response_1.valid = valid;
  1200. var _loop_2 = function () {
  1201. // Handle each error elements.
  1202. var last = stack.pop();
  1203. var oneBefore = back_1.default(stack);
  1204. if (last.parentNode && last.parentNode.parentNode) {
  1205. if (last.parentNode === oneBefore && last.tagName === oneBefore.tagName) {
  1206. // Pair error case <h3> <h3> handle : Fixes to <h3> </h3>
  1207. oneBefore.removeChild(last);
  1208. last.childNodes.forEach(function (child) {
  1209. oneBefore.parentNode.appendChild(child);
  1210. });
  1211. stack.pop();
  1212. }
  1213. else {
  1214. // Single error <div> <h3> </div> handle: Just removes <h3>
  1215. oneBefore.removeChild(last);
  1216. last.childNodes.forEach(function (child) {
  1217. oneBefore.appendChild(child);
  1218. });
  1219. }
  1220. }
  1221. else {
  1222. // If it's final element just skip.
  1223. }
  1224. };
  1225. while (stack.length > 1) {
  1226. _loop_2();
  1227. }
  1228. response_1.childNodes.forEach(function (node) {
  1229. if (node instanceof HTMLElement) {
  1230. node.parentNode = null;
  1231. }
  1232. });
  1233. return response_1;
  1234. }
  1235. var response = new text_1.default(data);
  1236. response.valid = valid;
  1237. return response;
  1238. }
  1239. exports.parse = parse;
  1240. });
  1241. define("index", ["require", "exports", "nodes/comment", "nodes/html", "nodes/node", "nodes/text", "nodes/type"], function (require, exports, comment_2, html_1, node_4, text_2, type_4) {
  1242. "use strict";
  1243. Object.defineProperty(exports, "__esModule", { value: true });
  1244. exports.NodeType = exports.TextNode = exports.Node = exports.default = exports.parse = exports.HTMLElement = exports.CommentNode = void 0;
  1245. Object.defineProperty(exports, "CommentNode", { enumerable: true, get: function () { return __importDefault(comment_2).default; } });
  1246. Object.defineProperty(exports, "HTMLElement", { enumerable: true, get: function () { return __importDefault(html_1).default; } });
  1247. Object.defineProperty(exports, "parse", { enumerable: true, get: function () { return html_1.parse; } });
  1248. Object.defineProperty(exports, "default", { enumerable: true, get: function () { return html_1.parse; } });
  1249. Object.defineProperty(exports, "Node", { enumerable: true, get: function () { return __importDefault(node_4).default; } });
  1250. Object.defineProperty(exports, "TextNode", { enumerable: true, get: function () { return __importDefault(text_2).default; } });
  1251. Object.defineProperty(exports, "NodeType", { enumerable: true, get: function () { return __importDefault(type_4).default; } });
  1252. });