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.
- package/cjs/event/EventTarget.cjs +9 -5
- package/cjs/event/EventTarget.cjs.map +1 -1
- package/cjs/event/EventTarget.d.ts.map +1 -1
- package/cjs/nodes/html-link-element/HTMLLinkElementUtility.cjs +21 -4
- package/cjs/nodes/html-link-element/HTMLLinkElementUtility.cjs.map +1 -1
- package/cjs/nodes/html-link-element/HTMLLinkElementUtility.d.ts.map +1 -1
- package/cjs/nodes/html-script-element/HTMLScriptElement.cjs +6 -1
- package/cjs/nodes/html-script-element/HTMLScriptElement.cjs.map +1 -1
- package/cjs/nodes/html-script-element/HTMLScriptElement.d.ts.map +1 -1
- package/cjs/nodes/html-script-element/HTMLScriptElementUtility.cjs +48 -8
- package/cjs/nodes/html-script-element/HTMLScriptElementUtility.cjs.map +1 -1
- package/cjs/nodes/html-script-element/HTMLScriptElementUtility.d.ts.map +1 -1
- package/cjs/version.cjs +1 -1
- package/cjs/window/IHappyDOMOptions.d.ts +1 -0
- package/cjs/window/IHappyDOMOptions.d.ts.map +1 -1
- package/cjs/window/IHappyDOMSettings.d.ts +1 -0
- package/cjs/window/IHappyDOMSettings.d.ts.map +1 -1
- package/cjs/window/Window.cjs +19 -3
- package/cjs/window/Window.cjs.map +1 -1
- package/cjs/window/Window.d.ts.map +1 -1
- package/cjs/window/WindowErrorUtility.cjs +1 -23
- package/cjs/window/WindowErrorUtility.cjs.map +1 -1
- package/cjs/window/WindowErrorUtility.d.ts +1 -12
- package/cjs/window/WindowErrorUtility.d.ts.map +1 -1
- package/lib/event/EventTarget.d.ts.map +1 -1
- package/lib/event/EventTarget.js +9 -5
- package/lib/event/EventTarget.js.map +1 -1
- package/lib/nodes/html-link-element/HTMLLinkElementUtility.d.ts.map +1 -1
- package/lib/nodes/html-link-element/HTMLLinkElementUtility.js +21 -4
- package/lib/nodes/html-link-element/HTMLLinkElementUtility.js.map +1 -1
- package/lib/nodes/html-script-element/HTMLScriptElement.d.ts.map +1 -1
- package/lib/nodes/html-script-element/HTMLScriptElement.js +6 -1
- package/lib/nodes/html-script-element/HTMLScriptElement.js.map +1 -1
- package/lib/nodes/html-script-element/HTMLScriptElementUtility.d.ts.map +1 -1
- package/lib/nodes/html-script-element/HTMLScriptElementUtility.js +48 -8
- package/lib/nodes/html-script-element/HTMLScriptElementUtility.js.map +1 -1
- package/lib/version.js +1 -1
- package/lib/window/IHappyDOMOptions.d.ts +1 -0
- package/lib/window/IHappyDOMOptions.d.ts.map +1 -1
- package/lib/window/IHappyDOMSettings.d.ts +1 -0
- package/lib/window/IHappyDOMSettings.d.ts.map +1 -1
- package/lib/window/Window.d.ts.map +1 -1
- package/lib/window/Window.js +19 -3
- package/lib/window/Window.js.map +1 -1
- package/lib/window/WindowErrorUtility.d.ts +1 -12
- package/lib/window/WindowErrorUtility.d.ts.map +1 -1
- package/lib/window/WindowErrorUtility.js +1 -23
- package/lib/window/WindowErrorUtility.js.map +1 -1
- package/package.json +1 -1
- package/src/event/EventTarget.ts +13 -5
- package/src/nodes/html-link-element/HTMLLinkElementUtility.ts +23 -14
- package/src/nodes/html-script-element/HTMLScriptElement.ts +7 -3
- package/src/nodes/html-script-element/HTMLScriptElementUtility.ts +51 -22
- package/src/window/IHappyDOMOptions.ts +1 -0
- package/src/window/IHappyDOMSettings.ts +1 -0
- package/src/window/Window.ts +21 -7
- package/src/window/WindowErrorUtility.ts +1 -27
package/src/event/EventTarget.ts
CHANGED
@@ -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 (
|
144
|
-
|
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 (
|
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.
|
182
|
+
WindowErrorUtility.captureError(
|
175
183
|
window,
|
176
184
|
(<IEventListener>listener).handleEvent.bind(this, event)
|
177
185
|
);
|
178
186
|
} else {
|
179
|
-
WindowErrorUtility.
|
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
|
-
|
28
|
-
|
29
|
-
|
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
|
-
|
41
|
-
|
42
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
42
|
-
|
43
|
-
async () => await ResourceFetch.fetch(element.ownerDocument, src)
|
44
|
-
);
|
42
|
+
let code: string | null = null;
|
43
|
+
let error: Error | null = null;
|
45
44
|
|
46
|
-
|
47
|
-
|
48
|
-
|
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
|
-
|
55
|
-
|
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 (
|
59
|
-
WindowErrorUtility.
|
60
|
-
|
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;
|
package/src/window/Window.ts
CHANGED
@@ -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
|
-
|
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
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
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
|
20
|
+
public static captureError<T>(
|
47
21
|
elementOrWindow: IWindow | IElement,
|
48
22
|
callback: () => T,
|
49
23
|
cleanup?: () => void
|