@@ -17,7 +17,7 @@ import {
17
17
} from '@angular/core' ;
18
18
import { Direction , Directionality } from '@angular/cdk/bidi' ;
19
19
import { OverlayContainer , Overlay } from '@angular/cdk/overlay' ;
20
- import { ESCAPE , LEFT_ARROW , RIGHT_ARROW , DOWN_ARROW , TAB } from '@angular/cdk/keycodes' ;
20
+ import { ESCAPE , LEFT_ARROW , RIGHT_ARROW , DOWN_ARROW , TAB , HOME , END } from '@angular/cdk/keycodes' ;
21
21
import {
22
22
MAT_MENU_DEFAULT_OPTIONS ,
23
23
MatMenu ,
@@ -624,6 +624,104 @@ describe('MatMenu', () => {
624
624
expect ( overlayContainerElement . textContent ) . toBe ( '' ) ;
625
625
} ) ) ;
626
626
627
+ it ( 'should focus the first item when pressing home' , fakeAsync ( ( ) => {
628
+ const fixture = createComponent ( SimpleMenu , [ ] , [ FakeIcon ] ) ;
629
+ fixture . detectChanges ( ) ;
630
+
631
+ fixture . componentInstance . trigger . openMenu ( ) ;
632
+ fixture . detectChanges ( ) ;
633
+
634
+ const panel = overlayContainerElement . querySelector ( '.mat-menu-panel' ) ! ;
635
+ const items = Array . from ( panel . querySelectorAll ( '.mat-menu-item' ) ) as HTMLElement [ ] ;
636
+ items . forEach ( patchElementFocus ) ;
637
+
638
+ // Focus the last item since focus starts from the first one.
639
+ items [ items . length - 1 ] . focus ( ) ;
640
+ fixture . detectChanges ( ) ;
641
+
642
+ spyOn ( items [ 0 ] , 'focus' ) . and . callThrough ( ) ;
643
+
644
+ const event = dispatchKeyboardEvent ( panel , 'keydown' , HOME ) ;
645
+ fixture . detectChanges ( ) ;
646
+
647
+ expect ( items [ 0 ] . focus ) . toHaveBeenCalled ( ) ;
648
+ expect ( event . defaultPrevented ) . toBe ( true ) ;
649
+ flush ( ) ;
650
+ } ) ) ;
651
+
652
+ it ( 'should not focus the first item when pressing home with a modifier key' , fakeAsync ( ( ) => {
653
+ const fixture = createComponent ( SimpleMenu , [ ] , [ FakeIcon ] ) ;
654
+ fixture . detectChanges ( ) ;
655
+
656
+ fixture . componentInstance . trigger . openMenu ( ) ;
657
+ fixture . detectChanges ( ) ;
658
+
659
+ const panel = overlayContainerElement . querySelector ( '.mat-menu-panel' ) ! ;
660
+ const items = Array . from ( panel . querySelectorAll ( '.mat-menu-item' ) ) as HTMLElement [ ] ;
661
+ items . forEach ( patchElementFocus ) ;
662
+
663
+ // Focus the last item since focus starts from the first one.
664
+ items [ items . length - 1 ] . focus ( ) ;
665
+ fixture . detectChanges ( ) ;
666
+
667
+ spyOn ( items [ 0 ] , 'focus' ) . and . callThrough ( ) ;
668
+
669
+ const event = createKeyboardEvent ( 'keydown' , HOME ) ;
670
+ Object . defineProperty ( event , 'altKey' , { get : ( ) => true } ) ;
671
+
672
+ dispatchEvent ( panel , event ) ;
673
+ fixture . detectChanges ( ) ;
674
+
675
+ expect ( items [ 0 ] . focus ) . not . toHaveBeenCalled ( ) ;
676
+ expect ( event . defaultPrevented ) . toBe ( false ) ;
677
+ flush ( ) ;
678
+ } ) ) ;
679
+
680
+ it ( 'should focus the last item when pressing end' , fakeAsync ( ( ) => {
681
+ const fixture = createComponent ( SimpleMenu , [ ] , [ FakeIcon ] ) ;
682
+ fixture . detectChanges ( ) ;
683
+
684
+ fixture . componentInstance . trigger . openMenu ( ) ;
685
+ fixture . detectChanges ( ) ;
686
+
687
+ const panel = overlayContainerElement . querySelector ( '.mat-menu-panel' ) ! ;
688
+ const items = Array . from ( panel . querySelectorAll ( '.mat-menu-item' ) ) as HTMLElement [ ] ;
689
+ items . forEach ( patchElementFocus ) ;
690
+
691
+ spyOn ( items [ items . length - 1 ] , 'focus' ) . and . callThrough ( ) ;
692
+
693
+ const event = dispatchKeyboardEvent ( panel , 'keydown' , END ) ;
694
+ fixture . detectChanges ( ) ;
695
+
696
+ expect ( items [ items . length - 1 ] . focus ) . toHaveBeenCalled ( ) ;
697
+ expect ( event . defaultPrevented ) . toBe ( true ) ;
698
+ flush ( ) ;
699
+ } ) ) ;
700
+
701
+ it ( 'should not focus the last item when pressing end with a modifier key' , fakeAsync ( ( ) => {
702
+ const fixture = createComponent ( SimpleMenu , [ ] , [ FakeIcon ] ) ;
703
+ fixture . detectChanges ( ) ;
704
+
705
+ fixture . componentInstance . trigger . openMenu ( ) ;
706
+ fixture . detectChanges ( ) ;
707
+
708
+ const panel = overlayContainerElement . querySelector ( '.mat-menu-panel' ) ! ;
709
+ const items = Array . from ( panel . querySelectorAll ( '.mat-menu-item' ) ) as HTMLElement [ ] ;
710
+ items . forEach ( patchElementFocus ) ;
711
+
712
+ spyOn ( items [ items . length - 1 ] , 'focus' ) . and . callThrough ( ) ;
713
+
714
+ const event = createKeyboardEvent ( 'keydown' , END ) ;
715
+ Object . defineProperty ( event , 'altKey' , { get : ( ) => true } ) ;
716
+
717
+ dispatchEvent ( panel , event ) ;
718
+ fixture . detectChanges ( ) ;
719
+
720
+ expect ( items [ items . length - 1 ] . focus ) . not . toHaveBeenCalled ( ) ;
721
+ expect ( event . defaultPrevented ) . toBe ( false ) ;
722
+ flush ( ) ;
723
+ } ) ) ;
724
+
627
725
describe ( 'lazy rendering' , ( ) => {
628
726
it ( 'should be able to render the menu content lazily' , fakeAsync ( ( ) => {
629
727
const fixture = createComponent ( SimpleLazyMenu ) ;
0 commit comments