@@ -92,24 +92,29 @@ return $.widget( "ui.selectmenu", {
92
92
"aria-owns" : this . ids . menu ,
93
93
"aria-haspopup" : "true"
94
94
} )
95
- . insertAfter ( this . element ) ;
95
+ . insertAfter ( this . element ) ;
96
96
97
97
$ ( "<span>" , {
98
98
"class" : "ui-icon " + this . options . icons . button
99
- } ) . prependTo ( this . button ) ;
99
+ } )
100
+ . prependTo ( this . button ) ;
100
101
101
102
this . buttonText = $ ( "<span>" , {
102
103
"class" : "ui-selectmenu-text"
103
104
} )
104
- . appendTo ( this . button ) ;
105
+ . appendTo ( this . button ) ;
105
106
106
107
this . _setText ( this . buttonText , this . element . find ( "option:selected" ) . text ( ) ) ;
107
108
this . _setOption ( "width" , this . options . width ) ;
108
109
109
110
this . _on ( this . button , this . _buttonEvents ) ;
110
111
this . button . one ( "focusin" , function ( ) {
111
- // Delay rendering the menu items until the button receives focus
112
- that . _refreshMenu ( ) ;
112
+
113
+ // Delay rendering the menu items until the button receives focus.
114
+ // The menu may have already been rendered via a programmatic open.
115
+ if ( ! that . menuItems ) {
116
+ that . _refreshMenu ( ) ;
117
+ }
113
118
} ) ;
114
119
this . _hoverable ( this . button ) ;
115
120
this . _focusable ( this . button ) ;
@@ -129,47 +134,49 @@ return $.widget( "ui.selectmenu", {
129
134
this . menuWrap = $ ( "<div>" , {
130
135
"class" : "ui-selectmenu-menu ui-front"
131
136
} )
132
- . append ( this . menu )
133
- . appendTo ( this . _appendTo ( ) ) ;
137
+ . append ( this . menu )
138
+ . appendTo ( this . _appendTo ( ) ) ;
134
139
135
140
// Initialize menu widget
136
- this . menuInstance = this . menu . menu ( {
137
- role : "listbox" ,
138
- select : function ( event , ui ) {
139
- event . preventDefault ( ) ;
140
- that . _select ( ui . item . data ( "ui-selectmenu-item" ) , event ) ;
141
- } ,
142
- focus : function ( event , ui ) {
143
- var item = ui . item . data ( "ui-selectmenu-item" ) ;
144
-
145
- // Prevent inital focus from firing and checks if its a newly focused item
146
- if ( that . focusIndex != null && item . index !== that . focusIndex ) {
147
- that . _trigger ( "focus" , event , { item : item } ) ;
148
- if ( ! that . isOpen ) {
149
- that . _select ( item , event ) ;
141
+ this . menuInstance = this . menu
142
+ . menu ( {
143
+ role : "listbox" ,
144
+ select : function ( event , ui ) {
145
+ event . preventDefault ( ) ;
146
+ that . _select ( ui . item . data ( "ui-selectmenu-item" ) , event ) ;
147
+ } ,
148
+ focus : function ( event , ui ) {
149
+ var item = ui . item . data ( "ui-selectmenu-item" ) ;
150
+
151
+ // Prevent inital focus from firing and check if its a newly focused item
152
+ if ( that . focusIndex != null && item . index !== that . focusIndex ) {
153
+ that . _trigger ( "focus" , event , { item : item } ) ;
154
+ if ( ! that . isOpen ) {
155
+ that . _select ( item , event ) ;
156
+ }
150
157
}
151
- }
152
- that . focusIndex = item . index ;
158
+ that . focusIndex = item . index ;
153
159
154
- that . button . attr ( "aria-activedescendant" ,
155
- that . menuItems . eq ( item . index ) . attr ( "id" ) ) ;
156
- }
157
- } )
158
- . menu ( "instance" ) ;
160
+ that . button . attr ( "aria-activedescendant" ,
161
+ that . menuItems . eq ( item . index ) . attr ( "id" ) ) ;
162
+ }
163
+ } )
164
+ . menu ( "instance" ) ;
159
165
160
166
// Adjust menu styles to dropdown
161
- this . menu . addClass ( "ui-corner-bottom" ) . removeClass ( "ui-corner-all" ) ;
167
+ this . menu
168
+ . addClass ( "ui-corner-bottom" )
169
+ . removeClass ( "ui-corner-all" ) ;
162
170
163
- // TODO: Can we make this cleaner?
164
- // If not, at least update the comment to say what we're removing
165
- // Unbind uneeded menu events
171
+ // Don't close the menu on mouseleave
166
172
this . menuInstance . _off ( this . menu , "mouseleave" ) ;
167
173
168
174
// Cancel the menu's collapseAll on document click
169
175
this . menuInstance . _closeOnDocumentClick = function ( ) {
170
176
return false ;
171
177
} ;
172
178
179
+ // Selects often contain empty items, but never contain dividers
173
180
this . menuInstance . _isDivider = function ( ) {
174
181
return false ;
175
182
} ;
@@ -191,7 +198,7 @@ return $.widget( "ui.selectmenu", {
191
198
return ;
192
199
}
193
200
194
- this . _readOptions ( options ) ;
201
+ this . _parseOptions ( options ) ;
195
202
this . _renderMenu ( this . menu , this . items ) ;
196
203
197
204
this . menuInstance . refresh ( ) ;
@@ -271,14 +278,16 @@ return $.widget( "ui.selectmenu", {
271
278
if ( item . optgroup !== currentOptgroup ) {
272
279
$ ( "<li>" , {
273
280
"class" : "ui-selectmenu-optgroup ui-menu-divider" +
274
- ( item . element . parent ( "optgroup" ) . attr ( "disabled" ) ?
281
+ ( item . element . parent ( "optgroup" ) . prop ( "disabled" ) ?
275
282
" ui-state-disabled" :
276
283
"" ) ,
277
284
text : item . optgroup
278
285
} )
279
- . appendTo ( ul ) ;
286
+ . appendTo ( ul ) ;
287
+
280
288
currentOptgroup = item . optgroup ;
281
289
}
290
+
282
291
that . _renderItemData ( ul , item ) ;
283
292
} ) ;
284
293
} ,
@@ -307,8 +316,8 @@ return $.widget( "ui.selectmenu", {
307
316
} ,
308
317
309
318
_move : function ( direction , event ) {
310
- var filter = ".ui-menu- item" ,
311
- item , next ;
319
+ var item , next ,
320
+ filter = ".ui-menu-item" ;
312
321
313
322
if ( this . isOpen ) {
314
323
item = this . menuItems . eq ( this . focusIndex ) ;
@@ -324,7 +333,7 @@ return $.widget( "ui.selectmenu", {
324
333
}
325
334
326
335
if ( next . length ) {
327
- this . menu . menu ( " focus" , event , next ) ;
336
+ this . menuInstance . focus ( event , next ) ;
328
337
}
329
338
} ,
330
339
@@ -333,16 +342,16 @@ return $.widget( "ui.selectmenu", {
333
342
} ,
334
343
335
344
_toggle : function ( event ) {
336
- if ( this . isOpen ) {
337
- this . close ( event ) ;
338
- } else {
339
- this . open ( event ) ;
340
- }
345
+ this [ this . isOpen ? "close" : "open" ] ( event ) ;
341
346
} ,
342
347
343
348
_documentClick : {
344
349
mousedown : function ( event ) {
345
- if ( this . isOpen && ! $ ( event . target ) . closest ( ".ui-selectmenu-menu, #" + this . ids . button ) . length ) {
350
+ if ( ! this . isOpen ) {
351
+ return ;
352
+ }
353
+
354
+ if ( ! $ ( event . target ) . closest ( ".ui-selectmenu-menu, #" + this . ids . button ) . length ) {
346
355
this . close ( event ) ;
347
356
}
348
357
}
@@ -453,6 +462,7 @@ return $.widget( "ui.selectmenu", {
453
462
if ( key === "appendTo" ) {
454
463
this . menuWrap . appendTo ( this . _appendTo ( ) ) ;
455
464
}
465
+
456
466
if ( key === "disabled" ) {
457
467
this . menuInstance . option ( "disabled" , value ) ;
458
468
this . button
@@ -467,6 +477,7 @@ return $.widget( "ui.selectmenu", {
467
477
this . button . attr ( "tabindex" , 0 ) ;
468
478
}
469
479
}
480
+
470
481
if ( key === "width" ) {
471
482
if ( ! value ) {
472
483
value = this . element . outerWidth ( ) ;
@@ -498,15 +509,17 @@ return $.widget( "ui.selectmenu", {
498
509
_toggleAttr : function ( ) {
499
510
this . button
500
511
. toggleClass ( "ui-corner-top" , this . isOpen )
501
- . toggleClass ( "ui-corner-all" , ! this . isOpen ) ;
512
+ . toggleClass ( "ui-corner-all" , ! this . isOpen )
513
+ . attr ( "aria-expanded" , this . isOpen ) ;
502
514
this . menuWrap . toggleClass ( "ui-selectmenu-open" , this . isOpen ) ;
503
515
this . menu . attr ( "aria-hidden" , ! this . isOpen ) ;
504
- this . button . attr ( "aria-expanded" , this . isOpen ) ;
505
516
} ,
506
517
507
518
_resizeMenu : function ( ) {
508
519
this . menu . outerWidth ( Math . max (
509
520
this . button . outerWidth ( ) ,
521
+
522
+ // support: IE10
510
523
// IE10 wraps long text (possibly a rounding bug)
511
524
// so we add 1px to avoid the wrapping
512
525
this . menu . width ( "" ) . outerWidth ( ) + 1
@@ -517,9 +530,9 @@ return $.widget( "ui.selectmenu", {
517
530
return { disabled : this . element . prop ( "disabled" ) } ;
518
531
} ,
519
532
520
- _readOptions : function ( options ) {
533
+ _parseOptions : function ( options ) {
521
534
var data = [ ] ;
522
- options . each ( function ( index , item ) {
535
+ options . each ( function ( index , item ) {
523
536
var option = $ ( item ) ,
524
537
optgroup = option . parent ( "optgroup" ) ;
525
538
data . push ( {
@@ -528,7 +541,7 @@ return $.widget( "ui.selectmenu", {
528
541
value : option . attr ( "value" ) ,
529
542
label : option . text ( ) ,
530
543
optgroup : optgroup . attr ( "label" ) || "" ,
531
- disabled : optgroup . attr ( "disabled" ) || option . attr ( "disabled" )
544
+ disabled : optgroup . prop ( "disabled" ) || option . prop ( "disabled" )
532
545
} ) ;
533
546
} ) ;
534
547
this . items = data ;
0 commit comments