fix(zone.js): Make EventTarget methods optional in zone.js extension API (#35954)

`zone.js` added `removeAllListeners` and `eventListeners` methods in `EventTarget.prototype`, but those methods only exists when user import `zone.js` and also enables `EventTarget` monkey patching.

If user:
1. Does not import `zone.js` and uses `noop` zone when bootstrapping Angular app. OR
2. Disable monkey patching of `EventTarget` patch by defining `__Zone_disable_EventTarget = true`.

Then `removeAllListeners` and `eventListeners`  methods will not be present.

PR Close #35954
This commit is contained in:
JiaLiPassion 2020-03-09 19:48:48 +09:00 committed by Andrew Kushnir
parent 8456c5ec60
commit 54634628ac
2 changed files with 37 additions and 31 deletions

View File

@ -17,22 +17,28 @@ interface EventTarget {
* *
* Remove all event listeners by name for this event target. * Remove all event listeners by name for this event target.
* *
* This method is optional because it may not be available if you use `noop zone` when
* bootstrapping Angular application or disable the `EventTarget` monkey patch by `zone.js`.
*
* If the `eventName` is provided, will remove event listeners of that name. * If the `eventName` is provided, will remove event listeners of that name.
* If the `eventName` is not provided, will remove all event listeners associated with * If the `eventName` is not provided, will remove all event listeners associated with
* `EventTarget`. * `EventTarget`.
* *
* @param eventName the name of the event, such as `click`. This parameter is optional. * @param eventName the name of the event, such as `click`. This parameter is optional.
*/ */
removeAllListeners(eventName?: string): void; removeAllListeners?(eventName?: string): void;
/** /**
* *
* Retrieve all event listeners by name. * Retrieve all event listeners by name.
* *
* This method is optional because it may not be available if you use `noop zone` when
* bootstrapping Angular application or disable the `EventTarget` monkey patch by `zone.js`.
*
* If the `eventName` is provided, will return an array of event handlers or event listener * If the `eventName` is provided, will return an array of event handlers or event listener
* objects of the given event. * objects of the given event.
* If the `eventName` is not provided, will return all listeners. * If the `eventName` is not provided, will return all listeners.
* *
* @param eventName the name of the event, such as click. This parameter is optional. * @param eventName the name of the event, such as click. This parameter is optional.
*/ */
eventListeners(eventName?: string): EventListenerOrEventListenerObject[]; eventListeners?(eventName?: string): EventListenerOrEventListenerObject[];
} }

View File

@ -1127,11 +1127,11 @@ describe('Zone', function() {
}); });
zone.run(() => { button.addEventListener('click', function() { logs.push('click'); }); }); zone.run(() => { button.addEventListener('click', function() { logs.push('click'); }); });
let listeners = button.eventListeners('click'); let listeners = button.eventListeners !('click');
expect(listeners.length).toBe(1); expect(listeners.length).toBe(1);
eventTask !.zone.cancelTask(eventTask !); eventTask !.zone.cancelTask(eventTask !);
listeners = button.eventListeners('click'); listeners = button.eventListeners !('click');
button.dispatchEvent(clickEvent); button.dispatchEvent(clickEvent);
expect(logs.length).toBe(0); expect(logs.length).toBe(0);
expect(listeners.length).toBe(0); expect(listeners.length).toBe(0);
@ -1153,11 +1153,11 @@ describe('Zone', function() {
zone.run(() => { zone.run(() => {
button.addEventListener('click', function() { logs.push('click'); }, true); button.addEventListener('click', function() { logs.push('click'); }, true);
}); });
let listeners = button.eventListeners('click'); let listeners = button.eventListeners !('click');
expect(listeners.length).toBe(1); expect(listeners.length).toBe(1);
eventTask !.zone.cancelTask(eventTask !); eventTask !.zone.cancelTask(eventTask !);
listeners = button.eventListeners('click'); listeners = button.eventListeners !('click');
button.dispatchEvent(clickEvent); button.dispatchEvent(clickEvent);
expect(logs.length).toBe(0); expect(logs.length).toBe(0);
expect(listeners.length).toBe(0); expect(listeners.length).toBe(0);
@ -1179,7 +1179,7 @@ describe('Zone', function() {
zone.run( zone.run(
() => { button.addEventListener('click', function() { logs.push('click1'); }); }); () => { button.addEventListener('click', function() { logs.push('click1'); }); });
button.addEventListener('click', function() { logs.push('click2'); }); button.addEventListener('click', function() { logs.push('click2'); });
let listeners = button.eventListeners('click'); let listeners = button.eventListeners !('click');
expect(listeners.length).toBe(2); expect(listeners.length).toBe(2);
button.dispatchEvent(clickEvent); button.dispatchEvent(clickEvent);
@ -1188,7 +1188,7 @@ describe('Zone', function() {
eventTask !.zone.cancelTask(eventTask !); eventTask !.zone.cancelTask(eventTask !);
logs = []; logs = [];
listeners = button.eventListeners('click'); listeners = button.eventListeners !('click');
button.dispatchEvent(clickEvent); button.dispatchEvent(clickEvent);
expect(logs.length).toBe(1); expect(logs.length).toBe(1);
expect(listeners.length).toBe(1); expect(listeners.length).toBe(1);
@ -1212,7 +1212,7 @@ describe('Zone', function() {
button.addEventListener('click', function() { logs.push('click1'); }, true); button.addEventListener('click', function() { logs.push('click1'); }, true);
}); });
button.addEventListener('click', function() { logs.push('click2'); }, true); button.addEventListener('click', function() { logs.push('click2'); }, true);
let listeners = button.eventListeners('click'); let listeners = button.eventListeners !('click');
expect(listeners.length).toBe(2); expect(listeners.length).toBe(2);
button.dispatchEvent(clickEvent); button.dispatchEvent(clickEvent);
@ -1221,7 +1221,7 @@ describe('Zone', function() {
eventTask !.zone.cancelTask(eventTask !); eventTask !.zone.cancelTask(eventTask !);
logs = []; logs = [];
listeners = button.eventListeners('click'); listeners = button.eventListeners !('click');
button.dispatchEvent(clickEvent); button.dispatchEvent(clickEvent);
expect(logs.length).toBe(1); expect(logs.length).toBe(1);
expect(listeners.length).toBe(1); expect(listeners.length).toBe(1);
@ -1245,7 +1245,7 @@ describe('Zone', function() {
button.addEventListener('click', function() { logs.push('click1'); }, true); button.addEventListener('click', function() { logs.push('click1'); }, true);
}); });
button.addEventListener('click', function() { logs.push('click2'); }); button.addEventListener('click', function() { logs.push('click2'); });
let listeners = button.eventListeners('click'); let listeners = button.eventListeners !('click');
expect(listeners.length).toBe(2); expect(listeners.length).toBe(2);
button.dispatchEvent(clickEvent); button.dispatchEvent(clickEvent);
@ -1254,7 +1254,7 @@ describe('Zone', function() {
eventTask !.zone.cancelTask(eventTask !); eventTask !.zone.cancelTask(eventTask !);
logs = []; logs = [];
listeners = button.eventListeners('click'); listeners = button.eventListeners !('click');
button.dispatchEvent(clickEvent); button.dispatchEvent(clickEvent);
expect(logs.length).toBe(1); expect(logs.length).toBe(1);
expect(listeners.length).toBe(1); expect(listeners.length).toBe(1);
@ -1796,7 +1796,7 @@ describe('Zone', function() {
function() { function() {
let logs: string[] = []; let logs: string[] = [];
const listener1 = function() { const listener1 = function() {
button.removeAllListeners('click'); button.removeAllListeners !('click');
logs.push('listener1'); logs.push('listener1');
}; };
const listener2 = function() { logs.push('listener2'); }; const listener2 = function() { logs.push('listener2'); };
@ -1819,7 +1819,7 @@ describe('Zone', function() {
function() { function() {
let logs: string[] = []; let logs: string[] = [];
const listener1 = function() { const listener1 = function() {
button.removeAllListeners('click'); button.removeAllListeners !('click');
logs.push('listener1'); logs.push('listener1');
}; };
const listener2 = function() { logs.push('listener2'); }; const listener2 = function() { logs.push('listener2'); };
@ -1843,7 +1843,7 @@ describe('Zone', function() {
let logs: string[] = []; let logs: string[] = [];
const listener1 = function() { logs.push('listener1'); }; const listener1 = function() { logs.push('listener1'); };
const listener2 = function() { const listener2 = function() {
button.removeAllListeners('click'); button.removeAllListeners !('click');
logs.push('listener2'); logs.push('listener2');
}; };
const listener3 = {handleEvent: function(event: Event) { logs.push('listener3'); }}; const listener3 = {handleEvent: function(event: Event) { logs.push('listener3'); }};
@ -1866,7 +1866,7 @@ describe('Zone', function() {
let logs: string[] = []; let logs: string[] = [];
const listener1 = function() { logs.push('listener1'); }; const listener1 = function() { logs.push('listener1'); };
const listener2 = function() { const listener2 = function() {
button.removeAllListeners('click'); button.removeAllListeners !('click');
logs.push('listener2'); logs.push('listener2');
}; };
const listener3 = {handleEvent: function(event: Event) { logs.push('listener3'); }}; const listener3 = {handleEvent: function(event: Event) { logs.push('listener3'); }};
@ -1892,7 +1892,7 @@ describe('Zone', function() {
const listener3 = { const listener3 = {
handleEvent: function(event: Event) { handleEvent: function(event: Event) {
logs.push('listener3'); logs.push('listener3');
button.removeAllListeners('click'); button.removeAllListeners !('click');
} }
}; };
@ -1917,7 +1917,7 @@ describe('Zone', function() {
const listener3 = { const listener3 = {
handleEvent: function(event: Event) { handleEvent: function(event: Event) {
logs.push('listener3'); logs.push('listener3');
button.removeAllListeners('click'); button.removeAllListeners !('click');
} }
}; };
@ -1946,7 +1946,7 @@ describe('Zone', function() {
button.addEventListener('click', listener3); button.addEventListener('click', listener3);
button.addEventListener('mouseover', listener4); button.addEventListener('mouseover', listener4);
const listeners = button.eventListeners('click'); const listeners = button.eventListeners !('click');
expect(listeners.length).toBe(3); expect(listeners.length).toBe(3);
expect(listeners).toEqual([listener1, listener2, listener3]); expect(listeners).toEqual([listener1, listener2, listener3]);
button.removeEventListener('click', listener1); button.removeEventListener('click', listener1);
@ -1963,7 +1963,7 @@ describe('Zone', function() {
button.addEventListener('mouseover', listener2); button.addEventListener('mouseover', listener2);
button.addEventListener('mousehover', listener3); button.addEventListener('mousehover', listener3);
const listeners = button.eventListeners(); const listeners = button.eventListeners !();
expect(listeners.length).toBe(3); expect(listeners.length).toBe(3);
expect(listeners).toEqual([listener1, listener2, listener3]); expect(listeners).toEqual([listener1, listener2, listener3]);
button.removeEventListener('click', listener1); button.removeEventListener('click', listener1);
@ -1986,8 +1986,8 @@ describe('Zone', function() {
button.onmouseover = listener5; button.onmouseover = listener5;
expect((button as any)[Zone.__symbol__('ON_PROPERTYmouseover')]).toEqual(listener5); expect((button as any)[Zone.__symbol__('ON_PROPERTYmouseover')]).toEqual(listener5);
button.removeAllListeners('mouseover'); button.removeAllListeners !('mouseover');
const listeners = button.eventListeners('mouseover'); const listeners = button.eventListeners !('mouseover');
expect(listeners.length).toBe(0); expect(listeners.length).toBe(0);
expect((button as any)[Zone.__symbol__('ON_PROPERTYmouseover')]).toBeNull(); expect((button as any)[Zone.__symbol__('ON_PROPERTYmouseover')]).toBeNull();
expect(!!button.onmouseover).toBeFalsy(); expect(!!button.onmouseover).toBeFalsy();
@ -2017,8 +2017,8 @@ describe('Zone', function() {
button.addEventListener('mouseover', listener3, true); button.addEventListener('mouseover', listener3, true);
button.addEventListener('click', listener4, true); button.addEventListener('click', listener4, true);
button.removeAllListeners('mouseover'); button.removeAllListeners !('mouseover');
const listeners = button.eventListeners('mouseover'); const listeners = button.eventListeners !('mouseover');
expect(listeners.length).toBe(0); expect(listeners.length).toBe(0);
const mouseEvent = document.createEvent('Event'); const mouseEvent = document.createEvent('Event');
@ -2046,8 +2046,8 @@ describe('Zone', function() {
button.addEventListener('mouseover', listener3, true); button.addEventListener('mouseover', listener3, true);
button.addEventListener('click', listener4, true); button.addEventListener('click', listener4, true);
button.removeAllListeners('mouseover'); button.removeAllListeners !('mouseover');
const listeners = button.eventListeners('mouseove'); const listeners = button.eventListeners !('mouseove');
expect(listeners.length).toBe(0); expect(listeners.length).toBe(0);
const mouseEvent = document.createEvent('Event'); const mouseEvent = document.createEvent('Event');
@ -2077,8 +2077,8 @@ describe('Zone', function() {
button.onmouseover = listener5; button.onmouseover = listener5;
expect((button as any)[Zone.__symbol__('ON_PROPERTYmouseover')]).toEqual(listener5); expect((button as any)[Zone.__symbol__('ON_PROPERTYmouseover')]).toEqual(listener5);
button.removeAllListeners(); button.removeAllListeners !();
const listeners = button.eventListeners('mouseover'); const listeners = button.eventListeners !('mouseover');
expect(listeners.length).toBe(0); expect(listeners.length).toBe(0);
expect((button as any)[Zone.__symbol__('ON_PROPERTYmouseover')]).toBeNull(); expect((button as any)[Zone.__symbol__('ON_PROPERTYmouseover')]).toBeNull();
expect(!!button.onmouseover).toBeFalsy(); expect(!!button.onmouseover).toBeFalsy();
@ -2109,7 +2109,7 @@ describe('Zone', function() {
button.removeEventListener('mouseover', listener2); button.removeEventListener('mouseover', listener2);
button.removeEventListener('click', listener3); button.removeEventListener('click', listener3);
button.removeEventListener('click', listener4); button.removeEventListener('click', listener4);
const listeners = button.eventListeners('mouseover'); const listeners = button.eventListeners !('mouseover');
expect(listeners.length).toBe(0); expect(listeners.length).toBe(0);
const mouseEvent = document.createEvent('Event'); const mouseEvent = document.createEvent('Event');
@ -2134,8 +2134,8 @@ describe('Zone', function() {
button.addEventListener('click', listener3); button.addEventListener('click', listener3);
(button as any)[Zone.__symbol__('addEventListener')]('click', listener4); (button as any)[Zone.__symbol__('addEventListener')]('click', listener4);
button.removeAllListeners(); button.removeAllListeners !();
const listeners = button.eventListeners('mouseover'); const listeners = button.eventListeners !('mouseover');
expect(listeners.length).toBe(0); expect(listeners.length).toBe(0);
const mouseEvent = document.createEvent('Event'); const mouseEvent = document.createEvent('Event');