Skip to content

Commit

Permalink
events: support emit on nodeeventtarget
Browse files Browse the repository at this point in the history
PR-URL: nodejs#35851
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Rich Trott <[email protected]>
Reviewed-By: Yongsheng Zhang <[email protected]>
Reviewed-By: Ricky Zhou <[email protected]>
  • Loading branch information
benjamingr authored and targos committed Apr 30, 2021
1 parent 01d2b67 commit 1ca549d
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 1 deletion.
20 changes: 20 additions & 0 deletions lib/internal/event_target.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,14 @@ Object.defineProperty(Event.prototype, SymbolToStringTag, {
value: 'Event',
});

class NodeCustomEvent extends Event {
constructor(type, options) {
super(type, options);
if (options && options.detail) {
this.detail = options.detail;
}
}
}
// The listeners for an EventTarget are maintained as a linked list.
// Unfortunately, the way EventTarget is defined, listeners are accounted
// using the tuple [handler,capture], and even if we don't actually make
Expand Down Expand Up @@ -376,6 +384,9 @@ class EventTarget {
event[kTarget] = undefined;
}

[kCreateEvent](nodeValue, type) {
return new NodeCustomEvent(type, { detail: nodeValue });
}
[customInspectSymbol](depth, options) {
const name = this.constructor.name;
if (depth < 0)
Expand Down Expand Up @@ -473,6 +484,14 @@ class NodeEventTarget extends EventTarget {
this.addEventListener(type, listener, { [kIsNodeStyleListener]: true });
return this;
}
emit(type, arg) {
if (typeof type !== 'string') {
throw new ERR_INVALID_ARG_TYPE('type', 'string', type);
}
const hadListeners = this.listenerCount(type) > 0;
this[kHybridDispatch](arg, type);
return hadListeners;
}

once(type, listener) {
this.addEventListener(type, listener,
Expand Down Expand Up @@ -501,6 +520,7 @@ Object.defineProperties(NodeEventTarget.prototype, {
on: { enumerable: true },
addListener: { enumerable: true },
once: { enumerable: true },
emit: { enumerable: true },
removeAllListeners: { enumerable: true },
});

Expand Down
5 changes: 5 additions & 0 deletions lib/internal/worker/io.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const {
const { Readable, Writable } = require('stream');
const {
Event,
EventTarget,
NodeEventTarget,
defineEventHandler,
initNodeEventTarget,
Expand Down Expand Up @@ -79,11 +80,15 @@ class MessageEvent extends Event {
}
}

const originalCreateEvent = EventTarget.prototype[kCreateEvent];
ObjectDefineProperty(
MessagePort.prototype,
kCreateEvent,
{
value: function(data, type) {
if (type !== 'message' && type !== 'messageerror') {
return originalCreateEvent.call(this, data, type);
}
return new MessageEvent(data, this, type);
},
configurable: false,
Expand Down
22 changes: 22 additions & 0 deletions test/parallel/test-nodeeventtarget.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const {
deepStrictEqual,
ok,
strictEqual,
throws,
} = require('assert');

const { on } = require('events');
Expand Down Expand Up @@ -145,6 +146,27 @@ const { on } = require('events');
target.on('foo', () => {});
target.on('foo', () => {});
}
{
// Test NodeEventTarget emit
const emitter = new NodeEventTarget();
emitter.addEventListener('foo', common.mustCall((e) => {
strictEqual(e.type, 'foo');
strictEqual(e.detail, 'bar');
ok(e instanceof Event);
}), { once: true });
emitter.once('foo', common.mustCall((e, droppedAdditionalArgument) => {
strictEqual(e, 'bar');
strictEqual(droppedAdditionalArgument, undefined);
}));
emitter.emit('foo', 'bar', 'baz');
}
{
// Test NodeEventTarget emit unsupported usage
const emitter = new NodeEventTarget();
throws(() => {
emitter.emit();
}, /ERR_INVALID_ARG_TYPE/);
}

(async () => {
// test NodeEventTarget async-iterability
Expand Down
13 changes: 12 additions & 1 deletion test/parallel/test-worker-message-port.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,18 @@ const { MessageChannel, MessagePort } = require('worker_threads');
port2.close(common.mustCall());
}));
}

{
// Test emitting non-message events on a port
const { port2 } = new MessageChannel();
port2.addEventListener('foo', common.mustCall((received) => {
assert.strictEqual(received.type, 'foo');
assert.strictEqual(received.detail, 'bar');
}));
port2.on('foo', common.mustCall((received) => {
assert.strictEqual(received, 'bar');
}));
port2.emit('foo', 'bar');
}
{
const { port1, port2 } = new MessageChannel();

Expand Down

0 comments on commit 1ca549d

Please sign in to comment.