happy-dom 12.0.1 → 12.1.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 (57) hide show
  1. package/cjs/event/EventTarget.cjs +9 -5
  2. package/cjs/event/EventTarget.cjs.map +1 -1
  3. package/cjs/event/EventTarget.d.ts.map +1 -1
  4. package/cjs/nodes/html-link-element/HTMLLinkElementUtility.cjs +21 -4
  5. package/cjs/nodes/html-link-element/HTMLLinkElementUtility.cjs.map +1 -1
  6. package/cjs/nodes/html-link-element/HTMLLinkElementUtility.d.ts.map +1 -1
  7. package/cjs/nodes/html-script-element/HTMLScriptElement.cjs +6 -1
  8. package/cjs/nodes/html-script-element/HTMLScriptElement.cjs.map +1 -1
  9. package/cjs/nodes/html-script-element/HTMLScriptElement.d.ts.map +1 -1
  10. package/cjs/nodes/html-script-element/HTMLScriptElementUtility.cjs +48 -8
  11. package/cjs/nodes/html-script-element/HTMLScriptElementUtility.cjs.map +1 -1
  12. package/cjs/nodes/html-script-element/HTMLScriptElementUtility.d.ts.map +1 -1
  13. package/cjs/version.cjs +1 -1
  14. package/cjs/window/IHappyDOMOptions.d.ts +1 -0
  15. package/cjs/window/IHappyDOMOptions.d.ts.map +1 -1
  16. package/cjs/window/IHappyDOMSettings.d.ts +1 -0
  17. package/cjs/window/IHappyDOMSettings.d.ts.map +1 -1
  18. package/cjs/window/Window.cjs +19 -3
  19. package/cjs/window/Window.cjs.map +1 -1
  20. package/cjs/window/Window.d.ts.map +1 -1
  21. package/cjs/window/WindowErrorUtility.cjs +1 -23
  22. package/cjs/window/WindowErrorUtility.cjs.map +1 -1
  23. package/cjs/window/WindowErrorUtility.d.ts +1 -12
  24. package/cjs/window/WindowErrorUtility.d.ts.map +1 -1
  25. package/lib/event/EventTarget.d.ts.map +1 -1
  26. package/lib/event/EventTarget.js +9 -5
  27. package/lib/event/EventTarget.js.map +1 -1
  28. package/lib/nodes/html-link-element/HTMLLinkElementUtility.d.ts.map +1 -1
  29. package/lib/nodes/html-link-element/HTMLLinkElementUtility.js +21 -4
  30. package/lib/nodes/html-link-element/HTMLLinkElementUtility.js.map +1 -1
  31. package/lib/nodes/html-script-element/HTMLScriptElement.d.ts.map +1 -1
  32. package/lib/nodes/html-script-element/HTMLScriptElement.js +6 -1
  33. package/lib/nodes/html-script-element/HTMLScriptElement.js.map +1 -1
  34. package/lib/nodes/html-script-element/HTMLScriptElementUtility.d.ts.map +1 -1
  35. package/lib/nodes/html-script-element/HTMLScriptElementUtility.js +48 -8
  36. package/lib/nodes/html-script-element/HTMLScriptElementUtility.js.map +1 -1
  37. package/lib/version.js +1 -1
  38. package/lib/window/IHappyDOMOptions.d.ts +1 -0
  39. package/lib/window/IHappyDOMOptions.d.ts.map +1 -1
  40. package/lib/window/IHappyDOMSettings.d.ts +1 -0
  41. package/lib/window/IHappyDOMSettings.d.ts.map +1 -1
  42. package/lib/window/Window.d.ts.map +1 -1
  43. package/lib/window/Window.js +19 -3
  44. package/lib/window/Window.js.map +1 -1
  45. package/lib/window/WindowErrorUtility.d.ts +1 -12
  46. package/lib/window/WindowErrorUtility.d.ts.map +1 -1
  47. package/lib/window/WindowErrorUtility.js +1 -23
  48. package/lib/window/WindowErrorUtility.js.map +1 -1
  49. package/package.json +1 -1
  50. package/src/event/EventTarget.ts +13 -5
  51. package/src/nodes/html-link-element/HTMLLinkElementUtility.ts +23 -14
  52. package/src/nodes/html-script-element/HTMLScriptElement.ts +7 -3
  53. package/src/nodes/html-script-element/HTMLScriptElementUtility.ts +51 -22
  54. package/src/window/IHappyDOMOptions.ts +1 -0
  55. package/src/window/IHappyDOMSettings.ts +1 -0
  56. package/src/window/Window.ts +21 -7
  57. package/src/window/WindowErrorUtility.ts +1 -27
@@ -140,8 +140,12 @@ export default abstract class EventTarget implements IEventTarget {
140
140
 
141
141
  if (typeof this[onEventName] === 'function') {
142
142
  // We can end up in a never ending loop if the listener for the error event on Window also throws an error.
143
- if (window && (this !== <IEventTarget>window || event.type !== 'error')) {
144
- WindowErrorUtility.captureErrorSync(window, this[onEventName].bind(this, event));
143
+ if (
144
+ window &&
145
+ (this !== <IEventTarget>window || event.type !== 'error') &&
146
+ !window.happyDOM.settings.disableErrorCapturing
147
+ ) {
148
+ WindowErrorUtility.captureError(window, this[onEventName].bind(this, event));
145
149
  } else {
146
150
  this[onEventName].call(this, event);
147
151
  }
@@ -169,14 +173,18 @@ export default abstract class EventTarget implements IEventTarget {
169
173
  }
170
174
 
171
175
  // We can end up in a never ending loop if the listener for the error event on Window also throws an error.
172
- if (window && (this !== <IEventTarget>window || event.type !== 'error')) {
176
+ if (
177
+ window &&
178
+ (this !== <IEventTarget>window || event.type !== 'error') &&
179
+ !window.happyDOM.settings.disableErrorCapturing
180
+ ) {
173
181
  if ((<IEventListener>listener).handleEvent) {
174
- WindowErrorUtility.captureErrorSync(
182
+ WindowErrorUtility.captureError(
175
183
  window,
176
184
  (<IEventListener>listener).handleEvent.bind(this, event)
177
185
  );
178
186
  } else {
179
- WindowErrorUtility.captureErrorSync(
187
+ WindowErrorUtility.captureError(
180
188
  window,
181
189
  (<(event: Event) => void>listener).bind(this, event)
182
190
  );
@@ -24,32 +24,41 @@ export default class HTMLLinkElementUtility {
24
24
 
25
25
  if (href !== null && rel && rel.toLowerCase() === 'stylesheet' && element.isConnected) {
26
26
  if (element.ownerDocument.defaultView.happyDOM.settings.disableCSSFileLoading) {
27
- WindowErrorUtility.dispatchError(
28
- element,
29
- new DOMException(
30
- `Failed to load external stylesheet "${href}". CSS file loading is disabled.`,
31
- DOMExceptionNameEnum.notSupportedError
32
- )
27
+ const error = new DOMException(
28
+ `Failed to load external stylesheet "${href}". CSS file loading is disabled.`,
29
+ DOMExceptionNameEnum.notSupportedError
33
30
  );
34
-
31
+ WindowErrorUtility.dispatchError(element, error);
32
+ if (element.ownerDocument.defaultView.happyDOM.settings.disableErrorCapturing) {
33
+ throw error;
34
+ }
35
35
  return;
36
36
  }
37
37
 
38
38
  (<Document>element.ownerDocument)._readyStateManager.startTask();
39
39
 
40
- const code: string | null = await WindowErrorUtility.captureErrorAsync<string>(
41
- element,
42
- async () => await ResourceFetch.fetch(element.ownerDocument, href)
43
- );
40
+ let code: string | null = null;
41
+ let error: Error | null = null;
42
+
43
+ try {
44
+ code = await ResourceFetch.fetch(element.ownerDocument, href);
45
+ } catch (e) {
46
+ error = e;
47
+ }
44
48
 
45
- if (code) {
49
+ (<Document>element.ownerDocument)._readyStateManager.endTask();
50
+
51
+ if (error) {
52
+ WindowErrorUtility.dispatchError(element, error);
53
+ if (element.ownerDocument.defaultView.happyDOM.settings.disableErrorCapturing) {
54
+ throw error;
55
+ }
56
+ } else {
46
57
  const styleSheet = new CSSStyleSheet();
47
58
  styleSheet.replaceSync(code);
48
59
  (<CSSStyleSheet>element.sheet) = styleSheet;
49
60
  element.dispatchEvent(new Event('load'));
50
61
  }
51
-
52
- (<Document>element.ownerDocument)._readyStateManager.endTask();
53
62
  }
54
63
  }
55
64
  }
@@ -189,9 +189,13 @@ export default class HTMLScriptElement extends HTMLElement implements IHTMLScrip
189
189
  type === 'application/x-javascript' ||
190
190
  type.startsWith('text/javascript'))
191
191
  ) {
192
- WindowErrorUtility.captureErrorSync(this.ownerDocument.defaultView, () =>
193
- this.ownerDocument.defaultView.eval(textContent)
194
- );
192
+ if (this.ownerDocument.defaultView.happyDOM.settings.disableErrorCapturing) {
193
+ this.ownerDocument.defaultView.eval(textContent);
194
+ } else {
195
+ WindowErrorUtility.captureError(this.ownerDocument.defaultView, () =>
196
+ this.ownerDocument.defaultView.eval(textContent)
197
+ );
198
+ }
195
199
  }
196
200
  }
197
201
  }
@@ -25,40 +25,69 @@ export default class HTMLScriptElementUtility {
25
25
  element.ownerDocument.defaultView.happyDOM.settings.disableJavaScriptFileLoading ||
26
26
  element.ownerDocument.defaultView.happyDOM.settings.disableJavaScriptEvaluation
27
27
  ) {
28
- WindowErrorUtility.dispatchError(
29
- element,
30
- new DOMException(
31
- `Failed to load external script "${src}". JavaScript file loading is disabled.`,
32
- DOMExceptionNameEnum.notSupportedError
33
- )
28
+ const error = new DOMException(
29
+ `Failed to load external script "${src}". JavaScript file loading is disabled.`,
30
+ DOMExceptionNameEnum.notSupportedError
34
31
  );
32
+ WindowErrorUtility.dispatchError(element, error);
33
+ if (element.ownerDocument.defaultView.happyDOM.settings.disableErrorCapturing) {
34
+ throw error;
35
+ }
35
36
  return;
36
37
  }
37
38
 
38
39
  if (async) {
39
40
  (<Document>element.ownerDocument)._readyStateManager.startTask();
40
41
 
41
- const code = await WindowErrorUtility.captureErrorAsync<string>(
42
- element,
43
- async () => await ResourceFetch.fetch(element.ownerDocument, src)
44
- );
42
+ let code: string | null = null;
43
+ let error: Error | null = null;
45
44
 
46
- if (code) {
47
- WindowErrorUtility.captureErrorSync(element.ownerDocument.defaultView, () =>
48
- element.ownerDocument.defaultView.eval(code)
49
- );
50
- element.dispatchEvent(new Event('load'));
45
+ try {
46
+ code = await ResourceFetch.fetch(element.ownerDocument, src);
47
+ } catch (e) {
48
+ error = e;
51
49
  }
50
+
52
51
  (<Document>element.ownerDocument)._readyStateManager.endTask();
52
+
53
+ if (error) {
54
+ WindowErrorUtility.dispatchError(element, error);
55
+ if (element.ownerDocument.defaultView.happyDOM.settings.disableErrorCapturing) {
56
+ throw error;
57
+ }
58
+ } else {
59
+ if (element.ownerDocument.defaultView.happyDOM.settings.disableErrorCapturing) {
60
+ element.ownerDocument.defaultView.eval(code);
61
+ } else {
62
+ WindowErrorUtility.captureError(element.ownerDocument.defaultView, () =>
63
+ element.ownerDocument.defaultView.eval(code)
64
+ );
65
+ }
66
+ element.dispatchEvent(new Event('load'));
67
+ }
53
68
  } else {
54
- const code = WindowErrorUtility.captureErrorSync<string>(element, () =>
55
- ResourceFetch.fetchSync(element.ownerDocument, src)
56
- );
69
+ let code: string | null = null;
70
+ let error: Error | null = null;
71
+
72
+ try {
73
+ code = ResourceFetch.fetchSync(element.ownerDocument, src);
74
+ } catch (e) {
75
+ error = e;
76
+ }
57
77
 
58
- if (code) {
59
- WindowErrorUtility.captureErrorSync(element.ownerDocument.defaultView, () =>
60
- element.ownerDocument.defaultView.eval(code)
61
- );
78
+ if (error) {
79
+ WindowErrorUtility.dispatchError(element, error);
80
+ if (element.ownerDocument.defaultView.happyDOM.settings.disableErrorCapturing) {
81
+ throw error;
82
+ }
83
+ } else {
84
+ if (element.ownerDocument.defaultView.happyDOM.settings.disableErrorCapturing) {
85
+ element.ownerDocument.defaultView.eval(code);
86
+ } else {
87
+ WindowErrorUtility.captureError(element.ownerDocument.defaultView, () =>
88
+ element.ownerDocument.defaultView.eval(code)
89
+ );
90
+ }
62
91
  element.dispatchEvent(new Event('load'));
63
92
  }
64
93
  }
@@ -12,6 +12,7 @@ export default interface IHappyDOMOptions {
12
12
  disableCSSFileLoading?: boolean;
13
13
  disableIframePageLoading?: boolean;
14
14
  disableComputedStyleRendering?: boolean;
15
+ disableErrorCapturing?: boolean;
15
16
  enableFileSystemHttpRequests?: boolean;
16
17
  navigator?: {
17
18
  userAgent?: string;
@@ -7,6 +7,7 @@ export default interface IHappyDOMSettings {
7
7
  disableCSSFileLoading: boolean;
8
8
  disableIframePageLoading: boolean;
9
9
  disableComputedStyleRendering: boolean;
10
+ disableErrorCapturing: boolean;
10
11
  enableFileSystemHttpRequests: boolean;
11
12
  navigator: {
12
13
  userAgent: string;
@@ -210,6 +210,7 @@ export default class Window extends EventTarget implements IWindow {
210
210
  disableCSSFileLoading: false,
211
211
  disableIframePageLoading: false,
212
212
  disableComputedStyleRendering: false,
213
+ disableErrorCapturing: false,
213
214
  enableFileSystemHttpRequests: false,
214
215
  navigator: {
215
216
  userAgent: `Mozilla/5.0 (X11; ${
@@ -736,7 +737,11 @@ export default class Window extends EventTarget implements IWindow {
736
737
  public setTimeout(callback: Function, delay = 0, ...args: unknown[]): NodeJS.Timeout {
737
738
  const id = this._setTimeout(() => {
738
739
  this.happyDOM.asyncTaskManager.endTimer(id);
739
- WindowErrorUtility.captureErrorSync(this, () => callback(...args));
740
+ if (this.happyDOM.settings.disableErrorCapturing) {
741
+ callback(...args);
742
+ } else {
743
+ WindowErrorUtility.captureError(this, () => callback(...args));
744
+ }
740
745
  }, delay);
741
746
  this.happyDOM.asyncTaskManager.startTimer(id);
742
747
  return id;
@@ -762,11 +767,15 @@ export default class Window extends EventTarget implements IWindow {
762
767
  */
763
768
  public setInterval(callback: Function, delay = 0, ...args: unknown[]): NodeJS.Timeout {
764
769
  const id = this._setInterval(() => {
765
- WindowErrorUtility.captureErrorSync(
766
- this,
767
- () => callback(...args),
768
- () => this.clearInterval(id)
769
- );
770
+ if (this.happyDOM.settings.disableErrorCapturing) {
771
+ callback(...args);
772
+ } else {
773
+ WindowErrorUtility.captureError(
774
+ this,
775
+ () => callback(...args),
776
+ () => this.clearInterval(id)
777
+ );
778
+ }
770
779
  }, delay);
771
780
  this.happyDOM.asyncTaskManager.startTimer(id);
772
781
  return id;
@@ -811,8 +820,13 @@ export default class Window extends EventTarget implements IWindow {
811
820
  const taskId = this.happyDOM.asyncTaskManager.startTask(() => (isAborted = true));
812
821
  this._queueMicrotask(() => {
813
822
  if (!isAborted) {
814
- WindowErrorUtility.captureErrorSync(this, <() => unknown>callback);
815
823
  this.happyDOM.asyncTaskManager.endTask(taskId);
824
+
825
+ if (this.happyDOM.settings.disableErrorCapturing) {
826
+ callback();
827
+ } else {
828
+ WindowErrorUtility.captureError(this, <() => unknown>callback);
829
+ }
816
830
  }
817
831
  });
818
832
  }
@@ -6,32 +6,6 @@ import { IElement } from '../index.js';
6
6
  * Error utility.
7
7
  */
8
8
  export default class WindowErrorUtility {
9
- /**
10
- * Calls a function asynchronously wrapped in a try/catch block to capture errors and dispatch error events.
11
- *
12
- * It will also output the errors to the console.
13
- *
14
- * @param elementOrWindow Element or Window.
15
- * @param callback Callback.
16
- * @param [cleanup] Cleanup callback on error.
17
- * @returns Promise.
18
- */
19
- public static async captureErrorAsync<T>(
20
- elementOrWindow: IWindow | IElement,
21
- callback: () => Promise<T>,
22
- cleanup?: () => void
23
- ): Promise<T | null> {
24
- try {
25
- return await callback();
26
- } catch (error) {
27
- this.dispatchError(elementOrWindow, error);
28
- if (cleanup) {
29
- cleanup();
30
- }
31
- }
32
- return null;
33
- }
34
-
35
9
  /**
36
10
  * Calls a function synchronously wrapped in a try/catch block to capture errors and dispatch error events.
37
11
  * If the callback returns a Promise, it will catch errors from the promise.
@@ -43,7 +17,7 @@ export default class WindowErrorUtility {
43
17
  * @param [cleanup] Cleanup callback on error.
44
18
  * @returns Result.
45
19
  */
46
- public static captureErrorSync<T>(
20
+ public static captureError<T>(
47
21
  elementOrWindow: IWindow | IElement,
48
22
  callback: () => T,
49
23
  cleanup?: () => void