@@ -24,6 +24,7 @@ const {
24
24
Symbol,
25
25
SymbolFor,
26
26
SymbolToStringTag,
27
+ globalThis,
27
28
} = primordials ;
28
29
29
30
const {
@@ -47,16 +48,11 @@ const kIsEventTarget = SymbolFor('nodejs.event_target');
47
48
const kIsNodeEventTarget = Symbol ( 'kIsNodeEventTarget' ) ;
48
49
49
50
const EventEmitter = require ( 'events' ) ;
50
- const {
51
- kMaxEventTargetListeners,
52
- kMaxEventTargetListenersWarned,
53
- } = EventEmitter ;
54
51
55
- const kEvents = Symbol ( 'kEvents ' ) ;
52
+ const kState = Symbol ( 'nodejs.internal.eventTargetState ' ) ;
56
53
const kIsBeingDispatched = Symbol ( 'kIsBeingDispatched' ) ;
57
54
const kStop = Symbol ( 'kStop' ) ;
58
55
const kTarget = Symbol ( 'kTarget' ) ;
59
- const kHandlers = Symbol ( 'khandlers' ) ;
60
56
const kWeakHandler = Symbol ( 'kWeak' ) ;
61
57
62
58
const kHybridDispatch = SymbolFor ( 'nodejs.internal.kHybridDispatch' ) ;
@@ -489,10 +485,13 @@ class Listener {
489
485
}
490
486
491
487
function initEventTarget ( self ) {
492
- self [ kEvents ] = new SafeMap ( ) ;
493
- self [ kMaxEventTargetListeners ] = EventEmitter . defaultMaxListeners ;
494
- self [ kMaxEventTargetListenersWarned ] = false ;
495
- self [ kHandlers ] = new SafeMap ( ) ;
488
+ self [ kState ] = {
489
+ __proto__ : null ,
490
+ events : new SafeMap ( ) ,
491
+ maxEventTargetListeners : EventTarget . defaultMaxListeners ,
492
+ maxEventTargetListenersWarned : false ,
493
+ handlers : new SafeMap ( ) ,
494
+ } ;
496
495
}
497
496
498
497
class EventTarget {
@@ -506,18 +505,19 @@ class EventTarget {
506
505
}
507
506
508
507
[ kNewListener ] ( size , type , listener , once , capture , passive , weak ) {
509
- if ( this [ kMaxEventTargetListeners ] > 0 &&
510
- size > this [ kMaxEventTargetListeners ] &&
511
- ! this [ kMaxEventTargetListenersWarned ] ) {
512
- this [ kMaxEventTargetListenersWarned ] = true ;
508
+ const self = this ?? globalThis
509
+ if ( self [ kState ] . maxEventTargetListeners > 0 &&
510
+ size > self [ kState ] . maxEventTargetListeners &&
511
+ ! self [ kState ] . maxEventTargetListenersWarned ) {
512
+ self [ kState ] . maxEventTargetListenersWarned = true ;
513
513
// No error code for this since it is a Warning
514
514
// eslint-disable-next-line no-restricted-syntax
515
515
const w = new Error ( 'Possible EventTarget memory leak detected. ' +
516
516
`${ size } ${ type } listeners ` +
517
- `added to ${ inspect ( this , { depth : - 1 } ) } . Use ` +
517
+ `added to ${ inspect ( self , { depth : - 1 } ) } . Use ` +
518
518
'events.setMaxListeners() to increase limit' ) ;
519
519
w . name = 'MaxListenersExceededWarning' ;
520
- w . target = this ;
520
+ w . target = self ;
521
521
w . type = type ;
522
522
w . count = size ;
523
523
process . emitWarning ( w ) ;
@@ -545,7 +545,8 @@ class EventTarget {
545
545
* }} [options]
546
546
*/
547
547
addEventListener ( type , listener , options = kEmptyObject ) {
548
- if ( ! isEventTarget ( this ) )
548
+ const self = this ?? globalThis
549
+ if ( ! isEventTarget ( self ) )
549
550
throw new ERR_INVALID_THIS ( 'EventTarget' ) ;
550
551
if ( arguments . length < 2 )
551
552
throw new ERR_MISSING_ARGS ( 'type' , 'listener' ) ;
@@ -568,7 +569,7 @@ class EventTarget {
568
569
const w = new Error ( `addEventListener called with ${ listener } ` +
569
570
' which has no effect.' ) ;
570
571
w . name = 'AddEventListenerArgumentTypeWarning' ;
571
- w . target = this ;
572
+ w . target = self ;
572
573
w . type = type ;
573
574
process . emitWarning ( w ) ;
574
575
return ;
@@ -584,26 +585,26 @@ class EventTarget {
584
585
// TODO(benjamingr) make this weak somehow? ideally the signal would
585
586
// not prevent the event target from GC.
586
587
signal . addEventListener ( 'abort' , ( ) => {
587
- this . removeEventListener ( type , listener , options ) ;
588
- } , { once : true , [ kWeakHandler ] : this } ) ;
588
+ self . removeEventListener ( type , listener , options ) ;
589
+ } , { once : true , [ kWeakHandler ] : self } ) ;
589
590
}
590
591
591
- let root = this [ kEvents ] . get ( type ) ;
592
+ let root = self [ kState ] . events . get ( type ) ;
592
593
593
594
if ( root === undefined ) {
594
595
root = { size : 1 , next : undefined } ;
595
596
// This is the first handler in our linked list.
596
597
new Listener ( root , listener , once , capture , passive ,
597
598
isNodeStyleListener , weak ) ;
598
- this [ kNewListener ] (
599
+ self [ kNewListener ] (
599
600
root . size ,
600
601
type ,
601
602
listener ,
602
603
once ,
603
604
capture ,
604
605
passive ,
605
606
weak ) ;
606
- this [ kEvents ] . set ( type , root ) ;
607
+ self [ kState ] . events . set ( type , root ) ;
607
608
return ;
608
609
}
609
610
@@ -623,7 +624,7 @@ class EventTarget {
623
624
new Listener ( previous , listener , once , capture , passive ,
624
625
isNodeStyleListener , weak ) ;
625
626
root . size ++ ;
626
- this [ kNewListener ] ( root . size , type , listener , once , capture , passive , weak ) ;
627
+ self [ kNewListener ] ( root . size , type , listener , once , capture , passive , weak ) ;
627
628
}
628
629
629
630
/**
@@ -634,7 +635,8 @@ class EventTarget {
634
635
* }} [options]
635
636
*/
636
637
removeEventListener ( type , listener , options = kEmptyObject ) {
637
- if ( ! isEventTarget ( this ) )
638
+ const self = this ?? globalThis
639
+ if ( ! isEventTarget ( self ) )
638
640
throw new ERR_INVALID_THIS ( 'EventTarget' ) ;
639
641
if ( arguments . length < 2 )
640
642
throw new ERR_MISSING_ARGS ( 'type' , 'listener' ) ;
@@ -644,7 +646,7 @@ class EventTarget {
644
646
type = String ( type ) ;
645
647
const capture = options ?. capture === true ;
646
648
647
- const root = this [ kEvents ] . get ( type ) ;
649
+ const root = self [ kState ] . events . get ( type ) ;
648
650
if ( root === undefined || root . next === undefined )
649
651
return ;
650
652
@@ -654,8 +656,8 @@ class EventTarget {
654
656
handler . remove ( ) ;
655
657
root . size -- ;
656
658
if ( root . size === 0 )
657
- this [ kEvents ] . delete ( type ) ;
658
- this [ kRemoveListener ] ( root . size , type , listener , capture ) ;
659
+ self [ kState ] . events . delete ( type ) ;
660
+ self [ kRemoveListener ] ( root . size , type , listener , capture ) ;
659
661
break ;
660
662
}
661
663
handler = handler . next ;
@@ -666,7 +668,8 @@ class EventTarget {
666
668
* @param {Event } event
667
669
*/
668
670
dispatchEvent ( event ) {
669
- if ( ! isEventTarget ( this ) )
671
+ const self = this ?? globalThis
672
+ if ( ! isEventTarget ( self ) )
670
673
throw new ERR_INVALID_THIS ( 'EventTarget' ) ;
671
674
if ( arguments . length < 1 )
672
675
throw new ERR_MISSING_ARGS ( 'event' ) ;
@@ -677,7 +680,7 @@ class EventTarget {
677
680
if ( event [ kIsBeingDispatched ] )
678
681
throw new ERR_EVENT_RECURSION ( event . type ) ;
679
682
680
- this [ kHybridDispatch ] ( event , event . type , event ) ;
683
+ self [ kHybridDispatch ] ( event , event . type , event ) ;
681
684
682
685
return event . defaultPrevented !== true ;
683
686
}
@@ -696,7 +699,7 @@ class EventTarget {
696
699
event [ kIsBeingDispatched ] = true ;
697
700
}
698
701
699
- const root = this [ kEvents ] . get ( type ) ;
702
+ const root = this [ kState ] . events . get ( type ) ;
700
703
if ( root === undefined || root . next === undefined ) {
701
704
if ( event !== undefined )
702
705
event [ kIsBeingDispatched ] = false ;
@@ -757,9 +760,10 @@ class EventTarget {
757
760
return new NodeCustomEvent ( type , { detail : nodeValue } ) ;
758
761
}
759
762
[ customInspectSymbol ] ( depth , options ) {
760
- if ( ! isEventTarget ( this ) )
763
+ const self = this ?? globalThis
764
+ if ( ! isEventTarget ( self ) )
761
765
throw new ERR_INVALID_THIS ( 'EventTarget' ) ;
762
- const name = this . constructor . name ;
766
+ const name = 'EventTarget' ;
763
767
if ( depth < 0 )
764
768
return name ;
765
769
@@ -812,7 +816,7 @@ class NodeEventTarget extends EventTarget {
812
816
getMaxListeners ( ) {
813
817
if ( ! isNodeEventTarget ( this ) )
814
818
throw new ERR_INVALID_THIS ( 'NodeEventTarget' ) ;
815
- return this [ kMaxEventTargetListeners ] ;
819
+ return this [ kState ] . maxEventTargetListeners ;
816
820
}
817
821
818
822
/**
@@ -821,7 +825,7 @@ class NodeEventTarget extends EventTarget {
821
825
eventNames ( ) {
822
826
if ( ! isNodeEventTarget ( this ) )
823
827
throw new ERR_INVALID_THIS ( 'NodeEventTarget' ) ;
824
- return ArrayFrom ( this [ kEvents ] . keys ( ) ) ;
828
+ return ArrayFrom ( this [ kState ] . events . keys ( ) ) ;
825
829
}
826
830
827
831
/**
@@ -831,7 +835,7 @@ class NodeEventTarget extends EventTarget {
831
835
listenerCount ( type ) {
832
836
if ( ! isNodeEventTarget ( this ) )
833
837
throw new ERR_INVALID_THIS ( 'NodeEventTarget' ) ;
834
- const root = this [ kEvents ] . get ( String ( type ) ) ;
838
+ const root = this [ kState ] . events . get ( String ( type ) ) ;
835
839
return root !== undefined ? root . size : 0 ;
836
840
}
837
841
@@ -924,9 +928,9 @@ class NodeEventTarget extends EventTarget {
924
928
if ( ! isNodeEventTarget ( this ) )
925
929
throw new ERR_INVALID_THIS ( 'NodeEventTarget' ) ;
926
930
if ( type !== undefined ) {
927
- this [ kEvents ] . delete ( String ( type ) ) ;
931
+ this [ kState ] . events . delete ( String ( type ) ) ;
928
932
} else {
929
- this [ kEvents ] . clear ( ) ;
933
+ this [ kState ] . events . clear ( ) ;
930
934
}
931
935
932
936
return this ;
@@ -991,7 +995,7 @@ function validateEventListenerOptions(options) {
991
995
// It stands in its current implementation as a compromise.
992
996
// Ref: https://github.com/nodejs/node/pull/33661
993
997
function isEventTarget ( obj ) {
994
- return obj ? .constructor ?. [ kIsEventTarget ] ;
998
+ return obj . constructor ?. [ kIsEventTarget ] || obj === globalThis ;
995
999
}
996
1000
997
1001
function isNodeEventTarget ( obj ) {
@@ -1030,34 +1034,36 @@ function defineEventHandler(emitter, name, event = name) {
1030
1034
// 8.1.5.1 Event handlers - basically `on[eventName]` attributes
1031
1035
const propName = `on${ name } ` ;
1032
1036
function get ( ) {
1033
- validateInternalField ( this , kHandlers , 'EventTarget' ) ;
1034
- return this [ kHandlers ] ?. get ( event ) ?. handler ?? null ;
1037
+ const self = this ?? globalThis ;
1038
+ validateInternalField ( self [ kState ] , 'handlers' , 'EventTarget' ) ;
1039
+ return self [ kState ] . handlers ?. get ( event ) ?. handler ?? null ;
1035
1040
}
1036
1041
ObjectDefineProperty ( get , 'name' , {
1037
1042
__proto__ : null ,
1038
1043
value : `get ${ propName } ` ,
1039
1044
} ) ;
1040
1045
1041
1046
function set ( value ) {
1042
- validateInternalField ( this , kHandlers , 'EventTarget' ) ;
1043
- let wrappedHandler = this [ kHandlers ] ?. get ( event ) ;
1047
+ const self = this ?? globalThis ;
1048
+ validateInternalField ( self [ kState ] , 'handlers' , 'EventTarget' ) ;
1049
+ let wrappedHandler = self [ kState ] . handlers ?. get ( event ) ;
1044
1050
if ( wrappedHandler ) {
1045
1051
if ( typeof wrappedHandler . handler === 'function' ) {
1046
- this [ kEvents ] . get ( event ) . size -- ;
1047
- const size = this [ kEvents ] . get ( event ) . size ;
1048
- this [ kRemoveListener ] ( size , event , wrappedHandler . handler , false ) ;
1052
+ self [ kState ] . events . get ( event ) . size -- ;
1053
+ const size = self [ kState ] . events . get ( event ) . size ;
1054
+ self [ kRemoveListener ] ( size , event , wrappedHandler . handler , false ) ;
1049
1055
}
1050
1056
wrappedHandler . handler = value ;
1051
1057
if ( typeof wrappedHandler . handler === 'function' ) {
1052
- this [ kEvents ] . get ( event ) . size ++ ;
1053
- const size = this [ kEvents ] . get ( event ) . size ;
1054
- this [ kNewListener ] ( size , event , value , false , false , false , false ) ;
1058
+ self [ kState ] . events . get ( event ) . size ++ ;
1059
+ const size = self [ kState ] . events . get ( event ) . size ;
1060
+ self [ kNewListener ] ( size , event , value , false , false , false , false ) ;
1055
1061
}
1056
1062
} else {
1057
1063
wrappedHandler = makeEventHandler ( value ) ;
1058
- this . addEventListener ( event , wrappedHandler ) ;
1064
+ self . addEventListener ( event , wrappedHandler ) ;
1059
1065
}
1060
- this [ kHandlers ] . set ( event , wrappedHandler ) ;
1066
+ self [ kState ] . handlers . set ( event , wrappedHandler ) ;
1061
1067
}
1062
1068
ObjectDefineProperty ( set , 'name' , {
1063
1069
__proto__ : null ,
@@ -1106,7 +1112,7 @@ module.exports = {
1106
1112
kNewListener,
1107
1113
kTrustEvent,
1108
1114
kRemoveListener,
1109
- kEvents ,
1115
+ kState ,
1110
1116
kWeakHandler,
1111
1117
isEventTarget,
1112
1118
} ;
0 commit comments