From 91b6c093b120d68f544ddc4c72911a9fc1c28386 Mon Sep 17 00:00:00 2001 From: Benjamin Gruenbaum Date: Sat, 30 May 2020 00:51:02 +0300 Subject: [PATCH] events: support event handlers PR-URL: https://github.com/nodejs/node/pull/34015 Reviewed-By: Denys Otrishko Reviewed-By: Benjamin Gruenbaum --- lib/internal/event_target.js | 21 +++++++++++++++++-- test/parallel/test-eventtarget.js | 34 +++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/lib/internal/event_target.js b/lib/internal/event_target.js index 7c34acd5c5dbe1..9fef64aaba2490 100644 --- a/lib/internal/event_target.js +++ b/lib/internal/event_target.js @@ -479,10 +479,27 @@ function emitUnhandledRejectionOrErr(that, err, event) { process.emit('error', err, event); } -// EventEmitter-ish API: - +function defineEventHandler(emitter, name) { + // 8.1.5.1 Event handlers - basically `on[eventName]` attributes + let eventHandlerValue; + Object.defineProperty(emitter, `on${name}`, { + get() { + return eventHandlerValue; + }, + set(value) { + if (eventHandlerValue) { + emitter.removeEventListener(name, eventHandlerValue); + } + if (typeof value === 'function') { + emitter.addEventListener(name, value); + } + eventHandlerValue = value; + } + }); +} module.exports = { Event, EventTarget, NodeEventTarget, + defineEventHandler, }; diff --git a/test/parallel/test-eventtarget.js b/test/parallel/test-eventtarget.js index 947477de5a7768..743221316382b8 100644 --- a/test/parallel/test-eventtarget.js +++ b/test/parallel/test-eventtarget.js @@ -6,6 +6,7 @@ const { Event, EventTarget, NodeEventTarget, + defineEventHandler } = require('internal/event_target'); const { @@ -438,6 +439,39 @@ ok(EventTarget); const event = new Event(''); strictEqual(event.toString(), '[object Event]'); } +{ + const target = new EventTarget(); + defineEventHandler(target, 'foo'); + target.onfoo = common.mustCall(); + target.dispatchEvent(new Event('foo')); +} +{ + const target = new EventTarget(); + defineEventHandler(target, 'foo'); + let count = 0; + target.onfoo = () => count++; + target.onfoo = common.mustCall(() => count++); + target.dispatchEvent(new Event('foo')); + strictEqual(count, 1); +} +{ + const target = new EventTarget(); + defineEventHandler(target, 'foo'); + let count = 0; + target.addEventListener('foo', () => count++); + target.onfoo = common.mustCall(() => count++); + target.dispatchEvent(new Event('foo')); + strictEqual(count, 2); +} +{ + const target = new EventTarget(); + defineEventHandler(target, 'foo'); + const fn = common.mustNotCall(); + target.onfoo = fn; + strictEqual(target.onfoo, fn); + target.onfoo = null; + target.dispatchEvent(new Event('foo')); +} { // `this` value of dispatchEvent