88 FunctionPrototypeCall,
99 NumberIsInteger,
1010 ObjectAssign,
11+ ObjectCreate,
1112 ObjectDefineProperties,
1213 ObjectDefineProperty,
1314 ObjectGetOwnPropertyDescriptor,
@@ -39,6 +40,7 @@ const { customInspectSymbol } = require('internal/util');
3940const { inspect } = require ( 'util' ) ;
4041
4142const kIsEventTarget = SymbolFor ( 'nodejs.event_target' ) ;
43+ const kIsNodeEventTarget = Symbol ( 'kIsNodeEventTarget' ) ;
4244
4345const EventEmitter = require ( 'events' ) ;
4446const {
@@ -80,6 +82,10 @@ const isTrusted = ObjectGetOwnPropertyDescriptor({
8082 }
8183} , 'isTrusted' ) . get ;
8284
85+ function isEvent ( value ) {
86+ return typeof value ?. [ kType ] === 'string' ;
87+ }
88+
8389class Event {
8490 constructor ( type , options = null ) {
8591 if ( arguments . length === 0 )
@@ -110,6 +116,8 @@ class Event {
110116 }
111117
112118 [ customInspectSymbol ] ( depth , options ) {
119+ if ( ! isEvent ( this ) )
120+ throw new ERR_INVALID_THIS ( 'Event' ) ;
113121 const name = this . constructor . name ;
114122 if ( depth < 0 )
115123 return name ;
@@ -127,46 +135,111 @@ class Event {
127135 }
128136
129137 stopImmediatePropagation ( ) {
138+ if ( ! isEvent ( this ) )
139+ throw new ERR_INVALID_THIS ( 'Event' ) ;
130140 this [ kStop ] = true ;
131141 }
132142
133143 preventDefault ( ) {
144+ if ( ! isEvent ( this ) )
145+ throw new ERR_INVALID_THIS ( 'Event' ) ;
134146 this [ kDefaultPrevented ] = true ;
135147 }
136148
137- get target ( ) { return this [ kTarget ] ; }
138- get currentTarget ( ) { return this [ kTarget ] ; }
139- get srcElement ( ) { return this [ kTarget ] ; }
149+ get target ( ) {
150+ if ( ! isEvent ( this ) )
151+ throw new ERR_INVALID_THIS ( 'Event' ) ;
152+ return this [ kTarget ] ;
153+ }
140154
141- get type ( ) { return this [ kType ] ; }
155+ get currentTarget ( ) {
156+ if ( ! isEvent ( this ) )
157+ throw new ERR_INVALID_THIS ( 'Event' ) ;
158+ return this [ kTarget ] ;
159+ }
142160
143- get cancelable ( ) { return this [ kCancelable ] ; }
161+ get srcElement ( ) {
162+ if ( ! isEvent ( this ) )
163+ throw new ERR_INVALID_THIS ( 'Event' ) ;
164+ return this [ kTarget ] ;
165+ }
166+
167+ get type ( ) {
168+ if ( ! isEvent ( this ) )
169+ throw new ERR_INVALID_THIS ( 'Event' ) ;
170+ return this [ kType ] ;
171+ }
172+
173+ get cancelable ( ) {
174+ if ( ! isEvent ( this ) )
175+ throw new ERR_INVALID_THIS ( 'Event' ) ;
176+ return this [ kCancelable ] ;
177+ }
144178
145179 get defaultPrevented ( ) {
180+ if ( ! isEvent ( this ) )
181+ throw new ERR_INVALID_THIS ( 'Event' ) ;
146182 return this [ kCancelable ] && this [ kDefaultPrevented ] ;
147183 }
148184
149- get timeStamp ( ) { return this [ kTimestamp ] ; }
185+ get timeStamp ( ) {
186+ if ( ! isEvent ( this ) )
187+ throw new ERR_INVALID_THIS ( 'Event' ) ;
188+ return this [ kTimestamp ] ;
189+ }
150190
151191
152192 // The following are non-op and unused properties/methods from Web API Event.
153193 // These are not supported in Node.js and are provided purely for
154194 // API completeness.
155195
156- composedPath ( ) { return this [ kIsBeingDispatched ] ? [ this [ kTarget ] ] : [ ] ; }
157- get returnValue ( ) { return ! this . defaultPrevented ; }
158- get bubbles ( ) { return this [ kBubbles ] ; }
159- get composed ( ) { return this [ kComposed ] ; }
196+ composedPath ( ) {
197+ if ( ! isEvent ( this ) )
198+ throw new ERR_INVALID_THIS ( 'Event' ) ;
199+ return this [ kIsBeingDispatched ] ? [ this [ kTarget ] ] : [ ] ;
200+ }
201+
202+ get returnValue ( ) {
203+ if ( ! isEvent ( this ) )
204+ throw new ERR_INVALID_THIS ( 'Event' ) ;
205+ return ! this . defaultPrevented ;
206+ }
207+
208+ get bubbles ( ) {
209+ if ( ! isEvent ( this ) )
210+ throw new ERR_INVALID_THIS ( 'Event' ) ;
211+ return this [ kBubbles ] ;
212+ }
213+
214+ get composed ( ) {
215+ if ( ! isEvent ( this ) )
216+ throw new ERR_INVALID_THIS ( 'Event' ) ;
217+ return this [ kComposed ] ;
218+ }
219+
160220 get eventPhase ( ) {
221+ if ( ! isEvent ( this ) )
222+ throw new ERR_INVALID_THIS ( 'Event' ) ;
161223 return this [ kIsBeingDispatched ] ? Event . AT_TARGET : Event . NONE ;
162224 }
163- get cancelBubble ( ) { return this [ kPropagationStopped ] ; }
225+
226+ get cancelBubble ( ) {
227+ if ( ! isEvent ( this ) )
228+ throw new ERR_INVALID_THIS ( 'Event' ) ;
229+ return this [ kPropagationStopped ] ;
230+ }
231+
164232 set cancelBubble ( value ) {
233+ if ( ! isEvent ( this ) )
234+ throw new ERR_INVALID_THIS ( 'Event' ) ;
165235 if ( value ) {
166236 this . stopPropagation ( ) ;
167237 }
168238 }
239+
169240 stopPropagation ( ) {
241+ if ( ! isEvent ( this ) )
242+ throw new ERR_INVALID_THIS ( 'Event' ) ;
170243 this [ kPropagationStopped ] = true ;
171244 }
172245
@@ -176,12 +249,34 @@ class Event {
176249 static BUBBLING_PHASE = 3 ;
177250}
178251
179- ObjectDefineProperty ( Event . prototype , SymbolToStringTag , {
180- writable : false ,
181- enumerable : false ,
182- configurable : true ,
183- value : 'Event' ,
184- } ) ;
252+ const kEnumerableProperty = ObjectCreate ( null ) ;
253+ kEnumerableProperty . enumerable = true ;
254+
255+ ObjectDefineProperties (
256+ Event . prototype , {
257+ [ SymbolToStringTag ] : {
258+ writable : false ,
259+ enumerable : false ,
260+ configurable : true ,
261+ value : 'Event' ,
262+ } ,
263+ stopImmediatePropagation : kEnumerableProperty ,
264+ preventDefault : kEnumerableProperty ,
265+ target : kEnumerableProperty ,
266+ currentTarget : kEnumerableProperty ,
267+ srcElement : kEnumerableProperty ,
268+ type : kEnumerableProperty ,
269+ cancelable : kEnumerableProperty ,
270+ defaultPrevented : kEnumerableProperty ,
271+ timeStamp : kEnumerableProperty ,
272+ composedPath : kEnumerableProperty ,
273+ returnValue : kEnumerableProperty ,
274+ bubbles : kEnumerableProperty ,
275+ composed : kEnumerableProperty ,
276+ eventPhase : kEnumerableProperty ,
277+ cancelBubble : kEnumerableProperty ,
278+ stopPropagation : kEnumerableProperty ,
279+ } ) ;
185280
186281class NodeCustomEvent extends Event {
187282 constructor ( type , options ) {
@@ -297,6 +392,8 @@ class EventTarget {
297392 [ kRemoveListener ] ( size , type , listener , capture ) { }
298393
299394 addEventListener ( type , listener , options = { } ) {
395+ if ( ! isEventTarget ( this ) )
396+ throw new ERR_INVALID_THIS ( 'EventTarget' ) ;
300397 if ( arguments . length < 2 )
301398 throw new ERR_MISSING_ARGS ( 'type' , 'listener' ) ;
302399
@@ -368,6 +465,8 @@ class EventTarget {
368465 }
369466
370467 removeEventListener ( type , listener , options = { } ) {
468+ if ( ! isEventTarget ( this ) )
469+ throw new ERR_INVALID_THIS ( 'EventTarget' ) ;
371470 if ( ! shouldAddListener ( listener ) )
372471 return ;
373472
@@ -393,12 +492,12 @@ class EventTarget {
393492 }
394493
395494 dispatchEvent ( event ) {
396- if ( ! ( event instanceof Event ) )
397- throw new ERR_INVALID_ARG_TYPE ( 'event' , 'Event' , event ) ;
398-
399495 if ( ! isEventTarget ( this ) )
400496 throw new ERR_INVALID_THIS ( 'EventTarget' ) ;
401497
498+ if ( ! ( event instanceof Event ) )
499+ throw new ERR_INVALID_ARG_TYPE ( 'event' , 'Event' , event ) ;
500+
402501 if ( event [ kIsBeingDispatched ] )
403502 throw new ERR_EVENT_RECURSION ( event . type ) ;
404503
@@ -479,6 +578,8 @@ class EventTarget {
479578 return new NodeCustomEvent ( type , { detail : nodeValue } ) ;
480579 }
481580 [ customInspectSymbol ] ( depth , options ) {
581+ if ( ! isEventTarget ( this ) )
582+ throw new ERR_INVALID_THIS ( 'EventTarget' ) ;
482583 const name = this . constructor . name ;
483584 if ( depth < 0 )
484585 return name ;
@@ -492,22 +593,23 @@ class EventTarget {
492593}
493594
494595ObjectDefineProperties ( EventTarget . prototype , {
495- addEventListener : { enumerable : true } ,
496- removeEventListener : { enumerable : true } ,
497- dispatchEvent : { enumerable : true }
498- } ) ;
499- ObjectDefineProperty ( EventTarget . prototype , SymbolToStringTag , {
500- writable : false ,
501- enumerable : false ,
502- configurable : true ,
503- value : 'EventTarget' ,
596+ addEventListener : kEnumerableProperty ,
597+ removeEventListener : kEnumerableProperty ,
598+ dispatchEvent : kEnumerableProperty ,
599+ [ SymbolToStringTag ] : {
600+ writable : false ,
601+ enumerable : false ,
602+ configurable : true ,
603+ value : 'EventTarget' ,
604+ }
504605} ) ;
505606
506607function initNodeEventTarget ( self ) {
507608 initEventTarget ( self ) ;
508609}
509610
510611class NodeEventTarget extends EventTarget {
612+ static [ kIsNodeEventTarget ] = true ;
511613 static defaultMaxListeners = 10 ;
512614
513615 constructor ( ) {
@@ -516,55 +618,77 @@ class NodeEventTarget extends EventTarget {
516618 }
517619
518620 setMaxListeners ( n ) {
621+ if ( ! isNodeEventTarget ( this ) )
622+ throw new ERR_INVALID_THIS ( 'NodeEventTarget' ) ;
519623 EventEmitter . setMaxListeners ( n , this ) ;
520624 }
521625
522626 getMaxListeners ( ) {
627+ if ( ! isNodeEventTarget ( this ) )
628+ throw new ERR_INVALID_THIS ( 'NodeEventTarget' ) ;
523629 return this [ kMaxEventTargetListeners ] ;
524630 }
525631
526632 eventNames ( ) {
633+ if ( ! isNodeEventTarget ( this ) )
634+ throw new ERR_INVALID_THIS ( 'NodeEventTarget' ) ;
527635 return ArrayFrom ( this [ kEvents ] . keys ( ) ) ;
528636 }
529637
530638 listenerCount ( type ) {
639+ if ( ! isNodeEventTarget ( this ) )
640+ throw new ERR_INVALID_THIS ( 'NodeEventTarget' ) ;
531641 const root = this [ kEvents ] . get ( String ( type ) ) ;
532642 return root !== undefined ? root . size : 0 ;
533643 }
534644
535645 off ( type , listener , options ) {
646+ if ( ! isNodeEventTarget ( this ) )
647+ throw new ERR_INVALID_THIS ( 'NodeEventTarget' ) ;
536648 this . removeEventListener ( type , listener , options ) ;
537649 return this ;
538650 }
539651
540652 removeListener ( type , listener , options ) {
653+ if ( ! isNodeEventTarget ( this ) )
654+ throw new ERR_INVALID_THIS ( 'NodeEventTarget' ) ;
541655 this . removeEventListener ( type , listener , options ) ;
542656 return this ;
543657 }
544658
545659 on ( type , listener ) {
660+ if ( ! isNodeEventTarget ( this ) )
661+ throw new ERR_INVALID_THIS ( 'NodeEventTarget' ) ;
546662 this . addEventListener ( type , listener , { [ kIsNodeStyleListener ] : true } ) ;
547663 return this ;
548664 }
549665
550666 addListener ( type , listener ) {
667+ if ( ! isNodeEventTarget ( this ) )
668+ throw new ERR_INVALID_THIS ( 'NodeEventTarget' ) ;
551669 this . addEventListener ( type , listener , { [ kIsNodeStyleListener ] : true } ) ;
552670 return this ;
553671 }
554672 emit ( type , arg ) {
673+ if ( ! isNodeEventTarget ( this ) )
674+ throw new ERR_INVALID_THIS ( 'NodeEventTarget' ) ;
555675 validateString ( type , 'type' ) ;
556676 const hadListeners = this . listenerCount ( type ) > 0 ;
557677 this [ kHybridDispatch ] ( arg , type ) ;
558678 return hadListeners ;
559679 }
560680
561681 once ( type , listener ) {
682+ if ( ! isNodeEventTarget ( this ) )
683+ throw new ERR_INVALID_THIS ( 'NodeEventTarget' ) ;
562684 this . addEventListener ( type , listener ,
563685 { once : true , [ kIsNodeStyleListener ] : true } ) ;
564686 return this ;
565687 }
566688
567689 removeAllListeners ( type ) {
690+ if ( ! isNodeEventTarget ( this ) )
691+ throw new ERR_INVALID_THIS ( 'NodeEventTarget' ) ;
568692 if ( type !== undefined ) {
569693 this [ kEvents ] . delete ( String ( type ) ) ;
570694 } else {
@@ -576,17 +700,17 @@ class NodeEventTarget extends EventTarget {
576700}
577701
578702ObjectDefineProperties ( NodeEventTarget . prototype , {
579- setMaxListeners : { enumerable : true } ,
580- getMaxListeners : { enumerable : true } ,
581- eventNames : { enumerable : true } ,
582- listenerCount : { enumerable : true } ,
583- off : { enumerable : true } ,
584- removeListener : { enumerable : true } ,
585- on : { enumerable : true } ,
586- addListener : { enumerable : true } ,
587- once : { enumerable : true } ,
588- emit : { enumerable : true } ,
589- removeAllListeners : { enumerable : true } ,
703+ setMaxListeners : kEnumerableProperty ,
704+ getMaxListeners : kEnumerableProperty ,
705+ eventNames : kEnumerableProperty ,
706+ listenerCount : kEnumerableProperty ,
707+ off : kEnumerableProperty ,
708+ removeListener : kEnumerableProperty ,
709+ on : kEnumerableProperty ,
710+ addListener : kEnumerableProperty ,
711+ once : kEnumerableProperty ,
712+ emit : kEnumerableProperty ,
713+ removeAllListeners : kEnumerableProperty ,
590714} ) ;
591715
592716// EventTarget API
@@ -631,6 +755,10 @@ function isEventTarget(obj) {
631755 return obj ?. constructor ?. [ kIsEventTarget ] ;
632756}
633757
758+ function isNodeEventTarget ( obj ) {
759+ return obj ?. constructor ?. [ kIsNodeEventTarget ] ;
760+ }
761+
634762function addCatch ( promise ) {
635763 const then = promise . then ;
636764 if ( typeof then === 'function' ) {
0 commit comments