Skip to content

Commit 1849655

Browse files
committed
Selectmenu: Cleanup
Ref gh-1224
1 parent 0f272ee commit 1849655

File tree

1 file changed

+62
-49
lines changed

1 file changed

+62
-49
lines changed

ui/selectmenu.js

Lines changed: 62 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -92,24 +92,29 @@ return $.widget( "ui.selectmenu", {
9292
"aria-owns": this.ids.menu,
9393
"aria-haspopup": "true"
9494
})
95-
.insertAfter( this.element );
95+
.insertAfter( this.element );
9696

9797
$( "<span>", {
9898
"class": "ui-icon " + this.options.icons.button
99-
}).prependTo( this.button );
99+
})
100+
.prependTo( this.button );
100101

101102
this.buttonText = $( "<span>", {
102103
"class": "ui-selectmenu-text"
103104
})
104-
.appendTo( this.button );
105+
.appendTo( this.button );
105106

106107
this._setText( this.buttonText, this.element.find( "option:selected" ).text() );
107108
this._setOption( "width", this.options.width );
108109

109110
this._on( this.button, this._buttonEvents );
110111
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+
}
113118
});
114119
this._hoverable( this.button );
115120
this._focusable( this.button );
@@ -129,47 +134,49 @@ return $.widget( "ui.selectmenu", {
129134
this.menuWrap = $( "<div>", {
130135
"class": "ui-selectmenu-menu ui-front"
131136
})
132-
.append( this.menu )
133-
.appendTo( this._appendTo() );
137+
.append( this.menu )
138+
.appendTo( this._appendTo() );
134139

135140
// 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+
}
150157
}
151-
}
152-
that.focusIndex = item.index;
158+
that.focusIndex = item.index;
153159

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" );
159165

160166
// 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" );
162170

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
166172
this.menuInstance._off( this.menu, "mouseleave" );
167173

168174
// Cancel the menu's collapseAll on document click
169175
this.menuInstance._closeOnDocumentClick = function() {
170176
return false;
171177
};
172178

179+
// Selects often contain empty items, but never contain dividers
173180
this.menuInstance._isDivider = function() {
174181
return false;
175182
};
@@ -191,7 +198,7 @@ return $.widget( "ui.selectmenu", {
191198
return;
192199
}
193200

194-
this._readOptions( options );
201+
this._parseOptions( options );
195202
this._renderMenu( this.menu, this.items );
196203

197204
this.menuInstance.refresh();
@@ -271,14 +278,16 @@ return $.widget( "ui.selectmenu", {
271278
if ( item.optgroup !== currentOptgroup ) {
272279
$( "<li>", {
273280
"class": "ui-selectmenu-optgroup ui-menu-divider" +
274-
( item.element.parent( "optgroup" ).attr( "disabled" ) ?
281+
( item.element.parent( "optgroup" ).prop( "disabled" ) ?
275282
" ui-state-disabled" :
276283
"" ),
277284
text: item.optgroup
278285
})
279-
.appendTo( ul );
286+
.appendTo( ul );
287+
280288
currentOptgroup = item.optgroup;
281289
}
290+
282291
that._renderItemData( ul, item );
283292
});
284293
},
@@ -307,8 +316,8 @@ return $.widget( "ui.selectmenu", {
307316
},
308317

309318
_move: function( direction, event ) {
310-
var filter = ".ui-menu-item",
311-
item, next;
319+
var item, next,
320+
filter = ".ui-menu-item";
312321

313322
if ( this.isOpen ) {
314323
item = this.menuItems.eq( this.focusIndex );
@@ -324,7 +333,7 @@ return $.widget( "ui.selectmenu", {
324333
}
325334

326335
if ( next.length ) {
327-
this.menu.menu( "focus", event, next );
336+
this.menuInstance.focus( event, next );
328337
}
329338
},
330339

@@ -333,16 +342,16 @@ return $.widget( "ui.selectmenu", {
333342
},
334343

335344
_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 );
341346
},
342347

343348
_documentClick: {
344349
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 ) {
346355
this.close( event );
347356
}
348357
}
@@ -453,6 +462,7 @@ return $.widget( "ui.selectmenu", {
453462
if ( key === "appendTo" ) {
454463
this.menuWrap.appendTo( this._appendTo() );
455464
}
465+
456466
if ( key === "disabled" ) {
457467
this.menuInstance.option( "disabled", value );
458468
this.button
@@ -467,6 +477,7 @@ return $.widget( "ui.selectmenu", {
467477
this.button.attr( "tabindex", 0 );
468478
}
469479
}
480+
470481
if ( key === "width" ) {
471482
if ( !value ) {
472483
value = this.element.outerWidth();
@@ -498,15 +509,17 @@ return $.widget( "ui.selectmenu", {
498509
_toggleAttr: function() {
499510
this.button
500511
.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 );
502514
this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
503515
this.menu.attr( "aria-hidden", !this.isOpen );
504-
this.button.attr( "aria-expanded", this.isOpen );
505516
},
506517

507518
_resizeMenu: function() {
508519
this.menu.outerWidth( Math.max(
509520
this.button.outerWidth(),
521+
522+
// support: IE10
510523
// IE10 wraps long text (possibly a rounding bug)
511524
// so we add 1px to avoid the wrapping
512525
this.menu.width( "" ).outerWidth() + 1
@@ -517,9 +530,9 @@ return $.widget( "ui.selectmenu", {
517530
return { disabled: this.element.prop( "disabled" ) };
518531
},
519532

520-
_readOptions: function( options ) {
533+
_parseOptions: function( options ) {
521534
var data = [];
522-
options.each( function( index, item ) {
535+
options.each(function( index, item ) {
523536
var option = $( item ),
524537
optgroup = option.parent( "optgroup" );
525538
data.push({
@@ -528,7 +541,7 @@ return $.widget( "ui.selectmenu", {
528541
value: option.attr( "value" ),
529542
label: option.text(),
530543
optgroup: optgroup.attr( "label" ) || "",
531-
disabled: optgroup.attr( "disabled" ) || option.attr( "disabled" )
544+
disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
532545
});
533546
});
534547
this.items = data;

0 commit comments

Comments
 (0)