happy-dom 7.4.0 → 7.5.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.
Potentially problematic release.
This version of happy-dom might be problematic. Click here for more details.
- package/lib/css/declaration/AbstractCSSStyleDeclaration.js +9 -0
- package/lib/css/declaration/AbstractCSSStyleDeclaration.js.map +1 -1
- package/lib/css/declaration/utilities/CSSStyleDeclarationElementStyle.d.ts +0 -2
- package/lib/css/declaration/utilities/CSSStyleDeclarationElementStyle.js +54 -25
- package/lib/css/declaration/utilities/CSSStyleDeclarationElementStyle.js.map +1 -1
- package/lib/nodes/character-data/CharacterData.js +3 -0
- package/lib/nodes/character-data/CharacterData.js.map +1 -1
- package/lib/nodes/document/Document.d.ts +1 -0
- package/lib/nodes/document/Document.js +2 -0
- package/lib/nodes/document/Document.js.map +1 -1
- package/lib/nodes/element/Element.js +7 -7
- package/lib/nodes/element/Element.js.map +1 -1
- package/lib/nodes/node/Node.d.ts +6 -0
- package/lib/nodes/node/Node.js +17 -0
- package/lib/nodes/node/Node.js.map +1 -1
- package/lib/nodes/node/NodeList.d.ts +6 -0
- package/lib/nodes/node/NodeList.js +8 -0
- package/lib/nodes/node/NodeList.js.map +1 -1
- package/lib/query-selector/QuerySelector.d.ts +21 -0
- package/lib/query-selector/QuerySelector.js +45 -4
- package/lib/query-selector/QuerySelector.js.map +1 -1
- package/lib/query-selector/SelectorItem.d.ts +14 -11
- package/lib/query-selector/SelectorItem.js +35 -19
- package/lib/query-selector/SelectorItem.js.map +1 -1
- package/package.json +2 -2
- package/src/css/declaration/AbstractCSSStyleDeclaration.ts +12 -0
- package/src/css/declaration/utilities/CSSStyleDeclarationElementStyle.ts +86 -36
- package/src/nodes/character-data/CharacterData.ts +4 -0
- package/src/nodes/document/Document.ts +4 -0
- package/src/nodes/element/Element.ts +9 -7
- package/src/nodes/node/Node.ts +21 -0
- package/src/nodes/node/NodeList.ts +9 -0
- package/src/query-selector/QuerySelector.ts +66 -5
- package/src/query-selector/SelectorItem.ts +66 -37
@@ -12,14 +12,29 @@ import CSSStyleRule from '../../rules/CSSStyleRule';
|
|
12
12
|
import CSSStyleDeclarationElementDefaultCSS from './CSSStyleDeclarationElementDefaultCSS';
|
13
13
|
import CSSStyleDeclarationElementInheritedProperties from './CSSStyleDeclarationElementInheritedProperties';
|
14
14
|
import CSSStyleDeclarationCSSParser from './CSSStyleDeclarationCSSParser';
|
15
|
+
import QuerySelector from '../../../query-selector/QuerySelector';
|
15
16
|
|
16
17
|
const CSS_VARIABLE_REGEXP = /var\( *(--[^) ]+)\)/g;
|
17
18
|
|
19
|
+
type IStyleAndElement = {
|
20
|
+
element: IElement | IShadowRoot | IDocument;
|
21
|
+
cssTexts: Array<{ cssText: string; priorityWeight: number }>;
|
22
|
+
};
|
23
|
+
|
18
24
|
/**
|
19
25
|
* CSS Style Declaration utility
|
20
26
|
*/
|
21
27
|
export default class CSSStyleDeclarationElementStyle {
|
22
|
-
private cache: {
|
28
|
+
private cache: {
|
29
|
+
propertyManager: CSSStyleDeclarationPropertyManager;
|
30
|
+
cssText: string;
|
31
|
+
documentCacheID: number;
|
32
|
+
} = {
|
33
|
+
propertyManager: null,
|
34
|
+
cssText: null,
|
35
|
+
documentCacheID: null
|
36
|
+
};
|
37
|
+
|
23
38
|
private element: IElement;
|
24
39
|
private computed: boolean;
|
25
40
|
|
@@ -47,11 +62,12 @@ export default class CSSStyleDeclarationElementStyle {
|
|
47
62
|
const cssText = this.element['_attributes']['style']?.value;
|
48
63
|
|
49
64
|
if (cssText) {
|
50
|
-
if (this.cache
|
51
|
-
return this.cache
|
65
|
+
if (this.cache.propertyManager && this.cache.cssText === cssText) {
|
66
|
+
return this.cache.propertyManager;
|
52
67
|
}
|
53
|
-
this.cache
|
54
|
-
|
68
|
+
this.cache.cssText = cssText;
|
69
|
+
this.cache.propertyManager = new CSSStyleDeclarationPropertyManager({ cssText });
|
70
|
+
return this.cache.propertyManager;
|
55
71
|
}
|
56
72
|
|
57
73
|
return new CSSStyleDeclarationPropertyManager();
|
@@ -64,28 +80,37 @@ export default class CSSStyleDeclarationElementStyle {
|
|
64
80
|
* @returns Style sheets.
|
65
81
|
*/
|
66
82
|
private getComputedElementStyle(): CSSStyleDeclarationPropertyManager {
|
67
|
-
const documentElements: Array<
|
68
|
-
const parentElements: Array<
|
69
|
-
let styleAndElement = {
|
83
|
+
const documentElements: Array<IStyleAndElement> = [];
|
84
|
+
const parentElements: Array<IStyleAndElement> = [];
|
85
|
+
let styleAndElement: IStyleAndElement = {
|
70
86
|
element: <IElement | IShadowRoot | IDocument>this.element,
|
71
|
-
|
87
|
+
cssTexts: []
|
72
88
|
};
|
73
|
-
let shadowRootElements: Array<
|
89
|
+
let shadowRootElements: Array<IStyleAndElement> = [];
|
74
90
|
|
75
91
|
if (!this.element.isConnected) {
|
76
92
|
return new CSSStyleDeclarationPropertyManager();
|
77
93
|
}
|
78
94
|
|
95
|
+
if (
|
96
|
+
this.cache.propertyManager &&
|
97
|
+
this.cache.documentCacheID === this.element.ownerDocument['_cacheID']
|
98
|
+
) {
|
99
|
+
return this.cache.propertyManager;
|
100
|
+
}
|
101
|
+
|
102
|
+
this.cache.documentCacheID = this.element.ownerDocument['_cacheID'];
|
103
|
+
|
79
104
|
// Walks through all parent elements and stores them in an array with element and matching CSS text.
|
80
105
|
while (styleAndElement.element) {
|
81
106
|
if (styleAndElement.element.nodeType === NodeTypeEnum.elementNode) {
|
82
107
|
const rootNode = styleAndElement.element.getRootNode();
|
83
108
|
if (rootNode.nodeType === NodeTypeEnum.documentNode) {
|
84
|
-
documentElements.unshift(
|
109
|
+
documentElements.unshift(styleAndElement);
|
85
110
|
} else {
|
86
|
-
shadowRootElements.unshift(
|
111
|
+
shadowRootElements.unshift(styleAndElement);
|
87
112
|
}
|
88
|
-
parentElements.unshift(
|
113
|
+
parentElements.unshift(styleAndElement);
|
89
114
|
}
|
90
115
|
|
91
116
|
if (styleAndElement.element === this.element.ownerDocument) {
|
@@ -103,7 +128,7 @@ export default class CSSStyleDeclarationElementStyle {
|
|
103
128
|
}
|
104
129
|
}
|
105
130
|
|
106
|
-
styleAndElement = { element: null,
|
131
|
+
styleAndElement = { element: null, cssTexts: [] };
|
107
132
|
} else if ((<IShadowRoot>styleAndElement.element).host) {
|
108
133
|
const styleSheets = <INodeList<IHTMLStyleElement>>(
|
109
134
|
(<IShadowRoot>styleAndElement.element).querySelectorAll('style,link[rel="stylesheet"]')
|
@@ -111,7 +136,7 @@ export default class CSSStyleDeclarationElementStyle {
|
|
111
136
|
|
112
137
|
styleAndElement = {
|
113
138
|
element: <IElement>(<IShadowRoot>styleAndElement.element).host,
|
114
|
-
|
139
|
+
cssTexts: []
|
115
140
|
};
|
116
141
|
|
117
142
|
for (const styleSheet of styleSheets) {
|
@@ -120,39 +145,58 @@ export default class CSSStyleDeclarationElementStyle {
|
|
120
145
|
this.parseCSSRules({
|
121
146
|
elements: shadowRootElements,
|
122
147
|
cssRules: sheet.cssRules,
|
123
|
-
hostElement:
|
148
|
+
hostElement: styleAndElement
|
124
149
|
});
|
125
150
|
}
|
126
151
|
}
|
127
152
|
shadowRootElements = [];
|
128
153
|
} else {
|
129
|
-
styleAndElement = { element: <IElement>styleAndElement.element.parentNode,
|
154
|
+
styleAndElement = { element: <IElement>styleAndElement.element.parentNode, cssTexts: [] };
|
130
155
|
}
|
131
156
|
}
|
132
157
|
|
133
158
|
// Concatenates all parent element CSS to one string.
|
134
159
|
const targetElement = parentElements[parentElements.length - 1];
|
135
|
-
let inheritedCSSText =
|
160
|
+
let inheritedCSSText = '';
|
136
161
|
|
137
162
|
for (const parentElement of parentElements) {
|
138
163
|
if (parentElement !== targetElement) {
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
164
|
+
parentElement.cssTexts.sort((a, b) => a.priorityWeight - b.priorityWeight);
|
165
|
+
|
166
|
+
if (CSSStyleDeclarationElementDefaultCSS[(<IElement>parentElement.element).tagName]) {
|
167
|
+
inheritedCSSText +=
|
168
|
+
CSSStyleDeclarationElementDefaultCSS[(<IElement>parentElement.element).tagName];
|
169
|
+
}
|
170
|
+
|
171
|
+
for (const cssText of parentElement.cssTexts) {
|
172
|
+
inheritedCSSText += cssText.cssText;
|
173
|
+
}
|
174
|
+
|
175
|
+
if (parentElement.element['_attributes']['style']?.value) {
|
176
|
+
inheritedCSSText += parentElement.element['_attributes']['style'].value;
|
177
|
+
}
|
143
178
|
}
|
144
179
|
}
|
145
180
|
|
146
181
|
const cssVariables: { [k: string]: string } = {};
|
147
182
|
const properties = {};
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
183
|
+
let targetCSSText =
|
184
|
+
CSSStyleDeclarationElementDefaultCSS[(<IElement>targetElement.element).tagName] || '';
|
185
|
+
|
186
|
+
targetElement.cssTexts.sort((a, b) => a.priorityWeight - b.priorityWeight);
|
187
|
+
|
188
|
+
for (const cssText of targetElement.cssTexts) {
|
189
|
+
targetCSSText += cssText.cssText;
|
190
|
+
}
|
191
|
+
|
192
|
+
if (targetElement.element['_attributes']['style']?.value) {
|
193
|
+
targetCSSText += targetElement.element['_attributes']['style'].value;
|
194
|
+
}
|
195
|
+
|
152
196
|
const combinedCSSText = inheritedCSSText + targetCSSText;
|
153
197
|
|
154
|
-
if (this.cache
|
155
|
-
return this.cache
|
198
|
+
if (this.cache.propertyManager && this.cache.cssText === combinedCSSText) {
|
199
|
+
return this.cache.propertyManager;
|
156
200
|
}
|
157
201
|
|
158
202
|
// Parses the parent element CSS and stores CSS variables and inherited properties.
|
@@ -204,7 +248,8 @@ export default class CSSStyleDeclarationElementStyle {
|
|
204
248
|
propertyManager.set(name, properties[name].value, properties[name].important);
|
205
249
|
}
|
206
250
|
|
207
|
-
this.cache
|
251
|
+
this.cache.cssText = combinedCSSText;
|
252
|
+
this.cache.propertyManager = propertyManager;
|
208
253
|
|
209
254
|
return propertyManager;
|
210
255
|
}
|
@@ -216,13 +261,11 @@ export default class CSSStyleDeclarationElementStyle {
|
|
216
261
|
* @param options.elements Elements.
|
217
262
|
* @param options.cssRules CSS rules.
|
218
263
|
* @param [options.hostElement] Host element.
|
219
|
-
* @param [options.hostElement.element] Element.
|
220
|
-
* @param [options.hostElement.cssText] CSS text.
|
221
264
|
*/
|
222
265
|
private parseCSSRules(options: {
|
223
266
|
cssRules: CSSRule[];
|
224
|
-
elements: Array<
|
225
|
-
hostElement?:
|
267
|
+
elements: Array<IStyleAndElement>;
|
268
|
+
hostElement?: IStyleAndElement;
|
226
269
|
}): void {
|
227
270
|
if (!options.elements.length) {
|
228
271
|
return;
|
@@ -236,12 +279,19 @@ export default class CSSStyleDeclarationElementStyle {
|
|
236
279
|
if (selectorText) {
|
237
280
|
if (selectorText.startsWith(':host')) {
|
238
281
|
if (options.hostElement) {
|
239
|
-
options.hostElement.
|
282
|
+
options.hostElement.cssTexts.push({
|
283
|
+
cssText: (<CSSStyleRule>rule)._cssText,
|
284
|
+
priorityWeight: 0
|
285
|
+
});
|
240
286
|
}
|
241
287
|
} else {
|
242
288
|
for (const element of options.elements) {
|
243
|
-
|
244
|
-
|
289
|
+
const matchResult = QuerySelector.match(element.element, selectorText);
|
290
|
+
if (matchResult.matches) {
|
291
|
+
element.cssTexts.push({
|
292
|
+
cssText: (<CSSStyleRule>rule)._cssText,
|
293
|
+
priorityWeight: matchResult.priorityWeight
|
294
|
+
});
|
245
295
|
}
|
246
296
|
}
|
247
297
|
}
|
@@ -56,6 +56,10 @@ export default abstract class CharacterData extends Node implements ICharacterDa
|
|
56
56
|
const oldValue = this._data;
|
57
57
|
this._data = data;
|
58
58
|
|
59
|
+
if (this.isConnected) {
|
60
|
+
this.ownerDocument['_cacheID']++;
|
61
|
+
}
|
62
|
+
|
59
63
|
// MutationObserver
|
60
64
|
if (this._observers.length > 0) {
|
61
65
|
for (const observer of this._observers) {
|
@@ -60,6 +60,10 @@ export default class Document extends Node implements IDocument {
|
|
60
60
|
public readonly defaultView: IWindow;
|
61
61
|
public readonly _readyStateManager: DocumentReadyStateManager;
|
62
62
|
public _activeElement: IHTMLElement = null;
|
63
|
+
|
64
|
+
// Used as an unique identifier which is updated whenever the DOM gets modified.
|
65
|
+
public _cacheID = 0;
|
66
|
+
|
63
67
|
protected _isFirstWrite = true;
|
64
68
|
protected _isFirstWriteAfterOpen = false;
|
65
69
|
private _cookie = '';
|
@@ -5,7 +5,6 @@ import DOMRect from './DOMRect';
|
|
5
5
|
import DOMTokenList from '../../dom-token-list/DOMTokenList';
|
6
6
|
import IDOMTokenList from '../../dom-token-list/IDOMTokenList';
|
7
7
|
import QuerySelector from '../../query-selector/QuerySelector';
|
8
|
-
import SelectorItem from '../../query-selector/SelectorItem';
|
9
8
|
import MutationRecord from '../../mutation-observer/MutationRecord';
|
10
9
|
import MutationTypeEnum from '../../mutation-observer/MutationTypeEnum';
|
11
10
|
import NamespaceURI from '../../config/NamespaceURI';
|
@@ -744,12 +743,7 @@ export default class Element extends Node implements IElement {
|
|
744
743
|
* @returns "true" if matching.
|
745
744
|
*/
|
746
745
|
public matches(selector: string): boolean {
|
747
|
-
|
748
|
-
if (new SelectorItem(part.trim()).match(this)) {
|
749
|
-
return true;
|
750
|
-
}
|
751
|
-
}
|
752
|
-
return false;
|
746
|
+
return QuerySelector.match(this, selector).matches;
|
753
747
|
}
|
754
748
|
|
755
749
|
/**
|
@@ -852,6 +846,10 @@ export default class Element extends Node implements IElement {
|
|
852
846
|
(<IElement>attribute.ownerElement) = <IElement>this;
|
853
847
|
(<IDocument>attribute.ownerDocument) = this.ownerDocument;
|
854
848
|
|
849
|
+
if (this.isConnected) {
|
850
|
+
this.ownerDocument['_cacheID']++;
|
851
|
+
}
|
852
|
+
|
855
853
|
this._attributes[name] = attribute;
|
856
854
|
|
857
855
|
this._updateDomListIndices();
|
@@ -937,6 +935,10 @@ export default class Element extends Node implements IElement {
|
|
937
935
|
public removeAttributeNode(attribute: IAttr): void {
|
938
936
|
delete this._attributes[attribute.name];
|
939
937
|
|
938
|
+
if (this.isConnected) {
|
939
|
+
this.ownerDocument['_cacheID']++;
|
940
|
+
}
|
941
|
+
|
940
942
|
this._updateDomListIndices();
|
941
943
|
|
942
944
|
if (
|
package/src/nodes/node/Node.ts
CHANGED
@@ -73,6 +73,15 @@ export default class Node extends EventTarget implements INode {
|
|
73
73
|
this.ownerDocument = (<typeof Node>this.constructor)._ownerDocument;
|
74
74
|
}
|
75
75
|
|
76
|
+
/**
|
77
|
+
* Returns `Symbol.toStringTag`.
|
78
|
+
*
|
79
|
+
* @returns `Symbol.toStringTag`.
|
80
|
+
*/
|
81
|
+
public get [Symbol.toStringTag](): string {
|
82
|
+
return this.constructor.name;
|
83
|
+
}
|
84
|
+
|
76
85
|
/**
|
77
86
|
* Get text value of children.
|
78
87
|
*
|
@@ -308,6 +317,10 @@ export default class Node extends EventTarget implements INode {
|
|
308
317
|
}
|
309
318
|
}
|
310
319
|
|
320
|
+
if (this.isConnected) {
|
321
|
+
(this.ownerDocument || this)['_cacheID']++;
|
322
|
+
}
|
323
|
+
|
311
324
|
this.childNodes.push(node);
|
312
325
|
|
313
326
|
(<Node>node)._connectToNode(this);
|
@@ -345,6 +358,10 @@ export default class Node extends EventTarget implements INode {
|
|
345
358
|
throw new DOMException('Failed to remove node. Node is not child of parent.');
|
346
359
|
}
|
347
360
|
|
361
|
+
if (this.isConnected) {
|
362
|
+
(this.ownerDocument || this)['_cacheID']++;
|
363
|
+
}
|
364
|
+
|
348
365
|
this.childNodes.splice(index, 1);
|
349
366
|
|
350
367
|
(<Node>node)._connectToNode(null);
|
@@ -404,6 +421,10 @@ export default class Node extends EventTarget implements INode {
|
|
404
421
|
);
|
405
422
|
}
|
406
423
|
|
424
|
+
if (this.isConnected) {
|
425
|
+
(this.ownerDocument || this)['_cacheID']++;
|
426
|
+
}
|
427
|
+
|
407
428
|
if (newNode.parentNode) {
|
408
429
|
const index = newNode.parentNode.childNodes.indexOf(newNode);
|
409
430
|
if (index !== -1) {
|
@@ -5,6 +5,15 @@ import INode from './INode';
|
|
5
5
|
* Class list.
|
6
6
|
*/
|
7
7
|
export default class NodeList extends Array implements INodeList<INode> {
|
8
|
+
/**
|
9
|
+
* Returns `Symbol.toStringTag`.
|
10
|
+
*
|
11
|
+
* @returns `Symbol.toStringTag`.
|
12
|
+
*/
|
13
|
+
public get [Symbol.toStringTag](): string {
|
14
|
+
return this.constructor.name;
|
15
|
+
}
|
16
|
+
|
8
17
|
/**
|
9
18
|
* Returns item by index.
|
10
19
|
*
|
@@ -8,9 +8,6 @@ import NodeListFactory from '../nodes/node/NodeListFactory';
|
|
8
8
|
|
9
9
|
const SELECTOR_PART_REGEXP = /(\[[^\]]+\]|[a-zA-Z0-9-_.#"*:()\]]+)|([ ,>]+)/g;
|
10
10
|
|
11
|
-
// The above one seem to work fine and is faster, but this one can be useful if more rules need to be added as it is more "correct".
|
12
|
-
// Const SELECTOR_PART_REGEXP = /([a-zA-Z0-9-$.]+|\[[a-zA-Z0-9-]+\]|\[[a-zA-Z0-9$-~|^$*]+[ ]*=[ ]*"[^"]+"\])|([ ,]+)/g;
|
13
|
-
|
14
11
|
/**
|
15
12
|
* Utility for query selection in an HTML element.
|
16
13
|
*
|
@@ -57,6 +54,70 @@ export default class QuerySelector {
|
|
57
54
|
return null;
|
58
55
|
}
|
59
56
|
|
57
|
+
/**
|
58
|
+
* Checks if a node matches a selector and returns priority weight.
|
59
|
+
*
|
60
|
+
* @param node Node to search in.
|
61
|
+
* @param selector Selector.
|
62
|
+
* @returns Result.
|
63
|
+
*/
|
64
|
+
public static match(node: INode, selector: string): { priorityWeight: number; matches: boolean } {
|
65
|
+
for (const parts of this.getSelectorParts(selector)) {
|
66
|
+
const result = this.matchesSelector(node, node, parts.reverse());
|
67
|
+
|
68
|
+
if (result.matches) {
|
69
|
+
return result;
|
70
|
+
}
|
71
|
+
}
|
72
|
+
|
73
|
+
return { priorityWeight: 0, matches: false };
|
74
|
+
}
|
75
|
+
|
76
|
+
/**
|
77
|
+
* Checks if a node matches a selector.
|
78
|
+
*
|
79
|
+
* @param targetNode Target node.
|
80
|
+
* @param currentNode Current node.
|
81
|
+
* @param selectorParts Selector parts.
|
82
|
+
* @param [priorityWeight] Priority weight.
|
83
|
+
* @returns Result.
|
84
|
+
*/
|
85
|
+
private static matchesSelector(
|
86
|
+
targetNode: INode,
|
87
|
+
currentNode: INode,
|
88
|
+
selectorParts: string[],
|
89
|
+
priorityWeight = 0
|
90
|
+
): {
|
91
|
+
priorityWeight: number;
|
92
|
+
matches: boolean;
|
93
|
+
} {
|
94
|
+
const isDirectChild = selectorParts[0] === '>';
|
95
|
+
if (isDirectChild) {
|
96
|
+
selectorParts = selectorParts.slice(1);
|
97
|
+
if (selectorParts.length === 0) {
|
98
|
+
return { priorityWeight: 0, matches: false };
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
if (selectorParts.length === 0) {
|
103
|
+
return { priorityWeight, matches: true };
|
104
|
+
}
|
105
|
+
|
106
|
+
const selector = new SelectorItem(selectorParts[0]);
|
107
|
+
const result = selector.match(<Element>currentNode);
|
108
|
+
|
109
|
+
if (targetNode === currentNode && !result.matches) {
|
110
|
+
return { priorityWeight: 0, matches: false };
|
111
|
+
}
|
112
|
+
|
113
|
+
return this.matchesSelector(
|
114
|
+
isDirectChild ? currentNode.parentNode : targetNode,
|
115
|
+
currentNode.parentNode,
|
116
|
+
selectorParts.slice(1),
|
117
|
+
priorityWeight + result.priorityWeight
|
118
|
+
);
|
119
|
+
}
|
120
|
+
|
60
121
|
/**
|
61
122
|
* Finds elements based on a query selector for a part of a list of selectors separated with comma.
|
62
123
|
*
|
@@ -81,7 +142,7 @@ export default class QuerySelector {
|
|
81
142
|
|
82
143
|
for (const node of nodes) {
|
83
144
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
84
|
-
if (selector.match(<Element>node)) {
|
145
|
+
if (selector.match(<Element>node).matches) {
|
85
146
|
if (selectorParts.length === 1) {
|
86
147
|
if (rootNode !== node) {
|
87
148
|
matched.push(node);
|
@@ -125,7 +186,7 @@ export default class QuerySelector {
|
|
125
186
|
const selector = selectorItem || new SelectorItem(selectorParts[0]);
|
126
187
|
|
127
188
|
for (const node of nodes) {
|
128
|
-
if (node.nodeType === Node.ELEMENT_NODE && selector.match(<Element>node)) {
|
189
|
+
if (node.nodeType === Node.ELEMENT_NODE && selector.match(<Element>node).matches) {
|
129
190
|
if (selectorParts.length === 1) {
|
130
191
|
if (rootNode !== node) {
|
131
192
|
return <Element>node;
|