happy-dom 17.1.2 → 17.1.4
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/cjs/PropertySymbol.cjs +4 -4
- package/cjs/PropertySymbol.cjs.map +1 -1
- package/cjs/PropertySymbol.d.ts +2 -2
- package/cjs/PropertySymbol.d.ts.map +1 -1
- package/cjs/dom/DOMStringMap.cjs +1 -1
- package/cjs/dom/DOMStringMap.cjs.map +1 -1
- package/cjs/exception/DOMExceptionNameEnum.cjs +1 -0
- package/cjs/exception/DOMExceptionNameEnum.cjs.map +1 -1
- package/cjs/exception/DOMExceptionNameEnum.d.ts +2 -1
- package/cjs/exception/DOMExceptionNameEnum.d.ts.map +1 -1
- package/cjs/html-serializer/HTMLSerializer.cjs +5 -5
- package/cjs/html-serializer/HTMLSerializer.cjs.map +1 -1
- package/cjs/nodes/document/Document.cjs +12 -1
- package/cjs/nodes/document/Document.cjs.map +1 -1
- package/cjs/nodes/document/Document.d.ts.map +1 -1
- package/cjs/nodes/element/Element.cjs +9 -5
- package/cjs/nodes/element/Element.cjs.map +1 -1
- package/cjs/nodes/element/Element.d.ts.map +1 -1
- package/cjs/nodes/element/NamedNodeMap.cjs +34 -26
- package/cjs/nodes/element/NamedNodeMap.cjs.map +1 -1
- package/cjs/nodes/element/NamedNodeMap.d.ts +3 -2
- package/cjs/nodes/element/NamedNodeMap.d.ts.map +1 -1
- package/cjs/nodes/element/NamedNodeMapProxyFactory.cjs +22 -16
- package/cjs/nodes/element/NamedNodeMapProxyFactory.cjs.map +1 -1
- package/cjs/nodes/element/NamedNodeMapProxyFactory.d.ts.map +1 -1
- package/cjs/nodes/html-element/HTMLElement.cjs +10 -7
- package/cjs/nodes/html-element/HTMLElement.cjs.map +1 -1
- package/cjs/nodes/html-element/HTMLElement.d.ts.map +1 -1
- package/cjs/nodes/node/Node.cjs +3 -3
- package/cjs/nodes/node/Node.cjs.map +1 -1
- package/cjs/nodes/node/NodeUtility.cjs +7 -8
- package/cjs/nodes/node/NodeUtility.cjs.map +1 -1
- package/cjs/nodes/node/NodeUtility.d.ts.map +1 -1
- package/cjs/tree-walker/TreeWalker.cjs +160 -70
- package/cjs/tree-walker/TreeWalker.cjs.map +1 -1
- package/cjs/tree-walker/TreeWalker.d.ts +18 -14
- package/cjs/tree-walker/TreeWalker.d.ts.map +1 -1
- package/cjs/xml-parser/XMLParser.cjs +2 -2
- package/cjs/xml-parser/XMLParser.cjs.map +1 -1
- package/cjs/xml-serializer/XMLSerializer.cjs +5 -8
- package/cjs/xml-serializer/XMLSerializer.cjs.map +1 -1
- package/cjs/xml-serializer/XMLSerializer.d.ts.map +1 -1
- package/lib/PropertySymbol.d.ts +2 -2
- package/lib/PropertySymbol.d.ts.map +1 -1
- package/lib/PropertySymbol.js +2 -2
- package/lib/PropertySymbol.js.map +1 -1
- package/lib/dom/DOMStringMap.js +1 -1
- package/lib/dom/DOMStringMap.js.map +1 -1
- package/lib/exception/DOMExceptionNameEnum.d.ts +2 -1
- package/lib/exception/DOMExceptionNameEnum.d.ts.map +1 -1
- package/lib/exception/DOMExceptionNameEnum.js +1 -0
- package/lib/exception/DOMExceptionNameEnum.js.map +1 -1
- package/lib/html-serializer/HTMLSerializer.js +5 -5
- package/lib/html-serializer/HTMLSerializer.js.map +1 -1
- package/lib/nodes/document/Document.d.ts.map +1 -1
- package/lib/nodes/document/Document.js +12 -1
- package/lib/nodes/document/Document.js.map +1 -1
- package/lib/nodes/element/Element.d.ts.map +1 -1
- package/lib/nodes/element/Element.js +9 -5
- package/lib/nodes/element/Element.js.map +1 -1
- package/lib/nodes/element/NamedNodeMap.d.ts +3 -2
- package/lib/nodes/element/NamedNodeMap.d.ts.map +1 -1
- package/lib/nodes/element/NamedNodeMap.js +34 -26
- package/lib/nodes/element/NamedNodeMap.js.map +1 -1
- package/lib/nodes/element/NamedNodeMapProxyFactory.d.ts.map +1 -1
- package/lib/nodes/element/NamedNodeMapProxyFactory.js +22 -16
- package/lib/nodes/element/NamedNodeMapProxyFactory.js.map +1 -1
- package/lib/nodes/html-element/HTMLElement.d.ts.map +1 -1
- package/lib/nodes/html-element/HTMLElement.js +10 -7
- package/lib/nodes/html-element/HTMLElement.js.map +1 -1
- package/lib/nodes/node/Node.js +3 -3
- package/lib/nodes/node/Node.js.map +1 -1
- package/lib/nodes/node/NodeUtility.d.ts.map +1 -1
- package/lib/nodes/node/NodeUtility.js +7 -8
- package/lib/nodes/node/NodeUtility.js.map +1 -1
- package/lib/tree-walker/TreeWalker.d.ts +18 -14
- package/lib/tree-walker/TreeWalker.d.ts.map +1 -1
- package/lib/tree-walker/TreeWalker.js +160 -70
- package/lib/tree-walker/TreeWalker.js.map +1 -1
- package/lib/xml-parser/XMLParser.js +2 -2
- package/lib/xml-parser/XMLParser.js.map +1 -1
- package/lib/xml-serializer/XMLSerializer.d.ts.map +1 -1
- package/lib/xml-serializer/XMLSerializer.js +5 -8
- package/lib/xml-serializer/XMLSerializer.js.map +1 -1
- package/package.json +1 -1
- package/src/PropertySymbol.ts +2 -2
- package/src/dom/DOMStringMap.ts +1 -1
- package/src/exception/DOMExceptionNameEnum.ts +2 -1
- package/src/html-serializer/HTMLSerializer.ts +5 -5
- package/src/nodes/document/Document.ts +22 -1
- package/src/nodes/element/Element.ts +20 -5
- package/src/nodes/element/NamedNodeMap.ts +42 -27
- package/src/nodes/element/NamedNodeMapProxyFactory.ts +22 -17
- package/src/nodes/html-element/HTMLElement.ts +11 -10
- package/src/nodes/node/Node.ts +5 -5
- package/src/nodes/node/NodeUtility.ts +7 -8
- package/src/tree-walker/TreeWalker.ts +195 -98
- package/src/xml-parser/XMLParser.ts +2 -2
- package/src/xml-serializer/XMLSerializer.ts +9 -12
@@ -5,8 +5,21 @@ import NodeFilterMask from './NodeFilterMask.js';
|
|
5
5
|
import DOMException from '../exception/DOMException.js';
|
6
6
|
import NodeFilter from './NodeFilter.js';
|
7
7
|
|
8
|
+
enum TraverseChildrenTypeEnum {
|
9
|
+
first = 'first',
|
10
|
+
last = 'last'
|
11
|
+
}
|
12
|
+
|
13
|
+
enum TraverseSiblingsTypeEnum {
|
14
|
+
next = 'next',
|
15
|
+
previous = 'previous'
|
16
|
+
}
|
17
|
+
|
8
18
|
/**
|
9
19
|
* The TreeWalker object represents the nodes of a document subtree and a position within them.
|
20
|
+
*
|
21
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker
|
22
|
+
* @see https://dom.spec.whatwg.org/#interface-treewalker
|
10
23
|
*/
|
11
24
|
export default class TreeWalker {
|
12
25
|
public root: Node = null;
|
@@ -32,52 +45,20 @@ export default class TreeWalker {
|
|
32
45
|
this.currentNode = root;
|
33
46
|
}
|
34
47
|
|
35
|
-
/**
|
36
|
-
* Moves the current Node to the next visible node in the document order.
|
37
|
-
*
|
38
|
-
* @returns Current node.
|
39
|
-
*/
|
40
|
-
public nextNode(): Node {
|
41
|
-
if (!this.firstChild()) {
|
42
|
-
while (!this.nextSibling() && this.parentNode()) {}
|
43
|
-
this.currentNode = this.currentNode === this.root ? null : this.currentNode || null;
|
44
|
-
}
|
45
|
-
return this.currentNode;
|
46
|
-
}
|
47
|
-
|
48
|
-
/**
|
49
|
-
* Moves the current Node to the previous visible node in the document order, and returns the found node. It also moves the current node to this one. If no such node exists, or if it is before that the root node defined at the object construction, returns null and the current node is not changed.
|
50
|
-
*
|
51
|
-
* @returns Current node.
|
52
|
-
*/
|
53
|
-
public previousNode(): Node {
|
54
|
-
while (!this.previousSibling() && this.parentNode()) {}
|
55
|
-
this.currentNode = this.currentNode === this.root ? null : this.currentNode || null;
|
56
|
-
return this.currentNode;
|
57
|
-
}
|
58
|
-
|
59
48
|
/**
|
60
49
|
* Moves the current Node to the first visible ancestor node in the document order, and returns the found node. It also moves the current node to this one. If no such node exists, or if it is before that the root node defined at the object construction, returns null and the current node is not changed.
|
61
50
|
*
|
62
51
|
* @returns Current node.
|
63
52
|
*/
|
64
53
|
public parentNode(): Node {
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
this
|
69
|
-
|
70
|
-
this.currentNode = this.currentNode[PropertySymbol.parentNode];
|
71
|
-
|
72
|
-
if (this[PropertySymbol.filterNode](this.currentNode) === NodeFilter.FILTER_ACCEPT) {
|
54
|
+
let node = this.currentNode;
|
55
|
+
while (node !== null && node !== this.root) {
|
56
|
+
node = node.parentNode;
|
57
|
+
if (node !== null && this[PropertySymbol.filterNode](node) === NodeFilter.FILTER_ACCEPT) {
|
58
|
+
this.currentNode = node;
|
73
59
|
return this.currentNode;
|
74
60
|
}
|
75
|
-
|
76
|
-
this.parentNode();
|
77
61
|
}
|
78
|
-
|
79
|
-
this.currentNode = null;
|
80
|
-
|
81
62
|
return null;
|
82
63
|
}
|
83
64
|
|
@@ -87,19 +68,7 @@ export default class TreeWalker {
|
|
87
68
|
* @returns Current node.
|
88
69
|
*/
|
89
70
|
public firstChild(): Node {
|
90
|
-
|
91
|
-
|
92
|
-
if (childNodes.length > 0) {
|
93
|
-
this.currentNode = childNodes[0];
|
94
|
-
|
95
|
-
if (this[PropertySymbol.filterNode](this.currentNode) === NodeFilter.FILTER_ACCEPT) {
|
96
|
-
return this.currentNode;
|
97
|
-
}
|
98
|
-
|
99
|
-
return this.nextSibling();
|
100
|
-
}
|
101
|
-
|
102
|
-
return null;
|
71
|
+
return this.#traverseChildren(TraverseChildrenTypeEnum.first);
|
103
72
|
}
|
104
73
|
|
105
74
|
/**
|
@@ -108,19 +77,16 @@ export default class TreeWalker {
|
|
108
77
|
* @returns Current node.
|
109
78
|
*/
|
110
79
|
public lastChild(): Node {
|
111
|
-
|
112
|
-
|
113
|
-
if (childNodes.length > 0) {
|
114
|
-
this.currentNode = childNodes[childNodes.length - 1];
|
115
|
-
|
116
|
-
if (this[PropertySymbol.filterNode](this.currentNode) === NodeFilter.FILTER_ACCEPT) {
|
117
|
-
return this.currentNode;
|
118
|
-
}
|
119
|
-
|
120
|
-
return this.previousSibling();
|
121
|
-
}
|
80
|
+
return this.#traverseChildren(TraverseChildrenTypeEnum.last);
|
81
|
+
}
|
122
82
|
|
123
|
-
|
83
|
+
/**
|
84
|
+
* Moves the current Node to its next sibling, if any, and returns the found sibling. If there is no such node, null is returned and the current node is not changed.
|
85
|
+
*
|
86
|
+
* @returns Current node.
|
87
|
+
*/
|
88
|
+
public nextSibling(): Node {
|
89
|
+
return this.#traverseSiblings(TraverseSiblingsTypeEnum.next);
|
124
90
|
}
|
125
91
|
|
126
92
|
/**
|
@@ -129,24 +95,46 @@ export default class TreeWalker {
|
|
129
95
|
* @returns Current node.
|
130
96
|
*/
|
131
97
|
public previousSibling(): Node {
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
98
|
+
return this.#traverseSiblings(TraverseSiblingsTypeEnum.previous);
|
99
|
+
}
|
100
|
+
|
101
|
+
/**
|
102
|
+
* Moves the current Node to the previous visible node in the document order, and returns the found node. It also moves the current node to this one. If no such node exists, or if it is before that the root node defined at the object construction, returns null and the current node is not changed.
|
103
|
+
*
|
104
|
+
* @returns Current node.
|
105
|
+
*/
|
106
|
+
public previousNode(): Node {
|
107
|
+
let node = this.currentNode;
|
108
|
+
|
109
|
+
while (node !== this.root) {
|
110
|
+
let sibling = node.previousSibling;
|
111
|
+
|
112
|
+
while (sibling !== null) {
|
113
|
+
let node = sibling;
|
114
|
+
let result = this[PropertySymbol.filterNode](node);
|
115
|
+
|
116
|
+
while (result !== NodeFilter.FILTER_REJECT && node[PropertySymbol.nodeArray].length) {
|
117
|
+
node = node.lastChild;
|
118
|
+
result = this[PropertySymbol.filterNode](node);
|
147
119
|
}
|
148
120
|
|
149
|
-
|
121
|
+
if (result === NodeFilter.FILTER_ACCEPT) {
|
122
|
+
this.currentNode = node;
|
123
|
+
return node;
|
124
|
+
}
|
125
|
+
|
126
|
+
sibling = node.previousSibling;
|
127
|
+
}
|
128
|
+
|
129
|
+
if (node === this.root || node.parentNode === null) {
|
130
|
+
return null;
|
131
|
+
}
|
132
|
+
|
133
|
+
node = node.parentNode;
|
134
|
+
|
135
|
+
if (this[PropertySymbol.filterNode](node) === NodeFilter.FILTER_ACCEPT) {
|
136
|
+
this.currentNode = node;
|
137
|
+
return node;
|
150
138
|
}
|
151
139
|
}
|
152
140
|
|
@@ -154,33 +142,51 @@ export default class TreeWalker {
|
|
154
142
|
}
|
155
143
|
|
156
144
|
/**
|
157
|
-
* Moves the current Node to
|
145
|
+
* Moves the current Node to the next visible node in the document order.
|
158
146
|
*
|
159
147
|
* @returns Current node.
|
160
148
|
*/
|
161
|
-
public
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
PropertySymbol.
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
this.currentNode = siblings[index + 1];
|
174
|
-
|
175
|
-
if (this[PropertySymbol.filterNode](this.currentNode) === NodeFilter.FILTER_ACCEPT) {
|
176
|
-
return this.currentNode;
|
149
|
+
public nextNode(): Node | null {
|
150
|
+
let node = this.currentNode;
|
151
|
+
let result = NodeFilter.FILTER_ACCEPT;
|
152
|
+
|
153
|
+
while (true) {
|
154
|
+
while (result !== NodeFilter.FILTER_REJECT && node[PropertySymbol.nodeArray].length) {
|
155
|
+
node = node.firstChild;
|
156
|
+
result = this[PropertySymbol.filterNode](node);
|
157
|
+
|
158
|
+
if (result === NodeFilter.FILTER_ACCEPT) {
|
159
|
+
this.currentNode = node;
|
160
|
+
return node;
|
177
161
|
}
|
162
|
+
}
|
178
163
|
|
179
|
-
|
164
|
+
while (node !== null) {
|
165
|
+
if (node === this.root) {
|
166
|
+
return null;
|
167
|
+
}
|
168
|
+
|
169
|
+
const sibling = node.nextSibling;
|
170
|
+
|
171
|
+
if (sibling !== null) {
|
172
|
+
node = sibling;
|
173
|
+
break;
|
174
|
+
}
|
175
|
+
|
176
|
+
node = node.parentNode;
|
180
177
|
}
|
181
|
-
}
|
182
178
|
|
183
|
-
|
179
|
+
if (node === null) {
|
180
|
+
return null;
|
181
|
+
}
|
182
|
+
|
183
|
+
result = this[PropertySymbol.filterNode](node);
|
184
|
+
|
185
|
+
if (result === NodeFilter.FILTER_ACCEPT) {
|
186
|
+
this.currentNode = node;
|
187
|
+
return node;
|
188
|
+
}
|
189
|
+
}
|
184
190
|
}
|
185
191
|
|
186
192
|
/**
|
@@ -207,4 +213,95 @@ export default class TreeWalker {
|
|
207
213
|
|
208
214
|
return NodeFilter.FILTER_ACCEPT;
|
209
215
|
}
|
216
|
+
|
217
|
+
/**
|
218
|
+
* Traverses children.
|
219
|
+
*
|
220
|
+
* @param type Type.
|
221
|
+
* @returns Node.
|
222
|
+
*/
|
223
|
+
#traverseChildren(type: TraverseChildrenTypeEnum): Node | null {
|
224
|
+
let node: Node = this.currentNode;
|
225
|
+
node = type === TraverseChildrenTypeEnum.first ? node.firstChild : node.lastChild;
|
226
|
+
|
227
|
+
while (node !== null) {
|
228
|
+
const result = this[PropertySymbol.filterNode](node);
|
229
|
+
|
230
|
+
if (result === NodeFilter.FILTER_ACCEPT) {
|
231
|
+
this.currentNode = node;
|
232
|
+
return node;
|
233
|
+
}
|
234
|
+
|
235
|
+
if (result === NodeFilter.FILTER_SKIP) {
|
236
|
+
const child = type === TraverseChildrenTypeEnum.first ? node.firstChild : node.lastChild;
|
237
|
+
|
238
|
+
if (child !== null) {
|
239
|
+
node = child;
|
240
|
+
continue;
|
241
|
+
}
|
242
|
+
}
|
243
|
+
|
244
|
+
while (node !== null) {
|
245
|
+
const sibling =
|
246
|
+
type === TraverseChildrenTypeEnum.first ? node.nextSibling : node.previousSibling;
|
247
|
+
if (sibling !== null) {
|
248
|
+
node = sibling;
|
249
|
+
break;
|
250
|
+
}
|
251
|
+
const parent = node.parentNode;
|
252
|
+
if (parent === null || parent === this.root || parent === this.currentNode) {
|
253
|
+
return null;
|
254
|
+
}
|
255
|
+
node = parent;
|
256
|
+
}
|
257
|
+
}
|
258
|
+
|
259
|
+
return null;
|
260
|
+
}
|
261
|
+
|
262
|
+
/**
|
263
|
+
* Traverses siblings.
|
264
|
+
*
|
265
|
+
* @param type Type.
|
266
|
+
* @returns Node.
|
267
|
+
*/
|
268
|
+
#traverseSiblings(type: TraverseSiblingsTypeEnum): Node | null {
|
269
|
+
let node: Node = this.currentNode;
|
270
|
+
|
271
|
+
if (node === this.root) {
|
272
|
+
return null;
|
273
|
+
}
|
274
|
+
|
275
|
+
while (true) {
|
276
|
+
let sibling =
|
277
|
+
type === TraverseSiblingsTypeEnum.next ? node.nextSibling : node.previousSibling;
|
278
|
+
|
279
|
+
while (sibling !== null) {
|
280
|
+
const node = sibling;
|
281
|
+
const result = this[PropertySymbol.filterNode](node);
|
282
|
+
|
283
|
+
if (result === NodeFilter.FILTER_ACCEPT) {
|
284
|
+
this.currentNode = node;
|
285
|
+
return node;
|
286
|
+
}
|
287
|
+
|
288
|
+
sibling = type === TraverseSiblingsTypeEnum.next ? node.firstChild : node.lastChild;
|
289
|
+
|
290
|
+
if (result === NodeFilter.FILTER_REJECT || sibling === null) {
|
291
|
+
sibling =
|
292
|
+
type === TraverseSiblingsTypeEnum.next ? node.nextSibling : node.previousSibling;
|
293
|
+
}
|
294
|
+
}
|
295
|
+
|
296
|
+
node = node.parentNode;
|
297
|
+
|
298
|
+
if (node === null || node === this.root) {
|
299
|
+
return null;
|
300
|
+
}
|
301
|
+
|
302
|
+
if (this[PropertySymbol.filterNode](node) === NodeFilter.FILTER_ACCEPT) {
|
303
|
+
return null;
|
304
|
+
}
|
305
|
+
}
|
306
|
+
}
|
210
307
|
}
|
@@ -533,8 +533,8 @@ export default class XMLParser {
|
|
533
533
|
);
|
534
534
|
this.nextElement[PropertySymbol.attributes] = attributes;
|
535
535
|
attributes[PropertySymbol.ownerElement] = this.nextElement;
|
536
|
-
for (const
|
537
|
-
|
536
|
+
for (const item of attributes[PropertySymbol.items].values()) {
|
537
|
+
item[PropertySymbol.ownerElement] = this.nextElement;
|
538
538
|
}
|
539
539
|
} else {
|
540
540
|
this.nextElement[PropertySymbol.namespaceURI] = value;
|
@@ -140,17 +140,15 @@ export default class XMLSerializer {
|
|
140
140
|
inheritedNamespacePrefixes: Map<string, string> | null
|
141
141
|
): Map<string, string> | null {
|
142
142
|
const namespacePrefixes = new Map<string, string>(inheritedNamespacePrefixes);
|
143
|
-
const namedItems = (<Element>element)[PropertySymbol.attributes][PropertySymbol.namedItems];
|
144
143
|
|
145
|
-
for (const
|
144
|
+
for (const attribute of (<Element>element)[PropertySymbol.attributes][
|
145
|
+
PropertySymbol.items
|
146
|
+
].values()) {
|
146
147
|
if (
|
147
|
-
|
148
|
-
|
148
|
+
attribute[PropertySymbol.namespaceURI] === NamespaceURI.xmlns &&
|
149
|
+
attribute[PropertySymbol.prefix]
|
149
150
|
) {
|
150
|
-
namespacePrefixes.set(
|
151
|
-
attributes[0][PropertySymbol.value],
|
152
|
-
attributes[0][PropertySymbol.localName]
|
153
|
-
);
|
151
|
+
namespacePrefixes.set(attribute[PropertySymbol.value], attribute[PropertySymbol.localName]);
|
154
152
|
}
|
155
153
|
}
|
156
154
|
|
@@ -216,12 +214,11 @@ export default class XMLSerializer {
|
|
216
214
|
let attributeString = '';
|
217
215
|
let namespaceString = '';
|
218
216
|
|
219
|
-
const namedItems = (<Element>element)[PropertySymbol.attributes][PropertySymbol.namedItems];
|
220
217
|
const handledNamespaces = new Set();
|
221
218
|
|
222
|
-
for (const
|
223
|
-
|
224
|
-
|
219
|
+
for (const attribute of (<Element>element)[PropertySymbol.attributes][
|
220
|
+
PropertySymbol.items
|
221
|
+
].values()) {
|
225
222
|
// Namespace attributes should be in the beginning of the string.
|
226
223
|
if (attribute[PropertySymbol.namespaceURI] === NamespaceURI.xmlns) {
|
227
224
|
if (
|