happy-dom 2.43.0 → 2.45.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/navigator/MimeType.d.ts +25 -0
- package/lib/navigator/MimeType.js +32 -0
- package/lib/navigator/MimeType.js.map +1 -0
- package/lib/navigator/MimeTypeArray.d.ts +31 -0
- package/lib/navigator/MimeTypeArray.js +45 -0
- package/lib/navigator/MimeTypeArray.js.map +1 -0
- package/lib/navigator/Navigator.d.ts +41 -0
- package/lib/navigator/Navigator.js +78 -0
- package/lib/navigator/Navigator.js.map +1 -0
- package/lib/navigator/Plugin.d.ts +40 -0
- package/lib/navigator/Plugin.js +55 -0
- package/lib/navigator/Plugin.js.map +1 -0
- package/lib/navigator/PluginArray.d.ts +38 -0
- package/lib/navigator/PluginArray.js +54 -0
- package/lib/navigator/PluginArray.js.map +1 -0
- package/lib/query-selector/SelectorItem.d.ts +19 -3
- package/lib/query-selector/SelectorItem.js +55 -27
- package/lib/query-selector/SelectorItem.js.map +1 -1
- package/lib/window/IWindow.d.ts +11 -3
- package/lib/window/Window.d.ts +11 -3
- package/lib/window/Window.js +11 -1
- package/lib/window/Window.js.map +1 -1
- package/package.json +2 -2
- package/src/navigator/MimeType.ts +35 -0
- package/src/navigator/MimeTypeArray.ts +48 -0
- package/src/navigator/Navigator.ts +93 -0
- package/src/navigator/Plugin.ts +61 -0
- package/src/navigator/PluginArray.ts +58 -0
- package/src/query-selector/SelectorItem.ts +62 -28
- package/src/window/IWindow.ts +11 -1
- package/src/window/Window.ts +11 -1
@@ -8,7 +8,7 @@ const CLASS_REGEXP = /\.([a-zA-Z0-9-_$]+)/g;
|
|
8
8
|
const TAG_NAME_REGEXP = /^[a-zA-Z0-9-]+/;
|
9
9
|
|
10
10
|
/**
|
11
|
-
*
|
11
|
+
* Selector item.
|
12
12
|
*/
|
13
13
|
export default class SelectorItem {
|
14
14
|
public isAll: boolean;
|
@@ -29,8 +29,7 @@ export default class SelectorItem {
|
|
29
29
|
constructor(selector: string) {
|
30
30
|
this.isAll = selector === '*';
|
31
31
|
this.isID = !this.isAll ? selector.startsWith('#') : false;
|
32
|
-
this.isAttribute =
|
33
|
-
!this.isAll && !this.isID && selector.includes('[') && !selector.includes(':not(');
|
32
|
+
this.isAttribute = !this.isAll && !this.isID && selector.includes('[');
|
34
33
|
this.isPseudo = !this.isAll && !this.isID && selector.includes(':');
|
35
34
|
this.isClass = !this.isAll && !this.isID && new RegExp(CLASS_REGEXP, 'g').test(selector);
|
36
35
|
this.tagName = !this.isAll && !this.isID ? selector.match(TAG_NAME_REGEXP) : null;
|
@@ -48,7 +47,6 @@ export default class SelectorItem {
|
|
48
47
|
*/
|
49
48
|
public match(element: Element): boolean {
|
50
49
|
const selector = this.selector;
|
51
|
-
let match;
|
52
50
|
|
53
51
|
// Is all (*)
|
54
52
|
if (this.isAll) {
|
@@ -68,29 +66,13 @@ export default class SelectorItem {
|
|
68
66
|
}
|
69
67
|
|
70
68
|
// Class match
|
71
|
-
if (this.isClass) {
|
72
|
-
|
73
|
-
|
74
|
-
while ((match = regexp.exec(selector))) {
|
75
|
-
if (!element.classList.contains(match[1])) {
|
76
|
-
return false;
|
77
|
-
}
|
78
|
-
}
|
69
|
+
if (this.isClass && !this.matchesClass(element, selector)) {
|
70
|
+
return false;
|
79
71
|
}
|
80
72
|
|
81
73
|
// Pseudo match
|
82
|
-
if (this.isPseudo) {
|
83
|
-
|
84
|
-
|
85
|
-
while ((match = regexp.exec(selector))) {
|
86
|
-
if (match[1] && !this.matchesNthChild(element, match[1], match[2])) {
|
87
|
-
return false;
|
88
|
-
} else if (match[3] && this.matchesAttribute(element, match[3])) {
|
89
|
-
return false;
|
90
|
-
} else if (match[4] && !this.matchesPsuedo(element, match[4])) {
|
91
|
-
return false;
|
92
|
-
}
|
93
|
-
}
|
74
|
+
if (this.isPseudo && !this.matchesPsuedo(element, selector)) {
|
75
|
+
return false;
|
94
76
|
}
|
95
77
|
|
96
78
|
// Attribute match
|
@@ -101,6 +83,35 @@ export default class SelectorItem {
|
|
101
83
|
return true;
|
102
84
|
}
|
103
85
|
|
86
|
+
/**
|
87
|
+
* Matches a psuedo selector.
|
88
|
+
*
|
89
|
+
* @param element Element.
|
90
|
+
* @param selector Selector.
|
91
|
+
* @returns True if it is a match.
|
92
|
+
*/
|
93
|
+
private matchesPsuedo(element: Element, selector: string): boolean {
|
94
|
+
const regexp = new RegExp(PSUEDO_REGEXP, 'g');
|
95
|
+
let match: RegExpMatchArray;
|
96
|
+
|
97
|
+
while ((match = regexp.exec(selector))) {
|
98
|
+
const isNotClass = match[3] && match[3].trim()[0] === '.';
|
99
|
+
if (match[1] && !this.matchesNthChild(element, match[1], match[2])) {
|
100
|
+
return false;
|
101
|
+
} else if (
|
102
|
+
match[3] &&
|
103
|
+
((isNotClass && this.matchesClass(element, match[3])) ||
|
104
|
+
(!isNotClass && this.matchesAttribute(element, match[3])))
|
105
|
+
) {
|
106
|
+
return false;
|
107
|
+
} else if (match[4] && !this.matchesPsuedoExpression(element, match[4])) {
|
108
|
+
return false;
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
return true;
|
113
|
+
}
|
114
|
+
|
104
115
|
/**
|
105
116
|
* Matches a nth-child selector.
|
106
117
|
*
|
@@ -158,13 +169,13 @@ export default class SelectorItem {
|
|
158
169
|
}
|
159
170
|
|
160
171
|
/**
|
161
|
-
* Matches a psuedo selector.
|
172
|
+
* Matches a psuedo selector expression.
|
162
173
|
*
|
163
174
|
* @param element Element.
|
164
175
|
* @param psuedo Psuedo name.
|
165
176
|
* @returns True if it is a match.
|
166
177
|
*/
|
167
|
-
private
|
178
|
+
private matchesPsuedoExpression(element: Element, psuedo: string): boolean {
|
168
179
|
const parent = <Element>element.parentNode;
|
169
180
|
|
170
181
|
if (!parent) {
|
@@ -220,10 +231,10 @@ export default class SelectorItem {
|
|
220
231
|
*/
|
221
232
|
private matchesAttribute(element: Element, selector: string): boolean {
|
222
233
|
const regexp = new RegExp(ATTRIBUTE_REGEXP, 'g');
|
223
|
-
let match;
|
234
|
+
let match: RegExpMatchArray;
|
224
235
|
|
225
236
|
while ((match = regexp.exec(selector))) {
|
226
|
-
const isPsuedo = match.index > 0 && selector[match.index] === '(';
|
237
|
+
const isPsuedo = match.index > 0 && selector[match.index - 1] === '(';
|
227
238
|
if (
|
228
239
|
!isPsuedo &&
|
229
240
|
((match[1] && !this.matchesAttributeName(element, match[1])) ||
|
@@ -236,6 +247,29 @@ export default class SelectorItem {
|
|
236
247
|
return true;
|
237
248
|
}
|
238
249
|
|
250
|
+
/**
|
251
|
+
* Matches class.
|
252
|
+
*
|
253
|
+
* @param element Element.
|
254
|
+
* @param selector Selector.
|
255
|
+
* @returns True if it is a match.
|
256
|
+
*/
|
257
|
+
private matchesClass(element: Element, selector: string): boolean {
|
258
|
+
const regexp = new RegExp(CLASS_REGEXP, 'g');
|
259
|
+
const classList = element.className.split(' ');
|
260
|
+
let previousIndex = 0;
|
261
|
+
let match: RegExpMatchArray;
|
262
|
+
|
263
|
+
while ((match = regexp.exec(selector)) && match.index === previousIndex) {
|
264
|
+
if (!classList.includes(match[1])) {
|
265
|
+
return false;
|
266
|
+
}
|
267
|
+
previousIndex = match.index + match[0].length - 1;
|
268
|
+
}
|
269
|
+
|
270
|
+
return true;
|
271
|
+
}
|
272
|
+
|
239
273
|
/**
|
240
274
|
* Matches attribute name only.
|
241
275
|
*
|
package/src/window/IWindow.ts
CHANGED
@@ -70,6 +70,11 @@ import HTMLCollection from '../nodes/element/HTMLCollection';
|
|
70
70
|
import NodeList from '../nodes/node/NodeList';
|
71
71
|
import Selection from '../selection/Selection';
|
72
72
|
import IEventTarget from '../event/IEventTarget';
|
73
|
+
import Navigator from '../navigator/Navigator';
|
74
|
+
import MimeType from '../navigator/MimeType';
|
75
|
+
import MimeTypeArray from '../navigator/MimeTypeArray';
|
76
|
+
import Plugin from '../navigator/Plugin';
|
77
|
+
import PluginArray from '../navigator/PluginArray';
|
73
78
|
|
74
79
|
/**
|
75
80
|
* Window.
|
@@ -151,6 +156,11 @@ export default interface IWindow extends IEventTarget {
|
|
151
156
|
readonly CSSUnitValue: typeof CSSUnitValue;
|
152
157
|
readonly CSS: CSS;
|
153
158
|
readonly Selection: typeof Selection;
|
159
|
+
readonly Navigator: typeof Navigator;
|
160
|
+
readonly MimeType: typeof MimeType;
|
161
|
+
readonly MimeTypeArray: typeof MimeTypeArray;
|
162
|
+
readonly Plugin: typeof Plugin;
|
163
|
+
readonly PluginArray: typeof PluginArray;
|
154
164
|
|
155
165
|
// Events
|
156
166
|
onload: (event: Event) => void;
|
@@ -161,7 +171,7 @@ export default interface IWindow extends IEventTarget {
|
|
161
171
|
readonly customElements: CustomElementRegistry;
|
162
172
|
readonly location: Location;
|
163
173
|
readonly history: History;
|
164
|
-
readonly navigator:
|
174
|
+
readonly navigator: Navigator;
|
165
175
|
readonly console: Console;
|
166
176
|
readonly self: IWindow;
|
167
177
|
readonly top: IWindow;
|
package/src/window/Window.ts
CHANGED
@@ -75,6 +75,11 @@ import NodeList from '../nodes/node/NodeList';
|
|
75
75
|
import MediaQueryList from '../match-media/MediaQueryList';
|
76
76
|
import Selection from '../selection/Selection';
|
77
77
|
import * as PerfHooks from 'perf_hooks';
|
78
|
+
import Navigator from '../navigator/Navigator';
|
79
|
+
import MimeType from '../navigator/MimeType';
|
80
|
+
import MimeTypeArray from '../navigator/MimeTypeArray';
|
81
|
+
import Plugin from '../navigator/Plugin';
|
82
|
+
import PluginArray from '../navigator/PluginArray';
|
78
83
|
|
79
84
|
const FETCH_RESPONSE_TYPE_METHODS = ['blob', 'json', 'text'];
|
80
85
|
|
@@ -162,6 +167,11 @@ export default class Window extends EventTarget implements IWindow, NodeJS.Globa
|
|
162
167
|
public readonly MediaQueryList = MediaQueryList;
|
163
168
|
public readonly CSSUnitValue = CSSUnitValue;
|
164
169
|
public readonly Selection = Selection;
|
170
|
+
public readonly Navigator = Navigator;
|
171
|
+
public readonly MimeType = MimeType;
|
172
|
+
public readonly MimeTypeArray = MimeTypeArray;
|
173
|
+
public readonly Plugin = Plugin;
|
174
|
+
public readonly PluginArray = PluginArray;
|
165
175
|
|
166
176
|
// Events
|
167
177
|
public onload: (event: Event) => void = null;
|
@@ -172,7 +182,7 @@ export default class Window extends EventTarget implements IWindow, NodeJS.Globa
|
|
172
182
|
public readonly customElements: CustomElementRegistry = new CustomElementRegistry();
|
173
183
|
public readonly location = new Location();
|
174
184
|
public readonly history = new History();
|
175
|
-
public readonly navigator =
|
185
|
+
public readonly navigator = new Navigator();
|
176
186
|
public readonly console = global ? global.console : null;
|
177
187
|
public readonly self = this;
|
178
188
|
public readonly top = this;
|