Skip to content

Commit a182714

Browse files
JiaLiPassionmhevery
authored andcommitted
fix(zone.js): should remove on symbol property after removeAllListeners (#31644)
Close #31643 PR Close #31644
1 parent 17b32b5 commit a182714

2 files changed

Lines changed: 33 additions & 5 deletions

File tree

packages/zone.js/lib/common/events.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,13 @@ export function patchEventTarget(
540540
// remove globalZoneAwareCallback and remove the task cache from target
541541
(existingTask as any).allRemoved = true;
542542
target[symbolEventName] = null;
543+
// in the target, we have an event listener which is added by on_property
544+
// such as target.onclick = function() {}, so we need to clear this internal
545+
// property too if all delegates all removed
546+
if (typeof eventName === 'string') {
547+
const onPropertySymbol = ZONE_SYMBOL_PREFIX + 'ON_PROPERTY' + eventName;
548+
target[onPropertySymbol] = null;
549+
}
543550
}
544551
existingTask.zone.cancelTask(existingTask);
545552
if (returnTarget) {

packages/zone.js/test/browser/browser.spec.ts

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ describe('Zone', function() {
245245
Zone.current.fork({name: 'test1'}).run(() => { testTarget.dispatchEvent('prop3'); });
246246
});
247247

248-
it('window onclick should be in zone',
248+
it('window onmousedown should be in zone',
249249
ifEnvSupports(canPatchOnProperty(window, 'onmousedown'), function() {
250250
zone.run(function() { window.onmousedown = eventListenerSpy; });
251251

@@ -254,6 +254,10 @@ describe('Zone', function() {
254254
expect(hookSpy).toHaveBeenCalled();
255255
expect(eventListenerSpy).toHaveBeenCalled();
256256
window.removeEventListener('mousedown', eventListenerSpy);
257+
expect((window as any)[zoneSymbol('ON_PROPERTYmousedown')])
258+
.toEqual(eventListenerSpy);
259+
window.onmousedown = null;
260+
expect(!!(window as any)[zoneSymbol('ON_PROPERTYmousedown')]).toBeFalsy();
257261
}));
258262

259263
it('window onresize should be patched',
@@ -264,9 +268,12 @@ describe('Zone', function() {
264268
innerResizeProp();
265269
expect(eventListenerSpy).toHaveBeenCalled();
266270
window.removeEventListener('resize', eventListenerSpy);
271+
expect((window as any)[zoneSymbol('ON_PROPERTYresize')]).toEqual(eventListenerSpy);
272+
window.onresize = null;
273+
expect(!!(window as any)[zoneSymbol('ON_PROPERTYresize')]).toBeFalsy();
267274
}));
268275

269-
it('document onclick should be in zone',
276+
it('document onmousedown should be in zone',
270277
ifEnvSupports(canPatchOnProperty(Document.prototype, 'onmousedown'), function() {
271278
zone.run(function() { document.onmousedown = eventListenerSpy; });
272279

@@ -275,6 +282,10 @@ describe('Zone', function() {
275282
expect(hookSpy).toHaveBeenCalled();
276283
expect(eventListenerSpy).toHaveBeenCalled();
277284
document.removeEventListener('mousedown', eventListenerSpy);
285+
expect((document as any)[zoneSymbol('ON_PROPERTYmousedown')])
286+
.toEqual(eventListenerSpy);
287+
document.onmousedown = null;
288+
expect(!!(document as any)[zoneSymbol('ON_PROPERTYmousedown')]).toBeFalsy();
278289
}));
279290

280291
// TODO: JiaLiPassion, need to find out why the test bundle is not `use strict`.
@@ -342,7 +353,7 @@ describe('Zone', function() {
342353
}
343354
}));
344355

345-
it('SVGElement onclick should be in zone',
356+
it('SVGElement onmousedown should be in zone',
346357
ifEnvSupports(
347358
canPatchOnProperty(SVGElement && SVGElement.prototype, 'onmousedown'), function() {
348359
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
@@ -1921,15 +1932,20 @@ describe('Zone', function() {
19211932
const listener2 = function() { logs.push('listener2'); };
19221933
const listener3 = {handleEvent: function(event: Event) { logs.push('listener3'); }};
19231934
const listener4 = function() { logs.push('listener4'); };
1935+
const listener5 = function() { logs.push('listener5'); };
19241936

19251937
button.addEventListener('mouseover', listener1);
19261938
button.addEventListener('mouseover', listener2);
19271939
button.addEventListener('mouseover', listener3);
19281940
button.addEventListener('click', listener4);
1941+
button.onmouseover = listener5;
1942+
expect((button as any)[Zone.__symbol__('ON_PROPERTYmouseover')]).toEqual(listener5);
19291943

19301944
(button as any).removeAllListeners('mouseover');
1931-
const listeners = (button as any).eventListeners('mouseove');
1945+
const listeners = (button as any).eventListeners('mouseover');
19321946
expect(listeners.length).toBe(0);
1947+
expect((button as any)[Zone.__symbol__('ON_PROPERTYmouseover')]).toBeNull();
1948+
expect(!!button.onmouseover).toBeFalsy();
19331949

19341950
const mouseEvent = document.createEvent('Event');
19351951
mouseEvent.initEvent('mouseover', true, true);
@@ -1957,7 +1973,7 @@ describe('Zone', function() {
19571973
button.addEventListener('click', listener4, true);
19581974

19591975
(button as any).removeAllListeners('mouseover');
1960-
const listeners = (button as any).eventListeners('mouseove');
1976+
const listeners = (button as any).eventListeners('mouseover');
19611977
expect(listeners.length).toBe(0);
19621978

19631979
const mouseEvent = document.createEvent('Event');
@@ -2007,15 +2023,20 @@ describe('Zone', function() {
20072023
const listener2 = function() { logs.push('listener2'); };
20082024
const listener3 = {handleEvent: function(event: Event) { logs.push('listener3'); }};
20092025
const listener4 = function() { logs.push('listener4'); };
2026+
const listener5 = function() { logs.push('listener5'); };
20102027

20112028
button.addEventListener('mouseover', listener1);
20122029
button.addEventListener('mouseover', listener2);
20132030
button.addEventListener('mouseover', listener3);
20142031
button.addEventListener('click', listener4);
2032+
button.onmouseover = listener5;
2033+
expect((button as any)[Zone.__symbol__('ON_PROPERTYmouseover')]).toEqual(listener5);
20152034

20162035
(button as any).removeAllListeners();
20172036
const listeners = (button as any).eventListeners('mouseover');
20182037
expect(listeners.length).toBe(0);
2038+
expect((button as any)[Zone.__symbol__('ON_PROPERTYmouseover')]).toBeNull();
2039+
expect(!!button.onmouseover).toBeFalsy();
20192040

20202041
const mouseEvent = document.createEvent('Event');
20212042
mouseEvent.initEvent('mouseover', true, true);

0 commit comments

Comments
 (0)