node-html-parser 6.1.15-0 → 7.0.1
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/CHANGELOG.md +23 -0
- package/README.md +1 -3
- package/dist/index.js +8 -9
- package/dist/main.js +27 -19
- package/dist/matcher.js +26 -26
- package/dist/nodes/comment.js +22 -46
- package/dist/nodes/html.js +542 -720
- package/dist/nodes/node.js +18 -29
- package/dist/nodes/text.js +61 -100
- package/dist/valid.js +3 -4
- package/dist/void-tag.js +13 -15
- package/package.json +1 -1
package/dist/nodes/html.js
CHANGED
|
@@ -1,141 +1,89 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __extends = (this && this.__extends) || (function () {
|
|
3
|
-
var extendStatics = function (d, b) {
|
|
4
|
-
extendStatics = Object.setPrototypeOf ||
|
|
5
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
-
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
-
return extendStatics(d, b);
|
|
8
|
-
};
|
|
9
|
-
return function (d, b) {
|
|
10
|
-
if (typeof b !== "function" && b !== null)
|
|
11
|
-
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
-
extendStatics(d, b);
|
|
13
|
-
function __() { this.constructor = d; }
|
|
14
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
-
};
|
|
16
|
-
})();
|
|
17
|
-
var __assign = (this && this.__assign) || function () {
|
|
18
|
-
__assign = Object.assign || function(t) {
|
|
19
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
20
|
-
s = arguments[i];
|
|
21
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
22
|
-
t[p] = s[p];
|
|
23
|
-
}
|
|
24
|
-
return t;
|
|
25
|
-
};
|
|
26
|
-
return __assign.apply(this, arguments);
|
|
27
|
-
};
|
|
28
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
29
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
30
|
-
if (ar || !(i in from)) {
|
|
31
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
32
|
-
ar[i] = from[i];
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
36
|
-
};
|
|
37
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
38
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
39
4
|
};
|
|
40
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
6
|
exports.parse = exports.base_parse = void 0;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
7
|
+
const css_select_1 = require("css-select");
|
|
8
|
+
const he_1 = __importDefault(require("he"));
|
|
9
|
+
const back_1 = __importDefault(require("../back"));
|
|
10
|
+
const matcher_1 = __importDefault(require("../matcher"));
|
|
11
|
+
const void_tag_1 = __importDefault(require("../void-tag"));
|
|
12
|
+
const comment_1 = __importDefault(require("./comment"));
|
|
13
|
+
const node_1 = __importDefault(require("./node"));
|
|
14
|
+
const text_1 = __importDefault(require("./text"));
|
|
15
|
+
const type_1 = __importDefault(require("./type"));
|
|
51
16
|
function decode(val) {
|
|
52
17
|
// clone string
|
|
53
18
|
return JSON.parse(JSON.stringify(he_1.default.decode(val)));
|
|
54
19
|
}
|
|
55
20
|
// https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
function addToKBlockElement() {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
var addToSet = function (array) {
|
|
68
|
-
for (var index = 0; index < array.length; index++) {
|
|
69
|
-
var element = array[index];
|
|
21
|
+
const Htags = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup'];
|
|
22
|
+
const Dtags = ['details', 'dialog', 'dd', 'div', 'dt'];
|
|
23
|
+
const Ftags = ['fieldset', 'figcaption', 'figure', 'footer', 'form'];
|
|
24
|
+
const tableTags = ['table', 'td', 'tr'];
|
|
25
|
+
const htmlTags = ['address', 'article', 'aside', 'blockquote', 'br', 'hr', 'li', 'main', 'nav', 'ol', 'p', 'pre', 'section', 'ul'];
|
|
26
|
+
const kBlockElements = new Set();
|
|
27
|
+
function addToKBlockElement(...args) {
|
|
28
|
+
const addToSet = (array) => {
|
|
29
|
+
for (let index = 0; index < array.length; index++) {
|
|
30
|
+
const element = array[index];
|
|
70
31
|
kBlockElements.add(element);
|
|
71
32
|
kBlockElements.add(element.toUpperCase());
|
|
72
33
|
}
|
|
73
34
|
};
|
|
74
|
-
for (
|
|
75
|
-
var arg = args_1[_a];
|
|
35
|
+
for (const arg of args)
|
|
76
36
|
addToSet(arg);
|
|
77
|
-
}
|
|
78
37
|
}
|
|
79
38
|
addToKBlockElement(Htags, Dtags, Ftags, tableTags, htmlTags);
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if (
|
|
83
|
-
|
|
39
|
+
class DOMTokenList {
|
|
40
|
+
_validate(c) {
|
|
41
|
+
if (/\s/.test(c)) {
|
|
42
|
+
throw new Error(`DOMException in DOMTokenList.add: The token '${c}' contains HTML space characters, which are not valid in tokens.`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
constructor(valuesInit = [], afterUpdate = () => null) {
|
|
84
46
|
this._set = new Set(valuesInit);
|
|
85
47
|
this._afterUpdate = afterUpdate;
|
|
86
48
|
}
|
|
87
|
-
|
|
88
|
-
if (/\s/.test(c)) {
|
|
89
|
-
throw new Error("DOMException in DOMTokenList.add: The token '".concat(c, "' contains HTML space characters, which are not valid in tokens."));
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
DOMTokenList.prototype.add = function (c) {
|
|
49
|
+
add(c) {
|
|
93
50
|
this._validate(c);
|
|
94
51
|
this._set.add(c);
|
|
95
52
|
this._afterUpdate(this); // eslint-disable-line @typescript-eslint/no-unsafe-call
|
|
96
|
-
}
|
|
97
|
-
|
|
53
|
+
}
|
|
54
|
+
replace(c1, c2) {
|
|
98
55
|
this._validate(c2);
|
|
99
56
|
this._set.delete(c1);
|
|
100
57
|
this._set.add(c2);
|
|
101
58
|
this._afterUpdate(this); // eslint-disable-line @typescript-eslint/no-unsafe-call
|
|
102
|
-
}
|
|
103
|
-
|
|
59
|
+
}
|
|
60
|
+
remove(c) {
|
|
104
61
|
this._set.delete(c) && this._afterUpdate(this); // eslint-disable-line @typescript-eslint/no-unsafe-call
|
|
105
|
-
}
|
|
106
|
-
|
|
62
|
+
}
|
|
63
|
+
toggle(c) {
|
|
107
64
|
this._validate(c);
|
|
108
65
|
if (this._set.has(c))
|
|
109
66
|
this._set.delete(c);
|
|
110
67
|
else
|
|
111
68
|
this._set.add(c);
|
|
112
69
|
this._afterUpdate(this); // eslint-disable-line @typescript-eslint/no-unsafe-call
|
|
113
|
-
}
|
|
114
|
-
|
|
70
|
+
}
|
|
71
|
+
contains(c) {
|
|
115
72
|
return this._set.has(c);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
enumerable: false,
|
|
122
|
-
configurable: true
|
|
123
|
-
});
|
|
124
|
-
DOMTokenList.prototype.values = function () {
|
|
73
|
+
}
|
|
74
|
+
get length() {
|
|
75
|
+
return this._set.size;
|
|
76
|
+
}
|
|
77
|
+
values() {
|
|
125
78
|
return this._set.values();
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
enumerable: false,
|
|
132
|
-
configurable: true
|
|
133
|
-
});
|
|
134
|
-
DOMTokenList.prototype.toString = function () {
|
|
79
|
+
}
|
|
80
|
+
get value() {
|
|
81
|
+
return Array.from(this._set.values());
|
|
82
|
+
}
|
|
83
|
+
toString() {
|
|
135
84
|
return Array.from(this._set.values()).join(' ');
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
}());
|
|
85
|
+
}
|
|
86
|
+
}
|
|
139
87
|
/**
|
|
140
88
|
* HTMLElement, which contains a set of children.
|
|
141
89
|
*
|
|
@@ -145,8 +93,22 @@ var DOMTokenList = /** @class */ (function () {
|
|
|
145
93
|
* @class HTMLElement
|
|
146
94
|
* @extends {Node}
|
|
147
95
|
*/
|
|
148
|
-
|
|
149
|
-
|
|
96
|
+
class HTMLElement extends node_1.default {
|
|
97
|
+
/**
|
|
98
|
+
* Quote attribute values
|
|
99
|
+
* @param attr attribute value
|
|
100
|
+
* @returns {string} quoted value
|
|
101
|
+
*/
|
|
102
|
+
quoteAttribute(attr) {
|
|
103
|
+
if (attr == null) {
|
|
104
|
+
return 'null';
|
|
105
|
+
}
|
|
106
|
+
return JSON.stringify(attr.replace(/"/g, '"'))
|
|
107
|
+
.replace(/\\t/g, '\t')
|
|
108
|
+
.replace(/\\n/g, '\n')
|
|
109
|
+
.replace(/\\r/g, '\r')
|
|
110
|
+
.replace(/\\/g, '');
|
|
111
|
+
}
|
|
150
112
|
/**
|
|
151
113
|
* Creates an instance of HTMLElement.
|
|
152
114
|
* @param keyAttrs id and class attribute
|
|
@@ -154,279 +116,220 @@ var HTMLElement = /** @class */ (function (_super) {
|
|
|
154
116
|
*
|
|
155
117
|
* @memberof HTMLElement
|
|
156
118
|
*/
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
if (_parseOptions === void 0) { _parseOptions = {}; }
|
|
162
|
-
var _this = _super.call(this, parentNode, range) || this;
|
|
163
|
-
_this.rawAttrs = rawAttrs;
|
|
164
|
-
_this.voidTag = voidTag;
|
|
119
|
+
constructor(tagName, keyAttrs, rawAttrs = '', parentNode = null, range, voidTag = new void_tag_1.default(), _parseOptions = {}) {
|
|
120
|
+
super(parentNode, range);
|
|
121
|
+
this.rawAttrs = rawAttrs;
|
|
122
|
+
this.voidTag = voidTag;
|
|
165
123
|
/**
|
|
166
124
|
* Node Type declaration.
|
|
167
125
|
*/
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
126
|
+
this.nodeType = type_1.default.ELEMENT_NODE;
|
|
127
|
+
this.rawTagName = tagName;
|
|
128
|
+
this.rawAttrs = rawAttrs || '';
|
|
129
|
+
this.id = keyAttrs.id || '';
|
|
130
|
+
this.childNodes = [];
|
|
131
|
+
this._parseOptions = _parseOptions;
|
|
132
|
+
this.classList = new DOMTokenList(keyAttrs.class ? keyAttrs.class.split(/\s+/) : [], (classList) => this.setAttribute('class', classList.toString()) // eslint-disable-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
175
133
|
);
|
|
176
134
|
if (keyAttrs.id) {
|
|
177
135
|
if (!rawAttrs) {
|
|
178
|
-
|
|
136
|
+
this.rawAttrs = `id="${keyAttrs.id}"`;
|
|
179
137
|
}
|
|
180
138
|
}
|
|
181
139
|
if (keyAttrs.class) {
|
|
182
140
|
if (!rawAttrs) {
|
|
183
|
-
|
|
184
|
-
if (
|
|
185
|
-
|
|
141
|
+
const cls = `class="${this.classList.toString()}"`;
|
|
142
|
+
if (this.rawAttrs) {
|
|
143
|
+
this.rawAttrs += ` ${cls}`;
|
|
186
144
|
}
|
|
187
145
|
else {
|
|
188
|
-
|
|
146
|
+
this.rawAttrs = cls;
|
|
189
147
|
}
|
|
190
148
|
}
|
|
191
149
|
}
|
|
192
|
-
return _this;
|
|
193
150
|
}
|
|
194
|
-
/**
|
|
195
|
-
* Quote attribute values
|
|
196
|
-
* @param attr attribute value
|
|
197
|
-
* @returns {string} quoted value
|
|
198
|
-
*/
|
|
199
|
-
HTMLElement.prototype.quoteAttribute = function (attr) {
|
|
200
|
-
if (attr == null) {
|
|
201
|
-
return 'null';
|
|
202
|
-
}
|
|
203
|
-
return JSON.stringify(attr.replace(/"/g, '"')).replace(/\\t/g, '\t').replace(/\\n/g, '\n').replace(/\\r/g, '\r').replace(/\\/g, '');
|
|
204
|
-
};
|
|
205
151
|
/**
|
|
206
152
|
* Remove Child element from childNodes array
|
|
207
153
|
* @param {HTMLElement} node node to remove
|
|
208
154
|
*/
|
|
209
|
-
|
|
210
|
-
this.childNodes = this.childNodes.filter(
|
|
155
|
+
removeChild(node) {
|
|
156
|
+
this.childNodes = this.childNodes.filter((child) => {
|
|
211
157
|
return child !== node;
|
|
212
158
|
});
|
|
213
159
|
return this;
|
|
214
|
-
}
|
|
160
|
+
}
|
|
215
161
|
/**
|
|
216
162
|
* Exchanges given child with new child
|
|
217
163
|
* @param {HTMLElement} oldNode node to exchange
|
|
218
164
|
* @param {HTMLElement} newNode new node
|
|
219
165
|
*/
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
this.childNodes = children.map(
|
|
166
|
+
exchangeChild(oldNode, newNode) {
|
|
167
|
+
const children = this.childNodes;
|
|
168
|
+
this.childNodes = children.map((child) => {
|
|
223
169
|
if (child === oldNode) {
|
|
224
170
|
return newNode;
|
|
225
171
|
}
|
|
226
172
|
return child;
|
|
227
173
|
});
|
|
228
174
|
return this;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
return
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
});
|
|
282
|
-
Object.defineProperty(HTMLElement.prototype, "text", {
|
|
283
|
-
/**
|
|
284
|
-
* Get unescaped text value of current node and its children.
|
|
285
|
-
* @return {string} text content
|
|
286
|
-
*/
|
|
287
|
-
get: function () {
|
|
288
|
-
return decode(this.rawText);
|
|
289
|
-
},
|
|
290
|
-
enumerable: false,
|
|
291
|
-
configurable: true
|
|
292
|
-
});
|
|
293
|
-
Object.defineProperty(HTMLElement.prototype, "structuredText", {
|
|
294
|
-
/**
|
|
295
|
-
* Get structured Text (with '\n' etc.)
|
|
296
|
-
* @return {string} structured text
|
|
297
|
-
*/
|
|
298
|
-
get: function () {
|
|
299
|
-
var currentBlock = [];
|
|
300
|
-
var blocks = [currentBlock];
|
|
301
|
-
function dfs(node) {
|
|
302
|
-
if (node.nodeType === type_1.default.ELEMENT_NODE) {
|
|
303
|
-
if (kBlockElements.has(node.rawTagName)) {
|
|
304
|
-
if (currentBlock.length > 0) {
|
|
305
|
-
blocks.push((currentBlock = []));
|
|
306
|
-
}
|
|
307
|
-
node.childNodes.forEach(dfs);
|
|
308
|
-
if (currentBlock.length > 0) {
|
|
309
|
-
blocks.push((currentBlock = []));
|
|
310
|
-
}
|
|
175
|
+
}
|
|
176
|
+
get tagName() {
|
|
177
|
+
return this.rawTagName ? this.rawTagName.toUpperCase() : this.rawTagName;
|
|
178
|
+
}
|
|
179
|
+
set tagName(newname) {
|
|
180
|
+
this.rawTagName = newname.toLowerCase();
|
|
181
|
+
}
|
|
182
|
+
get localName() {
|
|
183
|
+
return this.rawTagName.toLowerCase();
|
|
184
|
+
}
|
|
185
|
+
get isVoidElement() {
|
|
186
|
+
return this.voidTag.isVoidElement(this.localName);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Get escpaed (as-it) text value of current node and its children.
|
|
190
|
+
* @return {string} text content
|
|
191
|
+
*/
|
|
192
|
+
get rawText() {
|
|
193
|
+
// https://github.com/taoqf/node-html-parser/issues/249
|
|
194
|
+
if (/^br$/i.test(this.rawTagName)) {
|
|
195
|
+
return '\n';
|
|
196
|
+
}
|
|
197
|
+
return this.childNodes.reduce((pre, cur) => {
|
|
198
|
+
return (pre += cur.rawText);
|
|
199
|
+
}, '');
|
|
200
|
+
}
|
|
201
|
+
get textContent() {
|
|
202
|
+
return decode(this.rawText);
|
|
203
|
+
}
|
|
204
|
+
set textContent(val) {
|
|
205
|
+
const content = [new text_1.default(val, this)];
|
|
206
|
+
this.childNodes = content;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Get unescaped text value of current node and its children.
|
|
210
|
+
* @return {string} text content
|
|
211
|
+
*/
|
|
212
|
+
get text() {
|
|
213
|
+
return decode(this.rawText);
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Get structured Text (with '\n' etc.)
|
|
217
|
+
* @return {string} structured text
|
|
218
|
+
*/
|
|
219
|
+
get structuredText() {
|
|
220
|
+
let currentBlock = [];
|
|
221
|
+
const blocks = [currentBlock];
|
|
222
|
+
function dfs(node) {
|
|
223
|
+
if (node.nodeType === type_1.default.ELEMENT_NODE) {
|
|
224
|
+
if (kBlockElements.has(node.rawTagName)) {
|
|
225
|
+
if (currentBlock.length > 0) {
|
|
226
|
+
blocks.push((currentBlock = []));
|
|
311
227
|
}
|
|
312
|
-
|
|
313
|
-
|
|
228
|
+
node.childNodes.forEach(dfs);
|
|
229
|
+
if (currentBlock.length > 0) {
|
|
230
|
+
blocks.push((currentBlock = []));
|
|
314
231
|
}
|
|
315
232
|
}
|
|
316
|
-
else
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
233
|
+
else {
|
|
234
|
+
node.childNodes.forEach(dfs);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else if (node.nodeType === type_1.default.TEXT_NODE) {
|
|
238
|
+
if (node.isWhitespace) {
|
|
239
|
+
// Whitespace node, postponed output
|
|
240
|
+
currentBlock.prependWhitespace = true;
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
let text = node.trimmedText;
|
|
244
|
+
if (currentBlock.prependWhitespace) {
|
|
245
|
+
text = ` ${text}`;
|
|
246
|
+
currentBlock.prependWhitespace = false;
|
|
328
247
|
}
|
|
248
|
+
currentBlock.push(text);
|
|
329
249
|
}
|
|
330
250
|
}
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
})
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
HTMLElement.prototype.toString = function () {
|
|
343
|
-
var tag = this.rawTagName;
|
|
251
|
+
}
|
|
252
|
+
dfs(this);
|
|
253
|
+
return blocks
|
|
254
|
+
.map((block) => {
|
|
255
|
+
return block.join('').replace(/\s{2,}/g, ' '); // Normalize each line's whitespace
|
|
256
|
+
})
|
|
257
|
+
.join('\n')
|
|
258
|
+
.replace(/\s+$/, ''); // trimRight;
|
|
259
|
+
}
|
|
260
|
+
toString() {
|
|
261
|
+
const tag = this.rawTagName;
|
|
344
262
|
if (tag) {
|
|
345
|
-
|
|
263
|
+
const attrs = this.rawAttrs ? ` ${this.rawAttrs}` : '';
|
|
346
264
|
return this.voidTag.formatNode(tag, attrs, this.innerHTML);
|
|
347
265
|
}
|
|
348
266
|
return this.innerHTML;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
enumerable: false,
|
|
366
|
-
configurable: true
|
|
367
|
-
});
|
|
368
|
-
HTMLElement.prototype.set_content = function (content, options) {
|
|
369
|
-
if (options === void 0) { options = {}; }
|
|
267
|
+
}
|
|
268
|
+
get innerHTML() {
|
|
269
|
+
return this.childNodes
|
|
270
|
+
.map((child) => {
|
|
271
|
+
return child.toString();
|
|
272
|
+
})
|
|
273
|
+
.join('');
|
|
274
|
+
}
|
|
275
|
+
set innerHTML(content) {
|
|
276
|
+
const r = parse(content, this._parseOptions);
|
|
277
|
+
const nodes = r.childNodes.length ? r.childNodes : [new text_1.default(content, this)];
|
|
278
|
+
resetParent(nodes, this);
|
|
279
|
+
resetParent(this.childNodes, null);
|
|
280
|
+
this.childNodes = nodes;
|
|
281
|
+
}
|
|
282
|
+
set_content(content, options = {}) {
|
|
370
283
|
if (content instanceof node_1.default) {
|
|
371
284
|
content = [content];
|
|
372
285
|
}
|
|
373
286
|
else if (typeof content == 'string') {
|
|
374
|
-
options =
|
|
375
|
-
|
|
287
|
+
options = Object.assign(Object.assign({}, this._parseOptions), options);
|
|
288
|
+
const r = parse(content, options);
|
|
376
289
|
content = r.childNodes.length ? r.childNodes : [new text_1.default(r.innerHTML, this)];
|
|
377
290
|
}
|
|
378
291
|
resetParent(this.childNodes, null);
|
|
379
292
|
resetParent(content, this);
|
|
380
293
|
this.childNodes = content;
|
|
381
294
|
return this;
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
nodes[_i] = arguments[_i];
|
|
388
|
-
}
|
|
389
|
-
var parent = this.parentNode;
|
|
390
|
-
var content = nodes
|
|
391
|
-
.map(function (node) {
|
|
295
|
+
}
|
|
296
|
+
replaceWith(...nodes) {
|
|
297
|
+
const parent = this.parentNode;
|
|
298
|
+
const content = nodes
|
|
299
|
+
.map((node) => {
|
|
392
300
|
if (node instanceof node_1.default) {
|
|
393
301
|
return [node];
|
|
394
302
|
}
|
|
395
303
|
else if (typeof node == 'string') {
|
|
396
|
-
|
|
397
|
-
return r.childNodes.length ? r.childNodes : [new text_1.default(node,
|
|
304
|
+
const r = parse(node, this._parseOptions);
|
|
305
|
+
return r.childNodes.length ? r.childNodes : [new text_1.default(node, this)];
|
|
398
306
|
}
|
|
399
307
|
return [];
|
|
400
308
|
})
|
|
401
309
|
.flat();
|
|
402
|
-
|
|
403
|
-
return child ===
|
|
310
|
+
const idx = parent.childNodes.findIndex((child) => {
|
|
311
|
+
return child === this;
|
|
404
312
|
});
|
|
405
313
|
resetParent([this], null);
|
|
406
|
-
resetParent(content, parent);
|
|
407
|
-
parent.childNodes = __spreadArray(__spreadArray(__spreadArray([], parent.childNodes.slice(0, idx), true), content, true), parent.childNodes.slice(idx + 1), true);
|
|
314
|
+
parent.childNodes = [...parent.childNodes.slice(0, idx), ...resetParent(content, parent), ...parent.childNodes.slice(idx + 1)];
|
|
408
315
|
return this;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
},
|
|
414
|
-
enumerable: false,
|
|
415
|
-
configurable: true
|
|
416
|
-
});
|
|
316
|
+
}
|
|
317
|
+
get outerHTML() {
|
|
318
|
+
return this.toString();
|
|
319
|
+
}
|
|
417
320
|
/**
|
|
418
321
|
* Trim element from right (in block) after seeing pattern in a TextNode.
|
|
419
322
|
* @param {RegExp} pattern pattern to find
|
|
420
323
|
* @return {HTMLElement} reference to current node
|
|
421
324
|
*/
|
|
422
|
-
|
|
423
|
-
for (
|
|
424
|
-
|
|
325
|
+
trimRight(pattern) {
|
|
326
|
+
for (let i = 0; i < this.childNodes.length; i++) {
|
|
327
|
+
const childNode = this.childNodes[i];
|
|
425
328
|
if (childNode.nodeType === type_1.default.ELEMENT_NODE) {
|
|
426
329
|
childNode.trimRight(pattern);
|
|
427
330
|
}
|
|
428
331
|
else {
|
|
429
|
-
|
|
332
|
+
const index = childNode.rawText.search(pattern);
|
|
430
333
|
if (index > -1) {
|
|
431
334
|
childNode.rawText = childNode.rawText.substr(0, index);
|
|
432
335
|
// trim all following nodes.
|
|
@@ -435,49 +338,44 @@ var HTMLElement = /** @class */ (function (_super) {
|
|
|
435
338
|
}
|
|
436
339
|
}
|
|
437
340
|
return this;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
write('#text');
|
|
462
|
-
}
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Get DOM structure
|
|
344
|
+
* @return {string} structure
|
|
345
|
+
*/
|
|
346
|
+
get structure() {
|
|
347
|
+
const res = [];
|
|
348
|
+
let indention = 0;
|
|
349
|
+
function write(str) {
|
|
350
|
+
res.push(' '.repeat(indention) + str);
|
|
351
|
+
}
|
|
352
|
+
function dfs(node) {
|
|
353
|
+
const idStr = node.id ? `#${node.id}` : '';
|
|
354
|
+
const classStr = node.classList.length ? `.${node.classList.value.join('.')}` : ''; // eslint-disable-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/restrict-template-expressions, @typescript-eslint/no-unsafe-call
|
|
355
|
+
write(`${node.rawTagName}${idStr}${classStr}`);
|
|
356
|
+
indention++;
|
|
357
|
+
node.childNodes.forEach((childNode) => {
|
|
358
|
+
if (childNode.nodeType === type_1.default.ELEMENT_NODE) {
|
|
359
|
+
dfs(childNode);
|
|
360
|
+
}
|
|
361
|
+
else if (childNode.nodeType === type_1.default.TEXT_NODE) {
|
|
362
|
+
if (!childNode.isWhitespace) {
|
|
363
|
+
write('#text');
|
|
463
364
|
}
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
configurable: true
|
|
472
|
-
});
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
indention--;
|
|
368
|
+
}
|
|
369
|
+
dfs(this);
|
|
370
|
+
return res.join('\n');
|
|
371
|
+
}
|
|
473
372
|
/**
|
|
474
373
|
* Remove whitespaces in this sub tree.
|
|
475
374
|
* @return {HTMLElement} pointer to this
|
|
476
375
|
*/
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
this.childNodes.forEach(function (node) {
|
|
376
|
+
removeWhitespace() {
|
|
377
|
+
let o = 0;
|
|
378
|
+
this.childNodes.forEach((node) => {
|
|
481
379
|
if (node.nodeType === type_1.default.TEXT_NODE) {
|
|
482
380
|
if (node.isWhitespace) {
|
|
483
381
|
return;
|
|
@@ -487,54 +385,56 @@ var HTMLElement = /** @class */ (function (_super) {
|
|
|
487
385
|
else if (node.nodeType === type_1.default.ELEMENT_NODE) {
|
|
488
386
|
node.removeWhitespace();
|
|
489
387
|
}
|
|
490
|
-
|
|
388
|
+
this.childNodes[o++] = node;
|
|
491
389
|
});
|
|
492
390
|
this.childNodes.length = o;
|
|
493
391
|
// remove whitespace between attributes
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
392
|
+
const attrs = Object.keys(this.rawAttributes)
|
|
393
|
+
.map((key) => {
|
|
394
|
+
const val = this.rawAttributes[key];
|
|
395
|
+
return `${key}=${JSON.stringify(val)}`;
|
|
396
|
+
})
|
|
397
|
+
.join(' ');
|
|
498
398
|
this.rawAttrs = attrs;
|
|
499
399
|
delete this._rawAttrs;
|
|
500
400
|
return this;
|
|
501
|
-
}
|
|
401
|
+
}
|
|
502
402
|
/**
|
|
503
403
|
* Query CSS selector to find matching nodes.
|
|
504
404
|
* @param {string} selector Simplified CSS selector
|
|
505
405
|
* @return {HTMLElement[]} matching elements
|
|
506
406
|
*/
|
|
507
|
-
|
|
407
|
+
querySelectorAll(selector) {
|
|
508
408
|
return (0, css_select_1.selectAll)(selector, this, {
|
|
509
409
|
xmlMode: true,
|
|
510
410
|
adapter: matcher_1.default,
|
|
511
411
|
});
|
|
512
|
-
}
|
|
412
|
+
}
|
|
513
413
|
/**
|
|
514
414
|
* Query CSS Selector to find matching node.
|
|
515
415
|
* @param {string} selector Simplified CSS selector
|
|
516
416
|
* @return {(HTMLElement|null)} matching node
|
|
517
417
|
*/
|
|
518
|
-
|
|
418
|
+
querySelector(selector) {
|
|
519
419
|
return (0, css_select_1.selectOne)(selector, this, {
|
|
520
420
|
xmlMode: true,
|
|
521
421
|
adapter: matcher_1.default,
|
|
522
422
|
});
|
|
523
|
-
}
|
|
423
|
+
}
|
|
524
424
|
/**
|
|
525
425
|
* find elements by their tagName
|
|
526
426
|
* @param {string} tagName the tagName of the elements to select
|
|
527
427
|
*/
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
428
|
+
getElementsByTagName(tagName) {
|
|
429
|
+
const upperCasedTagName = tagName.toUpperCase();
|
|
430
|
+
const re = [];
|
|
431
|
+
const stack = [];
|
|
432
|
+
let currentNodeReference = this;
|
|
433
|
+
let index = 0;
|
|
534
434
|
// index turns to undefined once the stack is empty and the first condition occurs
|
|
535
435
|
// which happens once all relevant children are searched through
|
|
536
436
|
while (index !== undefined) {
|
|
537
|
-
|
|
437
|
+
let child;
|
|
538
438
|
// make it work with sparse arrays
|
|
539
439
|
do {
|
|
540
440
|
child = currentNodeReference.childNodes[index++];
|
|
@@ -558,20 +458,20 @@ var HTMLElement = /** @class */ (function (_super) {
|
|
|
558
458
|
}
|
|
559
459
|
}
|
|
560
460
|
return re;
|
|
561
|
-
}
|
|
461
|
+
}
|
|
562
462
|
/**
|
|
563
463
|
* find element by it's id
|
|
564
464
|
* @param {string} id the id of the element to select
|
|
565
465
|
* @returns {HTMLElement | null} the element with the given id or null if not found
|
|
566
466
|
*/
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
467
|
+
getElementById(id) {
|
|
468
|
+
const stack = [];
|
|
469
|
+
let currentNodeReference = this;
|
|
470
|
+
let index = 0;
|
|
571
471
|
// index turns to undefined once the stack is empty and the first condition occurs
|
|
572
472
|
// which happens once all relevant children are searched through
|
|
573
473
|
while (index !== undefined) {
|
|
574
|
-
|
|
474
|
+
let child;
|
|
575
475
|
// make it work with sparse arrays
|
|
576
476
|
do {
|
|
577
477
|
child = currentNodeReference.childNodes[index++];
|
|
@@ -586,7 +486,6 @@ var HTMLElement = /** @class */ (function (_super) {
|
|
|
586
486
|
if (child.id === id) {
|
|
587
487
|
return child;
|
|
588
488
|
}
|
|
589
|
-
;
|
|
590
489
|
// if children are existing push the current status to the stack and keep searching for elements in the level below
|
|
591
490
|
if (child.childNodes.length > 0) {
|
|
592
491
|
stack.push(index);
|
|
@@ -596,25 +495,25 @@ var HTMLElement = /** @class */ (function (_super) {
|
|
|
596
495
|
}
|
|
597
496
|
}
|
|
598
497
|
return null;
|
|
599
|
-
}
|
|
498
|
+
}
|
|
600
499
|
/**
|
|
601
500
|
* traverses the Element and its parents (heading toward the document root) until it finds a node that matches the provided selector string. Will return itself or the matching ancestor. If no such element exists, it returns null.
|
|
602
501
|
* @param selector a DOMString containing a selector list
|
|
603
502
|
* @returns {HTMLElement | null} the element with the given id or null if not found
|
|
604
503
|
*/
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
504
|
+
closest(selector) {
|
|
505
|
+
const mapChild = new Map();
|
|
506
|
+
let el = this;
|
|
507
|
+
let old = null;
|
|
609
508
|
function findOne(test, elems) {
|
|
610
|
-
|
|
611
|
-
for (
|
|
612
|
-
|
|
613
|
-
if (test(
|
|
614
|
-
elem =
|
|
509
|
+
let elem = null;
|
|
510
|
+
for (let i = 0, l = elems.length; i < l && !elem; i++) {
|
|
511
|
+
const el = elems[i];
|
|
512
|
+
if (test(el)) {
|
|
513
|
+
elem = el;
|
|
615
514
|
}
|
|
616
515
|
else {
|
|
617
|
-
|
|
516
|
+
const child = mapChild.get(el);
|
|
618
517
|
if (child) {
|
|
619
518
|
elem = findOne(test, [child]);
|
|
620
519
|
}
|
|
@@ -629,14 +528,17 @@ var HTMLElement = /** @class */ (function (_super) {
|
|
|
629
528
|
}
|
|
630
529
|
el = this;
|
|
631
530
|
while (el) {
|
|
632
|
-
|
|
531
|
+
const e = (0, css_select_1.selectOne)(selector, el, {
|
|
633
532
|
xmlMode: true,
|
|
634
|
-
adapter:
|
|
635
|
-
|
|
533
|
+
adapter: Object.assign(Object.assign({}, matcher_1.default), { getChildren(node) {
|
|
534
|
+
const child = mapChild.get(node);
|
|
636
535
|
return child && [child];
|
|
637
|
-
},
|
|
536
|
+
},
|
|
537
|
+
getSiblings(node) {
|
|
638
538
|
return [node];
|
|
639
|
-
},
|
|
539
|
+
},
|
|
540
|
+
findOne,
|
|
541
|
+
findAll() {
|
|
640
542
|
return [];
|
|
641
543
|
} }),
|
|
642
544
|
});
|
|
@@ -646,80 +548,67 @@ var HTMLElement = /** @class */ (function (_super) {
|
|
|
646
548
|
el = el.parentNode;
|
|
647
549
|
}
|
|
648
550
|
return null;
|
|
649
|
-
}
|
|
551
|
+
}
|
|
650
552
|
/**
|
|
651
553
|
* Append a child node to childNodes
|
|
652
554
|
* @param {Node} node node to append
|
|
653
555
|
* @return {Node} node appended
|
|
654
556
|
*/
|
|
655
|
-
|
|
557
|
+
appendChild(node) {
|
|
656
558
|
this.append(node);
|
|
657
559
|
return node;
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
if (this._attrs) {
|
|
667
|
-
return this._attrs;
|
|
668
|
-
}
|
|
669
|
-
this._attrs = {};
|
|
670
|
-
var attrs = this.rawAttributes;
|
|
671
|
-
for (var key in attrs) {
|
|
672
|
-
var val = attrs[key] || '';
|
|
673
|
-
this._attrs[key.toLowerCase()] = decode(val);
|
|
674
|
-
}
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Get attributes
|
|
563
|
+
* @access private
|
|
564
|
+
* @return {Object} parsed and unescaped attributes
|
|
565
|
+
*/
|
|
566
|
+
get attrs() {
|
|
567
|
+
if (this._attrs) {
|
|
675
568
|
return this._attrs;
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
}
|
|
569
|
+
}
|
|
570
|
+
this._attrs = {};
|
|
571
|
+
const attrs = this.rawAttributes;
|
|
572
|
+
for (const key in attrs) {
|
|
573
|
+
const val = attrs[key] || '';
|
|
574
|
+
this._attrs[key.toLowerCase()] = decode(val);
|
|
575
|
+
}
|
|
576
|
+
return this._attrs;
|
|
577
|
+
}
|
|
578
|
+
get attributes() {
|
|
579
|
+
const ret_attrs = {};
|
|
580
|
+
const attrs = this.rawAttributes;
|
|
581
|
+
for (const key in attrs) {
|
|
582
|
+
const val = attrs[key] || '';
|
|
583
|
+
ret_attrs[key] = decode(val);
|
|
584
|
+
}
|
|
585
|
+
return ret_attrs;
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Get escaped (as-is) attributes
|
|
589
|
+
* @return {Object} parsed attributes
|
|
590
|
+
*/
|
|
591
|
+
get rawAttributes() {
|
|
592
|
+
if (this._rawAttrs) {
|
|
593
|
+
return this._rawAttrs;
|
|
594
|
+
}
|
|
595
|
+
const attrs = {};
|
|
596
|
+
if (this.rawAttrs) {
|
|
597
|
+
const re = /([a-zA-Z()[\]#@$.?:][a-zA-Z0-9-._:()[\]#]*)(?:\s*=\s*((?:'[^']*')|(?:"[^"]*")|\S+))?/g;
|
|
598
|
+
let match;
|
|
599
|
+
while ((match = re.exec(this.rawAttrs))) {
|
|
600
|
+
const key = match[1];
|
|
601
|
+
let val = match[2] || null;
|
|
602
|
+
if (val && (val[0] === `'` || val[0] === `"`))
|
|
603
|
+
val = val.slice(1, val.length - 1);
|
|
604
|
+
attrs[key] = attrs[key] || val;
|
|
713
605
|
}
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
HTMLElement.prototype.removeAttribute = function (key) {
|
|
721
|
-
var _this = this;
|
|
722
|
-
var attrs = this.rawAttributes;
|
|
606
|
+
}
|
|
607
|
+
this._rawAttrs = attrs;
|
|
608
|
+
return attrs;
|
|
609
|
+
}
|
|
610
|
+
removeAttribute(key) {
|
|
611
|
+
const attrs = this.rawAttributes;
|
|
723
612
|
delete attrs[key];
|
|
724
613
|
// Update this.attribute
|
|
725
614
|
if (this._attrs) {
|
|
@@ -727,11 +616,11 @@ var HTMLElement = /** @class */ (function (_super) {
|
|
|
727
616
|
}
|
|
728
617
|
// Update rawString
|
|
729
618
|
this.rawAttrs = Object.keys(attrs)
|
|
730
|
-
.map(
|
|
731
|
-
|
|
619
|
+
.map((name) => {
|
|
620
|
+
const val = this.quoteAttribute(attrs[name]);
|
|
732
621
|
if (val === 'null' || val === '""')
|
|
733
622
|
return name;
|
|
734
|
-
return
|
|
623
|
+
return `${name}=${val}`;
|
|
735
624
|
})
|
|
736
625
|
.join(' ');
|
|
737
626
|
// Update this.id
|
|
@@ -739,30 +628,29 @@ var HTMLElement = /** @class */ (function (_super) {
|
|
|
739
628
|
this.id = '';
|
|
740
629
|
}
|
|
741
630
|
return this;
|
|
742
|
-
}
|
|
743
|
-
|
|
631
|
+
}
|
|
632
|
+
hasAttribute(key) {
|
|
744
633
|
return key.toLowerCase() in this.attrs;
|
|
745
|
-
}
|
|
634
|
+
}
|
|
746
635
|
/**
|
|
747
636
|
* Get an attribute
|
|
748
637
|
* @return {string | undefined} value of the attribute; or undefined if not exist
|
|
749
638
|
*/
|
|
750
|
-
|
|
639
|
+
getAttribute(key) {
|
|
751
640
|
return this.attrs[key.toLowerCase()];
|
|
752
|
-
}
|
|
641
|
+
}
|
|
753
642
|
/**
|
|
754
643
|
* Set an attribute value to the HTMLElement
|
|
755
644
|
* @param {string} key The attribute name
|
|
756
645
|
* @param {string} value The value to set, or null / undefined to remove an attribute
|
|
757
646
|
*/
|
|
758
|
-
|
|
759
|
-
var _this = this;
|
|
647
|
+
setAttribute(key, value) {
|
|
760
648
|
if (arguments.length < 2) {
|
|
761
649
|
throw new Error("Failed to execute 'setAttribute' on 'Element'");
|
|
762
650
|
}
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
for (
|
|
651
|
+
const k2 = key.toLowerCase();
|
|
652
|
+
const attrs = this.rawAttributes;
|
|
653
|
+
for (const k in attrs) {
|
|
766
654
|
if (k.toLowerCase() === k2) {
|
|
767
655
|
key = k;
|
|
768
656
|
break;
|
|
@@ -775,11 +663,11 @@ var HTMLElement = /** @class */ (function (_super) {
|
|
|
775
663
|
}
|
|
776
664
|
// Update rawString
|
|
777
665
|
this.rawAttrs = Object.keys(attrs)
|
|
778
|
-
.map(
|
|
779
|
-
|
|
666
|
+
.map((name) => {
|
|
667
|
+
const val = this.quoteAttribute(attrs[name]);
|
|
780
668
|
if (val === 'null' || val === '""')
|
|
781
669
|
return name;
|
|
782
|
-
return
|
|
670
|
+
return `${name}=${val}`;
|
|
783
671
|
})
|
|
784
672
|
.join(' ');
|
|
785
673
|
// Update this.id
|
|
@@ -787,13 +675,12 @@ var HTMLElement = /** @class */ (function (_super) {
|
|
|
787
675
|
this.id = value;
|
|
788
676
|
}
|
|
789
677
|
return this;
|
|
790
|
-
}
|
|
678
|
+
}
|
|
791
679
|
/**
|
|
792
680
|
* Replace all the attributes of the HTMLElement by the provided attributes
|
|
793
681
|
* @param {Attributes} attributes the new attribute set
|
|
794
682
|
*/
|
|
795
|
-
|
|
796
|
-
var _this = this;
|
|
683
|
+
setAttributes(attributes) {
|
|
797
684
|
// Invalidate current this.attributes
|
|
798
685
|
if (this._attrs) {
|
|
799
686
|
delete this._attrs;
|
|
@@ -804,243 +691,181 @@ var HTMLElement = /** @class */ (function (_super) {
|
|
|
804
691
|
}
|
|
805
692
|
// Update rawString
|
|
806
693
|
this.rawAttrs = Object.keys(attributes)
|
|
807
|
-
.map(
|
|
808
|
-
|
|
694
|
+
.map((name) => {
|
|
695
|
+
const val = attributes[name];
|
|
809
696
|
if (val === 'null' || val === '""')
|
|
810
697
|
return name;
|
|
811
|
-
return
|
|
698
|
+
return `${name}=${this.quoteAttribute(String(val))}`;
|
|
812
699
|
})
|
|
813
700
|
.join(' ');
|
|
814
701
|
return this;
|
|
815
|
-
}
|
|
816
|
-
|
|
702
|
+
}
|
|
703
|
+
insertAdjacentHTML(where, html) {
|
|
817
704
|
if (arguments.length < 2) {
|
|
818
705
|
throw new Error('2 arguments required');
|
|
819
706
|
}
|
|
820
|
-
|
|
707
|
+
const p = parse(html, this._parseOptions);
|
|
821
708
|
if (where === 'afterend') {
|
|
822
|
-
this.after
|
|
709
|
+
this.after(...p.childNodes);
|
|
823
710
|
}
|
|
824
711
|
else if (where === 'afterbegin') {
|
|
825
|
-
this.prepend
|
|
712
|
+
this.prepend(...p.childNodes);
|
|
826
713
|
}
|
|
827
714
|
else if (where === 'beforeend') {
|
|
828
|
-
this.append
|
|
715
|
+
this.append(...p.childNodes);
|
|
829
716
|
}
|
|
830
717
|
else if (where === 'beforebegin') {
|
|
831
|
-
this.before
|
|
718
|
+
this.before(...p.childNodes);
|
|
832
719
|
}
|
|
833
720
|
else {
|
|
834
|
-
throw new Error(
|
|
721
|
+
throw new Error(`The value provided ('${where}') is not one of 'beforebegin', 'afterbegin', 'beforeend', or 'afterend'`);
|
|
835
722
|
}
|
|
836
723
|
return this;
|
|
837
|
-
}
|
|
724
|
+
}
|
|
838
725
|
/** Prepend nodes or strings to this node's children. */
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
var insertable = [];
|
|
842
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
843
|
-
insertable[_i] = arguments[_i];
|
|
844
|
-
}
|
|
845
|
-
var nodes = resolveInsertable(insertable);
|
|
726
|
+
prepend(...insertable) {
|
|
727
|
+
const nodes = resolveInsertable(insertable);
|
|
846
728
|
resetParent(nodes, this);
|
|
847
|
-
|
|
848
|
-
}
|
|
729
|
+
this.childNodes.unshift(...nodes);
|
|
730
|
+
}
|
|
849
731
|
/** Append nodes or strings to this node's children. */
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
var insertable = [];
|
|
853
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
854
|
-
insertable[_i] = arguments[_i];
|
|
855
|
-
}
|
|
856
|
-
var nodes = resolveInsertable(insertable);
|
|
732
|
+
append(...insertable) {
|
|
733
|
+
const nodes = resolveInsertable(insertable);
|
|
857
734
|
resetParent(nodes, this);
|
|
858
|
-
|
|
859
|
-
}
|
|
735
|
+
this.childNodes.push(...nodes);
|
|
736
|
+
}
|
|
860
737
|
/** Insert nodes or strings before this node. */
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
insertable[_i] = arguments[_i];
|
|
865
|
-
}
|
|
866
|
-
var nodes = resolveInsertable(insertable);
|
|
867
|
-
var siblings = this.parentNode.childNodes;
|
|
738
|
+
before(...insertable) {
|
|
739
|
+
const nodes = resolveInsertable(insertable);
|
|
740
|
+
const siblings = this.parentNode.childNodes;
|
|
868
741
|
resetParent(nodes, this.parentNode);
|
|
869
|
-
siblings.splice
|
|
870
|
-
}
|
|
742
|
+
siblings.splice(siblings.indexOf(this), 0, ...nodes);
|
|
743
|
+
}
|
|
871
744
|
/** Insert nodes or strings after this node. */
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
insertable[_i] = arguments[_i];
|
|
876
|
-
}
|
|
877
|
-
var nodes = resolveInsertable(insertable);
|
|
878
|
-
var siblings = this.parentNode.childNodes;
|
|
745
|
+
after(...insertable) {
|
|
746
|
+
const nodes = resolveInsertable(insertable);
|
|
747
|
+
const siblings = this.parentNode.childNodes;
|
|
879
748
|
resetParent(nodes, this.parentNode);
|
|
880
|
-
siblings.splice
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
return children[i] || null;
|
|
891
|
-
}
|
|
892
|
-
return null;
|
|
749
|
+
siblings.splice(siblings.indexOf(this) + 1, 0, ...nodes);
|
|
750
|
+
}
|
|
751
|
+
get nextSibling() {
|
|
752
|
+
if (this.parentNode) {
|
|
753
|
+
const children = this.parentNode.childNodes;
|
|
754
|
+
let i = 0;
|
|
755
|
+
while (i < children.length) {
|
|
756
|
+
const child = children[i++];
|
|
757
|
+
if (this === child)
|
|
758
|
+
return children[i] || null;
|
|
893
759
|
}
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
if (child instanceof HTMLElement) {
|
|
908
|
-
return child || null;
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
else if (this === child) {
|
|
912
|
-
find = true;
|
|
760
|
+
return null;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
get nextElementSibling() {
|
|
764
|
+
if (this.parentNode) {
|
|
765
|
+
const children = this.parentNode.childNodes;
|
|
766
|
+
let i = 0;
|
|
767
|
+
let find = false;
|
|
768
|
+
while (i < children.length) {
|
|
769
|
+
const child = children[i++];
|
|
770
|
+
if (find) {
|
|
771
|
+
if (child instanceof HTMLElement) {
|
|
772
|
+
return child || null;
|
|
913
773
|
}
|
|
914
774
|
}
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
},
|
|
918
|
-
enumerable: false,
|
|
919
|
-
configurable: true
|
|
920
|
-
});
|
|
921
|
-
Object.defineProperty(HTMLElement.prototype, "previousSibling", {
|
|
922
|
-
get: function () {
|
|
923
|
-
if (this.parentNode) {
|
|
924
|
-
var children = this.parentNode.childNodes;
|
|
925
|
-
var i = children.length;
|
|
926
|
-
while (i > 0) {
|
|
927
|
-
var child = children[--i];
|
|
928
|
-
if (this === child)
|
|
929
|
-
return children[i - 1] || null;
|
|
775
|
+
else if (this === child) {
|
|
776
|
+
find = true;
|
|
930
777
|
}
|
|
931
|
-
return null;
|
|
932
778
|
}
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
779
|
+
return null;
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
get previousSibling() {
|
|
783
|
+
if (this.parentNode) {
|
|
784
|
+
const children = this.parentNode.childNodes;
|
|
785
|
+
let i = children.length;
|
|
786
|
+
while (i > 0) {
|
|
787
|
+
const child = children[--i];
|
|
788
|
+
if (this === child)
|
|
789
|
+
return children[i - 1] || null;
|
|
790
|
+
}
|
|
791
|
+
return null;
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
get previousElementSibling() {
|
|
795
|
+
if (this.parentNode) {
|
|
796
|
+
const children = this.parentNode.childNodes;
|
|
797
|
+
let i = children.length;
|
|
798
|
+
let find = false;
|
|
799
|
+
while (i > 0) {
|
|
800
|
+
const child = children[--i];
|
|
801
|
+
if (find) {
|
|
802
|
+
if (child instanceof HTMLElement) {
|
|
803
|
+
return child || null;
|
|
952
804
|
}
|
|
953
805
|
}
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
},
|
|
957
|
-
enumerable: false,
|
|
958
|
-
configurable: true
|
|
959
|
-
});
|
|
960
|
-
Object.defineProperty(HTMLElement.prototype, "children", {
|
|
961
|
-
/** Get all childNodes of type {@link HTMLElement}. */
|
|
962
|
-
get: function () {
|
|
963
|
-
var children = [];
|
|
964
|
-
for (var _i = 0, _a = this.childNodes; _i < _a.length; _i++) {
|
|
965
|
-
var childNode = _a[_i];
|
|
966
|
-
if (childNode instanceof HTMLElement) {
|
|
967
|
-
children.push(childNode);
|
|
806
|
+
else if (this === child) {
|
|
807
|
+
find = true;
|
|
968
808
|
}
|
|
969
809
|
}
|
|
970
|
-
return
|
|
971
|
-
}
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
}
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
configurable: true
|
|
1018
|
-
});
|
|
1019
|
-
Object.defineProperty(HTMLElement.prototype, "childElementCount", {
|
|
1020
|
-
get: function () {
|
|
1021
|
-
return this.children.length;
|
|
1022
|
-
},
|
|
1023
|
-
enumerable: false,
|
|
1024
|
-
configurable: true
|
|
1025
|
-
});
|
|
1026
|
-
Object.defineProperty(HTMLElement.prototype, "classNames", {
|
|
1027
|
-
get: function () {
|
|
1028
|
-
return this.classList.toString();
|
|
1029
|
-
},
|
|
1030
|
-
enumerable: false,
|
|
1031
|
-
configurable: true
|
|
1032
|
-
});
|
|
810
|
+
return null;
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
/** Get all childNodes of type {@link HTMLElement}. */
|
|
814
|
+
get children() {
|
|
815
|
+
const children = [];
|
|
816
|
+
for (const childNode of this.childNodes) {
|
|
817
|
+
if (childNode instanceof HTMLElement) {
|
|
818
|
+
children.push(childNode);
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
return children;
|
|
822
|
+
}
|
|
823
|
+
/**
|
|
824
|
+
* Get the first child node.
|
|
825
|
+
* @return The first child or undefined if none exists.
|
|
826
|
+
*/
|
|
827
|
+
get firstChild() {
|
|
828
|
+
return this.childNodes[0];
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* Get the first child node of type {@link HTMLElement}.
|
|
832
|
+
* @return The first child element or undefined if none exists.
|
|
833
|
+
*/
|
|
834
|
+
get firstElementChild() {
|
|
835
|
+
return this.children[0];
|
|
836
|
+
}
|
|
837
|
+
/**
|
|
838
|
+
* Get the last child node.
|
|
839
|
+
* @return The last child or undefined if none exists.
|
|
840
|
+
*/
|
|
841
|
+
get lastChild() {
|
|
842
|
+
return (0, back_1.default)(this.childNodes);
|
|
843
|
+
}
|
|
844
|
+
/**
|
|
845
|
+
* Get the last child node of type {@link HTMLElement}.
|
|
846
|
+
* @return The last child element or undefined if none exists.
|
|
847
|
+
*/
|
|
848
|
+
get lastElementChild() {
|
|
849
|
+
return this.children[this.children.length - 1];
|
|
850
|
+
}
|
|
851
|
+
get childElementCount() {
|
|
852
|
+
return this.children.length;
|
|
853
|
+
}
|
|
854
|
+
get classNames() {
|
|
855
|
+
return this.classList.toString();
|
|
856
|
+
}
|
|
1033
857
|
/** Clone this Node */
|
|
1034
|
-
|
|
858
|
+
clone() {
|
|
1035
859
|
return parse(this.toString(), this._parseOptions).firstChild;
|
|
1036
|
-
}
|
|
1037
|
-
|
|
1038
|
-
}(node_1.default));
|
|
860
|
+
}
|
|
861
|
+
}
|
|
1039
862
|
exports.default = HTMLElement;
|
|
863
|
+
// #xB7 | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x203F-#x2040] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
|
|
1040
864
|
// https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
865
|
+
const kMarkupPattern = /<!--[\s\S]*?-->|<(\/?)([a-zA-Z][-.:0-9_a-zA-Z@\xB7\xC0-\xD6\xD8-\xF6\u00F8-\u03A1\u03A3-\u03D9\u03DB-\u03EF\u03F7-\u03FF\u0400-\u04FF\u0500-\u052F\u1D00-\u1D2B\u1D6B-\u1D77\u1D79-\u1D9A\u1E00-\u1E9B\u1F00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2126\u212A-\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA78E\uA790-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64-\uAB65\uFB00-\uFB06\uFB13-\uFB17\uFF21-\uFF3A\uFF41-\uFF5A\x37F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]*)((?:\s+[^>]*?(?:(?:'[^']*')|(?:"[^"]*"))?)*)\s*(\/?)>/gu;
|
|
866
|
+
// const kMarkupPattern = /<!--[\s\S]*?-->|<(\/?)([a-zA-Z][-.:0-9_a-zA-Z]*)((?:\s+[^>]*?(?:(?:'[^']*')|(?:"[^"]*"))?)*)\s*(\/?)>/g;
|
|
867
|
+
const kAttributePattern = /(?:^|\s)(id|class)\s*=\s*((?:'[^']*')|(?:"[^"]*")|\S+)/gi;
|
|
868
|
+
const kElementsClosedByOpening = {
|
|
1044
869
|
li: { li: true, LI: true },
|
|
1045
870
|
LI: { li: true, LI: true },
|
|
1046
871
|
p: { p: true, div: true, P: true, DIV: true },
|
|
@@ -1064,7 +889,7 @@ var kElementsClosedByOpening = {
|
|
|
1064
889
|
h6: { h6: true, H6: true },
|
|
1065
890
|
H6: { h6: true, H6: true },
|
|
1066
891
|
};
|
|
1067
|
-
|
|
892
|
+
const kElementsClosedByClosing = {
|
|
1068
893
|
li: { ul: true, ol: true, UL: true, OL: true },
|
|
1069
894
|
LI: { ul: true, ol: true, UL: true, OL: true },
|
|
1070
895
|
a: { div: true, DIV: true },
|
|
@@ -1080,55 +905,54 @@ var kElementsClosedByClosing = {
|
|
|
1080
905
|
th: { tr: true, table: true, TR: true, TABLE: true },
|
|
1081
906
|
TH: { tr: true, table: true, TR: true, TABLE: true },
|
|
1082
907
|
};
|
|
1083
|
-
|
|
908
|
+
const frameflag = 'documentfragmentcontainer';
|
|
1084
909
|
/**
|
|
1085
910
|
* Parses HTML and returns a root element
|
|
1086
911
|
* Parse a chuck of HTML source.
|
|
1087
912
|
* @param {string} data html
|
|
1088
913
|
* @return {HTMLElement} root element
|
|
1089
914
|
*/
|
|
1090
|
-
function base_parse(data, options) {
|
|
915
|
+
function base_parse(data, options = {}) {
|
|
1091
916
|
var _a, _b;
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
var elements = options.blockTextElements || {
|
|
917
|
+
const voidTag = new void_tag_1.default((_a = options === null || options === void 0 ? void 0 : options.voidTag) === null || _a === void 0 ? void 0 : _a.closingSlash, (_b = options === null || options === void 0 ? void 0 : options.voidTag) === null || _b === void 0 ? void 0 : _b.tags);
|
|
918
|
+
const elements = options.blockTextElements || {
|
|
1095
919
|
script: true,
|
|
1096
920
|
noscript: true,
|
|
1097
921
|
style: true,
|
|
1098
922
|
pre: true,
|
|
1099
923
|
};
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
924
|
+
const element_names = Object.keys(elements);
|
|
925
|
+
const kBlockTextElements = element_names.map((it) => new RegExp(`^${it}$`, 'i'));
|
|
926
|
+
const kIgnoreElements = element_names.filter((it) => Boolean(elements[it])).map((it) => new RegExp(`^${it}$`, 'i'));
|
|
1103
927
|
function element_should_be_ignore(tag) {
|
|
1104
|
-
return kIgnoreElements.some(
|
|
928
|
+
return kIgnoreElements.some((it) => it.test(tag));
|
|
1105
929
|
}
|
|
1106
930
|
function is_block_text_element(tag) {
|
|
1107
|
-
return kBlockTextElements.some(
|
|
1108
|
-
}
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
931
|
+
return kBlockTextElements.some((it) => it.test(tag));
|
|
932
|
+
}
|
|
933
|
+
const createRange = (startPos, endPos) => [startPos - frameFlagOffset, endPos - frameFlagOffset];
|
|
934
|
+
const root = new HTMLElement(null, {}, '', null, [0, data.length], voidTag, options);
|
|
935
|
+
let currentParent = root;
|
|
936
|
+
const stack = [root];
|
|
937
|
+
let lastTextPos = -1;
|
|
938
|
+
let noNestedTagIndex = undefined;
|
|
939
|
+
let match;
|
|
1116
940
|
// https://github.com/taoqf/node-html-parser/issues/38
|
|
1117
|
-
data =
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
941
|
+
data = `<${frameflag}>${data}</${frameflag}>`;
|
|
942
|
+
const { lowerCaseTagName, fixNestedATags } = options;
|
|
943
|
+
const dataEndPos = data.length - (frameflag.length + 2);
|
|
944
|
+
const frameFlagOffset = frameflag.length + 2;
|
|
1121
945
|
while ((match = kMarkupPattern.exec(data))) {
|
|
1122
946
|
// Note: Object destructuring here consistently tests as higher performance than array destructuring
|
|
1123
947
|
// eslint-disable-next-line prefer-const
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
948
|
+
let { 0: matchText, 1: leadingSlash, 2: tagName, 3: attributes, 4: closingSlash } = match;
|
|
949
|
+
const matchLength = matchText.length;
|
|
950
|
+
const tagStartPos = kMarkupPattern.lastIndex - matchLength;
|
|
951
|
+
const tagEndPos = kMarkupPattern.lastIndex;
|
|
1128
952
|
// Add TextNode if content
|
|
1129
953
|
if (lastTextPos > -1) {
|
|
1130
954
|
if (lastTextPos + matchLength < tagEndPos) {
|
|
1131
|
-
|
|
955
|
+
const text = data.substring(lastTextPos, tagStartPos);
|
|
1132
956
|
currentParent.appendChild(new text_1.default(text, currentParent, createRange(lastTextPos, tagStartPos)));
|
|
1133
957
|
}
|
|
1134
958
|
}
|
|
@@ -1141,7 +965,7 @@ function base_parse(data, options) {
|
|
|
1141
965
|
if (matchText[1] === '!') {
|
|
1142
966
|
if (options.comment) {
|
|
1143
967
|
// Only keep what is in between <!-- and -->
|
|
1144
|
-
|
|
968
|
+
const text = data.substring(tagStartPos + 4, tagEndPos - 3);
|
|
1145
969
|
currentParent.appendChild(new comment_1.default(text, currentParent, createRange(tagStartPos, tagEndPos)));
|
|
1146
970
|
}
|
|
1147
971
|
continue;
|
|
@@ -1153,13 +977,13 @@ function base_parse(data, options) {
|
|
|
1153
977
|
// Handle opening tags (ie. <this> not </that>)
|
|
1154
978
|
if (!leadingSlash) {
|
|
1155
979
|
/* Populate attributes */
|
|
1156
|
-
|
|
1157
|
-
for (
|
|
1158
|
-
|
|
1159
|
-
|
|
980
|
+
const attrs = {};
|
|
981
|
+
for (let attMatch; (attMatch = kAttributePattern.exec(attributes));) {
|
|
982
|
+
const { 1: key, 2: val } = attMatch;
|
|
983
|
+
const isQuoted = val[0] === `'` || val[0] === `"`;
|
|
1160
984
|
attrs[key.toLowerCase()] = isQuoted ? val.slice(1, val.length - 1) : val;
|
|
1161
985
|
}
|
|
1162
|
-
|
|
986
|
+
const parentTagName = currentParent.rawTagName;
|
|
1163
987
|
if (!closingSlash && kElementsClosedByOpening[parentTagName]) {
|
|
1164
988
|
if (kElementsClosedByOpening[parentTagName][tagName]) {
|
|
1165
989
|
stack.pop();
|
|
@@ -1174,23 +998,23 @@ function base_parse(data, options) {
|
|
|
1174
998
|
}
|
|
1175
999
|
noNestedTagIndex = stack.length;
|
|
1176
1000
|
}
|
|
1177
|
-
|
|
1178
|
-
|
|
1001
|
+
const tagEndPos = kMarkupPattern.lastIndex;
|
|
1002
|
+
const tagStartPos = tagEndPos - matchLength;
|
|
1179
1003
|
currentParent = currentParent.appendChild(
|
|
1180
1004
|
// Initialize range (end position updated later for closed tags)
|
|
1181
|
-
new HTMLElement(tagName, attrs, attributes.slice(1), null, createRange(
|
|
1005
|
+
new HTMLElement(tagName, attrs, attributes.slice(1), null, createRange(tagStartPos, tagEndPos), voidTag, options));
|
|
1182
1006
|
stack.push(currentParent);
|
|
1183
1007
|
if (is_block_text_element(tagName)) {
|
|
1184
1008
|
// Find closing tag
|
|
1185
|
-
|
|
1186
|
-
|
|
1009
|
+
const closeMarkup = `</${tagName}>`;
|
|
1010
|
+
const closeIndex = lowerCaseTagName
|
|
1187
1011
|
? data.toLocaleLowerCase().indexOf(closeMarkup, kMarkupPattern.lastIndex)
|
|
1188
1012
|
: data.indexOf(closeMarkup, kMarkupPattern.lastIndex);
|
|
1189
|
-
|
|
1013
|
+
const textEndPos = closeIndex === -1 ? dataEndPos : closeIndex;
|
|
1190
1014
|
if (element_should_be_ignore(tagName)) {
|
|
1191
|
-
|
|
1015
|
+
const text = data.substring(tagEndPos, textEndPos);
|
|
1192
1016
|
if (text.length > 0 && /\S/.test(text)) {
|
|
1193
|
-
currentParent.appendChild(new text_1.default(text, currentParent, createRange(
|
|
1017
|
+
currentParent.appendChild(new text_1.default(text, currentParent, createRange(tagEndPos, textEndPos)));
|
|
1194
1018
|
}
|
|
1195
1019
|
}
|
|
1196
1020
|
if (closeIndex === -1) {
|
|
@@ -1216,7 +1040,7 @@ function base_parse(data, options) {
|
|
|
1216
1040
|
break;
|
|
1217
1041
|
}
|
|
1218
1042
|
else {
|
|
1219
|
-
|
|
1043
|
+
const parentTagName = currentParent.tagName;
|
|
1220
1044
|
// Trying to close current tag, and move on
|
|
1221
1045
|
if (kElementsClosedByClosing[parentTagName]) {
|
|
1222
1046
|
if (kElementsClosedByClosing[parentTagName][tagName]) {
|
|
@@ -1238,22 +1062,22 @@ exports.base_parse = base_parse;
|
|
|
1238
1062
|
* Parses HTML and returns a root element
|
|
1239
1063
|
* Parse a chuck of HTML source.
|
|
1240
1064
|
*/
|
|
1241
|
-
function parse(data, options) {
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
var stack = base_parse(data, options);
|
|
1245
|
-
var root = stack[0];
|
|
1065
|
+
function parse(data, options = {}) {
|
|
1066
|
+
const stack = base_parse(data, options);
|
|
1067
|
+
const [root] = stack;
|
|
1246
1068
|
while (stack.length > 1) {
|
|
1247
1069
|
// Handle each error elements.
|
|
1248
|
-
|
|
1249
|
-
|
|
1070
|
+
const last = stack.pop();
|
|
1071
|
+
const oneBefore = (0, back_1.default)(stack);
|
|
1250
1072
|
if (last.parentNode && last.parentNode.parentNode) {
|
|
1251
1073
|
if (last.parentNode === oneBefore && last.tagName === oneBefore.tagName) {
|
|
1252
1074
|
// Pair error case <h3> <h3> handle : Fixes to <h3> </h3>
|
|
1253
1075
|
// this is wrong, becouse this will put the H3 outside the current right position which should be inside the current Html Element, see issue 152 for more info
|
|
1254
1076
|
if (options.parseNoneClosedTags !== true) {
|
|
1255
1077
|
oneBefore.removeChild(last);
|
|
1256
|
-
|
|
1078
|
+
last.childNodes.forEach((child) => {
|
|
1079
|
+
oneBefore.parentNode.appendChild(child);
|
|
1080
|
+
});
|
|
1257
1081
|
stack.pop();
|
|
1258
1082
|
}
|
|
1259
1083
|
}
|
|
@@ -1263,7 +1087,9 @@ function parse(data, options) {
|
|
|
1263
1087
|
// eslint-disable-next-line no-lonely-if
|
|
1264
1088
|
if (options.parseNoneClosedTags !== true) {
|
|
1265
1089
|
oneBefore.removeChild(last);
|
|
1266
|
-
|
|
1090
|
+
last.childNodes.forEach((child) => {
|
|
1091
|
+
oneBefore.appendChild(child);
|
|
1092
|
+
});
|
|
1267
1093
|
}
|
|
1268
1094
|
}
|
|
1269
1095
|
}
|
|
@@ -1276,7 +1102,6 @@ function parse(data, options) {
|
|
|
1276
1102
|
// node.parentNode = null;
|
|
1277
1103
|
// }
|
|
1278
1104
|
// });
|
|
1279
|
-
resetParent(root.childNodes, root, true);
|
|
1280
1105
|
return root;
|
|
1281
1106
|
}
|
|
1282
1107
|
exports.parse = parse;
|
|
@@ -1285,7 +1110,7 @@ exports.parse = parse;
|
|
|
1285
1110
|
* and removes nodes from any potential parent.
|
|
1286
1111
|
*/
|
|
1287
1112
|
function resolveInsertable(insertable) {
|
|
1288
|
-
return insertable.map(
|
|
1113
|
+
return insertable.map((val) => {
|
|
1289
1114
|
if (typeof val === 'string') {
|
|
1290
1115
|
return new text_1.default(val);
|
|
1291
1116
|
}
|
|
@@ -1293,12 +1118,9 @@ function resolveInsertable(insertable) {
|
|
|
1293
1118
|
return val;
|
|
1294
1119
|
});
|
|
1295
1120
|
}
|
|
1296
|
-
function resetParent(nodes, parent
|
|
1297
|
-
|
|
1298
|
-
nodes.forEach(function (node) {
|
|
1121
|
+
function resetParent(nodes, parent) {
|
|
1122
|
+
return nodes.map((node) => {
|
|
1299
1123
|
node.parentNode = parent;
|
|
1300
|
-
|
|
1301
|
-
resetParent(node.childNodes, node, true);
|
|
1302
|
-
}
|
|
1124
|
+
return node;
|
|
1303
1125
|
});
|
|
1304
1126
|
}
|