license import { ifEnvSupports } from '../test-util' ; describe ( 'element' , function ( ) { let button ; beforeEach ( function ( ) { button = document . createElement ( 'button' ) ; document . body . appendChild ( button ) ; } ) ; afterEach ( function ( ) { document . body . removeChild ( button ) ; } ) ; it ( 'should work when addEventListener / removeEventListener are called in the global context' , function ( ) { const clickEvent = document . createEvent ( 'Event' ) ; let callCount = 0 ; clickEvent . initEvent ( 'click' , true , true ) ; const listener = function ( event ) { callCount ++ ; expect ( event ) . toBe ( clickEvent ) ; } ; addEventListener ( 'click' , listener ) ; button . dispatchEvent ( clickEvent ) ; expect ( callCount ) . toEqual ( 1 ) ; removeEventListener ( 'click' , listener ) ; button . dispatchEvent ( clickEvent ) ; expect ( callCount ) . toEqual ( 1 ) ; } ) ; it ( 'should work with addEventListener when called with a function listener' , function ( ) { const clickEvent = document . createEvent ( 'Event' ) ; clickEvent . initEvent ( 'click' , true , true ) ; button . addEventListener ( 'click' , function ( event ) { expect ( event ) . toBe ( clickEvent ) ; } ) ; button . dispatchEvent ( clickEvent ) ; } ) ; it ( 'should not call microtasks early when an event is invoked' , function ( done ) { let log = '' ; button . addEventListener ( 'click' , ( ) => { Zone . current . scheduleMicroTask ( 'test' , ( ) => log += 'microtask;' ) ; log += 'click;' ; } ) ; button . click ( ) ; expect ( log ) . toEqual ( 'click;' ) ; done ( ) ; } ) ; it ( 'should call microtasks early when an event is invoked' , function ( done ) { ( window as any ) [ ( Zone as any ) . __symbol__ ( 'setTimeout' ) ] ( ( ) => { let log = '' ; button . addEventListener ( 'click' , ( ) => { Zone . current . scheduleMicroTask ( 'test' , ( ) => log += 'microtask;' ) ; log += 'click;' ; } ) ; button . click ( ) ; expect ( log ) . toEqual ( 'click;microtask;' ) ; done ( ) ; } ) ; } ) ; it ( 'should work with addEventListener when called with an EventListener-implementing listener' , function ( ) { const eventListener = { x : 5 , handleEvent : function ( event ) { expect ( this . x ) . toBe ( 5 ) ; expect ( event ) . toBe ( clickEvent ) ; } } ; const clickEvent = document . createEvent ( 'Event' ) ; clickEvent . initEvent ( 'click' , true , true ) ; button . addEventListener ( 'click' , eventListener ) ; button . dispatchEvent ( clickEvent ) ; } ) ; it ( 'should respect removeEventListener when called with a function listener' , function ( ) { let log = '' ; const logFunction = function logFunction ( ) { log += 'a' ; } ; button . addEventListener ( 'click' , logFunction ) ; button . addEventListener ( 'focus' , logFunction ) ; button . click ( ) ; expect ( log ) . toEqual ( 'a' ) ; const focusEvent = document . createEvent ( 'Event' ) ; focusEvent . initEvent ( 'focus' , true , true ) ; button . dispatchEvent ( focusEvent ) ; expect ( log ) . toEqual ( 'aa' ) ; button . removeEventListener ( 'click' , logFunction ) ; button . click ( ) ; expect ( log ) . toEqual ( 'aa' ) ; } ) ; it ( 'should respect removeEventListener with an EventListener-implementing listener' , function ( ) { const eventListener = { x : 5 , handleEvent : jasmine . createSpy ( 'handleEvent' ) } ; button . addEventListener ( 'click' , eventListener ) ; button . removeEventListener ( 'click' , eventListener ) ; button . click ( ) ; expect ( eventListener . handleEvent ) . not . toHaveBeenCalled ( ) ; } ) ; it ( 'should have no effect while calling addEventListener without listener' , function ( ) { const onAddEventListenerSpy = jasmine . createSpy ( 'addEventListener' ) ; const eventListenerZone = Zone . current . fork ( { name : 'eventListenerZone' , onScheduleTask : onAddEventListenerSpy } ) ; expect ( function ( ) { eventListenerZone . run ( function ( ) { button . addEventListener ( 'click' , null as any ) ; button . addEventListener ( 'click' , undefined as any ) ; } ) ; } ) . not . toThrowError ( ) ; expect ( onAddEventListenerSpy ) . not . toHaveBeenCalledWith ( ) ; } ) ; it ( 'should have no effect while calling removeEventListener without listener' , function ( ) { const onAddEventListenerSpy = jasmine . createSpy ( 'removeEventListener' ) ; const eventListenerZone = Zone . current . fork ( { name : 'eventListenerZone' , onScheduleTask : onAddEventListenerSpy } ) ; expect ( function ( ) { eventListenerZone . run ( function ( ) { button . removeEventListener ( 'click' , null as any ) ; button . removeEventListener ( 'click' , undefined as any ) ; } ) ; } ) . not . toThrowError ( ) ; expect ( onAddEventListenerSpy ) . not . toHaveBeenCalledWith ( ) ; } ) ; it ( 'should only add a listener once for a given set of arguments' , function ( ) { const log = [ ] ; const clickEvent = document . createEvent ( 'Event' ) ; function listener ( ) { log . push ( 'listener' ) ; } clickEvent . initEvent ( 'click' , true , true ) ; button . addEventListener ( 'click' , listener ) ; button . addEventListener ( 'click' , listener ) ; button . addEventListener ( 'click' , listener ) ; button . dispatchEvent ( clickEvent ) ; expect ( log ) . toEqual ( [ 'listener' ] ) ; button . removeEventListener ( 'click' , listener ) ; button . dispatchEvent ( clickEvent ) ; expect ( log ) . toEqual ( [ 'listener' ] ) ; } ) ; it ( 'should correctly handler capturing versus nonCapturing eventListeners' , function ( ) { const log = [ ] ; const clickEvent = document . createEvent ( 'Event' ) ; function capturingListener ( ) { log . push ( 'capturingListener' ) ; } function bubblingListener ( ) { log . push ( 'bubblingListener' ) ; } clickEvent . initEvent ( 'click' , true , true ) ; document . body . addEventListener ( 'click' , capturingListener , true ) ; document . body . addEventListener ( 'click' , bubblingListener ) ; button . dispatchEvent ( clickEvent ) ; expect ( log ) . toEqual ( [ 'capturingListener' , 'bubblingListener' ] ) ; } ) ; it ( 'should correctly handler a listener that is both capturing and nonCapturing' , function ( ) { const log = [ ] ; const clickEvent = document . createEvent ( 'Event' ) ; function listener ( ) { log . push ( 'listener' ) ; } clickEvent . initEvent ( 'click' , true , true ) ; document . body . addEventListener ( 'click' , listener , true ) ; document . body . addEventListener ( 'click' , listener ) ; button . dispatchEvent ( clickEvent ) ; document . body . removeEventListener ( 'click' , listener , true ) ; document . body . removeEventListener ( 'click' , listener ) ; button . dispatchEvent ( clickEvent ) ; expect ( log ) . toEqual ( [ 'listener' , 'listener' ] ) ; } ) ; describe ( 'onclick' , function ( ) { function supportsOnClick ( ) { const div = document . createElement ( 'div' ) ; const clickPropDesc = Object . getOwnPropertyDescriptor ( div , 'onclick' ) ; return ! ( EventTarget && div instanceof EventTarget && clickPropDesc && clickPropDesc . value === null ) ; } ( < any > supportsOnClick ) . message = 'Supports Element#onclick patching' ; ifEnvSupports ( supportsOnClick , function ( ) { it ( 'should spawn new child zones' , function ( ) { let run = false ; button . onclick = function ( ) { run = true ; } ; button . click ( ) ; expect ( run ) . toBeTruthy ( ) ; } ) ; } ) ; it ( 'should only allow one onclick handler' , function ( ) { let log = '' ; button . onclick = function ( ) { log += 'a' ; } ; button . onclick = function ( ) { log += 'b' ; } ; button . click ( ) ; expect ( log ) . toEqual ( 'b' ) ; } ) ; it ( 'should handler removing onclick' , function ( ) { let log = '' ; button . onclick = function ( ) { log += 'a' ; } ; button . onclick = null as any ; button . click ( ) ; expect ( log ) . toEqual ( '' ) ; } ) ; it ( 'should be able to deregister the same event twice' , function ( ) { const listener = ( event ) => { } ; document . body . addEventListener ( 'click' , listener , false ) ; document . body . removeEventListener ( 'click' , listener , false ) ; document . body . removeEventListener ( 'click' , listener , false ) ; } ) ; } ) ; describe ( 'onEvent default behavior' , function ( ) { let checkbox ; beforeEach ( function ( ) { checkbox = document . createElement ( 'input' ) ; checkbox . type = 'checkbox' ; document . body . appendChild ( checkbox ) ; } ) ; afterEach ( function ( ) { document . body . removeChild ( checkbox ) ; } ) ; it ( 'should be possible to prevent default behavior by returning false' , function ( ) { checkbox . onclick = function ( ) { return false ; } ; checkbox . click ( ) ; expect ( checkbox . checked ) . toBe ( false ) ; } ) ; it ( 'should have no effect on default behavior when not returning anything' , function ( ) { checkbox . onclick = function ( ) { } ; checkbox . click ( ) ; expect ( checkbox . checked ) . toBe ( true ) ; } ) ; } ) ; } ) ;