@@ -8,7 +8,7 @@ import {MenuContentGesture, MenuTargetGesture} from './menu-gestures';
8
8
import { Gesture } from '../../gestures/gesture' ;
9
9
import { MenuController } from './menu-controller' ;
10
10
import { MenuType } from './menu-types' ;
11
- import { isFalseProperty } from '../../util/util' ;
11
+ import { isTrueProperty } from '../../util/util' ;
12
12
13
13
14
14
/**
@@ -17,12 +17,11 @@ import {isFalseProperty} from '../../util/util';
17
17
@Component ( {
18
18
selector : 'ion-menu' ,
19
19
host : {
20
- 'role' : 'navigation' ,
21
- '[attr.side]' : 'side' ,
22
- '[attr.type]' : 'type' ,
23
- '[attr.swipeEnabled]' : 'swipeEnabled'
20
+ 'role' : 'navigation'
24
21
} ,
25
- template : '<ng-content></ng-content><div tappable disable-activated class="backdrop"></div>' ,
22
+ template :
23
+ '<ng-content></ng-content>' +
24
+ '<div tappable disable-activated class="backdrop"></div>' ,
26
25
directives : [ forwardRef ( ( ) => MenuBackdrop ) ]
27
26
} )
28
27
export class Menu extends Ion {
@@ -32,23 +31,16 @@ export class Menu extends Ion {
32
31
private _menuGesture : Gesture ;
33
32
private _type : MenuType ;
34
33
private _resizeUnreg : Function ;
35
-
34
+ private _isEnabled : boolean = true ;
35
+ private _isSwipeEnabled : boolean = true ;
36
+ private _isListening : boolean = false ;
37
+ private _init : boolean = false ;
36
38
37
39
/**
38
40
* @private
39
41
*/
40
42
isOpen : boolean = false ;
41
43
42
- /**
43
- * @private
44
- */
45
- isEnabled : boolean = true ;
46
-
47
- /**
48
- * @private
49
- */
50
- isSwipeEnabled : boolean = true ;
51
-
52
44
/**
53
45
* @private
54
46
*/
@@ -83,7 +75,28 @@ export class Menu extends Ion {
83
75
/**
84
76
* @private
85
77
*/
86
- @Input ( ) swipeEnabled : any ;
78
+ @Input ( )
79
+ get enabled ( ) : boolean {
80
+ return this . _isEnabled ;
81
+ }
82
+
83
+ set enabled ( val : boolean ) {
84
+ this . _isEnabled = isTrueProperty ( val ) ;
85
+ this . _setListeners ( ) ;
86
+ }
87
+
88
+ /**
89
+ * @private
90
+ */
91
+ @Input ( )
92
+ get swipeEnabled ( ) : boolean {
93
+ return this . _isSwipeEnabled ;
94
+ }
95
+
96
+ set swipeEnabled ( val : boolean ) {
97
+ this . _isSwipeEnabled = isTrueProperty ( val ) ;
98
+ this . _setListeners ( ) ;
99
+ }
87
100
88
101
/**
89
102
* @private
@@ -112,6 +125,8 @@ export class Menu extends Ion {
112
125
*/
113
126
ngOnInit ( ) {
114
127
let self = this ;
128
+ self . _init = true ;
129
+
115
130
let content = self . content ;
116
131
self . _cntEle = ( content instanceof Node ) ? content : content && content . getNativeElement && content . getNativeElement ( ) ;
117
132
@@ -132,23 +147,29 @@ export class Menu extends Ion {
132
147
}
133
148
self . _renderer . setElementAttribute ( self . _elementRef . nativeElement , 'type' , self . type ) ;
134
149
135
- // add the gesture listeners
136
- self . _zone . runOutsideAngular ( function ( ) {
137
- self . _cntGesture = new MenuContentGesture ( self , self . getContentElement ( ) ) ;
138
- self . _menuGesture = new MenuTargetGesture ( self , self . getNativeElement ( ) ) ;
139
-
140
- self . onContentClick = function ( ev : UIEvent ) {
141
- if ( self . isEnabled ) {
142
- ev . preventDefault ( ) ;
143
- ev . stopPropagation ( ) ;
144
- self . close ( ) ;
145
- }
146
- } ;
147
- } ) ;
150
+ // add the gestures
151
+ self . _cntGesture = new MenuContentGesture ( self , self . getContentElement ( ) ) ;
152
+ self . _menuGesture = new MenuTargetGesture ( self , self . getNativeElement ( ) ) ;
148
153
149
- if ( isFalseProperty ( self . swipeEnabled ) ) {
150
- self . isSwipeEnabled = false ;
154
+ // register listeners if this menu is enabled
155
+ // check if more than one menu is on the same side
156
+ let hasEnabledSameSideMenu = self . _menuCtrl . getMenus ( ) . some ( m => {
157
+ return m . side === self . side && m . enabled ;
158
+ } ) ;
159
+ if ( hasEnabledSameSideMenu ) {
160
+ // auto-disable if another menu on the same side is already enabled
161
+ self . _isEnabled = false ;
151
162
}
163
+ self . _setListeners ( ) ;
164
+
165
+ // create a reusable click handler on this instance, but don't assign yet
166
+ self . onContentClick = function ( ev : UIEvent ) {
167
+ if ( self . _isEnabled ) {
168
+ ev . preventDefault ( ) ;
169
+ ev . stopPropagation ( ) ;
170
+ self . close ( ) ;
171
+ }
172
+ } ;
152
173
153
174
self . _cntEle . classList . add ( 'menu-content' ) ;
154
175
self . _cntEle . classList . add ( 'menu-content-' + self . type ) ;
@@ -157,6 +178,34 @@ export class Menu extends Ion {
157
178
self . _menuCtrl . register ( self ) ;
158
179
}
159
180
181
+ /**
182
+ * @private
183
+ */
184
+ private _setListeners ( ) {
185
+ let self = this ;
186
+
187
+ if ( self . _init ) {
188
+ // only listen/unlisten if the menu has initialized
189
+
190
+ if ( self . _isEnabled && self . _isSwipeEnabled && ! self . _isListening ) {
191
+ // should listen, but is not currently listening
192
+ console . debug ( 'menu, gesture listen' , self . side ) ;
193
+ self . _zone . runOutsideAngular ( function ( ) {
194
+ self . _cntGesture . listen ( ) ;
195
+ self . _menuGesture . listen ( ) ;
196
+ } ) ;
197
+ self . _isListening = true ;
198
+
199
+ } else if ( self . _isListening && ( ! self . _isEnabled || ! self . _isSwipeEnabled ) ) {
200
+ // should not listen, but is currently listening
201
+ console . debug ( 'menu, gesture unlisten' , self . side ) ;
202
+ self . _cntGesture . unlisten ( ) ;
203
+ self . _menuGesture . unlisten ( ) ;
204
+ self . _isListening = false ;
205
+ }
206
+ }
207
+ }
208
+
160
209
/**
161
210
* @private
162
211
*/
@@ -176,7 +225,7 @@ export class Menu extends Ion {
176
225
* @param {boolean } shouldOpen If the Menu is open or not.
177
226
* @return {Promise } returns a promise once set
178
227
*/
179
- setOpen ( shouldOpen ) : Promise < boolean > {
228
+ setOpen ( shouldOpen : boolean ) : Promise < boolean > {
180
229
// _isPrevented is used to prevent unwanted opening/closing after swiping open/close
181
230
// or swiping open the menu while pressing down on the menuToggle button
182
231
if ( ( shouldOpen && this . isOpen ) || this . _isPrevented ( ) ) {
@@ -198,7 +247,7 @@ export class Menu extends Ion {
198
247
*/
199
248
setProgressStart ( ) {
200
249
// user started swiping the menu open/close
201
- if ( this . _isPrevented ( ) || ! this . isEnabled || ! this . isSwipeEnabled ) return ;
250
+ if ( this . _isPrevented ( ) || ! this . _isEnabled || ! this . _isSwipeEnabled ) return ;
202
251
203
252
this . _before ( ) ;
204
253
this . _getType ( ) . setProgressStart ( this . isOpen ) ;
@@ -209,7 +258,7 @@ export class Menu extends Ion {
209
258
*/
210
259
setProgessStep ( stepValue : number ) {
211
260
// user actively dragging the menu
212
- if ( this . isEnabled && this . isSwipeEnabled ) {
261
+ if ( this . _isEnabled && this . _isSwipeEnabled ) {
213
262
this . _prevent ( ) ;
214
263
this . _getType ( ) . setProgessStep ( stepValue ) ;
215
264
this . opening . next ( stepValue ) ;
@@ -221,7 +270,7 @@ export class Menu extends Ion {
221
270
*/
222
271
setProgressEnd ( shouldComplete : boolean , currentStepValue : number ) {
223
272
// user has finished dragging the menu
224
- if ( this . isEnabled && this . isSwipeEnabled ) {
273
+ if ( this . _isEnabled && this . _isSwipeEnabled ) {
225
274
this . _prevent ( ) ;
226
275
this . _getType ( ) . setProgressEnd ( shouldComplete , currentStepValue , ( isOpen ) => {
227
276
console . debug ( 'menu, progress end' , this . side ) ;
@@ -236,7 +285,7 @@ export class Menu extends Ion {
236
285
private _before ( ) {
237
286
// this places the menu into the correct location before it animates in
238
287
// this css class doesn't actually kick off any animations
239
- if ( this . isEnabled ) {
288
+ if ( this . _isEnabled ) {
240
289
this . getNativeElement ( ) . classList . add ( 'show-menu' ) ;
241
290
this . getBackdropElement ( ) . classList . add ( 'show-backdrop' ) ;
242
291
@@ -252,7 +301,7 @@ export class Menu extends Ion {
252
301
// keep opening/closing the menu disabled for a touch more yet
253
302
// only add listeners/css if it's enabled and isOpen
254
303
// and only remove listeners/css if it's not open
255
- if ( ( this . isEnabled && isOpen ) || ! isOpen ) {
304
+ if ( ( this . _isEnabled && isOpen ) || ! isOpen ) {
256
305
this . _prevent ( ) ;
257
306
258
307
this . isOpen = isOpen ;
@@ -318,7 +367,7 @@ export class Menu extends Ion {
318
367
* @return {Menu } Returns the instance of the menu, which is useful for chaining.
319
368
*/
320
369
enable ( shouldEnable : boolean ) : Menu {
321
- this . isEnabled = shouldEnable ;
370
+ this . enabled = shouldEnable ;
322
371
if ( ! shouldEnable && this . isOpen ) {
323
372
this . close ( ) ;
324
373
}
@@ -331,7 +380,7 @@ export class Menu extends Ion {
331
380
* @return {Menu } Returns the instance of the menu, which is useful for chaining.
332
381
*/
333
382
swipeEnable ( shouldEnable : boolean ) : Menu {
334
- this . isSwipeEnabled = shouldEnable ;
383
+ this . swipeEnabled = shouldEnable ;
335
384
return this ;
336
385
}
337
386
0 commit comments