Skip to content

Commit

Permalink
events: support event handlers on prototypes
Browse files Browse the repository at this point in the history
PR-URL: #35931
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
  • Loading branch information
benjamingr authored and danielleadams committed Nov 9, 2020
1 parent 33e2ee5 commit ab0eb4f
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 12 deletions.
19 changes: 13 additions & 6 deletions lib/internal/event_target.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const {
Symbol,
SymbolFor,
SymbolToStringTag,
SafeWeakMap,
SafeWeakSet,
} = primordials;

Expand Down Expand Up @@ -577,21 +578,27 @@ function emitUnhandledRejectionOrErr(that, err, event) {
process.emit('error', err, event);
}

// A map of emitter -> map of name -> handler
const eventHandlerValueMap = new SafeWeakMap();

function defineEventHandler(emitter, name) {
// 8.1.5.1 Event handlers - basically `on[eventName]` attributes
let eventHandlerValue;
ObjectDefineProperty(emitter, `on${name}`, {
get() {
return eventHandlerValue;
return eventHandlerValueMap.get(this)?.get(name);
},
set(value) {
if (eventHandlerValue) {
emitter.removeEventListener(name, eventHandlerValue);
const oldValue = eventHandlerValueMap.get(this)?.get(name);
if (oldValue) {
this.removeEventListener(name, oldValue);
}
if (typeof value === 'function') {
emitter.addEventListener(name, value);
this.addEventListener(name, value);
}
if (!eventHandlerValueMap.has(this)) {
eventHandlerValueMap.set(this, new Map());
}
eventHandlerValue = value;
eventHandlerValueMap.get(this).set(name, value);
},
configurable: true,
enumerable: true
Expand Down
5 changes: 3 additions & 2 deletions lib/internal/worker/io.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,14 @@ ObjectDefineProperty(
// This is called from inside the `MessagePort` constructor.
function oninit() {
initNodeEventTarget(this);
// TODO(addaleax): This should be on MessagePort.prototype, but
// defineEventHandler() does not support that.
defineEventHandler(this, 'message');
defineEventHandler(this, 'messageerror');
setupPortReferencing(this, this, 'message');
}

defineEventHandler(MessagePort.prototype, 'message');
defineEventHandler(MessagePort.prototype, 'messageerror');

ObjectDefineProperty(MessagePort.prototype, onInitSymbol, {
enumerable: true,
writable: false,
Expand Down
6 changes: 2 additions & 4 deletions test/parallel/test-worker-message-port.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,7 @@ const { MessageChannel, MessagePort } = require('worker_threads');
assert.deepStrictEqual(
Object.getOwnPropertyNames(MessagePort.prototype).sort(),
[
// TODO(addaleax): This should include onmessage (and eventually
// onmessageerror).
'close', 'constructor', 'postMessage', 'ref', 'start',
'unref'
'close', 'constructor', 'onmessage', 'onmessageerror', 'postMessage',
'ref', 'start', 'unref'
]);
}

0 comments on commit ab0eb4f

Please sign in to comment.