Skip to content

Commit 7e6dfa3

Browse files
committed
fix(addEventListener): when called from the global scope
fixes angular#190
1 parent e6124dc commit 7e6dfa3

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

lib/utils.js

+11-4
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,18 @@ function patchEventTargetMethods(obj) {
110110
})(handler);
111111
} else {
112112
fn = handler;
113-
}
113+
}
114114

115115
handler[originalFnKey] = fn;
116116
handler[boundFnsKey] = handler[boundFnsKey] || {};
117117
handler[boundFnsKey][eventType] = handler[boundFnsKey][eventType] || zone.bind(fn);
118118
arguments[1] = handler[boundFnsKey][eventType];
119119
}
120120

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

123126
return global.zone.addEventListener.apply(target, arguments);
124127
};
@@ -129,11 +132,15 @@ function patchEventTargetMethods(obj) {
129132
var eventType = eventName + (useCapturing ? '$capturing' : '$bubbling');
130133
if (handler[boundFnsKey] && handler[boundFnsKey][eventType]) {
131134
var _bound = handler[boundFnsKey];
132-
133135
arguments[1] = _bound[eventType];
134136
delete _bound[eventType];
135137
}
136-
var target = isWebWorker() && !this ? self : this;
138+
139+
// - Inside a Web Worker, `this` is undefined, the context is `global`
140+
// - When `addEventListener` is called on the global context in strict mode, `this` is undefined
141+
// see https://github.com/angular/zone.js/issues/190
142+
var target = this || global;
143+
137144
var result = global.zone.removeEventListener.apply(target, arguments);
138145
global.zone.dequeueTask(handler[originalFnKey]);
139146
return result;

test/patch/element.spec.js

+26
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,32 @@ describe('element', function () {
1414
document.body.removeChild(button);
1515
});
1616

17+
// https://github.com/angular/zone.js/issues/190
18+
it('should work when addEventListener / removeEventListener are called in the global context', function () {
19+
var clickEvent = document.createEvent('Event');
20+
var callCount = 0;
21+
22+
clickEvent.initEvent('click', true, true);
23+
24+
var listener = function (event) {
25+
expect(zone).toBeDirectChildOf(testZone);
26+
expect(event).toBe(clickEvent)
27+
expect(++callCount).toEqual(1);
28+
removeEventListener('click', listener);
29+
};
30+
31+
testZone.run(function() {
32+
// `this` would be null inside the method when `addEventListener` is called from strict mode
33+
// it would be `window`:
34+
// - when called from non strict-mode,
35+
// - when `window.addEventListener` is called explicitely.
36+
addEventListener('click', listener);
37+
});
38+
39+
button.dispatchEvent(clickEvent);
40+
button.dispatchEvent(clickEvent);
41+
});
42+
1743
it('should work with addEventListener when called with a function listener', function () {
1844
var clickEvent = document.createEvent('Event');
1945
clickEvent.initEvent('click', true, true);

0 commit comments

Comments
 (0)