@@ -15,6 +15,7 @@ describe('material.components.menuBar', function() {
15
15
it ( 'sets md-position-mode to "bottom left" on nested menus' , function ( ) {
16
16
var menuBar = setup ( ) ;
17
17
var nestedMenu = menuBar [ 0 ] . querySelector ( 'md-menu' ) ;
18
+
18
19
expect ( nestedMenu . getAttribute ( 'md-position-mode' ) ) . toBe ( 'left bottom' ) ;
19
20
} ) ;
20
21
@@ -25,6 +26,92 @@ describe('material.components.menuBar', function() {
25
26
expect ( ariaRole ) . toBe ( 'menubar' ) ;
26
27
} ) ;
27
28
} ) ;
29
+
30
+ describe ( 'nested menus' , function ( ) {
31
+ var menuBar , menus , subMenuOpen , ctrl ;
32
+
33
+ it ( 'opens consecutive nested menus' , function ( ) {
34
+ menuBar = setup ( ) ;
35
+ ctrl = menuBar . controller ( 'mdMenuBar' ) ;
36
+ menus = menuBar [ 0 ] . querySelectorAll ( 'md-menu md-menu' ) ;
37
+
38
+ angular . element ( document . body ) . append ( menuBar ) ;
39
+
40
+ // Open the menu-bar menu
41
+ ctrl . focusMenu ( 1 ) ;
42
+ ctrl . openFocusedMenu ( ) ;
43
+ waitForMenuOpen ( ) ;
44
+
45
+ // Open the first nested menu
46
+ openSubMenu ( 0 ) ;
47
+ waitForMenuOpen ( ) ;
48
+ expect ( getOpenSubMenu ( ) . text ( ) . trim ( ) ) . toBe ( 'Sub 1 - Content' ) ;
49
+
50
+ // Open the second nested menu, the first menu should close
51
+ openSubMenu ( 1 ) ;
52
+ waitForMenuClose ( ) ;
53
+
54
+ // Then the second menu should become visible
55
+ waitForMenuOpen ( ) ;
56
+ expect ( getOpenSubMenu ( ) . text ( ) . trim ( ) ) . toBe ( 'Sub 2 - Content' ) ;
57
+
58
+ menuBar . remove ( ) ;
59
+ } ) ;
60
+
61
+ function openSubMenu ( index ) {
62
+ // If a menu is already open, trigger the mouse leave to close it
63
+ if ( subMenuOpen ) {
64
+ subMenuOpen . triggerHandler ( {
65
+ type : 'mouseleave' ,
66
+ target : subMenuOpen [ 0 ] ,
67
+ currentTarget : subMenuOpen [ 0 ]
68
+ } ) ;
69
+ }
70
+
71
+ // Set the currently open sub-menu and trigger the mouse enter
72
+ subMenuOpen = angular . element ( menus [ index ] ) ;
73
+ subMenuOpen . triggerHandler ( {
74
+ type : 'mouseenter' ,
75
+ target : subMenuOpen [ 0 ] ,
76
+ currentTarget : subMenuOpen [ 0 ]
77
+ } ) ;
78
+ }
79
+
80
+ function getOpenSubMenu ( ) {
81
+ debugger ;
82
+ var containers = document . body . querySelectorAll ( '._md-open-menu-container._md-active' ) ;
83
+ var lastContainer = containers . item ( containers . length - 1 ) ;
84
+
85
+ return angular . element ( lastContainer . querySelector ( 'md-menu-content' ) ) ;
86
+ }
87
+
88
+ function setup ( ) {
89
+ var el ;
90
+ inject ( function ( $compile , $rootScope ) {
91
+ el = $compile ( [
92
+ '<md-menu-bar>' ,
93
+ ' <md-menu>' ,
94
+ ' <md-menu-item>' ,
95
+ ' <button ng-click="clicked=true">Button {{i}}</button>' ,
96
+ ' </md-menu-item>' ,
97
+ ' <md-menu-content class="test-submenu">' ,
98
+ ' <md-menu ng-repeat="i in [1, 2]">' ,
99
+ ' <md-menu-item>' ,
100
+ ' <button ng-click="subclicked=true">Sub Button{{i}}</button>' ,
101
+ ' </md-menu-item>' ,
102
+ ' <md-menu-content>Sub {{i}} - Content</md-menu-content>' ,
103
+ ' </md-menu>' ,
104
+ ' </md-menu-content>' ,
105
+ ' </md-menu>' ,
106
+ '</md-menu-bar>'
107
+ ] . join ( '' ) ) ( $rootScope ) ;
108
+ $rootScope . $digest ( ) ;
109
+ } ) ;
110
+ attachedMenuElements . push ( el ) ;
111
+
112
+ return el ;
113
+ }
114
+ } ) ;
28
115
} ) ;
29
116
30
117
describe ( 'MenuBarCtrl' , function ( ) {
@@ -64,6 +151,13 @@ describe('material.components.menuBar', function() {
64
151
describe ( '#focusMenu' , function ( ) {
65
152
var focused ;
66
153
beforeEach ( function ( ) { focused = false ; } ) ;
154
+ it ( 'focuses the first menu if none is focused' , function ( ) {
155
+ var menus = mockButtonAtIndex ( 0 ) ;
156
+ spyOn ( ctrl , 'getFocusedMenuIndex' ) . and . returnValue ( - 1 ) ;
157
+ spyOn ( ctrl , 'getMenus' ) . and . returnValue ( menus ) ;
158
+ ctrl . focusMenu ( 1 ) ;
159
+ expect ( focused ) . toBe ( true ) ;
160
+ } ) ;
67
161
it ( 'focuses the next menu' , function ( ) {
68
162
var menus = mockButtonAtIndex ( 1 ) ;
69
163
spyOn ( ctrl , 'getFocusedMenuIndex' ) . and . returnValue ( 0 ) ;
@@ -100,13 +194,16 @@ describe('material.components.menuBar', function() {
100
194
var mockButton = {
101
195
querySelector : function ( ) { return {
102
196
focus : function ( ) { focused = true ; }
103
- } ; }
197
+ } ; } ,
198
+
199
+ // TODO: This may need to become more complex if more of the tests use it
200
+ classList : { contains : function ( ) { return false ; } }
104
201
} ;
105
202
for ( var i = 0 ; i < 3 ; ++ i ) {
106
203
if ( i == index ) {
107
204
result . push ( mockButton ) ;
108
205
} else {
109
- result . push ( { } ) ;
206
+ result . push ( { classList : mockButton . classList } ) ;
110
207
}
111
208
}
112
209
return result ;
@@ -307,5 +404,17 @@ describe('material.components.menuBar', function() {
307
404
}
308
405
} ) ;
309
406
} ) ;
407
+
408
+ function waitForMenuOpen ( ) {
409
+ inject ( function ( $material ) {
410
+ $material . flushInterimElement ( ) ;
411
+ } ) ;
412
+ }
413
+
414
+ function waitForMenuClose ( ) {
415
+ inject ( function ( $material ) {
416
+ $material . flushInterimElement ( ) ;
417
+ } ) ;
418
+ }
310
419
} ) ;
311
420
0 commit comments