happy-dom 9.10.8 → 9.11.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.

Files changed (64) hide show
  1. package/lib/config/PlainTextElements.d.ts +4 -1
  2. package/lib/config/PlainTextElements.d.ts.map +1 -1
  3. package/lib/config/PlainTextElements.js +4 -1
  4. package/lib/config/PlainTextElements.js.map +1 -1
  5. package/lib/config/UnnestableElements.d.ts +18 -1
  6. package/lib/config/UnnestableElements.d.ts.map +1 -1
  7. package/lib/config/UnnestableElements.js +18 -18
  8. package/lib/config/UnnestableElements.js.map +1 -1
  9. package/lib/config/VoidElements.d.ts +16 -1
  10. package/lib/config/VoidElements.d.ts.map +1 -1
  11. package/lib/config/VoidElements.js +16 -17
  12. package/lib/config/VoidElements.js.map +1 -1
  13. package/lib/dom-parser/DOMParser.js +2 -2
  14. package/lib/dom-parser/DOMParser.js.map +1 -1
  15. package/lib/fetch/Request.d.ts +7 -0
  16. package/lib/fetch/Request.d.ts.map +1 -1
  17. package/lib/fetch/Request.js +25 -0
  18. package/lib/fetch/Request.js.map +1 -1
  19. package/lib/fetch/types/IRequest.d.ts +7 -0
  20. package/lib/fetch/types/IRequest.d.ts.map +1 -1
  21. package/lib/nodes/document/Document.d.ts.map +1 -1
  22. package/lib/nodes/document/Document.js +19 -18
  23. package/lib/nodes/document/Document.js.map +1 -1
  24. package/lib/nodes/element/Element.d.ts.map +1 -1
  25. package/lib/nodes/element/Element.js +1 -3
  26. package/lib/nodes/element/Element.js.map +1 -1
  27. package/lib/nodes/html-template-element/HTMLTemplateElement.d.ts.map +1 -1
  28. package/lib/nodes/html-template-element/HTMLTemplateElement.js +2 -4
  29. package/lib/nodes/html-template-element/HTMLTemplateElement.js.map +1 -1
  30. package/lib/nodes/parent-node/ParentNodeUtility.d.ts +3 -3
  31. package/lib/nodes/parent-node/ParentNodeUtility.d.ts.map +1 -1
  32. package/lib/nodes/parent-node/ParentNodeUtility.js +1 -4
  33. package/lib/nodes/parent-node/ParentNodeUtility.js.map +1 -1
  34. package/lib/nodes/shadow-root/ShadowRoot.d.ts.map +1 -1
  35. package/lib/nodes/shadow-root/ShadowRoot.js +1 -3
  36. package/lib/nodes/shadow-root/ShadowRoot.js.map +1 -1
  37. package/lib/range/Range.js.map +1 -1
  38. package/lib/xml-parser/XMLParser.d.ts +14 -38
  39. package/lib/xml-parser/XMLParser.d.ts.map +1 -1
  40. package/lib/xml-parser/XMLParser.js +222 -200
  41. package/lib/xml-parser/XMLParser.js.map +1 -1
  42. package/lib/xml-serializer/XMLSerializer.d.ts.map +1 -1
  43. package/lib/xml-serializer/XMLSerializer.js +11 -7
  44. package/lib/xml-serializer/XMLSerializer.js.map +1 -1
  45. package/package.json +1 -1
  46. package/src/config/PlainTextElements.ts +4 -1
  47. package/src/config/UnnestableElements.ts +18 -18
  48. package/src/config/VoidElements.ts +16 -17
  49. package/src/dom-parser/DOMParser.ts +2 -2
  50. package/src/fetch/Request.ts +34 -0
  51. package/src/fetch/types/IRequest.ts +8 -0
  52. package/src/nodes/document/Document.ts +19 -18
  53. package/src/nodes/element/Element.ts +1 -3
  54. package/src/nodes/html-template-element/HTMLTemplateElement.ts +2 -4
  55. package/src/nodes/parent-node/ParentNodeUtility.ts +13 -11
  56. package/src/nodes/shadow-root/ShadowRoot.ts +1 -3
  57. package/src/range/Range.ts +1 -1
  58. package/src/xml-parser/XMLParser.ts +280 -226
  59. package/src/xml-serializer/XMLSerializer.ts +12 -7
  60. package/lib/config/ChildLessElements.d.ts +0 -3
  61. package/lib/config/ChildLessElements.d.ts.map +0 -1
  62. package/lib/config/ChildLessElements.js +0 -4
  63. package/lib/config/ChildLessElements.js.map +0 -1
  64. package/src/config/ChildLessElements.ts +0 -1
@@ -1,18 +1,18 @@
1
- export default [
2
- 'a',
3
- 'button',
4
- 'dd',
5
- 'dt',
6
- 'form',
7
- 'h1',
8
- 'h2',
9
- 'h3',
10
- 'h4',
11
- 'h5',
12
- 'h6',
13
- 'li',
14
- 'option',
15
- 'p',
16
- 'select',
17
- 'table'
18
- ];
1
+ export default {
2
+ A: true,
3
+ BUTTON: true,
4
+ DD: true,
5
+ DT: true,
6
+ FORM: true,
7
+ H1: true,
8
+ H2: true,
9
+ H3: true,
10
+ H4: true,
11
+ H5: true,
12
+ H6: true,
13
+ LI: true,
14
+ OPTION: true,
15
+ P: true,
16
+ SELECT: true,
17
+ TABLE: true
18
+ };
@@ -1,17 +1,16 @@
1
- export default [
2
- 'area',
3
- 'base',
4
- 'br',
5
- 'col',
6
- 'embed',
7
- 'hr',
8
- 'img',
9
- 'input',
10
- 'link',
11
- 'meta',
12
- 'param',
13
- 'source',
14
- 'track',
15
- 'wbr',
16
- 'meta'
17
- ];
1
+ export default {
2
+ AREA: true,
3
+ BASE: true,
4
+ BR: true,
5
+ COL: true,
6
+ EMBED: true,
7
+ HR: true,
8
+ IMG: true,
9
+ INPUT: true,
10
+ LINK: true,
11
+ META: true,
12
+ PARAM: true,
13
+ SOURCE: true,
14
+ TRACK: true,
15
+ WBR: true
16
+ };
@@ -44,7 +44,7 @@ export default class DOMParser {
44
44
  newDocument.childNodes.length = 0;
45
45
  newDocument.children.length = 0;
46
46
 
47
- const root = XMLParser.parse(newDocument, string, true);
47
+ const root = XMLParser.parse(newDocument, string, { evaluateScripts: true });
48
48
  let documentElement = null;
49
49
  let documentTypeNode = null;
50
50
 
@@ -65,7 +65,7 @@ export default class DOMParser {
65
65
  newDocument.appendChild(documentTypeNode);
66
66
  }
67
67
  newDocument.appendChild(documentElement);
68
- const body = newDocument.querySelector('body');
68
+ const body = newDocument.body;
69
69
  if (body) {
70
70
  for (const child of root.childNodes.slice()) {
71
71
  body.appendChild(child);
@@ -18,6 +18,8 @@ import IRequestRedirect from './types/IRequestRedirect';
18
18
  import FetchRequestReferrerUtility from './utilities/FetchRequestReferrerUtility';
19
19
  import FetchRequestHeaderUtility from './utilities/FetchRequestHeaderUtility';
20
20
  import IRequestCredentials from './types/IRequestCredentials';
21
+ import FormData from '../form-data/FormData';
22
+ import MultipartFormDataParser from './multipart/MultipartFormDataParser';
21
23
 
22
24
  /**
23
25
  * Fetch request.
@@ -280,6 +282,38 @@ export default class Request implements IRequest {
280
282
  return JSON.parse(text);
281
283
  }
282
284
 
285
+ /**
286
+ * Returns FormData.
287
+ *
288
+ * @returns FormData.
289
+ */
290
+ public async formData(): Promise<FormData> {
291
+ if (this.bodyUsed) {
292
+ throw new DOMException(
293
+ `Body has already been used for "${this.url}".`,
294
+ DOMExceptionNameEnum.invalidStateError
295
+ );
296
+ }
297
+
298
+ (<boolean>this.bodyUsed) = true;
299
+
300
+ const taskManager = this._ownerDocument.defaultView.happyDOM.asyncTaskManager;
301
+ const taskID = taskManager.startTask(() => this.signal._abort());
302
+ let formData: FormData;
303
+
304
+ try {
305
+ const type = this._contentType;
306
+ formData = await MultipartFormDataParser.streamToFormData(this.body, type);
307
+ } catch (error) {
308
+ taskManager.endTask(taskID);
309
+ throw error;
310
+ }
311
+
312
+ taskManager.endTask(taskID);
313
+
314
+ return formData;
315
+ }
316
+
283
317
  /**
284
318
  * Clones request.
285
319
  *
@@ -5,6 +5,7 @@ import Stream from 'stream';
5
5
  import IRequestReferrerPolicy from './IRequestReferrerPolicy';
6
6
  import IRequestRedirect from './IRequestRedirect';
7
7
  import IRequestCredentials from './IRequestCredentials';
8
+ import FormData from '../../form-data/FormData';
8
9
 
9
10
  /**
10
11
  * Fetch request.
@@ -56,6 +57,13 @@ export default interface IRequest {
56
57
  */
57
58
  json(): Promise<string>;
58
59
 
60
+ /**
61
+ * Returns FormData.
62
+ *
63
+ * @returns FormData.
64
+ */
65
+ formData(): Promise<FormData>;
66
+
59
67
  /**
60
68
  * Clones request.
61
69
  *
@@ -236,9 +236,9 @@ export default class Document extends Node implements IDocument {
236
236
  * @returns Title.
237
237
  */
238
238
  public get title(): string {
239
- const el = this.querySelector('title');
240
- if (el) {
241
- return el.textContent;
239
+ const element = ParentNodeUtility.getElementByTagName(this, 'title');
240
+ if (element) {
241
+ return element.textContent;
242
242
  }
243
243
  return '';
244
244
  }
@@ -248,13 +248,13 @@ export default class Document extends Node implements IDocument {
248
248
  *
249
249
  */
250
250
  public set title(title: string) {
251
- const el = this.querySelector('title');
252
- if (el) {
253
- el.textContent = title;
251
+ const element = ParentNodeUtility.getElementByTagName(this, 'title');
252
+ if (element) {
253
+ element.textContent = title;
254
254
  } else {
255
- const titleEl = this.createElement('title');
256
- titleEl.textContent = title;
257
- this.head.appendChild(titleEl);
255
+ const newElement = this.createElement('title');
256
+ newElement.textContent = title;
257
+ this.head.appendChild(newElement);
258
258
  }
259
259
  }
260
260
 
@@ -430,9 +430,9 @@ export default class Document extends Node implements IDocument {
430
430
  * @returns Base URI.
431
431
  */
432
432
  public get baseURI(): string {
433
- const base = <IHTMLBaseElement>this.querySelector('base');
434
- if (base) {
435
- return base.href;
433
+ const element = <IHTMLBaseElement | null>ParentNodeUtility.getElementByTagName(this, 'base');
434
+ if (element) {
435
+ return element.href;
436
436
  }
437
437
  return this.defaultView.location.href;
438
438
  }
@@ -653,7 +653,7 @@ export default class Document extends Node implements IDocument {
653
653
  * @param html HTML.
654
654
  */
655
655
  public write(html: string): void {
656
- const root = XMLParser.parse(this, html, true);
656
+ const root = XMLParser.parse(this, html, { evaluateScripts: true });
657
657
 
658
658
  if (this._isFirstWrite || this._isFirstWriteAfterOpen) {
659
659
  if (this._isFirstWrite) {
@@ -688,8 +688,8 @@ export default class Document extends Node implements IDocument {
688
688
 
689
689
  this.appendChild(documentElement);
690
690
  } else {
691
- const rootBody = root.querySelector('body');
692
- const body = this.querySelector('body');
691
+ const rootBody = ParentNodeUtility.getElementByTagName(root, 'body');
692
+ const body = ParentNodeUtility.getElementByTagName(this, 'body');
693
693
  if (rootBody && body) {
694
694
  for (const child of rootBody.childNodes.slice()) {
695
695
  body.appendChild(child);
@@ -697,7 +697,7 @@ export default class Document extends Node implements IDocument {
697
697
  }
698
698
  }
699
699
 
700
- const body = this.querySelector('body');
700
+ const body = ParentNodeUtility.getElementByTagName(this, 'body');
701
701
  if (body) {
702
702
  for (const child of root.childNodes.slice()) {
703
703
  if (child['tagName'] !== 'HTML' && child.nodeType !== Node.DOCUMENT_TYPE_NODE) {
@@ -720,9 +720,10 @@ export default class Document extends Node implements IDocument {
720
720
  this.appendChild(documentElement);
721
721
  }
722
722
  } else {
723
- const bodyNode = root.querySelector('body');
723
+ const bodyNode = ParentNodeUtility.getElementByTagName(root, 'body');
724
+ const body = ParentNodeUtility.getElementByTagName(this, 'body');
724
725
  for (const child of (bodyNode || root).childNodes.slice()) {
725
- this.body.appendChild(child);
726
+ body.appendChild(child);
726
727
  }
727
728
  }
728
729
  }
@@ -244,9 +244,7 @@ export default class Element extends Node implements IElement {
244
244
  this.removeChild(child);
245
245
  }
246
246
 
247
- for (const node of XMLParser.parse(this.ownerDocument, html).childNodes.slice()) {
248
- this.appendChild(node);
249
- }
247
+ XMLParser.parse(this.ownerDocument, html, { rootNode: this });
250
248
  }
251
249
 
252
250
  /**
@@ -2,8 +2,8 @@ import HTMLElement from '../html-element/HTMLElement';
2
2
  import IDocumentFragment from '../document-fragment/IDocumentFragment';
3
3
  import INode from '../node/INode';
4
4
  import IHTMLTemplateElement from './IHTMLTemplateElement';
5
- import XMLParser from '../../xml-parser/XMLParser';
6
5
  import XMLSerializer from '../../xml-serializer/XMLSerializer';
6
+ import XMLParser from '../../xml-parser/XMLParser';
7
7
 
8
8
  /**
9
9
  * HTML Template Element.
@@ -29,9 +29,7 @@ export default class HTMLTemplateElement extends HTMLElement implements IHTMLTem
29
29
  this.content.removeChild(child);
30
30
  }
31
31
 
32
- for (const node of XMLParser.parse(this.ownerDocument, html).childNodes.slice()) {
33
- this.content.appendChild(node);
34
- }
32
+ XMLParser.parse(this.ownerDocument, html, { rootNode: this.content });
35
33
  }
36
34
 
37
35
  /**
@@ -16,16 +16,13 @@ export default class ParentNodeUtility {
16
16
  * @param parentNode Parent node.
17
17
  * @param nodes List of Node or DOMString.
18
18
  */
19
- public static append(parentNode: INode, ...nodes: (INode | string)[]): void {
19
+ public static append(
20
+ parentNode: IElement | IDocument | IDocumentFragment,
21
+ ...nodes: (INode | string)[]
22
+ ): void {
20
23
  for (const node of nodes) {
21
24
  if (typeof node === 'string') {
22
- const newChildNodes = XMLParser.parse(
23
- <IDocument>parentNode.ownerDocument,
24
- node
25
- ).childNodes.slice();
26
- for (const newChildNode of newChildNodes) {
27
- parentNode.appendChild(newChildNode);
28
- }
25
+ XMLParser.parse(<IDocument>parentNode.ownerDocument, node, { rootNode: parentNode });
29
26
  } else {
30
27
  parentNode.appendChild(node);
31
28
  }
@@ -38,9 +35,11 @@ export default class ParentNodeUtility {
38
35
  * @param parentNode Parent node.
39
36
  * @param nodes List of Node or DOMString.
40
37
  */
41
- public static prepend(parentNode: INode, ...nodes: (string | INode)[]): void {
38
+ public static prepend(
39
+ parentNode: IElement | IDocument | IDocumentFragment,
40
+ ...nodes: (string | INode)[]
41
+ ): void {
42
42
  const firstChild = parentNode.firstChild;
43
-
44
43
  for (const node of nodes) {
45
44
  if (typeof node === 'string') {
46
45
  const newChildNodes = XMLParser.parse(
@@ -62,7 +61,10 @@ export default class ParentNodeUtility {
62
61
  * @param parentNode Parent node.
63
62
  * @param nodes List of Node or DOMString.
64
63
  */
65
- public static replaceChildren(parentNode: INode, ...nodes: (string | INode)[]): void {
64
+ public static replaceChildren(
65
+ parentNode: IElement | IDocument | IDocumentFragment,
66
+ ...nodes: (string | INode)[]
67
+ ): void {
66
68
  for (const node of parentNode.childNodes.slice()) {
67
69
  parentNode.removeChild(node);
68
70
  }
@@ -42,9 +42,7 @@ export default class ShadowRoot extends DocumentFragment implements IShadowRoot
42
42
  this.removeChild(child);
43
43
  }
44
44
 
45
- for (const node of XMLParser.parse(this.ownerDocument, html).childNodes.slice()) {
46
- this.appendChild(node);
47
- }
45
+ XMLParser.parse(this.ownerDocument, html, { rootNode: this });
48
46
  }
49
47
 
50
48
  /**
@@ -406,7 +406,7 @@ export default class Range {
406
406
  */
407
407
  public createContextualFragment(tagString: string): IDocumentFragment {
408
408
  // TODO: We only have support for HTML in the parser currently, so it is not necessary to check which context it is
409
- return XMLParser.parse(this._ownerDocument, tagString);
409
+ return <IDocumentFragment>XMLParser.parse(this._ownerDocument, tagString);
410
410
  }
411
411
 
412
412
  /**