happy-dom 10.11.1 → 11.0.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/.eslintrc.cjs +1 -1
- package/cjs/console/VirtualConsole.cjs +351 -0
- package/cjs/console/VirtualConsole.cjs.map +1 -0
- package/cjs/console/VirtualConsole.d.ts +163 -0
- package/cjs/console/VirtualConsole.d.ts.map +1 -0
- package/cjs/console/VirtualConsolePrinter.cjs +101 -0
- package/cjs/console/VirtualConsolePrinter.cjs.map +1 -0
- package/cjs/console/VirtualConsolePrinter.d.ts +55 -0
- package/cjs/console/VirtualConsolePrinter.d.ts.map +1 -0
- package/cjs/console/enums/VirtualConsoleLogLevelEnum.cjs +16 -0
- package/cjs/console/enums/VirtualConsoleLogLevelEnum.cjs.map +1 -0
- package/cjs/console/enums/VirtualConsoleLogLevelEnum.d.ts +13 -0
- package/cjs/console/enums/VirtualConsoleLogLevelEnum.d.ts.map +1 -0
- package/cjs/console/enums/VirtualConsoleLogTypeEnum.cjs +30 -0
- package/cjs/console/enums/VirtualConsoleLogTypeEnum.cjs.map +1 -0
- package/cjs/console/enums/VirtualConsoleLogTypeEnum.d.ts +23 -0
- package/cjs/console/enums/VirtualConsoleLogTypeEnum.d.ts.map +1 -0
- package/cjs/console/types/IVirtualConsoleLogEntry.cjs +3 -0
- package/cjs/console/types/IVirtualConsoleLogEntry.cjs.map +1 -0
- package/cjs/console/types/IVirtualConsoleLogEntry.d.ts +10 -0
- package/cjs/console/types/IVirtualConsoleLogEntry.d.ts.map +1 -0
- package/cjs/console/types/IVirtualConsoleLogGroup.cjs +3 -0
- package/cjs/console/types/IVirtualConsoleLogGroup.cjs.map +1 -0
- package/cjs/console/types/IVirtualConsoleLogGroup.d.ts +7 -0
- package/cjs/console/types/IVirtualConsoleLogGroup.d.ts.map +1 -0
- package/cjs/console/types/IVirtualConsolePrinter.cjs +3 -0
- package/cjs/console/types/IVirtualConsolePrinter.cjs.map +1 -0
- package/cjs/console/types/IVirtualConsolePrinter.d.ts +52 -0
- package/cjs/console/types/IVirtualConsolePrinter.d.ts.map +1 -0
- package/cjs/console/utilities/VirtualConsoleLogEntryStringifier.cjs +97 -0
- package/cjs/console/utilities/VirtualConsoleLogEntryStringifier.cjs.map +1 -0
- package/cjs/console/utilities/VirtualConsoleLogEntryStringifier.d.ts +35 -0
- package/cjs/console/utilities/VirtualConsoleLogEntryStringifier.d.ts.map +1 -0
- package/cjs/css/CSSParser.cjs +34 -13
- package/cjs/css/CSSParser.cjs.map +1 -1
- package/cjs/css/CSSParser.d.ts +8 -0
- package/cjs/css/CSSParser.d.ts.map +1 -1
- package/cjs/event/EventTarget.cjs +23 -5
- package/cjs/event/EventTarget.cjs.map +1 -1
- package/cjs/event/EventTarget.d.ts.map +1 -1
- package/cjs/nodes/element/Element.cjs.map +1 -1
- package/cjs/nodes/element/Element.d.ts +1 -1
- package/cjs/nodes/element/Element.d.ts.map +1 -1
- package/cjs/nodes/html-link-element/HTMLLinkElementUtility.cjs +8 -31
- package/cjs/nodes/html-link-element/HTMLLinkElementUtility.cjs.map +1 -1
- package/cjs/nodes/html-link-element/HTMLLinkElementUtility.d.ts +0 -7
- package/cjs/nodes/html-link-element/HTMLLinkElementUtility.d.ts.map +1 -1
- package/cjs/nodes/html-script-element/HTMLScriptElement.cjs +2 -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 +10 -55
- package/cjs/nodes/html-script-element/HTMLScriptElementUtility.cjs.map +1 -1
- package/cjs/nodes/html-script-element/HTMLScriptElementUtility.d.ts +0 -14
- package/cjs/nodes/html-script-element/HTMLScriptElementUtility.d.ts.map +1 -1
- package/cjs/window/GlobalWindow.cjs +1 -9
- package/cjs/window/GlobalWindow.cjs.map +1 -1
- package/cjs/window/GlobalWindow.d.ts +1 -7
- package/cjs/window/GlobalWindow.d.ts.map +1 -1
- package/cjs/window/IHappyDOMOptions.d.ts +2 -0
- package/cjs/window/IHappyDOMOptions.d.ts.map +1 -1
- package/cjs/window/IWindow.d.ts +2 -7
- package/cjs/window/IWindow.d.ts.map +1 -1
- package/cjs/window/VMGlobalPropertyScript.cjs +1 -0
- package/cjs/window/VMGlobalPropertyScript.cjs.map +1 -1
- package/cjs/window/VMGlobalPropertyScript.d.ts +1 -1
- package/cjs/window/VMGlobalPropertyScript.d.ts.map +1 -1
- package/cjs/window/Window.cjs +51 -64
- package/cjs/window/Window.cjs.map +1 -1
- package/cjs/window/Window.d.ts +6 -23
- package/cjs/window/Window.d.ts.map +1 -1
- package/cjs/window/WindowErrorUtility.cjs +84 -0
- package/cjs/window/WindowErrorUtility.cjs.map +1 -0
- package/cjs/window/WindowErrorUtility.d.ts +38 -0
- package/cjs/window/WindowErrorUtility.d.ts.map +1 -0
- package/lib/console/VirtualConsole.d.ts +163 -0
- package/lib/console/VirtualConsole.d.ts.map +1 -0
- package/lib/console/VirtualConsole.js +322 -0
- package/lib/console/VirtualConsole.js.map +1 -0
- package/lib/console/VirtualConsolePrinter.d.ts +55 -0
- package/lib/console/VirtualConsolePrinter.d.ts.map +1 -0
- package/lib/console/VirtualConsolePrinter.js +95 -0
- package/lib/console/VirtualConsolePrinter.js.map +1 -0
- package/lib/console/enums/VirtualConsoleLogLevelEnum.d.ts +13 -0
- package/lib/console/enums/VirtualConsoleLogLevelEnum.d.ts.map +1 -0
- package/lib/console/enums/VirtualConsoleLogLevelEnum.js +14 -0
- package/lib/console/enums/VirtualConsoleLogLevelEnum.js.map +1 -0
- package/lib/console/enums/VirtualConsoleLogTypeEnum.d.ts +23 -0
- package/lib/console/enums/VirtualConsoleLogTypeEnum.d.ts.map +1 -0
- package/lib/console/enums/VirtualConsoleLogTypeEnum.js +28 -0
- package/lib/console/enums/VirtualConsoleLogTypeEnum.js.map +1 -0
- package/lib/console/types/IVirtualConsoleLogEntry.d.ts +10 -0
- package/lib/console/types/IVirtualConsoleLogEntry.d.ts.map +1 -0
- package/lib/console/types/IVirtualConsoleLogEntry.js +2 -0
- package/lib/console/types/IVirtualConsoleLogEntry.js.map +1 -0
- package/lib/console/types/IVirtualConsoleLogGroup.d.ts +7 -0
- package/lib/console/types/IVirtualConsoleLogGroup.d.ts.map +1 -0
- package/lib/console/types/IVirtualConsoleLogGroup.js +2 -0
- package/lib/console/types/IVirtualConsoleLogGroup.js.map +1 -0
- package/lib/console/types/IVirtualConsolePrinter.d.ts +52 -0
- package/lib/console/types/IVirtualConsolePrinter.d.ts.map +1 -0
- package/lib/console/types/IVirtualConsolePrinter.js +2 -0
- package/lib/console/types/IVirtualConsolePrinter.js.map +1 -0
- package/lib/console/utilities/VirtualConsoleLogEntryStringifier.d.ts +35 -0
- package/lib/console/utilities/VirtualConsoleLogEntryStringifier.d.ts.map +1 -0
- package/lib/console/utilities/VirtualConsoleLogEntryStringifier.js +91 -0
- package/lib/console/utilities/VirtualConsoleLogEntryStringifier.js.map +1 -0
- package/lib/css/CSSParser.d.ts +8 -0
- package/lib/css/CSSParser.d.ts.map +1 -1
- package/lib/css/CSSParser.js +34 -13
- package/lib/css/CSSParser.js.map +1 -1
- package/lib/event/EventTarget.d.ts.map +1 -1
- package/lib/event/EventTarget.js +23 -5
- package/lib/event/EventTarget.js.map +1 -1
- package/lib/nodes/element/Element.d.ts +1 -1
- package/lib/nodes/element/Element.d.ts.map +1 -1
- package/lib/nodes/element/Element.js.map +1 -1
- package/lib/nodes/html-link-element/HTMLLinkElementUtility.d.ts +0 -7
- package/lib/nodes/html-link-element/HTMLLinkElementUtility.d.ts.map +1 -1
- package/lib/nodes/html-link-element/HTMLLinkElementUtility.js +8 -31
- 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 +2 -1
- package/lib/nodes/html-script-element/HTMLScriptElement.js.map +1 -1
- package/lib/nodes/html-script-element/HTMLScriptElementUtility.d.ts +0 -14
- package/lib/nodes/html-script-element/HTMLScriptElementUtility.d.ts.map +1 -1
- package/lib/nodes/html-script-element/HTMLScriptElementUtility.js +10 -55
- package/lib/nodes/html-script-element/HTMLScriptElementUtility.js.map +1 -1
- package/lib/window/GlobalWindow.d.ts +1 -7
- package/lib/window/GlobalWindow.d.ts.map +1 -1
- package/lib/window/GlobalWindow.js +1 -9
- package/lib/window/GlobalWindow.js.map +1 -1
- package/lib/window/IHappyDOMOptions.d.ts +2 -0
- package/lib/window/IHappyDOMOptions.d.ts.map +1 -1
- package/lib/window/IWindow.d.ts +2 -7
- package/lib/window/IWindow.d.ts.map +1 -1
- package/lib/window/VMGlobalPropertyScript.d.ts +1 -1
- package/lib/window/VMGlobalPropertyScript.d.ts.map +1 -1
- package/lib/window/VMGlobalPropertyScript.js +1 -0
- package/lib/window/VMGlobalPropertyScript.js.map +1 -1
- package/lib/window/Window.d.ts +6 -23
- package/lib/window/Window.d.ts.map +1 -1
- package/lib/window/Window.js +51 -64
- package/lib/window/Window.js.map +1 -1
- package/lib/window/WindowErrorUtility.d.ts +38 -0
- package/lib/window/WindowErrorUtility.d.ts.map +1 -0
- package/lib/window/WindowErrorUtility.js +78 -0
- package/lib/window/WindowErrorUtility.js.map +1 -0
- package/package.json +2 -2
- package/src/console/VirtualConsole.ts +356 -0
- package/src/console/VirtualConsolePrinter.ts +107 -0
- package/src/console/enums/VirtualConsoleLogLevelEnum.ts +12 -0
- package/src/console/enums/VirtualConsoleLogTypeEnum.ts +29 -0
- package/src/console/types/IVirtualConsoleLogEntry.ts +10 -0
- package/src/console/types/IVirtualConsoleLogGroup.ts +6 -0
- package/src/console/types/IVirtualConsolePrinter.ts +58 -0
- package/src/console/utilities/VirtualConsoleLogEntryStringifier.ts +100 -0
- package/src/css/CSSParser.ts +35 -14
- package/src/event/EventTarget.ts +27 -5
- package/src/nodes/element/Element.ts +1 -1
- package/src/nodes/html-link-element/HTMLLinkElementUtility.ts +13 -35
- package/src/nodes/html-script-element/HTMLScriptElement.ts +4 -1
- package/src/nodes/html-script-element/HTMLScriptElementUtility.ts +19 -62
- package/src/window/GlobalWindow.ts +1 -10
- package/src/window/IHappyDOMOptions.ts +1 -0
- package/src/window/IWindow.ts +2 -8
- package/src/window/VMGlobalPropertyScript.ts +1 -0
- package/src/window/Window.ts +77 -70
- package/src/window/WindowErrorUtility.ts +94 -0
- package/tsconfig.json +2 -3
package/src/css/CSSParser.ts
CHANGED
@@ -6,6 +6,7 @@ import CSSKeyframesRule from './rules/CSSKeyframesRule.js';
|
|
6
6
|
import CSSMediaRule from './rules/CSSMediaRule.js';
|
7
7
|
import CSSContainerRule from './rules/CSSContainerRule.js';
|
8
8
|
import CSSSupportsRule from './rules/CSSSupportsRule.js';
|
9
|
+
import SelectorParser from '../query-selector/SelectorParser.js';
|
9
10
|
|
10
11
|
const COMMENT_REGEXP = /\/\*[\s\S]*?\*\//gm;
|
11
12
|
|
@@ -96,23 +97,27 @@ export default class CSSParser {
|
|
96
97
|
parentRule.type === CSSRule.CONTAINER_RULE ||
|
97
98
|
parentRule.type === CSSRule.SUPPORTS_RULE)
|
98
99
|
) {
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
100
|
+
if (this.validateSelectorText(selectorText)) {
|
101
|
+
const newRule = new CSSStyleRule();
|
102
|
+
(<string>newRule.selectorText) = selectorText;
|
103
|
+
newRule.parentStyleSheet = parentStyleSheet;
|
104
|
+
newRule.parentRule = parentRule;
|
105
|
+
(<CSSMediaRule>parentRule).cssRules.push(newRule);
|
106
|
+
parentRule = newRule;
|
107
|
+
}
|
105
108
|
} else {
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
109
|
+
if (this.validateSelectorText(selectorText)) {
|
110
|
+
const newRule = new CSSStyleRule();
|
111
|
+
(<string>newRule.selectorText) = selectorText;
|
112
|
+
newRule.parentStyleSheet = parentStyleSheet;
|
113
|
+
newRule.parentRule = parentRule;
|
110
114
|
|
111
|
-
|
112
|
-
|
113
|
-
|
115
|
+
if (!parentRule) {
|
116
|
+
cssRules.push(newRule);
|
117
|
+
}
|
114
118
|
|
115
|
-
|
119
|
+
parentRule = newRule;
|
120
|
+
}
|
116
121
|
}
|
117
122
|
|
118
123
|
stack.push(parentRule);
|
@@ -140,4 +145,20 @@ export default class CSSParser {
|
|
140
145
|
|
141
146
|
return cssRules;
|
142
147
|
}
|
148
|
+
|
149
|
+
/**
|
150
|
+
* Validates a selector text.
|
151
|
+
*
|
152
|
+
* @see https://www.w3.org/TR/CSS21/syndata.html#rule-sets
|
153
|
+
* @param selectorText Selector text.
|
154
|
+
* @returns True if valid, false otherwise.
|
155
|
+
*/
|
156
|
+
private static validateSelectorText(selectorText: string): boolean {
|
157
|
+
try {
|
158
|
+
SelectorParser.getSelectorGroups(selectorText);
|
159
|
+
} catch (e) {
|
160
|
+
return false;
|
161
|
+
}
|
162
|
+
return true;
|
163
|
+
}
|
143
164
|
}
|
package/src/event/EventTarget.ts
CHANGED
@@ -6,6 +6,7 @@ import EventPhaseEnum from './EventPhaseEnum.js';
|
|
6
6
|
import INode from '../nodes/node/INode.js';
|
7
7
|
import IDocument from '../nodes/document/IDocument.js';
|
8
8
|
import IWindow from '../window/IWindow.js';
|
9
|
+
import WindowErrorUtility from '../window/WindowErrorUtility.js';
|
9
10
|
|
10
11
|
/**
|
11
12
|
* Handles events.
|
@@ -88,11 +89,12 @@ export default abstract class EventTarget implements IEventTarget {
|
|
88
89
|
* @returns The return value is false if event is cancelable and at least one of the event handlers which handled this event called Event.preventDefault().
|
89
90
|
*/
|
90
91
|
public dispatchEvent(event: Event): boolean {
|
92
|
+
const window = this._getWindow();
|
93
|
+
|
91
94
|
if (event.eventPhase === EventPhaseEnum.none) {
|
92
95
|
event._target = this;
|
93
96
|
|
94
97
|
const composedPath = event.composedPath();
|
95
|
-
const window = this._getWindow();
|
96
98
|
|
97
99
|
// Capturing phase
|
98
100
|
|
@@ -137,7 +139,12 @@ export default abstract class EventTarget implements IEventTarget {
|
|
137
139
|
const onEventName = 'on' + event.type.toLowerCase();
|
138
140
|
|
139
141
|
if (typeof this[onEventName] === 'function') {
|
140
|
-
|
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));
|
145
|
+
} else {
|
146
|
+
this[onEventName].call(this, event);
|
147
|
+
}
|
141
148
|
}
|
142
149
|
}
|
143
150
|
|
@@ -161,10 +168,25 @@ export default abstract class EventTarget implements IEventTarget {
|
|
161
168
|
event._isInPassiveEventListener = true;
|
162
169
|
}
|
163
170
|
|
164
|
-
if
|
165
|
-
|
171
|
+
// 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')) {
|
173
|
+
if ((<IEventListener>listener).handleEvent) {
|
174
|
+
WindowErrorUtility.captureErrorSync(
|
175
|
+
window,
|
176
|
+
(<IEventListener>listener).handleEvent.bind(this, event)
|
177
|
+
);
|
178
|
+
} else {
|
179
|
+
WindowErrorUtility.captureErrorSync(
|
180
|
+
window,
|
181
|
+
(<(event: Event) => void>listener).bind(this, event)
|
182
|
+
);
|
183
|
+
}
|
166
184
|
} else {
|
167
|
-
(<
|
185
|
+
if ((<IEventListener>listener).handleEvent) {
|
186
|
+
(<IEventListener>listener).handleEvent(event);
|
187
|
+
} else {
|
188
|
+
(<(event: Event) => void>listener).call(this, event);
|
189
|
+
}
|
168
190
|
}
|
169
191
|
|
170
192
|
event._isInPassiveEventListener = false;
|
@@ -42,7 +42,7 @@ export default class Element extends Node implements IElement {
|
|
42
42
|
public static observedAttributes: string[];
|
43
43
|
public tagName: string = null;
|
44
44
|
public nodeType = Node.ELEMENT_NODE;
|
45
|
-
public shadowRoot: IShadowRoot = null;
|
45
|
+
public shadowRoot: IShadowRoot | null = null;
|
46
46
|
public prefix: string = null;
|
47
47
|
|
48
48
|
public scrollHeight = 0;
|
@@ -1,11 +1,11 @@
|
|
1
1
|
import Document from '../document/Document.js';
|
2
2
|
import Event from '../../event/Event.js';
|
3
|
-
import ErrorEvent from '../../event/events/ErrorEvent.js';
|
4
3
|
import ResourceFetch from '../../fetch/ResourceFetch.js';
|
5
4
|
import HTMLLinkElement from './HTMLLinkElement.js';
|
6
5
|
import CSSStyleSheet from '../../css/CSSStyleSheet.js';
|
7
6
|
import DOMException from '../../exception/DOMException.js';
|
8
7
|
import DOMExceptionNameEnum from '../../exception/DOMExceptionNameEnum.js';
|
8
|
+
import WindowErrorUtility from '../../window/WindowErrorUtility.js';
|
9
9
|
|
10
10
|
/**
|
11
11
|
* Helper class for getting the URL relative to a Location object.
|
@@ -24,54 +24,32 @@ 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
|
-
|
27
|
+
WindowErrorUtility.dispatchError(
|
28
28
|
element,
|
29
29
|
new DOMException(
|
30
30
|
`Failed to load external stylesheet "${href}". CSS file loading is disabled.`,
|
31
31
|
DOMExceptionNameEnum.notSupportedError
|
32
32
|
)
|
33
33
|
);
|
34
|
+
|
34
35
|
return;
|
35
36
|
}
|
36
37
|
|
37
38
|
(<Document>element.ownerDocument)._readyStateManager.startTask();
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
const code: string | null = await WindowErrorUtility.captureErrorAsync<string>(
|
41
|
+
element,
|
42
|
+
async () => await ResourceFetch.fetch(element.ownerDocument, href)
|
43
|
+
);
|
44
|
+
|
45
|
+
if (code) {
|
46
|
+
const styleSheet = new CSSStyleSheet();
|
47
|
+
styleSheet.replaceSync(code);
|
48
|
+
(<CSSStyleSheet>element.sheet) = styleSheet;
|
49
|
+
element.dispatchEvent(new Event('load'));
|
45
50
|
}
|
46
51
|
|
47
|
-
const styleSheet = new CSSStyleSheet();
|
48
|
-
styleSheet.replaceSync(code);
|
49
|
-
(<CSSStyleSheet>element.sheet) = styleSheet;
|
50
|
-
element.dispatchEvent(new Event('load'));
|
51
52
|
(<Document>element.ownerDocument)._readyStateManager.endTask();
|
52
53
|
}
|
53
54
|
}
|
54
|
-
|
55
|
-
/**
|
56
|
-
* Triggered when an error occurs.
|
57
|
-
*
|
58
|
-
* @param element Element.
|
59
|
-
* @param error Error.
|
60
|
-
*/
|
61
|
-
private static onError(element: HTMLLinkElement, error: Error): void {
|
62
|
-
element.dispatchEvent(
|
63
|
-
new ErrorEvent('error', {
|
64
|
-
message: error.message,
|
65
|
-
error
|
66
|
-
})
|
67
|
-
);
|
68
|
-
element.ownerDocument.defaultView.dispatchEvent(
|
69
|
-
new ErrorEvent('error', {
|
70
|
-
message: error.message,
|
71
|
-
error
|
72
|
-
})
|
73
|
-
);
|
74
|
-
(<Document>element.ownerDocument)._readyStateManager.endTask();
|
75
|
-
element.ownerDocument.defaultView.console.error(error);
|
76
|
-
}
|
77
55
|
}
|
@@ -6,6 +6,7 @@ import ErrorEvent from '../../event/events/ErrorEvent.js';
|
|
6
6
|
import INode from '../../nodes/node/INode.js';
|
7
7
|
import INamedNodeMap from '../../named-node-map/INamedNodeMap.js';
|
8
8
|
import HTMLScriptElementNamedNodeMap from './HTMLScriptElementNamedNodeMap.js';
|
9
|
+
import WindowErrorUtility from '../../window/WindowErrorUtility.js';
|
9
10
|
|
10
11
|
/**
|
11
12
|
* HTML Script Element.
|
@@ -188,7 +189,9 @@ export default class HTMLScriptElement extends HTMLElement implements IHTMLScrip
|
|
188
189
|
type === 'application/x-javascript' ||
|
189
190
|
type.startsWith('text/javascript'))
|
190
191
|
) {
|
191
|
-
|
192
|
+
WindowErrorUtility.captureErrorSync(this.ownerDocument.defaultView, () =>
|
193
|
+
this.ownerDocument.defaultView.eval(textContent)
|
194
|
+
);
|
192
195
|
}
|
193
196
|
}
|
194
197
|
}
|
@@ -1,10 +1,10 @@
|
|
1
1
|
import Document from '../document/Document.js';
|
2
2
|
import Event from '../../event/Event.js';
|
3
|
-
import ErrorEvent from '../../event/events/ErrorEvent.js';
|
4
3
|
import DOMException from '../../exception/DOMException.js';
|
5
4
|
import DOMExceptionNameEnum from '../../exception/DOMExceptionNameEnum.js';
|
6
5
|
import ResourceFetch from '../../fetch/ResourceFetch.js';
|
7
6
|
import HTMLScriptElement from './HTMLScriptElement.js';
|
7
|
+
import WindowErrorUtility from '../../window/WindowErrorUtility.js';
|
8
8
|
|
9
9
|
/**
|
10
10
|
* Helper class for getting the URL relative to a Location object.
|
@@ -25,7 +25,7 @@ export default class HTMLScriptElementUtility {
|
|
25
25
|
element.ownerDocument.defaultView.happyDOM.settings.disableJavaScriptFileLoading ||
|
26
26
|
element.ownerDocument.defaultView.happyDOM.settings.disableJavaScriptEvaluation
|
27
27
|
) {
|
28
|
-
|
28
|
+
WindowErrorUtility.dispatchError(
|
29
29
|
element,
|
30
30
|
new DOMException(
|
31
31
|
`Failed to load external script "${src}". JavaScript file loading is disabled.`,
|
@@ -38,72 +38,29 @@ export default class HTMLScriptElementUtility {
|
|
38
38
|
if (async) {
|
39
39
|
(<Document>element.ownerDocument)._readyStateManager.startTask();
|
40
40
|
|
41
|
-
|
41
|
+
const code = await WindowErrorUtility.captureErrorAsync<string>(
|
42
|
+
element,
|
43
|
+
async () => await ResourceFetch.fetch(element.ownerDocument, src)
|
44
|
+
);
|
42
45
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
46
|
+
if (code) {
|
47
|
+
WindowErrorUtility.captureErrorSync(element.ownerDocument.defaultView, () =>
|
48
|
+
element.ownerDocument.defaultView.eval(code)
|
49
|
+
);
|
50
|
+
element.dispatchEvent(new Event('load'));
|
48
51
|
}
|
49
|
-
|
50
|
-
this.eval(element, code);
|
51
|
-
element.dispatchEvent(new Event('load'));
|
52
52
|
(<Document>element.ownerDocument)._readyStateManager.endTask();
|
53
53
|
} else {
|
54
|
-
|
54
|
+
const code = WindowErrorUtility.captureErrorSync<string>(element, () =>
|
55
|
+
ResourceFetch.fetchSync(element.ownerDocument, src)
|
56
|
+
);
|
55
57
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
if (code) {
|
59
|
+
WindowErrorUtility.captureErrorSync(element.ownerDocument.defaultView, () =>
|
60
|
+
element.ownerDocument.defaultView.eval(code)
|
61
|
+
);
|
62
|
+
element.dispatchEvent(new Event('load'));
|
61
63
|
}
|
62
|
-
|
63
|
-
this.eval(element, code);
|
64
|
-
element.dispatchEvent(new Event('load'));
|
65
64
|
}
|
66
65
|
}
|
67
|
-
|
68
|
-
/**
|
69
|
-
* Evaluates a script code.
|
70
|
-
*
|
71
|
-
* @param element Element.
|
72
|
-
* @param code Code.
|
73
|
-
*/
|
74
|
-
public static eval(element: HTMLScriptElement, code: string): void {
|
75
|
-
try {
|
76
|
-
element.ownerDocument.defaultView.eval(code);
|
77
|
-
} catch (error) {
|
78
|
-
element.ownerDocument.defaultView.console.error(error);
|
79
|
-
element.ownerDocument.defaultView.dispatchEvent(
|
80
|
-
new ErrorEvent('error', {
|
81
|
-
message: error.message,
|
82
|
-
error: error
|
83
|
-
})
|
84
|
-
);
|
85
|
-
}
|
86
|
-
}
|
87
|
-
|
88
|
-
/**
|
89
|
-
* Triggered when an error occurs.
|
90
|
-
*
|
91
|
-
* @param element Element.
|
92
|
-
* @param error Error.
|
93
|
-
*/
|
94
|
-
private static onError(element: HTMLScriptElement, error: Error): void {
|
95
|
-
element.dispatchEvent(
|
96
|
-
new ErrorEvent('error', {
|
97
|
-
message: error.message,
|
98
|
-
error
|
99
|
-
})
|
100
|
-
);
|
101
|
-
element.ownerDocument.defaultView.dispatchEvent(
|
102
|
-
new ErrorEvent('error', {
|
103
|
-
message: error.message,
|
104
|
-
error
|
105
|
-
})
|
106
|
-
);
|
107
|
-
element.ownerDocument.defaultView.console.error(error);
|
108
|
-
}
|
109
66
|
}
|
@@ -52,6 +52,7 @@ export default class GlobalWindow extends Window implements IWindow {
|
|
52
52
|
public decodeURIComponent: typeof decodeURIComponent = globalThis.decodeURIComponent;
|
53
53
|
public encodeURI: typeof encodeURI = globalThis.encodeURI;
|
54
54
|
public encodeURIComponent: typeof encodeURIComponent = globalThis.encodeURIComponent;
|
55
|
+
public eval: typeof eval = globalThis.eval;
|
55
56
|
/**
|
56
57
|
* @deprecated
|
57
58
|
*/
|
@@ -69,16 +70,6 @@ export default class GlobalWindow extends Window implements IWindow {
|
|
69
70
|
public gc: () => void = globalThis.gc;
|
70
71
|
public v8debug?: unknown = globalThis.v8debug;
|
71
72
|
|
72
|
-
/**
|
73
|
-
* Evaluates code.
|
74
|
-
*
|
75
|
-
* @param code Code.
|
76
|
-
* @returns Result.
|
77
|
-
*/
|
78
|
-
public override eval(code: string): unknown {
|
79
|
-
return eval(code);
|
80
|
-
}
|
81
|
-
|
82
73
|
/**
|
83
74
|
* Setup of VM context.
|
84
75
|
*/
|
package/src/window/IWindow.ts
CHANGED
@@ -123,6 +123,7 @@ import IHeadersInit from '../fetch/types/IHeadersInit.js';
|
|
123
123
|
import RadioNodeList from '../nodes/html-form-element/RadioNodeList.js';
|
124
124
|
import ValidityState from '../validity-state/ValidityState.js';
|
125
125
|
import INodeJSGlobal from './INodeJSGlobal.js';
|
126
|
+
import VirtualConsolePrinter from '../console/VirtualConsolePrinter.js';
|
126
127
|
|
127
128
|
/**
|
128
129
|
* Window without dependencies to server side specific packages.
|
@@ -135,6 +136,7 @@ export default interface IWindow extends IEventTarget, INodeJSGlobal {
|
|
135
136
|
asyncTaskManager: AsyncTaskManager;
|
136
137
|
setWindowSize: (options: { width?: number; height?: number }) => void;
|
137
138
|
setURL: (url: string) => void;
|
139
|
+
virtualConsolePrinter: VirtualConsolePrinter | null;
|
138
140
|
settings: IHappyDOMSettings;
|
139
141
|
|
140
142
|
/**
|
@@ -294,14 +296,6 @@ export default interface IWindow extends IEventTarget, INodeJSGlobal {
|
|
294
296
|
readonly scrollX: number;
|
295
297
|
readonly scrollY: number;
|
296
298
|
|
297
|
-
/**
|
298
|
-
* Evaluates code.
|
299
|
-
*
|
300
|
-
* @param code Code.
|
301
|
-
* @returns Result.
|
302
|
-
*/
|
303
|
-
eval(code: string): unknown;
|
304
|
-
|
305
299
|
/**
|
306
300
|
* Returns an object containing the values of all CSS properties of an element.
|
307
301
|
*
|
@@ -39,6 +39,7 @@ this.decodeURI = globalThis.decodeURI;
|
|
39
39
|
this.decodeURIComponent = globalThis.decodeURIComponent;
|
40
40
|
this.encodeURI = globalThis.encodeURI;
|
41
41
|
this.encodeURIComponent = globalThis.encodeURIComponent;
|
42
|
+
this.eval = globalThis.eval;
|
42
43
|
this.escape = globalThis.escape;
|
43
44
|
this.global = globalThis.global;
|
44
45
|
this.isFinite = globalThis.isFinite;
|
package/src/window/Window.ts
CHANGED
@@ -135,6 +135,10 @@ import DOMExceptionNameEnum from '../exception/DOMExceptionNameEnum.js';
|
|
135
135
|
import IHappyDOMOptions from './IHappyDOMOptions.js';
|
136
136
|
import RadioNodeList from '../nodes/html-form-element/RadioNodeList.js';
|
137
137
|
import ValidityState from '../validity-state/ValidityState.js';
|
138
|
+
import WindowErrorUtility from './WindowErrorUtility.js';
|
139
|
+
import VirtualConsole from '../console/VirtualConsole.js';
|
140
|
+
import VirtualConsolePrinter from '../console/VirtualConsolePrinter.js';
|
141
|
+
import IHappyDOMSettings from './IHappyDOMSettings.js';
|
138
142
|
|
139
143
|
const ORIGINAL_SET_TIMEOUT = setTimeout;
|
140
144
|
const ORIGINAL_CLEAR_TIMEOUT = clearTimeout;
|
@@ -150,7 +154,25 @@ const ORIGINAL_QUEUE_MICROTASK = queueMicrotask;
|
|
150
154
|
*/
|
151
155
|
export default class Window extends EventTarget implements IWindow {
|
152
156
|
// The Happy DOM property
|
153
|
-
public readonly happyDOM
|
157
|
+
public readonly happyDOM: {
|
158
|
+
whenAsyncComplete: () => Promise<void>;
|
159
|
+
cancelAsync: () => void;
|
160
|
+
asyncTaskManager: AsyncTaskManager;
|
161
|
+
setWindowSize: (options: { width?: number; height?: number }) => void;
|
162
|
+
setURL: (url: string) => void;
|
163
|
+
virtualConsolePrinter: VirtualConsolePrinter | null;
|
164
|
+
settings: IHappyDOMSettings;
|
165
|
+
|
166
|
+
/**
|
167
|
+
* @deprecated
|
168
|
+
*/
|
169
|
+
setInnerWidth: (width: number) => void;
|
170
|
+
|
171
|
+
/**
|
172
|
+
* @deprecated
|
173
|
+
*/
|
174
|
+
setInnerHeight: (height: number) => void;
|
175
|
+
} = {
|
154
176
|
whenAsyncComplete: async (): Promise<void> => {
|
155
177
|
return await this.happyDOM.asyncTaskManager.whenComplete();
|
156
178
|
},
|
@@ -158,9 +180,6 @@ export default class Window extends EventTarget implements IWindow {
|
|
158
180
|
this.happyDOM.asyncTaskManager.cancelAll();
|
159
181
|
},
|
160
182
|
asyncTaskManager: new AsyncTaskManager(),
|
161
|
-
setURL: (url: string) => {
|
162
|
-
this.location.href = url;
|
163
|
-
},
|
164
183
|
setWindowSize: (options: { width?: number; height?: number }): void => {
|
165
184
|
if (
|
166
185
|
(options.width !== undefined && this.innerWidth !== options.width) ||
|
@@ -179,6 +198,10 @@ export default class Window extends EventTarget implements IWindow {
|
|
179
198
|
this.dispatchEvent(new Event('resize'));
|
180
199
|
}
|
181
200
|
},
|
201
|
+
virtualConsolePrinter: null,
|
202
|
+
setURL: (url: string) => {
|
203
|
+
this.location.href = url;
|
204
|
+
},
|
182
205
|
settings: {
|
183
206
|
disableJavaScriptEvaluation: false,
|
184
207
|
disableJavaScriptFileLoading: false,
|
@@ -191,17 +214,7 @@ export default class Window extends EventTarget implements IWindow {
|
|
191
214
|
mediaType: 'screen'
|
192
215
|
}
|
193
216
|
},
|
194
|
-
|
195
|
-
/**
|
196
|
-
* @param width The width of the viewport.
|
197
|
-
* @deprecated
|
198
|
-
*/
|
199
217
|
setInnerWidth: (width: number): void => this.happyDOM.setWindowSize({ width }),
|
200
|
-
|
201
|
-
/**
|
202
|
-
* @param height The height of the viewport.
|
203
|
-
* @deprecated
|
204
|
-
*/
|
205
218
|
setInnerHeight: (height: number): void => this.happyDOM.setWindowSize({ height })
|
206
219
|
};
|
207
220
|
|
@@ -336,7 +349,7 @@ export default class Window extends EventTarget implements IWindow {
|
|
336
349
|
public readonly location: Location;
|
337
350
|
public readonly history: History;
|
338
351
|
public readonly navigator: Navigator;
|
339
|
-
public readonly console
|
352
|
+
public readonly console: Console;
|
340
353
|
public readonly self = this;
|
341
354
|
public readonly top = this;
|
342
355
|
public readonly parent = this;
|
@@ -347,10 +360,10 @@ export default class Window extends EventTarget implements IWindow {
|
|
347
360
|
public readonly sessionStorage: Storage;
|
348
361
|
public readonly localStorage: Storage;
|
349
362
|
public readonly performance = PerfHooks.performance;
|
350
|
-
public readonly innerWidth: number;
|
351
|
-
public readonly innerHeight: number;
|
352
|
-
public readonly outerWidth: number;
|
353
|
-
public readonly outerHeight: number;
|
363
|
+
public readonly innerWidth: number = 1024;
|
364
|
+
public readonly innerHeight: number = 768;
|
365
|
+
public readonly outerWidth: number = 1024;
|
366
|
+
public readonly outerHeight: number = 768;
|
354
367
|
|
355
368
|
// Node.js Globals
|
356
369
|
public Array: typeof Array;
|
@@ -395,6 +408,7 @@ export default class Window extends EventTarget implements IWindow {
|
|
395
408
|
public decodeURIComponent: typeof decodeURIComponent;
|
396
409
|
public encodeURI: typeof encodeURI;
|
397
410
|
public encodeURIComponent: typeof encodeURIComponent;
|
411
|
+
public eval: typeof eval;
|
398
412
|
/**
|
399
413
|
* @deprecated
|
400
414
|
*/
|
@@ -447,41 +461,44 @@ export default class Window extends EventTarget implements IWindow {
|
|
447
461
|
this.sessionStorage = new Storage();
|
448
462
|
this.localStorage = new Storage();
|
449
463
|
|
450
|
-
if (options
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
this.outerWidth = 1024;
|
459
|
-
}
|
464
|
+
if (options) {
|
465
|
+
if (options.width !== undefined) {
|
466
|
+
this.innerWidth = options.width;
|
467
|
+
this.outerWidth = options.width;
|
468
|
+
} else if (options.innerWidth !== undefined) {
|
469
|
+
this.innerWidth = options.innerWidth;
|
470
|
+
this.outerWidth = options.innerWidth;
|
471
|
+
}
|
460
472
|
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
this.innerHeight = 768;
|
469
|
-
this.outerHeight = 768;
|
470
|
-
}
|
473
|
+
if (options.height !== undefined) {
|
474
|
+
this.innerHeight = options.height;
|
475
|
+
this.outerHeight = options.height;
|
476
|
+
} else if (options.innerHeight !== undefined) {
|
477
|
+
this.innerHeight = options.innerHeight;
|
478
|
+
this.outerHeight = options.innerHeight;
|
479
|
+
}
|
471
480
|
|
472
|
-
|
473
|
-
|
481
|
+
if (options.url !== undefined) {
|
482
|
+
this.location.href = options.url;
|
483
|
+
}
|
484
|
+
|
485
|
+
if (options.settings) {
|
486
|
+
this.happyDOM.settings = {
|
487
|
+
...this.happyDOM.settings,
|
488
|
+
...options.settings,
|
489
|
+
device: {
|
490
|
+
...this.happyDOM.settings.device,
|
491
|
+
...options.settings.device
|
492
|
+
}
|
493
|
+
};
|
494
|
+
}
|
474
495
|
}
|
475
496
|
|
476
|
-
if (options && options.
|
477
|
-
this.
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
...this.happyDOM.settings.device,
|
482
|
-
...options.settings.device
|
483
|
-
}
|
484
|
-
};
|
497
|
+
if (options && options.console) {
|
498
|
+
this.console = options.console;
|
499
|
+
} else {
|
500
|
+
this.happyDOM.virtualConsolePrinter = new VirtualConsolePrinter();
|
501
|
+
this.console = new VirtualConsole(this.happyDOM.virtualConsolePrinter);
|
485
502
|
}
|
486
503
|
|
487
504
|
this._setTimeout = ORIGINAL_SET_TIMEOUT;
|
@@ -622,20 +639,6 @@ export default class Window extends EventTarget implements IWindow {
|
|
622
639
|
return new CSS();
|
623
640
|
}
|
624
641
|
|
625
|
-
/**
|
626
|
-
* Evaluates code.
|
627
|
-
*
|
628
|
-
* @override
|
629
|
-
* @param code Code.
|
630
|
-
* @returns Result.
|
631
|
-
*/
|
632
|
-
public eval(code: string): unknown {
|
633
|
-
if (VM.isContext(this)) {
|
634
|
-
return VM.runInContext(code, this);
|
635
|
-
}
|
636
|
-
return eval(code);
|
637
|
-
}
|
638
|
-
|
639
642
|
/**
|
640
643
|
* Returns an object containing the values of all CSS properties of an element.
|
641
644
|
*
|
@@ -721,7 +724,7 @@ export default class Window extends EventTarget implements IWindow {
|
|
721
724
|
public setTimeout(callback: Function, delay = 0, ...args: unknown[]): NodeJS.Timeout {
|
722
725
|
const id = this._setTimeout(() => {
|
723
726
|
this.happyDOM.asyncTaskManager.endTimer(id);
|
724
|
-
callback(...args);
|
727
|
+
WindowErrorUtility.captureErrorSync(this, () => callback(...args));
|
725
728
|
}, delay);
|
726
729
|
this.happyDOM.asyncTaskManager.startTimer(id);
|
727
730
|
return id;
|
@@ -746,7 +749,13 @@ export default class Window extends EventTarget implements IWindow {
|
|
746
749
|
* @returns Interval ID.
|
747
750
|
*/
|
748
751
|
public setInterval(callback: Function, delay = 0, ...args: unknown[]): NodeJS.Timeout {
|
749
|
-
const id = this._setInterval(
|
752
|
+
const id = this._setInterval(() => {
|
753
|
+
WindowErrorUtility.captureErrorSync(
|
754
|
+
this,
|
755
|
+
() => callback(...args),
|
756
|
+
() => this.clearInterval(id)
|
757
|
+
);
|
758
|
+
}, delay);
|
750
759
|
this.happyDOM.asyncTaskManager.startTimer(id);
|
751
760
|
return id;
|
752
761
|
}
|
@@ -768,9 +777,7 @@ export default class Window extends EventTarget implements IWindow {
|
|
768
777
|
* @returns Timeout ID.
|
769
778
|
*/
|
770
779
|
public requestAnimationFrame(callback: (timestamp: number) => void): NodeJS.Timeout {
|
771
|
-
return this.setTimeout(() =>
|
772
|
-
callback(this.performance.now());
|
773
|
-
});
|
780
|
+
return this.setTimeout(() => callback(this.performance.now()));
|
774
781
|
}
|
775
782
|
|
776
783
|
/**
|
@@ -792,8 +799,8 @@ export default class Window extends EventTarget implements IWindow {
|
|
792
799
|
const taskId = this.happyDOM.asyncTaskManager.startTask(() => (isAborted = true));
|
793
800
|
this._queueMicrotask(() => {
|
794
801
|
if (!isAborted) {
|
802
|
+
WindowErrorUtility.captureErrorSync(this, <() => unknown>callback);
|
795
803
|
this.happyDOM.asyncTaskManager.endTask(taskId);
|
796
|
-
callback();
|
797
804
|
}
|
798
805
|
});
|
799
806
|
}
|