Skip to content

Commit e21c817

Browse files
authored
fix(xmlhttprequest): add support EventListenerObject (#124)
1 parent f46cdc0 commit e21c817

File tree

2 files changed

+40
-5
lines changed

2 files changed

+40
-5
lines changed

src/dom/eventtarget.ts

+18-5
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,18 @@ interface EventListener {
3535
(event: Event): void;
3636
}
3737

38+
interface EventListenerObject {
39+
handleEvent(event: Event): void;
40+
}
41+
42+
type EventListenerOrEventListenerObject = EventListener | EventListenerObject;
43+
3844
/**
3945
* @see {@link https://dom.spec.whatwg.org/#interface-eventtarget DOM Standard - 2.7. Interface EventTarget}
4046
*/
4147
export default class EventTarget {
4248
#listeners: {
43-
[type: string]: Set<EventListener>;
49+
[type: string]: Set<EventListenerOrEventListenerObject>;
4450
};
4551

4652
constructor() {
@@ -52,11 +58,12 @@ export default class EventTarget {
5258
*/
5359
addEventListener(
5460
type: string,
55-
listener: EventListener,
61+
listener: EventListenerOrEventListenerObject,
5662
// eslint-disable-next-line @typescript-eslint/no-unused-vars
5763
options: boolean | AddEventListenerOptions = false
5864
): void {
59-
this.#listeners[type] = this.#listeners[type] ?? new Set<EventListener>();
65+
this.#listeners[type] =
66+
this.#listeners[type] ?? new Set<EventListenerOrEventListenerObject>();
6067

6168
if (!this.#listeners[type].has(listener)) {
6269
this.#listeners[type].add(listener);
@@ -80,7 +87,13 @@ export default class EventTarget {
8087

8188
if (listeners && !event[internalEventSymbol].propagationStoped) {
8289
for (const listener of listeners) {
83-
listener.call(this, event);
90+
if (typeof listener === 'undefined') continue;
91+
92+
if (typeof listener === 'function') {
93+
listener.call(this, event);
94+
} else if (typeof listener.handleEvent === 'function') {
95+
listener.handleEvent.call(listener, event);
96+
}
8497
}
8598
}
8699

@@ -98,7 +111,7 @@ export default class EventTarget {
98111
*/
99112
removeEventListener(
100113
type: string,
101-
listener: EventListener,
114+
listener: EventListenerOrEventListenerObject,
102115
// eslint-disable-next-line @typescript-eslint/no-unused-vars
103116
options: boolean | EventListenerOptions = false
104117
): void {

test/integration/xmlhttprequest.ts

+22
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,28 @@ describe('XMLHttpRequest', () => {
126126
client.send(null);
127127
});
128128

129+
it('use object with handleEvent', (done) => {
130+
const client = new XMLHttpRequest();
131+
132+
const obj = {
133+
handleEvent() {
134+
expect(client.status).toBe(expectedStatus);
135+
expect(client.statusText).toBe(expectedStatusText);
136+
137+
if (eventType !== 'progress') {
138+
expect(client.responseText).toBe(expectedResponseText);
139+
}
140+
141+
done();
142+
}
143+
};
144+
145+
client.addEventListener(eventType, obj);
146+
147+
client.open('GET', `${baseURL}/?body=response%20text`);
148+
client.send(null);
149+
});
150+
129151
it('use object property', (done) => {
130152
const client = new XMLHttpRequest();
131153
const prop = `on${eventType}` as

0 commit comments

Comments
 (0)