@@ -25,7 +25,6 @@ if (typeof window !== 'undefined') {
2525 try {
2626 const options =
2727 Object . defineProperty ( { } , 'passive' , { get : function ( ) { passiveSupported = true ; } } ) ;
28-
2928 window . addEventListener ( 'test' , options , options ) ;
3029 window . removeEventListener ( 'test' , options , options ) ;
3130 } catch ( err ) {
@@ -245,16 +244,30 @@ export function patchEventTarget(
245244 proto [ patchOptions . prepend ] ;
246245 }
247246
248- function checkIsPassive ( task : Task ) {
249- if ( ! passiveSupported && typeof taskData . options !== 'boolean' &&
250- typeof taskData . options !== 'undefined' && taskData . options !== null ) {
251- // options is a non-null non-undefined object
252- // passive is not supported
253- // don't pass options as object
254- // just pass capture as a boolean
255- ( task as any ) . options = ! ! taskData . options . capture ;
256- taskData . options = ( task as any ) . options ;
247+ /**
248+ * This util function will build an option object with passive option
249+ * to handle all possible input from the user.
250+ */
251+ function buildEventListenerOptions ( options : any , passive : boolean ) {
252+ if ( ! passiveSupported && typeof options === 'object' && options ) {
253+ // doesn't support passive but user want to pass an object as options.
254+ // this will not work on some old browser, so we just pass a boolean
255+ // as useCapture parameter
256+ return ! ! options . capture ;
257+ }
258+ if ( ! passiveSupported || ! passive ) {
259+ return options ;
260+ }
261+ if ( typeof options === 'boolean' ) {
262+ return { capture : options , passive : true } ;
257263 }
264+ if ( ! options ) {
265+ return { passive : true } ;
266+ }
267+ if ( typeof options === 'object' && options . passive !== false ) {
268+ return { ...options , passive : true } ;
269+ }
270+ return options ;
258271 }
259272
260273 const customScheduleGlobal = function ( task : Task ) {
@@ -263,7 +276,6 @@ export function patchEventTarget(
263276 if ( taskData . isExisting ) {
264277 return ;
265278 }
266- checkIsPassive ( task ) ;
267279 return nativeAddEventListener . call (
268280 taskData . target , taskData . eventName ,
269281 taskData . capture ? globalZoneAwareCaptureCallback : globalZoneAwareCallback ,
@@ -311,7 +323,6 @@ export function patchEventTarget(
311323 } ;
312324
313325 const customScheduleNonGlobal = function ( task : Task ) {
314- checkIsPassive ( task ) ;
315326 return nativeAddEventListener . call (
316327 taskData . target , taskData . eventName , task . invoke , taskData . options ) ;
317328 } ;
@@ -338,6 +349,7 @@ export function patchEventTarget(
338349 ( patchOptions && patchOptions . diff ) ? patchOptions . diff : compareTaskCallbackVsDelegate ;
339350
340351 const blackListedEvents : string [ ] = ( Zone as any ) [ zoneSymbol ( 'BLACK_LISTED_EVENTS' ) ] ;
352+ const passiveEvents : string [ ] = _global [ zoneSymbol ( 'PASSIVE_EVENTS' ) ] ;
341353
342354 const makeAddListener = function (
343355 nativeListener : any , addSource : string , customScheduleFn : any , customCancelFn : any ,
@@ -372,29 +384,25 @@ export function patchEventTarget(
372384 return ;
373385 }
374386
375- const options = arguments [ 2 ] ;
387+ const passive =
388+ passiveSupported && ! ! passiveEvents && passiveEvents . indexOf ( eventName ) !== - 1 ;
389+ const options = buildEventListenerOptions ( arguments [ 2 ] , passive ) ;
376390
377391 if ( blackListedEvents ) {
378392 // check black list
379393 for ( let i = 0 ; i < blackListedEvents . length ; i ++ ) {
380394 if ( eventName === blackListedEvents [ i ] ) {
381- return nativeListener . apply ( this , arguments ) ;
395+ if ( passive ) {
396+ return nativeListener . call ( target , eventName , delegate , options ) ;
397+ } else {
398+ return nativeListener . apply ( this , arguments ) ;
399+ }
382400 }
383401 }
384402 }
385403
386- let capture ;
387- let once = false ;
388- if ( options === undefined ) {
389- capture = false ;
390- } else if ( options === true ) {
391- capture = true ;
392- } else if ( options === false ) {
393- capture = false ;
394- } else {
395- capture = options ? ! ! options . capture : false ;
396- once = options ? ! ! options . once : false ;
397- }
404+ const capture = ! options ? false : typeof options === 'boolean' ? true : options . capture ;
405+ const once = options && typeof options === 'object' ? options . once : false ;
398406
399407 const zone = Zone . current ;
400408 let symbolEventNames = zoneSymbolEventNames [ eventName ] ;
@@ -508,17 +516,7 @@ export function patchEventTarget(
508516 }
509517 const options = arguments [ 2 ] ;
510518
511- let capture ;
512- if ( options === undefined ) {
513- capture = false ;
514- } else if ( options === true ) {
515- capture = true ;
516- } else if ( options === false ) {
517- capture = false ;
518- } else {
519- capture = options ? ! ! options . capture : false ;
520- }
521-
519+ const capture = ! options ? false : typeof options === 'boolean' ? true : options . capture ;
522520 const delegate = arguments [ 1 ] ;
523521 if ( ! delegate ) {
524522 return nativeRemoveEventListener . apply ( this , arguments ) ;
0 commit comments