Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Commit

Permalink
fix(lib/utils): adds compliant handling of useCapturing param for Eve…
Browse files Browse the repository at this point in the history
…ntTarget methods
  • Loading branch information
Matthew Hill authored and vicb committed Sep 11, 2015
1 parent f8a2be5 commit dd2e1bf
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 6 deletions.
14 changes: 8 additions & 6 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ var boundFnsKey = keys.create('boundFns');
function patchEventTargetMethods(obj) {
// This is required for the addEventListener hook on the root zone.
obj[keys.common.addEventListener] = obj.addEventListener;
obj.addEventListener = function (eventName, handler) {
obj.addEventListener = function (eventName, handler, useCapturing) {
var eventType = eventName + (useCapturing ? '$capturing' : '$bubbling');
var fn;
//Ignore special listeners of IE11 & Edge dev tools, see https://github.com/angular/zone.js/issues/150
if (handler.toString() !== "[object FunctionWrapper]") {
Expand All @@ -114,19 +115,20 @@ function patchEventTargetMethods(obj) {

handler[originalFnKey] = fn;
handler[boundFnsKey] = handler[boundFnsKey] || {};
arguments[1] = handler[boundFnsKey][eventName] = zone.bind(fn);
arguments[1] = handler[boundFnsKey][eventType] = zone.bind(fn);
}
return global.zone.addEventListener.apply(this, arguments);
};

// This is required for the removeEventListener hook on the root zone.
obj[keys.common.removeEventListener] = obj.removeEventListener;
obj.removeEventListener = function (eventName, handler) {
if(handler[boundFnsKey] && handler[boundFnsKey][eventName]) {
obj.removeEventListener = function (eventName, handler, useCapturing) {
var eventType = eventName + (useCapturing ? '$capturing' : '$bubbling');
if (handler[boundFnsKey] && handler[boundFnsKey][eventType]) {
var _bound = handler[boundFnsKey];

arguments[1] = _bound[eventName];
delete _bound[eventName];
arguments[1] = _bound[eventType];
delete _bound[eventType];
}
var result = global.zone.removeEventListener.apply(this, arguments);
global.zone.dequeueTask(handler[originalFnKey]);
Expand Down
50 changes: 50 additions & 0 deletions test/patch/element.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,56 @@ describe('element', function () {
expect(eventListener.handleEvent).not.toHaveBeenCalled();
});

it('should correctly handle capturing versus nonCapturing eventListeners', function () {
var log = [];
var clickEvent = document.createEvent('Event');

function capturingListener () {
log.push('capturingListener');
}

function bubblingListener () {
log.push('bubblingListener');
}

clickEvent.initEvent('click', true, true);

document.body.addEventListener('click', capturingListener, true);
document.body.addEventListener('click', bubblingListener);

button.dispatchEvent(clickEvent);

expect(log).toEqual([
'capturingListener',
'bubblingListener'
]);
});

it('should correctly handle a listener that is both capturing and nonCapturing', function () {
var log = [];
var clickEvent = document.createEvent('Event');

function listener () {
log.push('listener');
}

clickEvent.initEvent('click', true, true);

document.body.addEventListener('click', listener, true);
document.body.addEventListener('click', listener);

button.dispatchEvent(clickEvent);

document.body.removeEventListener('click', listener, true);
document.body.removeEventListener('click', listener);

button.dispatchEvent(clickEvent);

expect(log).toEqual([
'listener',
'listener'
]);
});

describe('onclick', function() {

Expand Down

0 comments on commit dd2e1bf

Please sign in to comment.