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

fix(event): fix #1110, nodejs EventEmitter should support Symbol eventName #1113

Merged
merged 1 commit into from
Jan 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
]
}