Skip to content

Commit

Permalink
fix(event): fix angular#930, should be able to remove listener added …
Browse files Browse the repository at this point in the history
…outside of zone (angular#960)
  • Loading branch information
JiaLiPassion authored and mhevery committed Dec 27, 2017
1 parent 07b0987 commit d8b09eb
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 1 deletion.
5 changes: 5 additions & 0 deletions lib/common/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,11 @@ export function patchEventTarget(
}
}
}
// issue 930, didn't find the event name or callback
// from zone kept existingTasks, the callback maybe
// added outside of zone, we need to call native removeEventListener
// to try to remove it.
return nativeRemoveEventListener.apply(this, arguments);
};

proto[LISTENERS_EVENT_LISTENER] = function() {
Expand Down
77 changes: 76 additions & 1 deletion test/browser/browser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2112,7 +2112,7 @@ describe('Zone', function() {
button.addEventListener('click', listener4);

(button as any).removeAllListeners();
const listeners = (button as any).eventListeners('mouseove');
const listeners = (button as any).eventListeners('mouseover');
expect(listeners.length).toBe(0);

const mouseEvent = document.createEvent('Event');
Expand All @@ -2125,6 +2125,81 @@ describe('Zone', function() {
expect(logs).toEqual([]);
});

it('should be able to remove listener which was added outside of zone ', function() {
let logs: string[] = [];
const listener1 = function() {
logs.push('listener1');
};
const listener2 = function() {
logs.push('listener2');
};
const listener3 = {
handleEvent: function(event: Event) {
logs.push('listener3');
}
};
const listener4 = function() {
logs.push('listener4');
};

button.addEventListener('mouseover', listener1);
(button as any)[Zone.__symbol__('addEventListener')]('mouseover', listener2);
button.addEventListener('click', listener3);
(button as any)[Zone.__symbol__('addEventListener')]('click', listener4);

button.removeEventListener('mouseover', listener1);
button.removeEventListener('mouseover', listener2);
button.removeEventListener('click', listener3);
button.removeEventListener('click', listener4);
const listeners = (button as any).eventListeners('mouseover');
expect(listeners.length).toBe(0);

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

button.dispatchEvent(mouseEvent);
expect(logs).toEqual([]);

button.dispatchEvent(clickEvent);
expect(logs).toEqual([]);
});

it('should be able to remove all listeners which were added inside of zone ', function() {
let logs: string[] = [];
const listener1 = function() {
logs.push('listener1');
};
const listener2 = function() {
logs.push('listener2');
};
const listener3 = {
handleEvent: function(event: Event) {
logs.push('listener3');
}
};
const listener4 = function() {
logs.push('listener4');
};

button.addEventListener('mouseover', listener1);
(button as any)[Zone.__symbol__('addEventListener')]('mouseover', listener2);
button.addEventListener('click', listener3);
(button as any)[Zone.__symbol__('addEventListener')]('click', listener4);

(button as any).removeAllListeners();
const listeners = (button as any).eventListeners('mouseover');
expect(listeners.length).toBe(0);

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

button.dispatchEvent(mouseEvent);
expect(logs).toEqual(['listener2']);

button.dispatchEvent(clickEvent);
expect(logs).toEqual(['listener2', 'listener4']);
});

it('should bypass addEventListener of FunctionWrapper and __BROWSERTOOLS_CONSOLE_SAFEFUNC of IE/Edge',
ifEnvSupports(ieOrEdge, function() {
const hookSpy = jasmine.createSpy('hook');
Expand Down

0 comments on commit d8b09eb

Please sign in to comment.