happy-dom 13.8.4 → 13.8.6
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/config/HTMLElementConfig.cjs +11 -11
- package/cjs/config/HTMLElementConfig.cjs.map +1 -1
- package/cjs/config/HTMLElementConfigContentModelEnum.cjs +1 -1
- package/cjs/config/HTMLElementConfigContentModelEnum.cjs.map +1 -1
- package/cjs/config/HTMLElementConfigContentModelEnum.d.ts +1 -1
- package/cjs/config/HTMLElementConfigContentModelEnum.d.ts.map +1 -1
- package/cjs/css/declaration/element-style/CSSStyleDeclarationElementStyle.cjs +2 -3
- package/cjs/css/declaration/element-style/CSSStyleDeclarationElementStyle.cjs.map +1 -1
- package/cjs/css/declaration/element-style/CSSStyleDeclarationElementStyle.d.ts.map +1 -1
- package/cjs/query-selector/SelectorItem.cjs +90 -76
- package/cjs/query-selector/SelectorItem.cjs.map +1 -1
- package/cjs/query-selector/SelectorItem.d.ts +9 -1
- package/cjs/query-selector/SelectorItem.d.ts.map +1 -1
- package/cjs/version.cjs +1 -1
- package/cjs/xml-parser/XMLParser.cjs +1 -1
- package/cjs/xml-parser/XMLParser.cjs.map +1 -1
- package/lib/config/HTMLElementConfig.js +11 -11
- package/lib/config/HTMLElementConfig.js.map +1 -1
- package/lib/config/HTMLElementConfigContentModelEnum.d.ts +1 -1
- package/lib/config/HTMLElementConfigContentModelEnum.d.ts.map +1 -1
- package/lib/config/HTMLElementConfigContentModelEnum.js +1 -1
- package/lib/config/HTMLElementConfigContentModelEnum.js.map +1 -1
- package/lib/css/declaration/element-style/CSSStyleDeclarationElementStyle.d.ts.map +1 -1
- package/lib/css/declaration/element-style/CSSStyleDeclarationElementStyle.js +2 -3
- package/lib/css/declaration/element-style/CSSStyleDeclarationElementStyle.js.map +1 -1
- package/lib/query-selector/SelectorItem.d.ts +9 -1
- package/lib/query-selector/SelectorItem.d.ts.map +1 -1
- package/lib/query-selector/SelectorItem.js +90 -76
- package/lib/query-selector/SelectorItem.js.map +1 -1
- package/lib/version.js +1 -1
- package/lib/xml-parser/XMLParser.js +1 -1
- package/lib/xml-parser/XMLParser.js.map +1 -1
- package/package.json +1 -1
- package/src/config/HTMLElementConfig.ts +11 -11
- package/src/config/HTMLElementConfigContentModelEnum.ts +1 -1
- package/src/css/declaration/element-style/CSSStyleDeclarationElementStyle.ts +2 -3
- package/src/query-selector/SelectorItem.ts +97 -80
- package/src/xml-parser/XMLParser.ts +1 -1
package/package.json
CHANGED
@@ -219,7 +219,7 @@ export default <{ [key: string]: IHTMLElementConfigEntity }>{
|
|
219
219
|
className: 'HTMLElement',
|
220
220
|
localName: 'dd',
|
221
221
|
tagName: 'DD',
|
222
|
-
contentModel: HTMLElementConfigContentModelEnum.
|
222
|
+
contentModel: HTMLElementConfigContentModelEnum.noFirstLevelSelfDescendants
|
223
223
|
},
|
224
224
|
del: {
|
225
225
|
className: 'HTMLElement',
|
@@ -261,7 +261,7 @@ export default <{ [key: string]: IHTMLElementConfigEntity }>{
|
|
261
261
|
className: 'HTMLElement',
|
262
262
|
localName: 'dt',
|
263
263
|
tagName: 'DT',
|
264
|
-
contentModel: HTMLElementConfigContentModelEnum.
|
264
|
+
contentModel: HTMLElementConfigContentModelEnum.noFirstLevelSelfDescendants
|
265
265
|
},
|
266
266
|
em: {
|
267
267
|
className: 'HTMLElement',
|
@@ -303,37 +303,37 @@ export default <{ [key: string]: IHTMLElementConfigEntity }>{
|
|
303
303
|
className: 'HTMLElement',
|
304
304
|
localName: 'h1',
|
305
305
|
tagName: 'H1',
|
306
|
-
contentModel: HTMLElementConfigContentModelEnum.
|
306
|
+
contentModel: HTMLElementConfigContentModelEnum.noFirstLevelSelfDescendants
|
307
307
|
},
|
308
308
|
h2: {
|
309
309
|
className: 'HTMLElement',
|
310
310
|
localName: 'h2',
|
311
311
|
tagName: 'H2',
|
312
|
-
contentModel: HTMLElementConfigContentModelEnum.
|
312
|
+
contentModel: HTMLElementConfigContentModelEnum.noFirstLevelSelfDescendants
|
313
313
|
},
|
314
314
|
h3: {
|
315
315
|
className: 'HTMLElement',
|
316
316
|
localName: 'h3',
|
317
317
|
tagName: 'H3',
|
318
|
-
contentModel: HTMLElementConfigContentModelEnum.
|
318
|
+
contentModel: HTMLElementConfigContentModelEnum.noFirstLevelSelfDescendants
|
319
319
|
},
|
320
320
|
h4: {
|
321
321
|
className: 'HTMLElement',
|
322
322
|
localName: 'h4',
|
323
323
|
tagName: 'H4',
|
324
|
-
contentModel: HTMLElementConfigContentModelEnum.
|
324
|
+
contentModel: HTMLElementConfigContentModelEnum.noFirstLevelSelfDescendants
|
325
325
|
},
|
326
326
|
h5: {
|
327
327
|
className: 'HTMLElement',
|
328
328
|
localName: 'h5',
|
329
329
|
tagName: 'H5',
|
330
|
-
contentModel: HTMLElementConfigContentModelEnum.
|
330
|
+
contentModel: HTMLElementConfigContentModelEnum.noFirstLevelSelfDescendants
|
331
331
|
},
|
332
332
|
h6: {
|
333
333
|
className: 'HTMLElement',
|
334
334
|
localName: 'h6',
|
335
335
|
tagName: 'H6',
|
336
|
-
contentModel: HTMLElementConfigContentModelEnum.
|
336
|
+
contentModel: HTMLElementConfigContentModelEnum.noFirstLevelSelfDescendants
|
337
337
|
},
|
338
338
|
head: {
|
339
339
|
className: 'HTMLElement',
|
@@ -399,7 +399,7 @@ export default <{ [key: string]: IHTMLElementConfigEntity }>{
|
|
399
399
|
className: 'HTMLElement',
|
400
400
|
localName: 'li',
|
401
401
|
tagName: 'LI',
|
402
|
-
contentModel: HTMLElementConfigContentModelEnum.
|
402
|
+
contentModel: HTMLElementConfigContentModelEnum.noFirstLevelSelfDescendants
|
403
403
|
},
|
404
404
|
main: {
|
405
405
|
className: 'HTMLElement',
|
@@ -477,7 +477,7 @@ export default <{ [key: string]: IHTMLElementConfigEntity }>{
|
|
477
477
|
className: 'HTMLOptionElement',
|
478
478
|
localName: 'option',
|
479
479
|
tagName: 'OPTION',
|
480
|
-
contentModel: HTMLElementConfigContentModelEnum.
|
480
|
+
contentModel: HTMLElementConfigContentModelEnum.noFirstLevelSelfDescendants
|
481
481
|
},
|
482
482
|
output: {
|
483
483
|
className: 'HTMLElement',
|
@@ -621,7 +621,7 @@ export default <{ [key: string]: IHTMLElementConfigEntity }>{
|
|
621
621
|
className: 'HTMLElement',
|
622
622
|
localName: 'table',
|
623
623
|
tagName: 'TABLE',
|
624
|
-
contentModel: HTMLElementConfigContentModelEnum.
|
624
|
+
contentModel: HTMLElementConfigContentModelEnum.noFirstLevelSelfDescendants
|
625
625
|
},
|
626
626
|
tbody: {
|
627
627
|
className: 'HTMLElement',
|
@@ -1,7 +1,7 @@
|
|
1
1
|
enum HTMLElementConfigContentModelEnum {
|
2
2
|
rawText = 'rawText',
|
3
3
|
noSelfDescendants = 'noSelfDescendants',
|
4
|
-
|
4
|
+
noFirstLevelSelfDescendants = 'noFirstLevelSelfDescendants',
|
5
5
|
noDescendants = 'noDescendants',
|
6
6
|
anyDescendants = 'anyDescendants'
|
7
7
|
}
|
@@ -19,7 +19,7 @@ import CSSMeasurementConverter from '../measurement-converter/CSSMeasurementConv
|
|
19
19
|
import MediaQueryList from '../../../match-media/MediaQueryList.js';
|
20
20
|
import WindowBrowserSettingsReader from '../../../window/WindowBrowserSettingsReader.js';
|
21
21
|
|
22
|
-
const CSS_VARIABLE_REGEXP = /var\( *(--[^), ]+)\)|var\( *(--[^), ]+), *([^), ]+)\)
|
22
|
+
const CSS_VARIABLE_REGEXP = /var\( *(--[^), ]+)\)|var\( *(--[^), ]+), *([^), ]+)\)/;
|
23
23
|
const CSS_MEASUREMENT_REGEXP = /[0-9.]+(px|rem|em|vw|vh|%|vmin|vmax|cm|mm|in|pt|pc|Q)/g;
|
24
24
|
|
25
25
|
type IStyleAndElement = {
|
@@ -364,11 +364,10 @@ export default class CSSStyleDeclarationElementStyle {
|
|
364
364
|
* @returns CSS value.
|
365
365
|
*/
|
366
366
|
private parseCSSVariablesInValue(value: string, cssVariables: { [k: string]: string }): string {
|
367
|
-
const regexp = new RegExp(CSS_VARIABLE_REGEXP);
|
368
367
|
let newValue = value;
|
369
368
|
let match;
|
370
369
|
|
371
|
-
while ((match =
|
370
|
+
while ((match = newValue.match(CSS_VARIABLE_REGEXP)) !== null) {
|
372
371
|
// Fallback value - E.g. var(--my-var, #FFFFFF)
|
373
372
|
if (match[2] !== undefined) {
|
374
373
|
newValue = newValue.replace(match[0], cssVariables[match[2]] || match[3]);
|
@@ -106,7 +106,7 @@ export default class SelectorItem {
|
|
106
106
|
}
|
107
107
|
|
108
108
|
/**
|
109
|
-
* Matches a
|
109
|
+
* Matches a pseudo selector.
|
110
110
|
*
|
111
111
|
* @param element Element.
|
112
112
|
* @returns Result.
|
@@ -121,15 +121,15 @@ export default class SelectorItem {
|
|
121
121
|
return true;
|
122
122
|
}
|
123
123
|
|
124
|
-
for (const
|
124
|
+
for (const pseudo of this.pseudos) {
|
125
125
|
// Validation
|
126
|
-
switch (
|
126
|
+
switch (pseudo.name) {
|
127
127
|
case 'not':
|
128
128
|
case 'nth-child':
|
129
129
|
case 'nth-of-type':
|
130
130
|
case 'nth-last-child':
|
131
131
|
case 'nth-last-of-type':
|
132
|
-
if (!
|
132
|
+
if (!pseudo.arguments) {
|
133
133
|
throw new DOMException(`The selector "${this.getSelectorString()}" is not valid.`);
|
134
134
|
}
|
135
135
|
break;
|
@@ -137,7 +137,7 @@ export default class SelectorItem {
|
|
137
137
|
|
138
138
|
// Check if parent exists
|
139
139
|
if (!parent) {
|
140
|
-
switch (
|
140
|
+
switch (pseudo.name) {
|
141
141
|
case 'first-child':
|
142
142
|
case 'last-child':
|
143
143
|
case 'only-child':
|
@@ -152,86 +152,103 @@ export default class SelectorItem {
|
|
152
152
|
}
|
153
153
|
}
|
154
154
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
155
|
+
if (!this.matchPseudoItem(element, parentChildren, pseudo)) {
|
156
|
+
return false;
|
157
|
+
}
|
158
|
+
}
|
159
|
+
|
160
|
+
return true;
|
161
|
+
}
|
162
|
+
|
163
|
+
/**
|
164
|
+
* Matches a pseudo selector.
|
165
|
+
*
|
166
|
+
* @param element Element.
|
167
|
+
* @param parentChildren Parent children.
|
168
|
+
* @param pseudo Pseudo.
|
169
|
+
*/
|
170
|
+
private matchPseudoItem(
|
171
|
+
element: IElement,
|
172
|
+
parentChildren: IElement[],
|
173
|
+
pseudo: ISelectorPseudo
|
174
|
+
): boolean {
|
175
|
+
switch (pseudo.name) {
|
176
|
+
case 'first-child':
|
177
|
+
return parentChildren[0] === element;
|
178
|
+
case 'last-child':
|
179
|
+
return parentChildren.length && parentChildren[parentChildren.length - 1] === element;
|
180
|
+
case 'only-child':
|
181
|
+
return parentChildren.length === 1 && parentChildren[0] === element;
|
182
|
+
case 'first-of-type':
|
183
|
+
for (const child of parentChildren) {
|
184
|
+
if (child[PropertySymbol.tagName] === element[PropertySymbol.tagName]) {
|
185
|
+
return child === element;
|
167
186
|
}
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
187
|
+
}
|
188
|
+
return false;
|
189
|
+
case 'last-of-type':
|
190
|
+
for (let i = parentChildren.length - 1; i >= 0; i--) {
|
191
|
+
const child = parentChildren[i];
|
192
|
+
if (child[PropertySymbol.tagName] === element[PropertySymbol.tagName]) {
|
193
|
+
return child === element;
|
175
194
|
}
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
isFound = true;
|
195
|
+
}
|
196
|
+
return false;
|
197
|
+
case 'only-of-type':
|
198
|
+
let isFound = false;
|
199
|
+
for (const child of parentChildren) {
|
200
|
+
if (child[PropertySymbol.tagName] === element[PropertySymbol.tagName]) {
|
201
|
+
if (isFound || child !== element) {
|
202
|
+
return false;
|
185
203
|
}
|
204
|
+
isFound = true;
|
186
205
|
}
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
206
|
+
}
|
207
|
+
return isFound;
|
208
|
+
case 'checked':
|
209
|
+
return element[PropertySymbol.tagName] === 'INPUT' && (<IHTMLInputElement>element).checked;
|
210
|
+
case 'empty':
|
211
|
+
return !(<Element>element)[PropertySymbol.children].length;
|
212
|
+
case 'root':
|
213
|
+
return element[PropertySymbol.tagName] === 'HTML';
|
214
|
+
case 'not':
|
215
|
+
return !pseudo.selectorItem.match(element);
|
216
|
+
case 'nth-child':
|
217
|
+
const nthChildIndex = pseudo.selectorItem
|
218
|
+
? parentChildren.filter((child) => pseudo.selectorItem.match(child)).indexOf(element)
|
219
|
+
: parentChildren.indexOf(element);
|
220
|
+
return nthChildIndex !== -1 && pseudo.nthFunction(nthChildIndex + 1);
|
221
|
+
case 'nth-of-type':
|
222
|
+
if (!element[PropertySymbol.parentNode]) {
|
223
|
+
return false;
|
224
|
+
}
|
225
|
+
const nthOfTypeIndex = parentChildren
|
226
|
+
.filter((child) => child[PropertySymbol.tagName] === element[PropertySymbol.tagName])
|
227
|
+
.indexOf(element);
|
228
|
+
return nthOfTypeIndex !== -1 && pseudo.nthFunction(nthOfTypeIndex + 1);
|
229
|
+
case 'nth-last-child':
|
230
|
+
const nthLastChildIndex = pseudo.selectorItem
|
231
|
+
? parentChildren
|
232
|
+
.filter((child) => pseudo.selectorItem.match(child))
|
233
|
+
.reverse()
|
234
|
+
.indexOf(element)
|
235
|
+
: parentChildren.reverse().indexOf(element);
|
236
|
+
return nthLastChildIndex !== -1 && pseudo.nthFunction(nthLastChildIndex + 1);
|
237
|
+
case 'nth-last-of-type':
|
238
|
+
const nthLastOfTypeIndex = parentChildren
|
239
|
+
.filter((child) => child[PropertySymbol.tagName] === element[PropertySymbol.tagName])
|
240
|
+
.reverse()
|
241
|
+
.indexOf(element);
|
242
|
+
return nthLastOfTypeIndex !== -1 && pseudo.nthFunction(nthLastOfTypeIndex + 1);
|
243
|
+
case 'target':
|
244
|
+
const hash = element[PropertySymbol.ownerDocument].location.hash;
|
245
|
+
if (!hash) {
|
246
|
+
return false;
|
247
|
+
}
|
248
|
+
return element.isConnected && element.id === hash.slice(1);
|
249
|
+
default:
|
250
|
+
return false;
|
232
251
|
}
|
233
|
-
|
234
|
-
return true;
|
235
252
|
}
|
236
253
|
|
237
254
|
/**
|
@@ -114,7 +114,7 @@ export default class XMLParser {
|
|
114
114
|
// Therefore we need to auto-close the tag, so that it become valid (e.g. "<a></a><a></a>").
|
115
115
|
if (
|
116
116
|
config?.contentModel ===
|
117
|
-
HTMLElementConfigContentModelEnum.
|
117
|
+
HTMLElementConfigContentModelEnum.noFirstLevelSelfDescendants &&
|
118
118
|
stackTagNames[stackTagNames.length - 1] === tagName
|
119
119
|
) {
|
120
120
|
stack.pop();
|