happy-dom 14.1.1 → 14.2.0
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/cjs/query-selector/ISelectorPseudo.d.ts +1 -1
- package/cjs/query-selector/ISelectorPseudo.d.ts.map +1 -1
- package/cjs/query-selector/SelectorItem.cjs +69 -32
- package/cjs/query-selector/SelectorItem.cjs.map +1 -1
- package/cjs/query-selector/SelectorItem.d.ts.map +1 -1
- package/cjs/query-selector/SelectorParser.cjs +18 -5
- package/cjs/query-selector/SelectorParser.cjs.map +1 -1
- package/cjs/query-selector/SelectorParser.d.ts.map +1 -1
- package/cjs/window/GlobalWindow.cjs +39 -2
- package/cjs/window/GlobalWindow.cjs.map +1 -1
- package/cjs/window/GlobalWindow.d.ts +25 -0
- package/cjs/window/GlobalWindow.d.ts.map +1 -1
- package/lib/query-selector/ISelectorPseudo.d.ts +1 -1
- package/lib/query-selector/ISelectorPseudo.d.ts.map +1 -1
- package/lib/query-selector/SelectorItem.d.ts.map +1 -1
- package/lib/query-selector/SelectorItem.js +69 -32
- package/lib/query-selector/SelectorItem.js.map +1 -1
- package/lib/query-selector/SelectorParser.d.ts.map +1 -1
- package/lib/query-selector/SelectorParser.js +18 -5
- package/lib/query-selector/SelectorParser.js.map +1 -1
- package/lib/window/GlobalWindow.d.ts +25 -0
- package/lib/window/GlobalWindow.d.ts.map +1 -1
- package/lib/window/GlobalWindow.js +39 -2
- package/lib/window/GlobalWindow.js.map +1 -1
- package/package.json +3 -3
- package/src/query-selector/ISelectorPseudo.ts +1 -1
- package/src/query-selector/SelectorItem.ts +74 -34
- package/src/query-selector/SelectorParser.ts +18 -5
- package/src/window/GlobalWindow.ts +57 -0
@@ -97,8 +97,12 @@ export default class SelectorItem {
|
|
97
97
|
}
|
98
98
|
|
99
99
|
// Pseudo match
|
100
|
-
if (this.pseudos
|
101
|
-
|
100
|
+
if (this.pseudos) {
|
101
|
+
const result = this.matchPsuedo(element);
|
102
|
+
if (!result) {
|
103
|
+
return null;
|
104
|
+
}
|
105
|
+
priorityWeight += result.priorityWeight;
|
102
106
|
}
|
103
107
|
|
104
108
|
return { priorityWeight };
|
@@ -110,16 +114,18 @@ export default class SelectorItem {
|
|
110
114
|
* @param element Element.
|
111
115
|
* @returns Result.
|
112
116
|
*/
|
113
|
-
private matchPsuedo(element: Element):
|
117
|
+
private matchPsuedo(element: Element): ISelectorMatch | null {
|
114
118
|
const parent = <Element>element[PropertySymbol.parentNode];
|
115
119
|
const parentChildren = element[PropertySymbol.parentNode]
|
116
120
|
? (<Element>element[PropertySymbol.parentNode])[PropertySymbol.children]
|
117
121
|
: [];
|
118
122
|
|
119
123
|
if (!this.pseudos) {
|
120
|
-
return
|
124
|
+
return { priorityWeight: 0 };
|
121
125
|
}
|
122
126
|
|
127
|
+
let priorityWeight = 0;
|
128
|
+
|
123
129
|
for (const pseudo of this.pseudos) {
|
124
130
|
// Validation
|
125
131
|
switch (pseudo.name) {
|
@@ -147,16 +153,20 @@ export default class SelectorItem {
|
|
147
153
|
case 'nth-of-type':
|
148
154
|
case 'nth-last-child':
|
149
155
|
case 'nth-last-of-type':
|
150
|
-
return
|
156
|
+
return null;
|
151
157
|
}
|
152
158
|
}
|
153
159
|
|
154
|
-
|
155
|
-
|
160
|
+
const selectorMatch = this.matchPseudoItem(element, parentChildren, pseudo);
|
161
|
+
|
162
|
+
if (!selectorMatch) {
|
163
|
+
return null;
|
156
164
|
}
|
165
|
+
|
166
|
+
priorityWeight += selectorMatch.priorityWeight;
|
157
167
|
}
|
158
168
|
|
159
|
-
return
|
169
|
+
return { priorityWeight };
|
160
170
|
}
|
161
171
|
|
162
172
|
/**
|
@@ -170,83 +180,113 @@ export default class SelectorItem {
|
|
170
180
|
element: Element,
|
171
181
|
parentChildren: Element[],
|
172
182
|
pseudo: ISelectorPseudo
|
173
|
-
):
|
183
|
+
): ISelectorMatch | null {
|
174
184
|
switch (pseudo.name) {
|
175
185
|
case 'first-child':
|
176
|
-
return parentChildren[0] === element;
|
186
|
+
return parentChildren[0] === element ? { priorityWeight: 10 } : null;
|
177
187
|
case 'last-child':
|
178
|
-
return parentChildren.length && parentChildren[parentChildren.length - 1] === element
|
188
|
+
return parentChildren.length && parentChildren[parentChildren.length - 1] === element
|
189
|
+
? { priorityWeight: 10 }
|
190
|
+
: null;
|
179
191
|
case 'only-child':
|
180
|
-
return parentChildren.length === 1 && parentChildren[0] === element
|
192
|
+
return parentChildren.length === 1 && parentChildren[0] === element
|
193
|
+
? { priorityWeight: 10 }
|
194
|
+
: null;
|
181
195
|
case 'first-of-type':
|
182
196
|
for (const child of parentChildren) {
|
183
197
|
if (child[PropertySymbol.tagName] === element[PropertySymbol.tagName]) {
|
184
|
-
return child === element;
|
198
|
+
return child === element ? { priorityWeight: 10 } : null;
|
185
199
|
}
|
186
200
|
}
|
187
|
-
return
|
201
|
+
return null;
|
188
202
|
case 'last-of-type':
|
189
203
|
for (let i = parentChildren.length - 1; i >= 0; i--) {
|
190
204
|
const child = parentChildren[i];
|
191
205
|
if (child[PropertySymbol.tagName] === element[PropertySymbol.tagName]) {
|
192
|
-
return child === element;
|
206
|
+
return child === element ? { priorityWeight: 10 } : null;
|
193
207
|
}
|
194
208
|
}
|
195
|
-
return
|
209
|
+
return null;
|
196
210
|
case 'only-of-type':
|
197
211
|
let isFound = false;
|
198
212
|
for (const child of parentChildren) {
|
199
213
|
if (child[PropertySymbol.tagName] === element[PropertySymbol.tagName]) {
|
200
214
|
if (isFound || child !== element) {
|
201
|
-
return
|
215
|
+
return null;
|
202
216
|
}
|
203
217
|
isFound = true;
|
204
218
|
}
|
205
219
|
}
|
206
|
-
return isFound;
|
220
|
+
return isFound ? { priorityWeight: 10 } : null;
|
207
221
|
case 'checked':
|
208
|
-
return element[PropertySymbol.tagName] === 'INPUT' && (<HTMLInputElement>element).checked
|
222
|
+
return element[PropertySymbol.tagName] === 'INPUT' && (<HTMLInputElement>element).checked
|
223
|
+
? { priorityWeight: 10 }
|
224
|
+
: null;
|
209
225
|
case 'empty':
|
210
|
-
return !(<Element>element)[PropertySymbol.children].length;
|
226
|
+
return !(<Element>element)[PropertySymbol.children].length ? { priorityWeight: 10 } : null;
|
211
227
|
case 'root':
|
212
|
-
return element[PropertySymbol.tagName] === 'HTML';
|
228
|
+
return element[PropertySymbol.tagName] === 'HTML' ? { priorityWeight: 10 } : null;
|
213
229
|
case 'not':
|
214
|
-
return !pseudo.
|
230
|
+
return !pseudo.selectorItems[0].match(element) ? { priorityWeight: 10 } : null;
|
215
231
|
case 'nth-child':
|
216
|
-
const nthChildIndex = pseudo.
|
217
|
-
? parentChildren.filter((child) => pseudo.
|
232
|
+
const nthChildIndex = pseudo.selectorItems[0]
|
233
|
+
? parentChildren.filter((child) => pseudo.selectorItems[0].match(child)).indexOf(element)
|
218
234
|
: parentChildren.indexOf(element);
|
219
|
-
return nthChildIndex !== -1 && pseudo.nthFunction(nthChildIndex + 1)
|
235
|
+
return nthChildIndex !== -1 && pseudo.nthFunction(nthChildIndex + 1)
|
236
|
+
? { priorityWeight: 10 }
|
237
|
+
: null;
|
220
238
|
case 'nth-of-type':
|
221
239
|
if (!element[PropertySymbol.parentNode]) {
|
222
|
-
return
|
240
|
+
return null;
|
223
241
|
}
|
224
242
|
const nthOfTypeIndex = parentChildren
|
225
243
|
.filter((child) => child[PropertySymbol.tagName] === element[PropertySymbol.tagName])
|
226
244
|
.indexOf(element);
|
227
|
-
return nthOfTypeIndex !== -1 && pseudo.nthFunction(nthOfTypeIndex + 1)
|
245
|
+
return nthOfTypeIndex !== -1 && pseudo.nthFunction(nthOfTypeIndex + 1)
|
246
|
+
? { priorityWeight: 10 }
|
247
|
+
: null;
|
228
248
|
case 'nth-last-child':
|
229
|
-
const nthLastChildIndex = pseudo.
|
249
|
+
const nthLastChildIndex = pseudo.selectorItems[0]
|
230
250
|
? parentChildren
|
231
|
-
.filter((child) => pseudo.
|
251
|
+
.filter((child) => pseudo.selectorItems[0].match(child))
|
232
252
|
.reverse()
|
233
253
|
.indexOf(element)
|
234
254
|
: parentChildren.reverse().indexOf(element);
|
235
|
-
return nthLastChildIndex !== -1 && pseudo.nthFunction(nthLastChildIndex + 1)
|
255
|
+
return nthLastChildIndex !== -1 && pseudo.nthFunction(nthLastChildIndex + 1)
|
256
|
+
? { priorityWeight: 10 }
|
257
|
+
: null;
|
236
258
|
case 'nth-last-of-type':
|
237
259
|
const nthLastOfTypeIndex = parentChildren
|
238
260
|
.filter((child) => child[PropertySymbol.tagName] === element[PropertySymbol.tagName])
|
239
261
|
.reverse()
|
240
262
|
.indexOf(element);
|
241
|
-
return nthLastOfTypeIndex !== -1 && pseudo.nthFunction(nthLastOfTypeIndex + 1)
|
263
|
+
return nthLastOfTypeIndex !== -1 && pseudo.nthFunction(nthLastOfTypeIndex + 1)
|
264
|
+
? { priorityWeight: 10 }
|
265
|
+
: null;
|
242
266
|
case 'target':
|
243
267
|
const hash = element[PropertySymbol.ownerDocument].location.hash;
|
244
268
|
if (!hash) {
|
245
|
-
return
|
269
|
+
return null;
|
270
|
+
}
|
271
|
+
return element.isConnected && element.id === hash.slice(1) ? { priorityWeight: 10 } : null;
|
272
|
+
case 'is':
|
273
|
+
let priorityWeight = 0;
|
274
|
+
for (const selectorItem of pseudo.selectorItems) {
|
275
|
+
const match = selectorItem.match(element);
|
276
|
+
if (match) {
|
277
|
+
priorityWeight = match.priorityWeight;
|
278
|
+
}
|
246
279
|
}
|
247
|
-
return
|
280
|
+
return priorityWeight ? { priorityWeight } : null;
|
281
|
+
case 'where':
|
282
|
+
for (const selectorItem of pseudo.selectorItems) {
|
283
|
+
if (selectorItem.match(element)) {
|
284
|
+
return { priorityWeight: 0 };
|
285
|
+
}
|
286
|
+
}
|
287
|
+
return null;
|
248
288
|
default:
|
249
|
-
return
|
289
|
+
return null;
|
250
290
|
}
|
251
291
|
}
|
252
292
|
|
@@ -247,7 +247,7 @@ export default class SelectorParser {
|
|
247
247
|
const lowerName = name.toLowerCase();
|
248
248
|
|
249
249
|
if (!args) {
|
250
|
-
return { name: lowerName, arguments: null,
|
250
|
+
return { name: lowerName, arguments: null, selectorItems: null, nthFunction: null };
|
251
251
|
}
|
252
252
|
|
253
253
|
switch (lowerName) {
|
@@ -260,7 +260,7 @@ export default class SelectorParser {
|
|
260
260
|
return {
|
261
261
|
name: lowerName,
|
262
262
|
arguments: args,
|
263
|
-
selectorItem,
|
263
|
+
selectorItems: [selectorItem],
|
264
264
|
nthFunction: this.getPseudoNthFunction(nthFunction)
|
265
265
|
};
|
266
266
|
case 'nth-of-type':
|
@@ -268,18 +268,31 @@ export default class SelectorParser {
|
|
268
268
|
return {
|
269
269
|
name: lowerName,
|
270
270
|
arguments: args,
|
271
|
-
|
271
|
+
selectorItems: null,
|
272
272
|
nthFunction: this.getPseudoNthFunction(args)
|
273
273
|
};
|
274
274
|
case 'not':
|
275
275
|
return {
|
276
276
|
name: lowerName,
|
277
277
|
arguments: args,
|
278
|
-
|
278
|
+
selectorItems: [this.getSelectorItem(args)],
|
279
|
+
nthFunction: null
|
280
|
+
};
|
281
|
+
case 'is':
|
282
|
+
case 'where':
|
283
|
+
const selectorGroups = this.getSelectorGroups(args);
|
284
|
+
const selectorItems = [];
|
285
|
+
for (const group of selectorGroups) {
|
286
|
+
selectorItems.push(group[0]);
|
287
|
+
}
|
288
|
+
return {
|
289
|
+
name: lowerName,
|
290
|
+
arguments: args,
|
291
|
+
selectorItems,
|
279
292
|
nthFunction: null
|
280
293
|
};
|
281
294
|
default:
|
282
|
-
return { name: lowerName, arguments: args,
|
295
|
+
return { name: lowerName, arguments: args, selectorItems: null, nthFunction: null };
|
283
296
|
}
|
284
297
|
}
|
285
298
|
|
@@ -1,4 +1,6 @@
|
|
1
1
|
import * as PropertySymbol from '../PropertySymbol.js';
|
2
|
+
import { IOptionalBrowserSettings } from '../index.js';
|
3
|
+
import BrowserWindow from './BrowserWindow.js';
|
2
4
|
import Window from './Window.js';
|
3
5
|
import { Buffer } from 'buffer';
|
4
6
|
|
@@ -70,6 +72,61 @@ export default class GlobalWindow extends Window {
|
|
70
72
|
public gc: () => void = globalThis.gc;
|
71
73
|
public v8debug?: unknown = globalThis.v8debug;
|
72
74
|
|
75
|
+
/**
|
76
|
+
* Constructor.
|
77
|
+
*
|
78
|
+
* @param [options] Options.
|
79
|
+
* @param [options.width] Window width. Defaults to "1024".
|
80
|
+
* @param [options.height] Window height. Defaults to "768".
|
81
|
+
* @param [options.innerWidth] Inner width. Deprecated. Defaults to "1024".
|
82
|
+
* @param [options.innerHeight] Inner height. Deprecated. Defaults to "768".
|
83
|
+
* @param [options.url] URL.
|
84
|
+
* @param [options.console] Console.
|
85
|
+
* @param [options.settings] Settings.
|
86
|
+
*/
|
87
|
+
constructor(options?: {
|
88
|
+
width?: number;
|
89
|
+
height?: number;
|
90
|
+
/** @deprecated Replaced by the "width" property. */
|
91
|
+
innerWidth?: number;
|
92
|
+
/** @deprecated Replaced by the "height" property. */
|
93
|
+
innerHeight?: number;
|
94
|
+
url?: string;
|
95
|
+
console?: Console;
|
96
|
+
settings?: IOptionalBrowserSettings;
|
97
|
+
}) {
|
98
|
+
super(options);
|
99
|
+
|
100
|
+
/**
|
101
|
+
* Binds getts and setters, so that they will appear as an "own" property when using Object.getOwnPropertyNames().
|
102
|
+
*
|
103
|
+
* This is needed for Vitest to work as it relies on Object.getOwnPropertyNames() to get the list of properties.
|
104
|
+
*
|
105
|
+
* @see https://github.com/capricorn86/happy-dom/issues/1339
|
106
|
+
*/
|
107
|
+
for (const windowClass of [GlobalWindow, Window, BrowserWindow]) {
|
108
|
+
const propertyDescriptors = Object.getOwnPropertyDescriptors(
|
109
|
+
Reflect.getPrototypeOf(windowClass.prototype)
|
110
|
+
);
|
111
|
+
|
112
|
+
for (const key of Object.keys(propertyDescriptors)) {
|
113
|
+
const windowPropertyDescriptor = propertyDescriptors[key];
|
114
|
+
if (windowPropertyDescriptor.get || windowPropertyDescriptor.set) {
|
115
|
+
const ownPropertyDescriptor = Object.getOwnPropertyDescriptor(this, key);
|
116
|
+
|
117
|
+
if (!ownPropertyDescriptor) {
|
118
|
+
Object.defineProperty(this, key, {
|
119
|
+
configurable: true,
|
120
|
+
enumerable: windowPropertyDescriptor.enumerable,
|
121
|
+
get: windowPropertyDescriptor.get?.bind(this),
|
122
|
+
set: windowPropertyDescriptor.set?.bind(this)
|
123
|
+
});
|
124
|
+
}
|
125
|
+
}
|
126
|
+
}
|
127
|
+
}
|
128
|
+
}
|
129
|
+
|
73
130
|
/**
|
74
131
|
* Setup of VM context.
|
75
132
|
*/
|