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

Commit

Permalink
fix(event): fix #1110, nodejs EventEmitter should support Symbol even…
Browse files Browse the repository at this point in the history
…tName (#1113)
  • Loading branch information
JiaLiPassion authored and mhevery committed Jan 8, 2019
1 parent eb72ff4 commit 96420d6
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 10 deletions.
2 changes: 1 addition & 1 deletion file-size-limit.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{
"path": "dist/zone.min.js",
"checkTarget": true,
"limit": 42500
"limit": 43000
}
]
}
16 changes: 12 additions & 4 deletions lib/common/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ export interface PatchEventTargetOptions {
diff?: (task: any, delegate: any) => boolean;
// support passive or not
supportPassive?: boolean;
// get string from eventName (in nodejs, eventName maybe Symbol)
eventNameToString?: (eventName: any) => string;
}

export function patchEventTarget(
Expand Down Expand Up @@ -212,6 +214,8 @@ export function patchEventTarget(
return false;
}

const eventNameToString = patchOptions && patchOptions.eventNameToString;

// a shared global taskData to pass data for scheduleEventTask
// so we do not need to create a new object just for pass some data
const taskData: any = {};
Expand Down Expand Up @@ -384,8 +388,10 @@ export function patchEventTarget(
let symbolEventName;
if (!symbolEventNames) {
// the code is duplicate, but I just want to get some better performance
const falseEventName = eventName + FALSE_STR;
const trueEventName = eventName + TRUE_STR;
const falseEventName =
(eventNameToString ? eventNameToString(eventName) : eventName) + FALSE_STR;
const trueEventName =
(eventNameToString ? eventNameToString(eventName) : eventName) + TRUE_STR;
const symbol = ZONE_SYMBOL_PREFIX + falseEventName;
const symbolCapture = ZONE_SYMBOL_PREFIX + trueEventName;
zoneSymbolEventNames[eventName] = {};
Expand Down Expand Up @@ -418,7 +424,8 @@ export function patchEventTarget(
source = targetSource[eventName];
}
if (!source) {
source = constructorName + addSource + eventName;
source = constructorName + addSource +
(eventNameToString ? eventNameToString(eventName) : eventName);
}
// do not create a new object as task.data to pass those things
// just use the global shared one
Expand Down Expand Up @@ -556,7 +563,8 @@ export function patchEventTarget(
const eventName = arguments[0];

const listeners: any[] = [];
const tasks = findEventTasks(target, eventName);
const tasks =
findEventTasks(target, eventNameToString ? eventNameToString(eventName) : eventName);

for (let i = 0; i < tasks.length; i++) {
const task: any = tasks[i];
Expand Down
13 changes: 12 additions & 1 deletion lib/node/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ Zone.__load_patch('EventEmitter', (global: any) => {
return task.callback === delegate || task.callback.listener === delegate;
};

const eventNameToString = function(eventName: string|Symbol) {
if (typeof eventName === 'string') {
return eventName as string;
}
if (!eventName) {
return '';
}
return eventName.toString().replace('(', '_').replace(')', '_');
};

function patchEventEmitterMethods(obj: any) {
const result = patchEventTarget(global, [obj], {
useG: false,
Expand All @@ -32,7 +42,8 @@ Zone.__load_patch('EventEmitter', (global: any) => {
listeners: EE_LISTENERS,
chkDup: false,
rt: true,
diff: compareTaskCallbackVsDelegate
diff: compareTaskCallbackVsDelegate,
eventNameToString: eventNameToString
});
if (result && result[0]) {
obj[EE_ON] = obj[EE_ADD_LISTENER];
Expand Down
12 changes: 12 additions & 0 deletions test/node/events.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,4 +189,16 @@ describe('nodejs EventEmitter', () => {
process.on('uncaughtException', function() {});
});
});
it('should be able to addEventListener with symbol eventName', () => {
zoneA.run(() => {
const testSymbol = Symbol('test');
const test1Symbol = Symbol('test1');
emitter.on(testSymbol, expectZoneA);
emitter.on(test1Symbol, shouldNotRun);
emitter.removeListener(test1Symbol, shouldNotRun);
expect(emitter.listeners(testSymbol).length).toBe(1);
expect(emitter.listeners(test1Symbol).length).toBe(0);
emitter.emit(testSymbol, 'test value');
});
});
});
3 changes: 2 additions & 1 deletion tsconfig-esm-node.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"lib": [
"es5",
"dom",
"es2015.promise"
"es2015.promise",
"es2015.symbol"
]
},
"exclude": [
Expand Down
9 changes: 8 additions & 1 deletion tsconfig-esm.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@
"build",
"build-esm",
"dist",
"lib/closure"
"lib/closure",
"lib/node/**",
"lib/mix/**",
"test/node/**",
"test/node_bluebird_entry_point.ts",
"test/node_entry_point.ts",
"test/node_error_entry_point.ts",
"test/node_tests.ts"
]
}
3 changes: 2 additions & 1 deletion tsconfig-node.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"lib": [
"es5",
"dom",
"es2015.promise"
"es2015.promise",
"es2015.symbol"
]
},
"exclude": [
Expand Down
9 changes: 8 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
"build",
"build-esm",
"dist",
"lib/closure"
"lib/closure",
"lib/node/**",
"lib/mix/**",
"test/node/**",
"test/node_bluebird_entry_point.ts",
"test/node_entry_point.ts",
"test/node_error_entry_point.ts",
"test/node_tests.ts"
]
}

0 comments on commit 96420d6

Please sign in to comment.