happy-dom 14.3.10 → 14.5.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/PropertySymbol.cjs +2 -1
- package/cjs/PropertySymbol.cjs.map +1 -1
- package/cjs/PropertySymbol.d.ts +1 -0
- package/cjs/PropertySymbol.d.ts.map +1 -1
- package/cjs/fetch/Request.cjs +28 -14
- package/cjs/fetch/Request.cjs.map +1 -1
- package/cjs/fetch/Request.d.ts.map +1 -1
- package/cjs/fetch/Response.cjs +26 -19
- package/cjs/fetch/Response.cjs.map +1 -1
- package/cjs/fetch/Response.d.ts.map +1 -1
- package/cjs/nodes/html-iframe-element/HTMLIFrameElement.cjs +9 -6
- package/cjs/nodes/html-iframe-element/HTMLIFrameElement.cjs.map +1 -1
- package/cjs/nodes/html-iframe-element/HTMLIFrameElement.d.ts +4 -4
- package/cjs/nodes/html-iframe-element/HTMLIFrameElement.d.ts.map +1 -1
- package/cjs/nodes/html-iframe-element/HTMLIFrameElementNamedNodeMap.cjs +43 -2
- package/cjs/nodes/html-iframe-element/HTMLIFrameElementNamedNodeMap.cjs.map +1 -1
- package/cjs/nodes/html-iframe-element/HTMLIFrameElementNamedNodeMap.d.ts.map +1 -1
- package/lib/PropertySymbol.d.ts +1 -0
- package/lib/PropertySymbol.d.ts.map +1 -1
- package/lib/PropertySymbol.js +1 -0
- package/lib/PropertySymbol.js.map +1 -1
- package/lib/fetch/Request.d.ts.map +1 -1
- package/lib/fetch/Request.js +28 -14
- package/lib/fetch/Request.js.map +1 -1
- package/lib/fetch/Response.d.ts.map +1 -1
- package/lib/fetch/Response.js +26 -19
- package/lib/fetch/Response.js.map +1 -1
- package/lib/nodes/html-iframe-element/HTMLIFrameElement.d.ts +4 -4
- package/lib/nodes/html-iframe-element/HTMLIFrameElement.d.ts.map +1 -1
- package/lib/nodes/html-iframe-element/HTMLIFrameElement.js +9 -6
- package/lib/nodes/html-iframe-element/HTMLIFrameElement.js.map +1 -1
- package/lib/nodes/html-iframe-element/HTMLIFrameElementNamedNodeMap.d.ts.map +1 -1
- package/lib/nodes/html-iframe-element/HTMLIFrameElementNamedNodeMap.js +43 -2
- package/lib/nodes/html-iframe-element/HTMLIFrameElementNamedNodeMap.js.map +1 -1
- package/package.json +1 -1
- package/src/PropertySymbol.ts +1 -0
- package/src/fetch/Request.ts +38 -17
- package/src/fetch/Response.ts +36 -21
- package/src/nodes/html-iframe-element/HTMLIFrameElement.ts +8 -6
- package/src/nodes/html-iframe-element/HTMLIFrameElementNamedNodeMap.ts +60 -0
package/src/fetch/Response.ts
CHANGED
@@ -225,37 +225,52 @@ export default class Response implements Response {
|
|
225
225
|
*/
|
226
226
|
public async formData(): Promise<FormData> {
|
227
227
|
const contentType = this.headers.get('Content-Type');
|
228
|
+
const asyncTaskManager = this.#browserFrame[PropertySymbol.asyncTaskManager];
|
229
|
+
|
230
|
+
if (/multipart/i.test(contentType)) {
|
231
|
+
if (this.bodyUsed) {
|
232
|
+
throw new DOMException(
|
233
|
+
`Body has already been used for "${this.url}".`,
|
234
|
+
DOMExceptionNameEnum.invalidStateError
|
235
|
+
);
|
236
|
+
}
|
228
237
|
|
229
|
-
|
230
|
-
const formData = new FormData();
|
231
|
-
const text = await this.text();
|
232
|
-
const parameters = new URLSearchParams(text);
|
238
|
+
(<boolean>this.bodyUsed) = true;
|
233
239
|
|
234
|
-
|
235
|
-
|
240
|
+
const taskID = asyncTaskManager.startTask();
|
241
|
+
let formData: FormData;
|
242
|
+
let buffer: Buffer;
|
243
|
+
|
244
|
+
try {
|
245
|
+
const result = await MultipartFormDataParser.streamToFormData(this.body, contentType);
|
246
|
+
formData = result.formData;
|
247
|
+
buffer = result.buffer;
|
248
|
+
} catch (error) {
|
249
|
+
asyncTaskManager.endTask(taskID);
|
250
|
+
throw error;
|
236
251
|
}
|
237
252
|
|
253
|
+
this.#storeBodyInCache(buffer);
|
254
|
+
asyncTaskManager.endTask(taskID);
|
255
|
+
|
238
256
|
return formData;
|
239
257
|
}
|
240
258
|
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
try {
|
246
|
-
const result = await MultipartFormDataParser.streamToFormData(this.body, contentType);
|
247
|
-
formData = result.formData;
|
248
|
-
buffer = result.buffer;
|
249
|
-
} catch (error) {
|
250
|
-
this.#browserFrame[PropertySymbol.asyncTaskManager].endTask(taskID);
|
251
|
-
throw error;
|
252
|
-
}
|
259
|
+
if (contentType?.startsWith('application/x-www-form-urlencoded')) {
|
260
|
+
const parameters = new URLSearchParams(await this.text());
|
261
|
+
const formData = new FormData();
|
253
262
|
|
254
|
-
|
263
|
+
for (const [key, value] of parameters) {
|
264
|
+
formData.append(key, value);
|
265
|
+
}
|
255
266
|
|
256
|
-
|
267
|
+
return formData;
|
268
|
+
}
|
257
269
|
|
258
|
-
|
270
|
+
throw new DOMException(
|
271
|
+
`Failed to build FormData object: The "content-type" header is neither "application/x-www-form-urlencoded" nor "multipart/form-data".`,
|
272
|
+
DOMExceptionNameEnum.invalidStateError
|
273
|
+
);
|
259
274
|
}
|
260
275
|
|
261
276
|
/**
|
@@ -9,6 +9,7 @@ import HTMLIFrameElementNamedNodeMap from './HTMLIFrameElementNamedNodeMap.js';
|
|
9
9
|
import CrossOriginBrowserWindow from '../../window/CrossOriginBrowserWindow.js';
|
10
10
|
import IBrowserFrame from '../../browser/types/IBrowserFrame.js';
|
11
11
|
import HTMLIFrameElementPageLoader from './HTMLIFrameElementPageLoader.js';
|
12
|
+
import DOMTokenList from '../../dom-token-list/DOMTokenList.js';
|
12
13
|
|
13
14
|
/**
|
14
15
|
* HTML Iframe Element.
|
@@ -23,7 +24,7 @@ export default class HTMLIFrameElement extends HTMLElement {
|
|
23
24
|
|
24
25
|
// Internal properties
|
25
26
|
public override [PropertySymbol.attributes]: NamedNodeMap;
|
26
|
-
|
27
|
+
public [PropertySymbol.sandbox]: DOMTokenList = null;
|
27
28
|
// Private properties
|
28
29
|
#contentWindowContainer: { window: BrowserWindow | CrossOriginBrowserWindow | null } = {
|
29
30
|
window: null
|
@@ -140,14 +141,15 @@ export default class HTMLIFrameElement extends HTMLElement {
|
|
140
141
|
*
|
141
142
|
* @returns Sandbox.
|
142
143
|
*/
|
143
|
-
public get sandbox():
|
144
|
-
|
144
|
+
public get sandbox(): DOMTokenList {
|
145
|
+
if (!this[PropertySymbol.sandbox]) {
|
146
|
+
this[PropertySymbol.sandbox] = new DOMTokenList(this, 'sandbox');
|
147
|
+
}
|
148
|
+
return <DOMTokenList>this[PropertySymbol.sandbox];
|
145
149
|
}
|
146
150
|
|
147
151
|
/**
|
148
152
|
* Sets sandbox.
|
149
|
-
*
|
150
|
-
* @param sandbox Sandbox.
|
151
153
|
*/
|
152
154
|
public set sandbox(sandbox: string) {
|
153
155
|
this.setAttribute('sandbox', sandbox);
|
@@ -163,7 +165,7 @@ export default class HTMLIFrameElement extends HTMLElement {
|
|
163
165
|
}
|
164
166
|
|
165
167
|
/**
|
166
|
-
* Sets
|
168
|
+
* Sets srcdoc.
|
167
169
|
*
|
168
170
|
* @param srcdoc Srcdoc.
|
169
171
|
*/
|
@@ -3,6 +3,23 @@ import Element from '../element/Element.js';
|
|
3
3
|
import HTMLElementNamedNodeMap from '../html-element/HTMLElementNamedNodeMap.js';
|
4
4
|
import HTMLIFrameElementPageLoader from './HTMLIFrameElementPageLoader.js';
|
5
5
|
import * as PropertySymbol from '../../PropertySymbol.js';
|
6
|
+
import DOMTokenList from '../../dom-token-list/DOMTokenList.js';
|
7
|
+
|
8
|
+
const SANDBOX_FLAGS = [
|
9
|
+
'allow-downloads',
|
10
|
+
'allow-forms',
|
11
|
+
'allow-modals',
|
12
|
+
'allow-orientation-lock',
|
13
|
+
'allow-pointer-lock',
|
14
|
+
'allow-popups',
|
15
|
+
'allow-popups-to-escape-sandbox',
|
16
|
+
'allow-presentation',
|
17
|
+
'allow-same-origin',
|
18
|
+
'allow-scripts',
|
19
|
+
'allow-top-navigation',
|
20
|
+
'allow-top-navigation-by-user-activation',
|
21
|
+
'allow-top-navigation-to-custom-protocols'
|
22
|
+
];
|
6
23
|
|
7
24
|
/**
|
8
25
|
* Named Node Map.
|
@@ -37,6 +54,49 @@ export default class HTMLIFrameElementNamedNodeMap extends HTMLElementNamedNodeM
|
|
37
54
|
this.#pageLoader.loadPage();
|
38
55
|
}
|
39
56
|
|
57
|
+
if (item[PropertySymbol.name] === 'sandbox') {
|
58
|
+
if (!this[PropertySymbol.ownerElement][PropertySymbol.sandbox]) {
|
59
|
+
this[PropertySymbol.ownerElement][PropertySymbol.sandbox] = new DOMTokenList(
|
60
|
+
this[PropertySymbol.ownerElement],
|
61
|
+
'sandbox'
|
62
|
+
);
|
63
|
+
} else {
|
64
|
+
this[PropertySymbol.ownerElement][PropertySymbol.sandbox][PropertySymbol.updateIndices]();
|
65
|
+
}
|
66
|
+
|
67
|
+
this.#validateSandboxFlags();
|
68
|
+
}
|
69
|
+
|
40
70
|
return replacedAttribute || null;
|
41
71
|
}
|
72
|
+
|
73
|
+
/**
|
74
|
+
*
|
75
|
+
* @param tokens
|
76
|
+
* @param vconsole
|
77
|
+
*/
|
78
|
+
#validateSandboxFlags(): void {
|
79
|
+
const window =
|
80
|
+
this[PropertySymbol.ownerElement][PropertySymbol.ownerDocument][PropertySymbol.ownerWindow];
|
81
|
+
const values = this[PropertySymbol.ownerElement][PropertySymbol.sandbox].values();
|
82
|
+
const invalidFlags: string[] = [];
|
83
|
+
|
84
|
+
for (const token of values) {
|
85
|
+
if (!SANDBOX_FLAGS.includes(token)) {
|
86
|
+
invalidFlags.push(token);
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
if (invalidFlags.length === 1) {
|
91
|
+
window.console.error(
|
92
|
+
`Error while parsing the 'sandbox' attribute: '${invalidFlags[0]}' is an invalid sandbox flag.`
|
93
|
+
);
|
94
|
+
} else if (invalidFlags.length > 1) {
|
95
|
+
window.console.error(
|
96
|
+
`Error while parsing the 'sandbox' attribute: '${invalidFlags.join(
|
97
|
+
`', '`
|
98
|
+
)}' are invalid sandbox flags.`
|
99
|
+
);
|
100
|
+
}
|
101
|
+
}
|
42
102
|
}
|