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

Commit

Permalink
fix(addEventListener): when called from the global scope
Browse files Browse the repository at this point in the history
fixes #190
  • Loading branch information
vicb committed Oct 6, 2015
1 parent e6124dc commit a23d61a
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 4 deletions.
15 changes: 11 additions & 4 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,18 @@ function patchEventTargetMethods(obj) {
})(handler);
} else {
fn = handler;
}
}

handler[originalFnKey] = fn;
handler[boundFnsKey] = handler[boundFnsKey] || {};
handler[boundFnsKey][eventType] = handler[boundFnsKey][eventType] || zone.bind(fn);
arguments[1] = handler[boundFnsKey][eventType];
}

var target = isWebWorker() && !this ? self : this;
// - Inside a Web Worker, `this` is undefined, the context is `global` (= `self`)
// - When `addEventListener` is called on the global context in strict mode, `this` is undefined
// see https://github.com/angular/zone.js/issues/190
var target = this || global;

return global.zone.addEventListener.apply(target, arguments);
};
Expand All @@ -129,11 +132,15 @@ function patchEventTargetMethods(obj) {
var eventType = eventName + (useCapturing ? '$capturing' : '$bubbling');
if (handler[boundFnsKey] && handler[boundFnsKey][eventType]) {
var _bound = handler[boundFnsKey];

arguments[1] = _bound[eventType];
delete _bound[eventType];
}
var target = isWebWorker() && !this ? self : this;

// - Inside a Web Worker, `this` is undefined, the context is `global`
// - When `addEventListener` is called on the global context in strict mode, `this` is undefined
// see https://github.com/angular/zone.js/issues/190
var target = this || global;

var result = global.zone.removeEventListener.apply(target, arguments);
global.zone.dequeueTask(handler[originalFnKey]);
return result;
Expand Down
29 changes: 29 additions & 0 deletions test/patch/element.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,35 @@ describe('element', function () {
document.body.removeChild(button);
});

// https://github.com/angular/zone.js/issues/190
it('should work when addEventListener / removeEventListener are called in the global context', function () {
var clickEvent = document.createEvent('Event');
var callCount = 0;

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

var listener = function (event) {
callCount++;
expect(zone).toBeDirectChildOf(testZone);
expect(event).toBe(clickEvent)
};

testZone.run(function() {
// `this` would be null inside the method when `addEventListener` is called from strict mode
// it would be `window`:
// - when called from non strict-mode,
// - when `window.addEventListener` is called explicitely.
addEventListener('click', listener);
});

button.dispatchEvent(clickEvent);
expect(callCount).toEqual(1);

removeEventListener('click', listener);
button.dispatchEvent(clickEvent);
expect(callCount).toEqual(1);
});

it('should work with addEventListener when called with a function listener', function () {
var clickEvent = document.createEvent('Event');
clickEvent.initEvent('click', true, true);
Expand Down

0 comments on commit a23d61a

Please sign in to comment.