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