Skip to content

Commit 65a2cb8

Browse files
JiaLiPassionmhevery
authored andcommitted
fix(core): should use native addEventListener in ngZone (angular#20672)
PR Close angular#20672
1 parent 0bef021 commit 65a2cb8

2 files changed

Lines changed: 41 additions & 26 deletions

File tree

packages/platform-browser/src/dom/events/dom_events.ts

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -154,37 +154,50 @@ export class DomEventsPlugin extends EventManagerPlugin {
154154
let callback: EventListener = handler as EventListener;
155155
// if zonejs is loaded and current zone is not ngZone
156156
// we keep Zone.current on target for later restoration.
157-
if (zoneJsLoaded && (!NgZone.isInAngularZone() || isBlackListedEvent(eventName))) {
158-
let symbolName = symbolNames[eventName];
159-
if (!symbolName) {
160-
symbolName = symbolNames[eventName] = __symbol__(ANGULAR + eventName + FALSE);
161-
}
162-
let taskDatas: TaskData[] = (element as any)[symbolName];
163-
const globalListenerRegistered = taskDatas && taskDatas.length > 0;
164-
if (!taskDatas) {
165-
taskDatas = (element as any)[symbolName] = [];
166-
}
167-
168-
const zone = isBlackListedEvent(eventName) ? Zone.root : Zone.current;
169-
if (taskDatas.length === 0) {
170-
taskDatas.push({zone: zone, handler: callback});
171-
} else {
172-
let callbackRegistered = false;
173-
for (let i = 0; i < taskDatas.length; i++) {
174-
if (taskDatas[i].handler === callback) {
175-
callbackRegistered = true;
176-
break;
177-
}
157+
if (zoneJsLoaded) {
158+
if (!NgZone.isInAngularZone() || isBlackListedEvent(eventName)) {
159+
let symbolName = symbolNames[eventName];
160+
if (!symbolName) {
161+
symbolName = symbolNames[eventName] = __symbol__(ANGULAR + eventName + FALSE);
162+
}
163+
let taskDatas: TaskData[] = (element as any)[symbolName];
164+
const globalListenerRegistered = taskDatas && taskDatas.length > 0;
165+
if (!taskDatas) {
166+
taskDatas = (element as any)[symbolName] = [];
178167
}
179-
if (!callbackRegistered) {
168+
169+
const zone = isBlackListedEvent(eventName) ? Zone.root : Zone.current;
170+
if (taskDatas.length === 0) {
180171
taskDatas.push({zone: zone, handler: callback});
172+
} else {
173+
let callbackRegistered = false;
174+
for (let i = 0; i < taskDatas.length; i++) {
175+
if (taskDatas[i].handler === callback) {
176+
callbackRegistered = true;
177+
break;
178+
}
179+
}
180+
if (!callbackRegistered) {
181+
taskDatas.push({zone: zone, handler: callback});
182+
}
181183
}
182-
}
183184

184-
if (!globalListenerRegistered) {
185-
element[ADD_EVENT_LISTENER](eventName, globalListener, false);
185+
if (!globalListenerRegistered) {
186+
element[ADD_EVENT_LISTENER](eventName, globalListener, false);
187+
}
188+
} else {
189+
// if zone.js loaded and we are in angular zone, we don't need to
190+
// use zone.js patched addEventListener
191+
const wrappedCallback = function() {
192+
return self.ngZone.run(callback, this, arguments as any);
193+
};
194+
zoneJsLoaded.apply(element, [eventName, wrappedCallback, false]);
195+
// we just use the underlying removeEventListener
196+
return () => element[REMOVE_EVENT_LISTENER].apply(
197+
element, [eventName, wrappedCallback, false]);
186198
}
187199
} else {
200+
// use zone.js patched addEventListener or native addEventListener if zone.js not loaded
188201
element[NATIVE_ADD_LISTENER](eventName, callback, false);
189202
}
190203
return () => this.removeEventListener(element, eventName, callback);
@@ -196,6 +209,8 @@ export class DomEventsPlugin extends EventManagerPlugin {
196209
if (!underlyingRemove) {
197210
return target[NATIVE_REMOVE_LISTENER].apply(target, [eventName, callback, false]);
198211
}
212+
213+
// if zone.js loaded and wrappedCallback not exists, the callback was added in different zone
199214
let symbolName = symbolNames[eventName];
200215
let taskDatas: TaskData[] = symbolName && target[symbolName];
201216
if (!taskDatas) {

packages/platform-browser/test/dom/events/event_manager_spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ export function main() {
283283
});
284284
getDOM().dispatchEvent(element, dispatchedEvent);
285285
expect(receivedEvents).toEqual([dispatchedEvent, dispatchedEvent]);
286-
expect(receivedZones).toEqual([Zone.root.name, 'fakeAngularZone']);
286+
expect(receivedZones).toEqual([Zone.root.name, 'angular']);
287287

288288
receivedEvents = [];
289289
remover1 && remover1();

0 commit comments

Comments
 (0)