@remote-dom/polyfill 1.4.5 → 1.4.7
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.
- package/CHANGELOG.md +12 -0
- package/build/cjs/ClipboardEvent.cjs +15 -0
- package/build/cjs/ErrorEvent.cjs +19 -0
- package/build/cjs/FocusEvent.cjs +15 -0
- package/build/cjs/PromiseRejectionEvent.cjs +16 -0
- package/build/cjs/ToggleEvent.cjs +16 -0
- package/build/cjs/Window.cjs +50 -0
- package/build/esm/ClipboardEvent.mjs +11 -0
- package/build/esm/ErrorEvent.mjs +15 -0
- package/build/esm/FocusEvent.mjs +11 -0
- package/build/esm/PromiseRejectionEvent.mjs +12 -0
- package/build/esm/ToggleEvent.mjs +12 -0
- package/build/esm/Window.mjs +50 -0
- package/build/esnext/ClipboardEvent.esnext +11 -0
- package/build/esnext/ErrorEvent.esnext +19 -0
- package/build/esnext/FocusEvent.esnext +11 -0
- package/build/esnext/PromiseRejectionEvent.esnext +13 -0
- package/build/esnext/ToggleEvent.esnext +13 -0
- package/build/esnext/Window.esnext +57 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/typescript/ClipboardEvent.d.ts +6 -0
- package/build/typescript/ClipboardEvent.d.ts.map +1 -0
- package/build/typescript/ErrorEvent.d.ts +10 -0
- package/build/typescript/ErrorEvent.d.ts.map +1 -0
- package/build/typescript/FocusEvent.d.ts +6 -0
- package/build/typescript/FocusEvent.d.ts.map +1 -0
- package/build/typescript/PromiseRejectionEvent.d.ts +7 -0
- package/build/typescript/PromiseRejectionEvent.d.ts.map +1 -0
- package/build/typescript/ToggleEvent.d.ts +7 -0
- package/build/typescript/ToggleEvent.d.ts.map +1 -0
- package/build/typescript/Window.d.ts +17 -0
- package/build/typescript/Window.d.ts.map +1 -1
- package/build/typescript/tests/global-errors.test.d.ts +2 -0
- package/build/typescript/tests/global-errors.test.d.ts.map +1 -0
- package/package.json +1 -1
- package/source/ClipboardEvent.ts +12 -0
- package/source/ErrorEvent.ts +20 -0
- package/source/FocusEvent.ts +12 -0
- package/source/PromiseRejectionEvent.ts +14 -0
- package/source/ToggleEvent.ts +14 -0
- package/source/Window.ts +78 -0
- package/source/tests/global-errors.test.ts +149 -0
package/source/Window.ts
CHANGED
|
@@ -2,6 +2,11 @@ import {Document} from './Document.ts';
|
|
|
2
2
|
import {Event} from './Event.ts';
|
|
3
3
|
import {EventTarget} from './EventTarget.ts';
|
|
4
4
|
import {CustomEvent} from './CustomEvent.ts';
|
|
5
|
+
import {ErrorEvent} from './ErrorEvent.ts';
|
|
6
|
+
import {PromiseRejectionEvent} from './PromiseRejectionEvent.ts';
|
|
7
|
+
import {ToggleEvent} from './ToggleEvent.ts';
|
|
8
|
+
import {FocusEvent} from './FocusEvent.ts';
|
|
9
|
+
import {ClipboardEvent} from './ClipboardEvent.ts';
|
|
5
10
|
import {Node} from './Node.ts';
|
|
6
11
|
import {ParentNode} from './ParentNode.ts';
|
|
7
12
|
import {ChildNode} from './ChildNode.ts';
|
|
@@ -18,6 +23,16 @@ import {MutationObserver} from './MutationObserver.ts';
|
|
|
18
23
|
import {HOOKS} from './constants.ts';
|
|
19
24
|
import type {Hooks} from './hooks.ts';
|
|
20
25
|
|
|
26
|
+
type OnErrorHandler =
|
|
27
|
+
| ((
|
|
28
|
+
message: string,
|
|
29
|
+
filename?: string,
|
|
30
|
+
lineno?: number,
|
|
31
|
+
colno?: number,
|
|
32
|
+
error?: any,
|
|
33
|
+
) => void)
|
|
34
|
+
| null;
|
|
35
|
+
|
|
21
36
|
export class Window extends EventTarget {
|
|
22
37
|
[HOOKS]: Partial<Hooks> = {};
|
|
23
38
|
name = '';
|
|
@@ -30,6 +45,11 @@ export class Window extends EventTarget {
|
|
|
30
45
|
location = globalThis.location;
|
|
31
46
|
navigator = globalThis.navigator;
|
|
32
47
|
Event = Event;
|
|
48
|
+
ErrorEvent = ErrorEvent;
|
|
49
|
+
PromiseRejectionEvent = PromiseRejectionEvent;
|
|
50
|
+
ToggleEvent = ToggleEvent;
|
|
51
|
+
FocusEvent = FocusEvent;
|
|
52
|
+
ClipboardEvent = ClipboardEvent;
|
|
33
53
|
EventTarget = EventTarget;
|
|
34
54
|
CustomEvent = CustomEvent;
|
|
35
55
|
Node = Node;
|
|
@@ -46,6 +66,64 @@ export class Window extends EventTarget {
|
|
|
46
66
|
HTMLTemplateElement = HTMLTemplateElement;
|
|
47
67
|
MutationObserver = MutationObserver;
|
|
48
68
|
|
|
69
|
+
#currentOnErrorHandler: ((event: any) => void) | null = null;
|
|
70
|
+
#currentOriginalOnErrorHandler: OnErrorHandler = null;
|
|
71
|
+
#currentOnUnhandledRejectionHandler: WindowEventHandlers['onunhandledrejection'] =
|
|
72
|
+
null;
|
|
73
|
+
|
|
74
|
+
get onerror() {
|
|
75
|
+
return this.#currentOriginalOnErrorHandler;
|
|
76
|
+
}
|
|
77
|
+
set onerror(handler: OnErrorHandler) {
|
|
78
|
+
if (this.#currentOnErrorHandler) {
|
|
79
|
+
this.removeEventListener('error', this.#currentOnErrorHandler);
|
|
80
|
+
}
|
|
81
|
+
if (handler && typeof handler === 'function') {
|
|
82
|
+
// the event listener version receives an event object
|
|
83
|
+
// whereas winwow.onerror receives 5 arguments instead
|
|
84
|
+
// we need to wrap the handler to convert the event object to the 5 arguments
|
|
85
|
+
// and also make sure that when window.onerror is read to return the original handler
|
|
86
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Window/error_event#syntax
|
|
87
|
+
this.#currentOriginalOnErrorHandler = handler;
|
|
88
|
+
this.#currentOnErrorHandler = (event: ErrorEvent) => {
|
|
89
|
+
handler(
|
|
90
|
+
event.message ?? 'Error',
|
|
91
|
+
event.filename,
|
|
92
|
+
event.lineno,
|
|
93
|
+
event.colno,
|
|
94
|
+
event.error,
|
|
95
|
+
);
|
|
96
|
+
};
|
|
97
|
+
this.addEventListener('error', this.#currentOnErrorHandler);
|
|
98
|
+
} else {
|
|
99
|
+
this.#currentOnErrorHandler = null;
|
|
100
|
+
this.#currentOriginalOnErrorHandler = null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
get onunhandledrejection() {
|
|
105
|
+
return this.#currentOnUnhandledRejectionHandler;
|
|
106
|
+
}
|
|
107
|
+
set onunhandledrejection(
|
|
108
|
+
handler: WindowEventHandlers['onunhandledrejection'],
|
|
109
|
+
) {
|
|
110
|
+
if (this.#currentOnUnhandledRejectionHandler) {
|
|
111
|
+
this.removeEventListener(
|
|
112
|
+
'unhandledrejection',
|
|
113
|
+
this.#currentOnUnhandledRejectionHandler as any,
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
if (handler && typeof handler === 'function') {
|
|
117
|
+
this.#currentOnUnhandledRejectionHandler = handler;
|
|
118
|
+
this.addEventListener(
|
|
119
|
+
'unhandledrejection',
|
|
120
|
+
this.#currentOnUnhandledRejectionHandler as any,
|
|
121
|
+
);
|
|
122
|
+
} else {
|
|
123
|
+
this.#currentOnUnhandledRejectionHandler = null;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
49
127
|
static setGlobal(window: Window) {
|
|
50
128
|
const properties = Object.getOwnPropertyDescriptors(window);
|
|
51
129
|
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import {ErrorEvent} from '../ErrorEvent.ts';
|
|
2
|
+
import {PromiseRejectionEvent} from '../PromiseRejectionEvent.ts';
|
|
3
|
+
import {Window} from '../Window.ts';
|
|
4
|
+
import {describe, it, expect, beforeEach, afterEach, vi} from 'vitest';
|
|
5
|
+
|
|
6
|
+
describe('global errors', () => {
|
|
7
|
+
describe('onerror', () => {
|
|
8
|
+
let originalOnerror: any;
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
originalOnerror = globalThis.onerror;
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
afterEach(() => {
|
|
15
|
+
globalThis.onerror = originalOnerror;
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('sets onerror handler on window instance', () => {
|
|
19
|
+
const handler = vi.fn();
|
|
20
|
+
const window = new Window();
|
|
21
|
+
|
|
22
|
+
window.onerror = handler;
|
|
23
|
+
expect(window.onerror).toBe(handler);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('overrides onerror handler on window instance', () => {
|
|
27
|
+
const handler = vi.fn();
|
|
28
|
+
const handler2 = vi.fn();
|
|
29
|
+
|
|
30
|
+
const window = new Window();
|
|
31
|
+
window.onerror = handler;
|
|
32
|
+
window.onerror = handler2;
|
|
33
|
+
|
|
34
|
+
expect(window.onerror).toBe(handler2);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('calls handler when error occurs', () => {
|
|
38
|
+
const handler = vi.fn();
|
|
39
|
+
const window = new Window();
|
|
40
|
+
|
|
41
|
+
const error = new Error('test');
|
|
42
|
+
|
|
43
|
+
window.onerror = handler;
|
|
44
|
+
window.dispatchEvent(
|
|
45
|
+
new ErrorEvent('error', {
|
|
46
|
+
error,
|
|
47
|
+
filename: 'test.ts',
|
|
48
|
+
lineno: 1,
|
|
49
|
+
colno: 1,
|
|
50
|
+
}),
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
expect(handler).toHaveBeenCalledWith('Error', 'test.ts', 1, 1, error);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('allows null assignment', () => {
|
|
57
|
+
const handler = vi.fn();
|
|
58
|
+
const window = new Window();
|
|
59
|
+
window.onerror = handler;
|
|
60
|
+
expect(window.onerror).toBe(handler);
|
|
61
|
+
|
|
62
|
+
window.onerror = null;
|
|
63
|
+
expect(window.onerror).toBe(null);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('works when window is set as global', () => {
|
|
67
|
+
const window = new Window();
|
|
68
|
+
Window.setGlobalThis(window);
|
|
69
|
+
const handler = vi.fn();
|
|
70
|
+
window.onerror = handler;
|
|
71
|
+
|
|
72
|
+
expect(window.onerror).toBe(handler);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
describe('onunhandledrejection', () => {
|
|
77
|
+
let originalOnunhandledrejection: any;
|
|
78
|
+
|
|
79
|
+
beforeEach(() => {
|
|
80
|
+
originalOnunhandledrejection = globalThis.onunhandledrejection;
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
afterEach(() => {
|
|
84
|
+
globalThis.onunhandledrejection = originalOnunhandledrejection;
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('sets onunhandledrejection handler on window instance', () => {
|
|
88
|
+
const handler = vi.fn();
|
|
89
|
+
const window = new Window();
|
|
90
|
+
|
|
91
|
+
window.onunhandledrejection = handler;
|
|
92
|
+
expect(window.onunhandledrejection).toBe(handler);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('overrides onunhandledrejection handler on window instance', () => {
|
|
96
|
+
const handler = vi.fn();
|
|
97
|
+
const handler2 = vi.fn();
|
|
98
|
+
const window = new Window();
|
|
99
|
+
|
|
100
|
+
window.onunhandledrejection = handler;
|
|
101
|
+
window.onunhandledrejection = handler2;
|
|
102
|
+
expect(window.onunhandledrejection).toBe(handler2);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('calls handler when unhandled rejection occurs', () => {
|
|
106
|
+
const handler = vi.fn();
|
|
107
|
+
const window = new Window();
|
|
108
|
+
window.onunhandledrejection = handler;
|
|
109
|
+
|
|
110
|
+
const error = new Error('test');
|
|
111
|
+
const promise = Promise.resolve();
|
|
112
|
+
|
|
113
|
+
window.dispatchEvent(
|
|
114
|
+
new PromiseRejectionEvent('unhandledrejection', {
|
|
115
|
+
promise: promise,
|
|
116
|
+
reason: error,
|
|
117
|
+
}),
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
expect(handler).toHaveBeenCalledWith(
|
|
121
|
+
expect.objectContaining({
|
|
122
|
+
promise,
|
|
123
|
+
reason: error,
|
|
124
|
+
}),
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
expect(handler).toHaveBeenCalledWith(expect.any(PromiseRejectionEvent));
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('allows null assignment', () => {
|
|
131
|
+
const handler = vi.fn();
|
|
132
|
+
const window = new Window();
|
|
133
|
+
window.onunhandledrejection = handler;
|
|
134
|
+
expect(window.onunhandledrejection).toBe(handler);
|
|
135
|
+
|
|
136
|
+
window.onunhandledrejection = null;
|
|
137
|
+
expect(window.onunhandledrejection).toBe(null);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('works when window is set as global', () => {
|
|
141
|
+
const window = new Window();
|
|
142
|
+
Window.setGlobalThis(window);
|
|
143
|
+
const handler = vi.fn();
|
|
144
|
+
window.onunhandledrejection = handler;
|
|
145
|
+
|
|
146
|
+
expect(window.onunhandledrejection).toBe(handler);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
});
|