node-html-parser 1.4.4 → 1.4.8

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.
package/README.md CHANGED
@@ -62,7 +62,7 @@ var HTMLParser = require('node-html-parser');
62
62
  var root = HTMLParser.parse('<ul id="list"><li>Hello World</li></ul>');
63
63
  ```
64
64
 
65
- ## HTMLElement Methods
65
+ ## Global Methods
66
66
 
67
67
  ### parse(data[, options])
68
68
 
@@ -84,6 +84,8 @@ Parse given data, and return root of the generated DOM.
84
84
  }
85
85
  ```
86
86
 
87
+ ## HTMLElement Methods
88
+
87
89
  ### HTMLElement#trimRight()
88
90
 
89
91
  Trim element from right (in block) after seeing pattern in a TextNode.
@@ -140,6 +142,10 @@ Same as [outerHTML](#htmlelementouterhtml)
140
142
 
141
143
  Set content. **Notice**: Do not set content of the **root** node.
142
144
 
145
+ ### HTMLElement#remove()
146
+
147
+ Remove current element.
148
+
143
149
  ## HTMLElement Properties
144
150
 
145
151
  ### HTMLElement#text
@@ -175,3 +181,11 @@ Get innerHTML.
175
181
  ### HTMLElement#outerHTML
176
182
 
177
183
  Get outerHTML.
184
+
185
+ ### HTMLElement#nextSibling
186
+
187
+ Returns a reference to the next child node of the current element's parent.
188
+
189
+ ### HTMLElement#nextElementSibling
190
+
191
+ Returns a reference to the next child element of the current element's parent.
@@ -161,31 +161,18 @@ export default class Matcher {
161
161
  let attr_key = '';
162
162
  let value = '';
163
163
  if (tagName && tagName !== '*') {
164
- let reg;
165
164
  if (tagName.startsWith('#')) {
166
165
  // source += 'if (el.id != ' + JSON.stringify(tagName.substr(1)) + ') return false;';// 1
167
166
  function_name += '1';
168
167
  }
169
168
  else {
170
- reg = /^\[\s*(\S+)\s*(=|!=)\s*((((["'])([^\6]*)\6))|(\S*?))\]\s*/.exec(tagName);
169
+ const reg = /\[\s*([\w-]+)(\s*=\s*(((?<quote>'|")\s*(.*)(\k<quote>))|(\S*)))?\s*\]/.exec(tagName);
171
170
  if (reg) {
172
171
  attr_key = reg[1];
173
- let method = reg[2];
174
- if (method !== '=' && method !== '!=') {
175
- // eslint-disable-next-line no-template-curly-in-string
176
- throw new Error('Selector not supported, Expect [key${op}value].op must be =,!=');
177
- }
178
- if (method === '=') {
179
- method = '==';
180
- }
181
- value = reg[7] || reg[8];
172
+ value = reg[6] || reg[8];
182
173
  // 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
183
174
  function_name += '2';
184
175
  }
185
- else if ((reg = /^\[(.*?)\]/.exec(tagName))) {
186
- attr_key = reg[1];
187
- function_name += '5';
188
- }
189
176
  else {
190
177
  // source += 'if (el.tagName != ' + JSON.stringify(tagName) + ') return false;';// 3
191
178
  function_name += '3';
@@ -71,6 +71,17 @@ export default class HTMLElement extends Node {
71
71
  }
72
72
  }
73
73
  }
74
+ /**
75
+ * Remove current element
76
+ */
77
+ remove() {
78
+ if (this.parentNode) {
79
+ const children = this.parentNode.childNodes;
80
+ this.parentNode.childNodes = children.filter((child) => {
81
+ return this !== child;
82
+ });
83
+ }
84
+ }
74
85
  /**
75
86
  * Remove Child element from childNodes array
76
87
  * @param {HTMLElement} node node to remove
@@ -86,14 +97,13 @@ export default class HTMLElement extends Node {
86
97
  * @param {HTMLElement} newNode new node
87
98
  */
88
99
  exchangeChild(oldNode, newNode) {
89
- let idx = -1;
90
- for (let i = 0; i < this.childNodes.length; i++) {
91
- if (this.childNodes[i] === oldNode) {
92
- idx = i;
93
- break;
100
+ const children = this.childNodes;
101
+ this.childNodes = children.map((child) => {
102
+ if (child === oldNode) {
103
+ return newNode;
94
104
  }
95
- }
96
- this.childNodes[idx] = newNode;
105
+ return child;
106
+ });
97
107
  }
98
108
  get tagName() {
99
109
  return this.rawTagName ? this.rawTagName.toUpperCase() : this.rawTagName;
@@ -545,6 +555,38 @@ export default class HTMLElement extends Node {
545
555
  // return;
546
556
  // }
547
557
  }
558
+ get nextSibling() {
559
+ if (this.parentNode) {
560
+ const children = this.parentNode.childNodes;
561
+ let i = 0;
562
+ while (i < children.length) {
563
+ const child = children[i++];
564
+ if (this === child) {
565
+ return children[i] || null;
566
+ }
567
+ }
568
+ return null;
569
+ }
570
+ }
571
+ get nextElementSibling() {
572
+ if (this.parentNode) {
573
+ const children = this.parentNode.childNodes;
574
+ let i = 0;
575
+ let find = false;
576
+ while (i < children.length) {
577
+ const child = children[i++];
578
+ if (find) {
579
+ if (child instanceof HTMLElement) {
580
+ return child || null;
581
+ }
582
+ }
583
+ else if (this === child) {
584
+ find = true;
585
+ }
586
+ }
587
+ return null;
588
+ }
589
+ }
548
590
  }
549
591
  // https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name
550
592
  const kMarkupPattern = /<!--[^]*?(?=-->)-->|<(\/?)([a-z][-.:0-9_a-z]*)\s*([^>]*?)(\/?)>/ig;
@@ -573,7 +615,15 @@ const kSelfClosingElements = {
573
615
  meta: true,
574
616
  META: true,
575
617
  source: true,
576
- SOURCE: true
618
+ SOURCE: true,
619
+ embed: true,
620
+ EMBED: true,
621
+ param: true,
622
+ PARAM: true,
623
+ track: true,
624
+ TRACK: true,
625
+ wbr: true,
626
+ WBR: true
577
627
  };
578
628
  const kElementsClosedByOpening = {
579
629
  li: { li: true, LI: true },
package/dist/main.js CHANGED
@@ -312,31 +312,18 @@ define("matcher", ["require", "exports"], function (require, exports) {
312
312
  var attr_key = '';
313
313
  var value = '';
314
314
  if (tagName && tagName !== '*') {
315
- var reg = void 0;
316
315
  if (tagName.startsWith('#')) {
317
316
  // source += 'if (el.id != ' + JSON.stringify(tagName.substr(1)) + ') return false;';// 1
318
317
  function_name += '1';
319
318
  }
320
319
  else {
321
- reg = /^\[\s*(\S+)\s*(=|!=)\s*((((["'])([^\6]*)\6))|(\S*?))\]\s*/.exec(tagName);
320
+ var reg = /\[\s*([\w-]+)(\s*=\s*(((?<quote>'|")\s*(.*)(\k<quote>))|(\S*)))?\s*\]/.exec(tagName);
322
321
  if (reg) {
323
322
  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];
323
+ value = reg[6] || reg[8];
333
324
  // 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
325
  function_name += '2';
335
326
  }
336
- else if ((reg = /^\[(.*?)\]/.exec(tagName))) {
337
- attr_key = reg[1];
338
- function_name += '5';
339
- }
340
327
  else {
341
328
  // source += 'if (el.tagName != ' + JSON.stringify(tagName) + ') return false;';// 3
342
329
  function_name += '3';
@@ -487,6 +474,18 @@ define("nodes/html", ["require", "exports", "he", "nodes/node", "nodes/type", "n
487
474
  }
488
475
  return _this;
489
476
  }
477
+ /**
478
+ * Remove current element
479
+ */
480
+ HTMLElement.prototype.remove = function () {
481
+ var _this = this;
482
+ if (this.parentNode) {
483
+ var children = this.parentNode.childNodes;
484
+ this.parentNode.childNodes = children.filter(function (child) {
485
+ return _this !== child;
486
+ });
487
+ }
488
+ };
490
489
  /**
491
490
  * Remove Child element from childNodes array
492
491
  * @param {HTMLElement} node node to remove
@@ -502,14 +501,13 @@ define("nodes/html", ["require", "exports", "he", "nodes/node", "nodes/type", "n
502
501
  * @param {HTMLElement} newNode new node
503
502
  */
504
503
  HTMLElement.prototype.exchangeChild = function (oldNode, newNode) {
505
- var idx = -1;
506
- for (var i = 0; i < this.childNodes.length; i++) {
507
- if (this.childNodes[i] === oldNode) {
508
- idx = i;
509
- break;
504
+ var children = this.childNodes;
505
+ this.childNodes = children.map(function (child) {
506
+ if (child === oldNode) {
507
+ return newNode;
510
508
  }
511
- }
512
- this.childNodes[idx] = newNode;
509
+ return child;
510
+ });
513
511
  };
514
512
  Object.defineProperty(HTMLElement.prototype, "tagName", {
515
513
  get: function () {
@@ -1011,6 +1009,46 @@ define("nodes/html", ["require", "exports", "he", "nodes/node", "nodes/type", "n
1011
1009
  // return;
1012
1010
  // }
1013
1011
  };
1012
+ Object.defineProperty(HTMLElement.prototype, "nextSibling", {
1013
+ get: function () {
1014
+ if (this.parentNode) {
1015
+ var children = this.parentNode.childNodes;
1016
+ var i = 0;
1017
+ while (i < children.length) {
1018
+ var child = children[i++];
1019
+ if (this === child) {
1020
+ return children[i] || null;
1021
+ }
1022
+ }
1023
+ return null;
1024
+ }
1025
+ },
1026
+ enumerable: false,
1027
+ configurable: true
1028
+ });
1029
+ Object.defineProperty(HTMLElement.prototype, "nextElementSibling", {
1030
+ get: function () {
1031
+ if (this.parentNode) {
1032
+ var children = this.parentNode.childNodes;
1033
+ var i = 0;
1034
+ var find = false;
1035
+ while (i < children.length) {
1036
+ var child = children[i++];
1037
+ if (find) {
1038
+ if (child instanceof HTMLElement) {
1039
+ return child || null;
1040
+ }
1041
+ }
1042
+ else if (this === child) {
1043
+ find = true;
1044
+ }
1045
+ }
1046
+ return null;
1047
+ }
1048
+ },
1049
+ enumerable: false,
1050
+ configurable: true
1051
+ });
1014
1052
  return HTMLElement;
1015
1053
  }(node_3.default));
1016
1054
  exports.default = HTMLElement;
@@ -1041,7 +1079,15 @@ define("nodes/html", ["require", "exports", "he", "nodes/node", "nodes/type", "n
1041
1079
  meta: true,
1042
1080
  META: true,
1043
1081
  source: true,
1044
- SOURCE: true
1082
+ SOURCE: true,
1083
+ embed: true,
1084
+ EMBED: true,
1085
+ param: true,
1086
+ PARAM: true,
1087
+ track: true,
1088
+ TRACK: true,
1089
+ wbr: true,
1090
+ WBR: true
1045
1091
  };
1046
1092
  var kElementsClosedByOpening = {
1047
1093
  li: { li: true, LI: true },
package/dist/matcher.js CHANGED
@@ -163,31 +163,18 @@ var Matcher = /** @class */ (function () {
163
163
  var attr_key = '';
164
164
  var value = '';
165
165
  if (tagName && tagName !== '*') {
166
- var reg = void 0;
167
166
  if (tagName.startsWith('#')) {
168
167
  // source += 'if (el.id != ' + JSON.stringify(tagName.substr(1)) + ') return false;';// 1
169
168
  function_name += '1';
170
169
  }
171
170
  else {
172
- reg = /^\[\s*(\S+)\s*(=|!=)\s*((((["'])([^\6]*)\6))|(\S*?))\]\s*/.exec(tagName);
171
+ var reg = /\[\s*([\w-]+)(\s*=\s*(((?<quote>'|")\s*(.*)(\k<quote>))|(\S*)))?\s*\]/.exec(tagName);
173
172
  if (reg) {
174
173
  attr_key = reg[1];
175
- var method = reg[2];
176
- if (method !== '=' && method !== '!=') {
177
- // eslint-disable-next-line no-template-curly-in-string
178
- throw new Error('Selector not supported, Expect [key${op}value].op must be =,!=');
179
- }
180
- if (method === '=') {
181
- method = '==';
182
- }
183
- value = reg[7] || reg[8];
174
+ value = reg[6] || reg[8];
184
175
  // 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
185
176
  function_name += '2';
186
177
  }
187
- else if ((reg = /^\[(.*?)\]/.exec(tagName))) {
188
- attr_key = reg[1];
189
- function_name += '5';
190
- }
191
178
  else {
192
179
  // source += 'if (el.tagName != ' + JSON.stringify(tagName) + ') return false;';// 3
193
180
  function_name += '3';
@@ -42,6 +42,10 @@ export default class HTMLElement extends Node {
42
42
  * @memberof HTMLElement
43
43
  */
44
44
  constructor(tagName: string, keyAttrs: KeyAttributes, rawAttrs?: string, parentNode?: Node);
45
+ /**
46
+ * Remove current element
47
+ */
48
+ remove(): void;
45
49
  /**
46
50
  * Remove Child element from childNodes array
47
51
  * @param {HTMLElement} node node to remove
@@ -148,6 +152,8 @@ export default class HTMLElement extends Node {
148
152
  */
149
153
  setAttributes(attributes: Attributes): void;
150
154
  insertAdjacentHTML(where: InsertPosition, html: string): void;
155
+ get nextSibling(): Node;
156
+ get nextElementSibling(): HTMLElement;
151
157
  }
152
158
  export interface Options {
153
159
  lowerCaseTagName: boolean;
@@ -101,6 +101,18 @@ var HTMLElement = /** @class */ (function (_super) {
101
101
  }
102
102
  return _this;
103
103
  }
104
+ /**
105
+ * Remove current element
106
+ */
107
+ HTMLElement.prototype.remove = function () {
108
+ var _this = this;
109
+ if (this.parentNode) {
110
+ var children = this.parentNode.childNodes;
111
+ this.parentNode.childNodes = children.filter(function (child) {
112
+ return _this !== child;
113
+ });
114
+ }
115
+ };
104
116
  /**
105
117
  * Remove Child element from childNodes array
106
118
  * @param {HTMLElement} node node to remove
@@ -116,14 +128,13 @@ var HTMLElement = /** @class */ (function (_super) {
116
128
  * @param {HTMLElement} newNode new node
117
129
  */
118
130
  HTMLElement.prototype.exchangeChild = function (oldNode, newNode) {
119
- var idx = -1;
120
- for (var i = 0; i < this.childNodes.length; i++) {
121
- if (this.childNodes[i] === oldNode) {
122
- idx = i;
123
- break;
131
+ var children = this.childNodes;
132
+ this.childNodes = children.map(function (child) {
133
+ if (child === oldNode) {
134
+ return newNode;
124
135
  }
125
- }
126
- this.childNodes[idx] = newNode;
136
+ return child;
137
+ });
127
138
  };
128
139
  Object.defineProperty(HTMLElement.prototype, "tagName", {
129
140
  get: function () {
@@ -625,6 +636,46 @@ var HTMLElement = /** @class */ (function (_super) {
625
636
  // return;
626
637
  // }
627
638
  };
639
+ Object.defineProperty(HTMLElement.prototype, "nextSibling", {
640
+ get: function () {
641
+ if (this.parentNode) {
642
+ var children = this.parentNode.childNodes;
643
+ var i = 0;
644
+ while (i < children.length) {
645
+ var child = children[i++];
646
+ if (this === child) {
647
+ return children[i] || null;
648
+ }
649
+ }
650
+ return null;
651
+ }
652
+ },
653
+ enumerable: false,
654
+ configurable: true
655
+ });
656
+ Object.defineProperty(HTMLElement.prototype, "nextElementSibling", {
657
+ get: function () {
658
+ if (this.parentNode) {
659
+ var children = this.parentNode.childNodes;
660
+ var i = 0;
661
+ var find = false;
662
+ while (i < children.length) {
663
+ var child = children[i++];
664
+ if (find) {
665
+ if (child instanceof HTMLElement) {
666
+ return child || null;
667
+ }
668
+ }
669
+ else if (this === child) {
670
+ find = true;
671
+ }
672
+ }
673
+ return null;
674
+ }
675
+ },
676
+ enumerable: false,
677
+ configurable: true
678
+ });
628
679
  return HTMLElement;
629
680
  }(node_1.default));
630
681
  exports.default = HTMLElement;
@@ -655,7 +706,15 @@ var kSelfClosingElements = {
655
706
  meta: true,
656
707
  META: true,
657
708
  source: true,
658
- SOURCE: true
709
+ SOURCE: true,
710
+ embed: true,
711
+ EMBED: true,
712
+ param: true,
713
+ PARAM: true,
714
+ track: true,
715
+ TRACK: true,
716
+ wbr: true,
717
+ WBR: true
659
718
  };
660
719
  var kElementsClosedByOpening = {
661
720
  li: { li: true, LI: true },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-html-parser",
3
- "version": "1.4.4",
3
+ "version": "1.4.8",
4
4
  "description": "A very fast HTML parser, generating a simplified DOM, with basic element query support.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -13,11 +13,14 @@
13
13
  "ts:amd": "tsc -t es5 -m amd -d false --outFile ./dist/main.js",
14
14
  "ts:esm": "tsc -t esnext -m esnext -d false --outDir ./dist/esm/",
15
15
  "build": "npm run lint && npm run clean && npm run ts:cjs && npm run ts:amd && npm run ts:esm",
16
- "dev": "tsc -w",
16
+ "dev": "tsc -w & mocha -w ./test/*.js",
17
17
  "pretest": "tsc -m commonjs"
18
18
  },
19
19
  "keywords": [
20
- "fast html parser nodejs typescript"
20
+ "parser",
21
+ "html",
22
+ "nodejs",
23
+ "typescript"
21
24
  ],
22
25
  "author": "Xiaoyi Shi <ashi009@gmail.com>",
23
26
  "contributors": [