|
8 | 8 | Object,
|
9 | 9 | ObjectDefineProperty,
|
10 | 10 | ObjectGetOwnPropertyDescriptor,
|
| 11 | + ReflectApply, |
11 | 12 | SafeMap,
|
12 | 13 | String,
|
13 | 14 | Symbol,
|
@@ -577,24 +578,47 @@ function emitUnhandledRejectionOrErr(that, err, event) {
|
577 | 578 | process.emit('error', err, event);
|
578 | 579 | }
|
579 | 580 |
|
| 581 | +function makeEventHandler(handler) { |
| 582 | + // Event handlers are dispatched in the order they were first set |
| 583 | + // See https://github.com/nodejs/node/pull/35949#issuecomment-722496598 |
| 584 | + function eventHandler(...args) { |
| 585 | + if (typeof eventHandler.handler !== 'function') { |
| 586 | + return; |
| 587 | + } |
| 588 | + return ReflectApply(eventHandler.handler, this, args); |
| 589 | + } |
| 590 | + eventHandler.handler = handler; |
| 591 | + return eventHandler; |
| 592 | +} |
| 593 | + |
580 | 594 | function defineEventHandler(emitter, name) {
|
581 | 595 | // 8.1.5.1 Event handlers - basically `on[eventName]` attributes
|
582 | 596 | ObjectDefineProperty(emitter, `on${name}`, {
|
583 | 597 | get() {
|
584 |
| - return this[kHandlers]?.get(name); |
| 598 | + return this[kHandlers]?.get(name)?.handler; |
585 | 599 | },
|
586 | 600 | set(value) {
|
587 |
| - const oldValue = this[kHandlers]?.get(name); |
588 |
| - if (oldValue) { |
589 |
| - this.removeEventListener(name, oldValue); |
590 |
| - } |
591 |
| - if (typeof value === 'function') { |
592 |
| - this.addEventListener(name, value); |
593 |
| - } |
594 | 601 | if (!this[kHandlers]) {
|
595 | 602 | this[kHandlers] = new SafeMap();
|
596 | 603 | }
|
597 |
| - this[kHandlers].set(name, value); |
| 604 | + let wrappedHandler = this[kHandlers]?.get(name); |
| 605 | + if (wrappedHandler) { |
| 606 | + if (typeof wrappedHandler.handler === 'function') { |
| 607 | + this[kEvents].get(name).size--; |
| 608 | + const size = this[kEvents].get(name).size; |
| 609 | + this[kRemoveListener](size, name, wrappedHandler.handler, false); |
| 610 | + } |
| 611 | + wrappedHandler.handler = value; |
| 612 | + if (typeof wrappedHandler.handler === 'function') { |
| 613 | + this[kEvents].get(name).size++; |
| 614 | + const size = this[kEvents].get(name).size; |
| 615 | + this[kNewListener](size, name, value, false, false, false); |
| 616 | + } |
| 617 | + } else { |
| 618 | + wrappedHandler = makeEventHandler(value); |
| 619 | + this.addEventListener(name, wrappedHandler); |
| 620 | + } |
| 621 | + this[kHandlers].set(name, wrappedHandler); |
598 | 622 | },
|
599 | 623 | configurable: true,
|
600 | 624 | enumerable: true
|
|
0 commit comments