happy-dom 16.5.3 → 16.7.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.
Files changed (77) hide show
  1. package/cjs/browser/DefaultBrowserSettings.cjs +3 -1
  2. package/cjs/browser/DefaultBrowserSettings.cjs.map +1 -1
  3. package/cjs/browser/DefaultBrowserSettings.d.ts.map +1 -1
  4. package/cjs/browser/types/IBrowserSettings.d.ts +9 -1
  5. package/cjs/browser/types/IBrowserSettings.d.ts.map +1 -1
  6. package/cjs/browser/types/IOptionalBrowserSettings.d.ts +9 -1
  7. package/cjs/browser/types/IOptionalBrowserSettings.d.ts.map +1 -1
  8. package/cjs/fetch/Fetch.cjs +62 -9
  9. package/cjs/fetch/Fetch.cjs.map +1 -1
  10. package/cjs/fetch/Fetch.d.ts +7 -1
  11. package/cjs/fetch/Fetch.d.ts.map +1 -1
  12. package/cjs/fetch/SyncFetch.cjs +45 -1
  13. package/cjs/fetch/SyncFetch.cjs.map +1 -1
  14. package/cjs/fetch/SyncFetch.d.ts +6 -0
  15. package/cjs/fetch/SyncFetch.d.ts.map +1 -1
  16. package/cjs/fetch/types/IVirtualServer.cjs +3 -0
  17. package/cjs/fetch/types/IVirtualServer.cjs.map +1 -0
  18. package/cjs/fetch/types/IVirtualServer.d.ts +8 -0
  19. package/cjs/fetch/types/IVirtualServer.d.ts.map +1 -0
  20. package/cjs/fetch/utilities/VirtualServerUtility.cjs +83 -0
  21. package/cjs/fetch/utilities/VirtualServerUtility.cjs.map +1 -0
  22. package/cjs/fetch/utilities/VirtualServerUtility.d.ts +30 -0
  23. package/cjs/fetch/utilities/VirtualServerUtility.d.ts.map +1 -0
  24. package/cjs/query-selector/QuerySelector.cjs +39 -4
  25. package/cjs/query-selector/QuerySelector.cjs.map +1 -1
  26. package/cjs/query-selector/QuerySelector.d.ts.map +1 -1
  27. package/cjs/query-selector/SelectorCombinatorEnum.cjs +1 -0
  28. package/cjs/query-selector/SelectorCombinatorEnum.cjs.map +1 -1
  29. package/cjs/query-selector/SelectorCombinatorEnum.d.ts +2 -1
  30. package/cjs/query-selector/SelectorCombinatorEnum.d.ts.map +1 -1
  31. package/cjs/query-selector/SelectorParser.cjs +8 -1
  32. package/cjs/query-selector/SelectorParser.cjs.map +1 -1
  33. package/cjs/query-selector/SelectorParser.d.ts.map +1 -1
  34. package/lib/browser/DefaultBrowserSettings.d.ts.map +1 -1
  35. package/lib/browser/DefaultBrowserSettings.js +3 -1
  36. package/lib/browser/DefaultBrowserSettings.js.map +1 -1
  37. package/lib/browser/types/IBrowserSettings.d.ts +9 -1
  38. package/lib/browser/types/IBrowserSettings.d.ts.map +1 -1
  39. package/lib/browser/types/IOptionalBrowserSettings.d.ts +9 -1
  40. package/lib/browser/types/IOptionalBrowserSettings.d.ts.map +1 -1
  41. package/lib/fetch/Fetch.d.ts +7 -1
  42. package/lib/fetch/Fetch.d.ts.map +1 -1
  43. package/lib/fetch/Fetch.js +62 -9
  44. package/lib/fetch/Fetch.js.map +1 -1
  45. package/lib/fetch/SyncFetch.d.ts +6 -0
  46. package/lib/fetch/SyncFetch.d.ts.map +1 -1
  47. package/lib/fetch/SyncFetch.js +45 -1
  48. package/lib/fetch/SyncFetch.js.map +1 -1
  49. package/lib/fetch/types/IVirtualServer.d.ts +8 -0
  50. package/lib/fetch/types/IVirtualServer.d.ts.map +1 -0
  51. package/lib/fetch/types/IVirtualServer.js +2 -0
  52. package/lib/fetch/types/IVirtualServer.js.map +1 -0
  53. package/lib/fetch/utilities/VirtualServerUtility.d.ts +30 -0
  54. package/lib/fetch/utilities/VirtualServerUtility.d.ts.map +1 -0
  55. package/lib/fetch/utilities/VirtualServerUtility.js +77 -0
  56. package/lib/fetch/utilities/VirtualServerUtility.js.map +1 -0
  57. package/lib/query-selector/QuerySelector.d.ts.map +1 -1
  58. package/lib/query-selector/QuerySelector.js +39 -4
  59. package/lib/query-selector/QuerySelector.js.map +1 -1
  60. package/lib/query-selector/SelectorCombinatorEnum.d.ts +2 -1
  61. package/lib/query-selector/SelectorCombinatorEnum.d.ts.map +1 -1
  62. package/lib/query-selector/SelectorCombinatorEnum.js +1 -0
  63. package/lib/query-selector/SelectorCombinatorEnum.js.map +1 -1
  64. package/lib/query-selector/SelectorParser.d.ts.map +1 -1
  65. package/lib/query-selector/SelectorParser.js +8 -1
  66. package/lib/query-selector/SelectorParser.js.map +1 -1
  67. package/package.json +1 -1
  68. package/src/browser/DefaultBrowserSettings.ts +3 -1
  69. package/src/browser/types/IBrowserSettings.ts +10 -1
  70. package/src/browser/types/IOptionalBrowserSettings.ts +10 -1
  71. package/src/fetch/Fetch.ts +91 -12
  72. package/src/fetch/SyncFetch.ts +60 -1
  73. package/src/fetch/types/IVirtualServer.ts +7 -0
  74. package/src/fetch/utilities/VirtualServerUtility.ts +89 -0
  75. package/src/query-selector/QuerySelector.ts +58 -4
  76. package/src/query-selector/SelectorCombinatorEnum.ts +2 -1
  77. package/src/query-selector/SelectorParser.ts +8 -1
@@ -0,0 +1,89 @@
1
+ import BrowserWindow from '../../window/BrowserWindow.js';
2
+ import WindowBrowserContext from '../../window/WindowBrowserContext.js';
3
+ import Path from 'path';
4
+ import Response from '../Response.js';
5
+ import ISyncResponse from '../types/ISyncResponse.js';
6
+
7
+ const NOT_FOUND_HTML =
8
+ '<html><head><title>Happy DOM Virtual Server - 404 Not Found</title></head><body><h1>Happy DOM Virtual Server - 404 Not Found</h1></body></html>';
9
+
10
+ /**
11
+ * Virtual server utility.
12
+ */
13
+ export default class VirtualServerUtility {
14
+ /**
15
+ * Returns the filesystem path for a request URL if it matches a virtual server.
16
+ *
17
+ * @param window Window.
18
+ * @param requestURL Request URL.
19
+ */
20
+ public static getFilepath(window: BrowserWindow, requestURL: string): string | null {
21
+ const browserSettings = new WindowBrowserContext(window).getSettings();
22
+ if (!browserSettings || !browserSettings.fetch.virtualServers) {
23
+ return null;
24
+ }
25
+ for (const virtualServer of browserSettings.fetch.virtualServers) {
26
+ let baseURL: URL;
27
+ if (typeof virtualServer.url === 'string') {
28
+ const url = new URL(
29
+ virtualServer.url[virtualServer.url.length - 1] === '/'
30
+ ? virtualServer.url.slice(0, -1)
31
+ : virtualServer.url,
32
+ window.location.origin
33
+ );
34
+ if (requestURL.startsWith(url.href)) {
35
+ baseURL = url;
36
+ }
37
+ } else if (virtualServer.url instanceof RegExp) {
38
+ const match = requestURL.match(virtualServer.url);
39
+ if (match) {
40
+ baseURL = new URL(
41
+ match[0][match[0].length - 1] === '/' ? match[0].slice(0, -1) : match[0],
42
+ window.location.origin
43
+ );
44
+ }
45
+ }
46
+ if (baseURL) {
47
+ const path = requestURL.slice(baseURL.href.length).split('?')[0].split('#')[0];
48
+ return Path.join(Path.resolve(virtualServer.directory), path.replaceAll('/', Path.sep));
49
+ }
50
+ }
51
+ return null;
52
+ }
53
+
54
+ /**
55
+ * Returns a 404 response.
56
+ *
57
+ * @param window Window.
58
+ * @returns 404 response.
59
+ */
60
+ public static getNotFoundResponse(window: BrowserWindow): Response {
61
+ return new window.Response(NOT_FOUND_HTML, {
62
+ status: 404,
63
+ statusText: 'Not Found',
64
+ headers: {
65
+ 'Content-Type': 'text/html'
66
+ }
67
+ });
68
+ }
69
+
70
+ /**
71
+ * Returns a 404 response.
72
+ *
73
+ * @param window Window.
74
+ * @returns 404 response.
75
+ */
76
+ public static getNotFoundSyncResponse(window: BrowserWindow): ISyncResponse {
77
+ return <ISyncResponse>{
78
+ status: 404,
79
+ statusText: 'Not Found',
80
+ ok: false,
81
+ url: null,
82
+ redirected: false,
83
+ headers: new window.Headers({
84
+ 'Content-Type': 'text/html'
85
+ }),
86
+ body: Buffer.from(NOT_FOUND_HTML)
87
+ };
88
+ }
89
+ }
@@ -387,6 +387,7 @@ export default class QuerySelector {
387
387
  const previousElementSibling = element.previousElementSibling;
388
388
  if (previousElementSibling) {
389
389
  previousElementSibling[PropertySymbol.affectsCache].push(cachedItem);
390
+
390
391
  const match = this.matchSelector(
391
392
  previousElementSibling,
392
393
  selectorItems.slice(1),
@@ -419,6 +420,33 @@ export default class QuerySelector {
419
420
  }
420
421
  }
421
422
  break;
423
+ case SelectorCombinatorEnum.subsequentSibling:
424
+ const siblingParentElement = element.parentElement;
425
+ if (siblingParentElement) {
426
+ const siblings = siblingParentElement[PropertySymbol.elementArray];
427
+ const index = siblings.indexOf(element);
428
+
429
+ siblingParentElement[PropertySymbol.affectsCache].push(cachedItem);
430
+
431
+ for (let i = index - 1; i >= 0; i--) {
432
+ const sibling = siblings[i];
433
+
434
+ sibling[PropertySymbol.affectsCache].push(cachedItem);
435
+
436
+ const match = this.matchSelector(
437
+ sibling,
438
+ selectorItems.slice(1),
439
+ cachedItem,
440
+ selectorItem,
441
+ priorityWeight + result.priorityWeight
442
+ );
443
+
444
+ if (match) {
445
+ return match;
446
+ }
447
+ }
448
+ }
449
+ break;
422
450
  }
423
451
  }
424
452
 
@@ -477,11 +505,12 @@ export default class QuerySelector {
477
505
  } else {
478
506
  switch (nextSelectorItem.combinator) {
479
507
  case SelectorCombinatorEnum.adjacentSibling:
480
- if (child.nextElementSibling) {
508
+ const nextElementSibling = child.nextElementSibling;
509
+ if (nextElementSibling) {
481
510
  matched = matched.concat(
482
511
  this.findAll(
483
512
  rootElement,
484
- [child.nextElementSibling],
513
+ [nextElementSibling],
485
514
  selectorItems.slice(1),
486
515
  cachedItem,
487
516
  position
@@ -501,6 +530,15 @@ export default class QuerySelector {
501
530
  )
502
531
  );
503
532
  break;
533
+ case SelectorCombinatorEnum.subsequentSibling:
534
+ const index = children.indexOf(child);
535
+ for (let j = index + 1; j < children.length; j++) {
536
+ const sibling = children[j];
537
+ matched = matched.concat(
538
+ this.findAll(rootElement, [sibling], selectorItems.slice(1), cachedItem, position)
539
+ );
540
+ }
541
+ break;
504
542
  }
505
543
  }
506
544
  }
@@ -546,10 +584,11 @@ export default class QuerySelector {
546
584
  } else {
547
585
  switch (nextSelectorItem.combinator) {
548
586
  case SelectorCombinatorEnum.adjacentSibling:
549
- if (child.nextElementSibling) {
587
+ const nextElementSibling = child.nextElementSibling;
588
+ if (nextElementSibling) {
550
589
  const match = this.findFirst(
551
590
  rootElement,
552
- [child.nextElementSibling],
591
+ [nextElementSibling],
553
592
  selectorItems.slice(1),
554
593
  cachedItem
555
594
  );
@@ -570,6 +609,21 @@ export default class QuerySelector {
570
609
  return match;
571
610
  }
572
611
  break;
612
+ case SelectorCombinatorEnum.subsequentSibling:
613
+ const index = children.indexOf(child);
614
+ for (let i = index + 1; i < children.length; i++) {
615
+ const sibling = children[i];
616
+ const match = this.findFirst(
617
+ rootElement,
618
+ [sibling],
619
+ selectorItems.slice(1),
620
+ cachedItem
621
+ );
622
+ if (match) {
623
+ return match;
624
+ }
625
+ }
626
+ break;
573
627
  }
574
628
  }
575
629
  }
@@ -1,7 +1,8 @@
1
1
  enum SelectorCombinatorEnum {
2
2
  descendant = 'descendant',
3
3
  child = 'child',
4
- adjacentSibling = 'adjacentSibling'
4
+ adjacentSibling = 'adjacentSibling',
5
+ subsequentSibling = 'subsequentSibling'
5
6
  }
6
7
 
7
8
  export default SelectorCombinatorEnum;
@@ -25,7 +25,7 @@ import ISelectorPseudo from './ISelectorPseudo.js';
25
25
  * Group 17: Combinator.
26
26
  */
27
27
  const SELECTOR_REGEXP =
28
- /(\*)|([a-zA-Z0-9-]+)|#((?:[a-zA-Z0-9-_]|\\.)+)|\.((?:[a-zA-Z0-9-_]|\\.)+)|\[([a-zA-Z0-9-_\\:]+)\]|\[([a-zA-Z0-9-_\\:]+)\s*([~|^$*]{0,1})\s*=\s*["']{1}([^"']*)["']{1}\s*(s|i){0,1}\]|\[([a-zA-Z0-9-_]+)\s*([~|^$*]{0,1})\s*=\s*([^\]]*)\]|:([a-zA-Z-]+)\s*\(([^)]+)\){0,1}|:([a-zA-Z-]+)|::([a-zA-Z-]+)|([\s,+>]*)/gm;
28
+ /(\*)|([a-zA-Z0-9-]+)|#((?:[a-zA-Z0-9-_]|\\.)+)|\.((?:[a-zA-Z0-9-_]|\\.)+)|\[([a-zA-Z0-9-_\\:]+)\]|\[([a-zA-Z0-9-_\\:]+)\s*([~|^$*]{0,1})\s*=\s*["']{1}([^"']*)["']{1}\s*(s|i){0,1}\]|\[([a-zA-Z0-9-_]+)\s*([~|^$*]{0,1})\s*=\s*([^\]]*)\]|:([a-zA-Z-]+)\s*\(([^)]+)\){0,1}|:([a-zA-Z-]+)|::([a-zA-Z-]+)|([\s,+>~]*)/gm;
29
29
 
30
30
  /**
31
31
  * Escaped Character RegExp.
@@ -193,6 +193,13 @@ export default class SelectorParser {
193
193
  });
194
194
  currentGroup.push(currentSelectorItem);
195
195
  break;
196
+ case '~':
197
+ currentSelectorItem = new SelectorItem({
198
+ combinator: SelectorCombinatorEnum.subsequentSibling,
199
+ ignoreErrors
200
+ });
201
+ currentGroup.push(currentSelectorItem);
202
+ break;
196
203
  case '':
197
204
  currentSelectorItem = new SelectorItem({
198
205
  combinator: SelectorCombinatorEnum.descendant,