@@ -289,9 +289,9 @@ export function main() {
289
289
expect ( el . nativeElement . className ) . toContain ( 'md-checkbox-disabled' ) ;
290
290
} ) ;
291
291
292
- it ( 'sets the tabindex to -1 on the host element' , function ( ) {
292
+ it ( 'removes the tabindex attribute from the host element' , function ( ) {
293
293
let el = fixture . debugElement . query ( By . css ( '.md-checkbox' ) ) ;
294
- expect ( el . nativeElement . getAttribute ( 'tabindex' ) ) . toEqual ( '-1' ) ;
294
+ expect ( el . nativeElement . hasAttribute ( 'tabindex' ) ) . toBe ( false ) ;
295
295
} ) ;
296
296
297
297
it ( 'sets "aria-disabled" to "true" on the host element' , function ( ) {
@@ -307,7 +307,7 @@ export function main() {
307
307
tabindexController . isDisabled = true ;
308
308
fixture . detectChanges ( ) ;
309
309
let el = fixture . debugElement . query ( By . css ( '.md-checkbox' ) ) ;
310
- expect ( el . nativeElement . getAttribute ( 'tabindex' ) ) . toEqual ( '-1' ) ;
310
+ expect ( el . nativeElement . hasAttribute ( 'tabindex' ) ) . toBe ( false ) ;
311
311
312
312
tabindexController . isDisabled = false ;
313
313
fixture . detectChanges ( ) ;
@@ -334,9 +334,9 @@ export function main() {
334
334
} ) . then ( done ) . catch ( done ) ;
335
335
} ) ;
336
336
337
- it ( 'keeps the tabindex at -1 ' , function ( ) {
337
+ it ( 'keeps the tabindex removed from the host ' , function ( ) {
338
338
let el = fixture . debugElement . query ( By . css ( '.md-checkbox' ) ) ;
339
- expect ( el . nativeElement . getAttribute ( 'tabindex' ) ) . toEqual ( '-1' ) ;
339
+ expect ( el . nativeElement . hasAttribute ( 'tabindex' ) ) . toBe ( false ) ;
340
340
} ) ;
341
341
342
342
it ( 'uses the newly changed tabindex when re-enabled' , function ( ) {
@@ -394,6 +394,102 @@ export function main() {
394
394
} ) ;
395
395
} ) ;
396
396
397
+ describe ( 'when the checkbox is focused' , function ( ) {
398
+ var browserSupportsDom3KeyProp : boolean = ( { } ) . hasOwnProperty . call (
399
+ KeyboardEvent . prototype , 'key' ) ;
400
+ var fixture : ComponentFixture ;
401
+ var controller : CheckboxController ;
402
+ var el : DebugElement ;
403
+ var windowListenerSpy : jasmine . Spy ;
404
+ var windowKeydownListeners : EventListener [ ] ;
405
+
406
+ function keydown ( target : EventTarget , key : string , keyCode : number ) : Event {
407
+ var evt : Event ;
408
+ if ( BROWSER_SUPPORTS_EVENT_CONSTRUCTORS && browserSupportsDom3KeyProp ) {
409
+ evt = new KeyboardEvent ( 'keydown' , { key} ) ;
410
+ } else {
411
+ // NOTE(traviskaufman): Chrome/Webkit-based browsers do not support any mechanism for
412
+ // creating keyboard events with the correct keyCode. Therefore, the object.defineProperty
413
+ // hack is the only way to make this work correctly.
414
+ // see: https://bugs.webkit.org/show_bug.cgi?id=16735
415
+ // see: https://bugs.chromium.org/p/chromium/issues/detail?id=227231
416
+ // see: http://goo.gl/vrh534 (stackoverflow post on the topic).
417
+ evt = document . createEvent ( 'Event' ) ;
418
+ evt . initEvent ( 'keydown' , true , true ) ;
419
+ Object . defineProperty ( evt , 'keyCode' , {
420
+ value : keyCode ,
421
+ enumerable : true ,
422
+ writable : false ,
423
+ configurable : true
424
+ } ) ;
425
+ }
426
+ spyOn ( evt , 'preventDefault' ) . and . callThrough ( ) ;
427
+ target . dispatchEvent ( evt ) ;
428
+ return evt ;
429
+ } ;
430
+
431
+ function dispatchUIEventOnEl ( evtName : string ) {
432
+ var evt : Event ;
433
+ if ( BROWSER_SUPPORTS_EVENT_CONSTRUCTORS ) {
434
+ evt = new Event ( evtName ) ;
435
+ } else {
436
+ evt = document . createEvent ( 'Event' ) ;
437
+ evt . initEvent ( evtName , true , true ) ;
438
+ }
439
+ el . nativeElement . dispatchEvent ( evt ) ;
440
+ fixture . detectChanges ( ) ;
441
+ }
442
+
443
+ beforeEach ( function ( done : ( ) => void ) {
444
+ var windowAddEventListener = window . addEventListener . bind ( window ) ;
445
+ windowKeydownListeners = [ ] ;
446
+ windowListenerSpy = spyOn ( window , 'addEventListener' ) . and . callFake (
447
+ function ( name : string , listener : EventListener ) {
448
+ if ( name === 'keydown' ) {
449
+ windowKeydownListeners . push ( listener ) ;
450
+ }
451
+ windowAddEventListener ( name , listener ) ;
452
+ } ) ;
453
+
454
+ builder . createAsync ( CheckboxController ) . then ( function ( f ) {
455
+ fixture = f ;
456
+ controller = fixture . componentInstance ;
457
+
458
+ fixture . detectChanges ( ) ;
459
+ el = fixture . debugElement . query ( By . css ( '.md-checkbox' ) ) ;
460
+ } ) . then ( done ) . catch ( done ) ;
461
+ } ) ;
462
+
463
+ afterEach ( function ( ) {
464
+ windowKeydownListeners . forEach ( ( l ) => window . removeEventListener ( 'keydown' , l ) ) ;
465
+ } ) ;
466
+
467
+ it ( 'blocks spacebar keydown events from performing their default behavior' , function ( ) {
468
+ dispatchUIEventOnEl ( 'focus' ) ;
469
+
470
+ var evt = keydown ( window , ' ' , 32 ) ;
471
+ expect ( evt . preventDefault ) . toHaveBeenCalled ( ) ;
472
+ } ) ;
473
+
474
+ it ( 'does not block other keyboard events from performing their default behavior' , function ( ) {
475
+ dispatchUIEventOnEl ( 'focus' ) ;
476
+
477
+ var evt = keydown ( window , 'Tab' , 9 ) ;
478
+ expect ( evt . preventDefault ) . not . toHaveBeenCalled ( ) ;
479
+ } ) ;
480
+
481
+ it ( 'stops blocking spacebar keydown events when un-focused' , function ( ) {
482
+ dispatchUIEventOnEl ( 'focus' ) ;
483
+ // sanity check.
484
+ var evt = keydown ( window , ' ' , 32 ) ;
485
+ expect ( evt . preventDefault ) . toHaveBeenCalled ( ) ;
486
+
487
+ dispatchUIEventOnEl ( 'blur' ) ;
488
+ evt = keydown ( window , ' ' , 32 ) ;
489
+ expect ( evt . preventDefault ) . not . toHaveBeenCalled ( ) ;
490
+ } ) ;
491
+ } ) ;
492
+
397
493
describe ( 'when a spacebar press occurs on the checkbox' , function ( ) {
398
494
var fixture : ComponentFixture ;
399
495
var controller : CheckboxController ;
@@ -602,10 +698,11 @@ function keyup(el: DebugElement, key: string, fixture: ComponentFixture) {
602
698
if ( BROWSER_SUPPORTS_EVENT_CONSTRUCTORS ) {
603
699
kbdEvent = new KeyboardEvent ( 'keyup' ) ;
604
700
} else {
605
- kbdEvent = document . createEvent ( 'Events ' ) ;
701
+ kbdEvent = document . createEvent ( 'Event ' ) ;
606
702
kbdEvent . initEvent ( 'keyup' , true , true ) ;
607
703
}
608
704
// Hack DOM Level 3 Events "key" prop into keyboard event.
705
+ // See note above for explanation of this defineProperty hack.
609
706
Object . defineProperty ( kbdEvent , 'key' , {
610
707
value : ' ' ,
611
708
enumerable : false ,
0 commit comments