diff --git a/Gruntfile.js b/Gruntfile.js
index 63ff1cf396..24b9632f0b 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -35,6 +35,7 @@ var
"progressbar",
"resizable",
"selectable",
+ "selectmenu",
"slider",
"spinner",
"tabs",
diff --git a/build/tasks/testswarm.js b/build/tasks/testswarm.js
index 2bce06f265..86a06a69df 100644
--- a/build/tasks/testswarm.js
+++ b/build/tasks/testswarm.js
@@ -26,6 +26,7 @@ var versions = {
"Progressbar": "progressbar/progressbar.html",
"Resizable": "resizable/resizable.html",
"Selectable": "selectable/selectable.html",
+ "Selectmenu": "selectmenu/selectmenu.html",
"Slider": "slider/slider.html",
"Sortable": "sortable/sortable.html",
"Spinner": "spinner/spinner.html",
diff --git a/demos/index.html b/demos/index.html
index 4739d76cd5..338da841aa 100644
--- a/demos/index.html
+++ b/demos/index.html
@@ -24,6 +24,7 @@
removeClass
resizable
selectable
+ selectmenu
show
slider
sortable
diff --git a/demos/selectmenu/custom_render.html b/demos/selectmenu/custom_render.html
new file mode 100644
index 0000000000..fb8127bbd7
--- /dev/null
+++ b/demos/selectmenu/custom_render.html
@@ -0,0 +1,143 @@
+
+
+
+
+
+ jQuery UI Selectmenu - Default functionality
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The whole rendering process is extendable to make custom styling as easy as possible.
+
+
+
diff --git a/demos/selectmenu/default.html b/demos/selectmenu/default.html
new file mode 100644
index 0000000000..69bde2a55f
--- /dev/null
+++ b/demos/selectmenu/default.html
@@ -0,0 +1,104 @@
+
+
+
+
+
+ jQuery UI Selectmenu - Default functionality
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The Selectmenu widgets provides a styleable select element replacement. It will act as a proxy back to the original select element, controlling its state for form submission or serialization
+
The datasource is a native select element. Supports optgroups.
+
+
+
diff --git a/demos/selectmenu/images/24-podcast-square.png b/demos/selectmenu/images/24-podcast-square.png
new file mode 100644
index 0000000000..3c3e38f3fc
Binary files /dev/null and b/demos/selectmenu/images/24-podcast-square.png differ
diff --git a/demos/selectmenu/images/24-rss-square.png b/demos/selectmenu/images/24-rss-square.png
new file mode 100644
index 0000000000..f59b69ed38
Binary files /dev/null and b/demos/selectmenu/images/24-rss-square.png differ
diff --git a/demos/selectmenu/images/24-video-square.png b/demos/selectmenu/images/24-video-square.png
new file mode 100644
index 0000000000..ce50ccfde3
Binary files /dev/null and b/demos/selectmenu/images/24-video-square.png differ
diff --git a/demos/selectmenu/index.html b/demos/selectmenu/index.html
new file mode 100644
index 0000000000..3b035f5fb0
--- /dev/null
+++ b/demos/selectmenu/index.html
@@ -0,0 +1,16 @@
+
+
+
+
+
+ jQuery UI Selectmenu Demos
+
+
+
+
+
+
+
diff --git a/tests/unit/selectmenu/all.html b/tests/unit/selectmenu/all.html
new file mode 100644
index 0000000000..c3089ae66c
--- /dev/null
+++ b/tests/unit/selectmenu/all.html
@@ -0,0 +1,30 @@
+
+
+
+
+ jQuery UI Selectmenu Test Suite
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/unit/selectmenu/selectmenu.html b/tests/unit/selectmenu/selectmenu.html
new file mode 100644
index 0000000000..584a47b53c
--- /dev/null
+++ b/tests/unit/selectmenu/selectmenu.html
@@ -0,0 +1,91 @@
+
+
+
+
+ jQuery UI Selectmenu Test Suite
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Select a number:
+
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+
+
+ Select a file:
+
+
+ jQuery.js
+ ui.jQuery.js
+
+
+ Some unknown file
+ Some other file
+
+
+
+
+
+
diff --git a/tests/unit/selectmenu/selectmenu_common.js b/tests/unit/selectmenu/selectmenu_common.js
new file mode 100644
index 0000000000..93b526bd82
--- /dev/null
+++ b/tests/unit/selectmenu/selectmenu_common.js
@@ -0,0 +1,23 @@
+TestHelpers.commonWidgetTests( "selectmenu", {
+ defaults: {
+ appendTo: null,
+ disabled: false,
+ icons: {
+ button: "ui-icon-triangle-1-s"
+ },
+ position: {
+ my: "left top",
+ at: "left bottom",
+ collision: "none"
+ },
+ width: null,
+
+ // callbacks
+ create: null,
+ change: null,
+ close: null,
+ focus: null,
+ open: null,
+ select: null
+ }
+});
diff --git a/tests/unit/selectmenu/selectmenu_core.js b/tests/unit/selectmenu/selectmenu_core.js
new file mode 100644
index 0000000000..60c350eb30
--- /dev/null
+++ b/tests/unit/selectmenu/selectmenu_core.js
@@ -0,0 +1,235 @@
+(function( $ ) {
+
+module( "selectmenu: core" );
+
+asyncTest( "accessibility", function() {
+ var links,
+ element = $( "#speed" ).selectmenu(),
+ button = element.selectmenu( "widget" ),
+ menu = element.selectmenu( "menuWidget" );
+
+ button.simulate( "focus" );
+ links = menu.find( "li.ui-menu-item" );
+
+ expect( 12 + links.length * 2 );
+
+ setTimeout(function() {
+ equal( button.attr( "role" ), "combobox", "button link role" );
+ equal( button.attr( "aria-haspopup" ), "true", "button link aria-haspopup" );
+ equal( button.attr( "aria-expanded" ), "false", "button link aria-expanded" );
+ equal( button.attr( "aria-autocomplete" ), "list", "button link aria-autocomplete" );
+ equal( button.attr( "aria-owns" ), menu.attr("id"), "button link aria-owns" );
+ equal(
+ button.attr( "aria-labelledby" ),
+ links.eq( element[ 0 ].selectedIndex ).attr( "id" ),
+ "button link aria-labelledby"
+ );
+ equal( button.attr( "tabindex" ), 0, "button link tabindex" );
+
+ equal( menu.attr( "role" ), "listbox", "menu role" );
+ equal( menu.attr( "aria-labelledby" ), button.attr( "id" ), "menu aria-labelledby" );
+ equal( menu.attr( "aria-hidden" ), "true", "menu aria-hidden" );
+ equal( menu.attr( "tabindex" ), 0, "menu tabindex" );
+ equal(
+ menu.attr( "aria-activedescendant" ),
+ links.eq( element[ 0 ].selectedIndex ).attr( "id" ),
+ "menu aria-activedescendant"
+ );
+ $.each( links, function( index ){
+ equal( $( this ).attr( "role" ), "option", "menu link #" + index +" role" );
+ equal( $( this ).attr( "tabindex" ), -1, "menu link #" + index +" tabindex" );
+ });
+ start();
+ });
+});
+
+
+$.each([
+ {
+ type: "default",
+ selector: "#speed"
+ },
+ {
+ type: "optgroups",
+ selector: "#files"
+ }
+], function( i, settings ) {
+ asyncTest( "state synchronization - after keydown on button - " + settings.type, function () {
+ expect( 4 );
+
+ var links,
+ element = $( settings.selector ).selectmenu(),
+ button = element.selectmenu( "widget" ),
+ menu = element.selectmenu( "menuWidget" ),
+ selected = element.find( "option:selected" );
+
+ button.simulate( "focus" );
+ setTimeout(function() {
+ links = menu.find("li.ui-menu-item");
+
+ button.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+ equal(
+ menu.attr( "aria-activedescendant" ),
+ links.eq( element[ 0 ].selectedIndex ).attr( "id" ),
+ "menu aria-activedescendant"
+ );
+ equal(
+ button.attr( "aria-activedescendant" ),
+ links.eq( element[ 0 ].selectedIndex ).attr( "id" ),
+ "button aria-activedescendant"
+ );
+ equal(
+ element.find( "option:selected" ).val(),
+ selected.next( "option" ).val() ,
+ "original select state"
+ );
+ equal( button.text(), selected.next( "option" ).text(), "button text" );
+ start();
+ }, 1 );
+ });
+
+ asyncTest( "state synchronization - after click on item - " + settings.type, function () {
+ expect( 4 );
+
+ var links,
+ element = $( settings.selector ).selectmenu(),
+ button = element.selectmenu( "widget" ),
+ menu = element.selectmenu( "menuWidget" );
+
+ button.simulate( "focus" );
+ setTimeout(function() {
+ links = menu.find("li.ui-menu-item");
+
+ button.trigger( "click" );
+ menu.find( "li" ).last().simulate( "mouseover" ).trigger( "click" );
+ equal(
+ menu.attr( "aria-activedescendant" ),
+ links.eq( element[ 0 ].selectedIndex ).attr( "id" ),
+ "menu aria-activedescendant"
+ );
+ equal(
+ button.attr( "aria-activedescendant" ),
+ links.eq( element[ 0 ].selectedIndex ).attr( "id" ),
+ "button aria-activedescendant"
+ );
+ equal(
+ element.find( "option:selected" ).val(),
+ element.find( "option" ).last().val(),
+ "original select state"
+ );
+ equal( button.text(), element.find( "option" ).last().text(), "button text" );
+ start();
+ }, 1 );
+ });
+
+ asyncTest( "state synchronization - after focus item and keydown on button - " + settings.type, function () {
+ expect( 4 );
+
+ var links,
+ element = $( settings.selector ).selectmenu(),
+ button = element.selectmenu( "widget" ),
+ menu = element.selectmenu( "menuWidget" ),
+ options = element.find( "option" );
+
+ // init menu
+ button.simulate( "focus" );
+
+ setTimeout(function() {
+ links = menu.find( "li.ui-menu-item" );
+ // open menu and click first item
+ button.trigger( "click" );
+ links.first().simulate( "mouseover" ).trigger( "click" );
+ // open menu again and hover item
+ button.trigger( "click" );
+ links.eq( 3 ).simulate( "mouseover" );
+ // close and use keyboard control on button
+ button.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
+ button.simulate( "focus" );
+ setTimeout(function() {
+ button.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+
+ equal( menu.attr( "aria-activedescendant" ), links.eq( 1 ).attr( "id" ), "menu aria-activedescendant" );
+ equal( button.attr( "aria-activedescendant" ), links.eq( 1 ).attr( "id" ), "button aria-activedescendant" );
+ equal( element.find( "option:selected" ).val(), options.eq( 1 ).val() , "original select state" );
+ equal( button.text(), options.eq( 1 ).text(), "button text" );
+ start();
+ }, 1 );
+ }, 1 );
+ });
+
+ asyncTest( "item looping - " + settings.type, function () {
+ expect( 2 );
+
+ var links,
+ element = $( settings.selector ).selectmenu(),
+ button = element.selectmenu( "widget" ),
+ menu = element.selectmenu( "menuWidget" );
+
+ // init menu
+ button.simulate( "focus" );
+
+ setTimeout(function() {
+ links = menu.find( "li.ui-menu-item" );
+
+ button.trigger( "click" );
+ links.first().simulate( "mouseover" ).trigger( "click" );
+ button.simulate( "keydown", { keyCode: $.ui.keyCode.UP } );
+ equal( element[ 0 ].selectedIndex, 0, "No looping beyond first item" );
+
+ button.trigger( "click" );
+ links.last().simulate( "mouseover" ).trigger( "click" );
+ button.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+ equal( element[ 0 ].selectedIndex + 1, links.length, "No looping behind last item" );
+ start();
+ }, 1 );
+ });
+
+ asyncTest( "item focus and active state - " + settings.type, function () {
+ expect( 8 );
+
+ var element = $( settings.selector ).selectmenu(),
+ button = element.selectmenu( "widget" ),
+ menu = element.selectmenu( "menuWidget" ),
+ links, focusedItem, activeItem;
+
+ // init menu
+ button.simulate( "focus" );
+
+ setTimeout(function() {
+ links = menu.find( "li.ui-menu-item" );
+
+ button.trigger( "click" );
+ setTimeout(function() {
+ checkItemClasses();
+
+ links.eq( 3 ).simulate( "mouseover" ).trigger( "click" );
+
+ button.trigger( "click" );
+ links.eq( 2 ).simulate( "mouseover" );
+ $( document ).trigger( "click" );
+
+ button.trigger( "click" );
+ links.eq( 1 ).simulate( "mouseover" );
+ $( document ).trigger( "click" );
+
+ button.trigger( "click" );
+ setTimeout(function() {
+ checkItemClasses();
+ start();
+ }, 350 );
+ }, 350 );
+ }, 1 );
+
+ function checkItemClasses() {
+ focusedItem = menu.find( "li.ui-state-focus" );
+ equal( focusedItem.length, 1, "only one item has ui-state-focus class" );
+ equal( focusedItem.attr( "id" ), links.eq( element[ 0 ].selectedIndex ).attr( "id" ), "selected item has ui-state-focus class" );
+
+ activeItem = menu.find( "li.ui-state-active" );
+ equal( activeItem.length, 1, "only one item has ui-state-active class" );
+ equal( activeItem.attr( "id" ), links.eq( element[ 0 ].selectedIndex ).attr( "id" ), "selected item has ui-state-active class" );
+ }
+ });
+});
+
+})( jQuery );
diff --git a/tests/unit/selectmenu/selectmenu_events.js b/tests/unit/selectmenu/selectmenu_events.js
new file mode 100644
index 0000000000..2c10b4c87d
--- /dev/null
+++ b/tests/unit/selectmenu/selectmenu_events.js
@@ -0,0 +1,135 @@
+(function ( $ ) {
+
+module( "selectmenu: events", {
+ setup: function () {
+ this.element = $( "#speed" );
+ }
+});
+
+asyncTest( "change", function () {
+ expect( 5 );
+
+ var optionIndex = 1,
+ button, menu, options;
+
+ this.element.selectmenu({
+ change: function ( event, ui ) {
+ ok( event, "change event fired on change" );
+ equal( event.type, "selectmenuchange", "event type set to selectmenuchange" );
+ equal( ui.item.index, optionIndex, "ui.item.index contains correct option index" );
+ equal( ui.item.element[ 0 ], options.eq( optionIndex )[ 0 ], "ui.item.element contains original option element" );
+ equal( ui.item.value, options.eq( optionIndex ).text(), "ui.item.value property updated correctly" );
+ }
+ });
+
+ button = this.element.selectmenu( "widget" );
+ menu = this.element.selectmenu( "menuWidget" ).parent();
+ options = this.element.find( "option" );
+
+ button.simulate( "focus" );
+
+ setTimeout(function() {
+ button.trigger( "click" );
+ menu.find( "li" ).eq( optionIndex ).simulate( "mouseover" ).trigger( "click" );
+ start();
+ }, 1 );
+});
+
+
+test( "close", function () {
+ expect( 4 );
+
+ this.element.selectmenu({
+ close: function ( event ) {
+ ok( event, "close event fired on close" );
+ equal( event.type, "selectmenuclose", "event type set to selectmenuclose" );
+ }
+ });
+
+ this.element.selectmenu( "open" ).selectmenu( "close" );
+
+ this.element.selectmenu( "open" );
+ $( "body" ).trigger( "mousedown" );
+});
+
+
+asyncTest( "focus", function () {
+ expect( 12 );
+
+ var that = this,
+ optionIndex = this.element[ 0 ].selectedIndex + 1,
+ options = this.element.find( "option" ),
+ button, menu, links;
+
+ this.element.selectmenu({
+ focus: function ( event, ui ) {
+ ok( event, "focus event fired on element #" + optionIndex + " mouseover" );
+ equal( event.type, "selectmenufocus", "event type set to selectmenufocus" );
+ equal( ui.item.index, optionIndex, "ui.item.index contains correct option index" );
+ equal( ui.item.element[ 0 ], options.eq( optionIndex )[ 0 ], "ui.item.element contains original option element" );
+ }
+ });
+
+ button = this.element.selectmenu( "widget" );
+ menu = this.element.selectmenu( "menuWidget" );
+
+ button.simulate( "focus" );
+
+ setTimeout(function() {
+ button.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
+
+ button.trigger( "click" );
+ links = menu.find( "li.ui-menu-item" );
+ optionIndex = 0;
+ links.eq( optionIndex ).simulate( "mouseover" );
+ optionIndex += 1;
+ links.eq( optionIndex ).simulate( "mouseover" );
+
+ // this tests for unwanted, additional focus event on close
+ that.element.selectmenu( "close" );
+ start();
+ }, 1 );
+});
+
+
+test( "open", function () {
+ expect( 2 );
+
+ this.element.selectmenu({
+ open: function ( event ) {
+ ok( event, "open event fired on open" );
+ equal( event.type, "selectmenuopen", "event type set to selectmenuopen" );
+ }
+ });
+
+ this.element.selectmenu( "open" );
+});
+
+
+asyncTest( "select", function () {
+ expect( 4 );
+
+ this.element.selectmenu({
+ select: function ( event, ui ) {
+ ok( event, "select event fired on item select" );
+ equal( event.type, "selectmenuselect", "event type set to selectmenuselect" );
+ equal( ui.item.index, optionIndex, "ui.item.index contains correct option index" );
+ equal( ui.item.element[ 0 ], options.eq( optionIndex )[ 0 ], "ui.item.element contains original option element" );
+ }
+ });
+
+ var button = this.element.selectmenu( "widget" ),
+ menu = this.element.selectmenu( "menuWidget" ).parent(),
+ options = this.element.find( "option" ),
+ optionIndex = 1;
+
+ button.simulate( "focus" );
+
+ setTimeout(function() {
+ button.trigger( "click" );
+ menu.find( "li" ).eq( optionIndex ).simulate( "mouseover" ).trigger( "click" );
+ start();
+ }, 1 );
+});
+
+})(jQuery);
diff --git a/tests/unit/selectmenu/selectmenu_methods.js b/tests/unit/selectmenu/selectmenu_methods.js
new file mode 100644
index 0000000000..f2b56e8350
--- /dev/null
+++ b/tests/unit/selectmenu/selectmenu_methods.js
@@ -0,0 +1,169 @@
+(function( $ ) {
+
+module( "selectmenu: methods" );
+
+test( "destroy", function() {
+ expect( 1 );
+ domEqual( "#speed", function() {
+ $( "#speed" ).selectmenu().selectmenu( "destroy" );
+ });
+});
+
+
+test( "open / close", function() {
+ expect( 4 );
+
+ var element = $( "#speed" ).selectmenu(),
+ menu = element.selectmenu( "menuWidget" );
+
+ element.selectmenu( "open" );
+ ok( menu.is( ":visible" ), "open: menu visible" );
+ equal( menu.attr( "aria-hidden" ), "false", "open: menu aria-disabled" );
+
+ element.selectmenu( "close" );
+ ok( menu.is( ":hidden" ), "close: menu hidden" );
+ equal( menu.attr( "aria-hidden" ), "true", "close: menu aria-disabled" );
+});
+
+
+test( "enable / disable", function () {
+ expect(10);
+
+ var element = $( "#speed" ).selectmenu(),
+ button = element.selectmenu( "widget" ),
+ menu = element.selectmenu( "menuWidget" );
+
+ element.selectmenu( "disable" );
+ ok( element.selectmenu( "option", "disabled" ), "disable: widget option" );
+ equal( element.attr( "disabled" ), "disabled", "disable: native select disabled" );
+ equal( button.attr( "aria-disabled" ), "true", "disable: button wrapper ARIA" );
+ equal( button.attr( "tabindex" ), -1, "disable: button tabindex" );
+ equal( menu.attr( "aria-disabled" ), "true", "disable: menu wrapper ARIA" );
+
+ element.selectmenu( "enable" );
+ ok( !element.selectmenu( "option", "disabled" ), "enable: widget option" );
+ equal( element.attr( "disabled" ), undefined, "enable: native select disabled" );
+ equal( button.attr( "aria-disabled" ), "false", "enable: button wrapper ARIA" );
+ equal( button.attr( "tabindex" ), 0, "enable: button tabindex" );
+ equal( menu.attr( "aria-disabled" ), "false", "enable: menu wrapper ARIA" );
+});
+
+
+test( "refresh - structure", function () {
+ expect( 3 );
+
+ var element = $( "#speed" ).selectmenu(),
+ menu = element.selectmenu( "menuWidget" ).parent();
+
+ element.find( "option" ).eq( 2 ).remove();
+ element.find( "option" ).eq( 3 ).remove();
+ element.append( "Added option " );
+ element.find( "option" ).first()
+ .attr( "value", "changed_value" )
+ .text( "Changed value" );
+ element.selectmenu( "refresh" );
+
+ equal( element.find( "option" ).length, menu.find( "li" ).not( ".ui-selectmenu-optgroup" ).length, "menu item length" );
+ equal( element.find( "option" ).last().text(), menu.find( "li" ).not( ".ui-selectmenu-optgroup" ).last().text(), "added item" );
+ equal( element.find( "option" ).first().text(), menu.find( "li" ).not( ".ui-selectmenu-optgroup" ).first().text(), "changed item" );
+});
+
+asyncTest( "refresh - change selected option", function () {
+ expect( 4 );
+
+ var element = $( "#speed" ).selectmenu(),
+ button = element.selectmenu( "widget" );
+
+ equal( element.find( "option:selected" ).text(), button.text(), "button text after init" );
+
+ button.simulate( "focus" );
+
+ setTimeout(function() {
+ equal( element.find( "option:selected" ).text(), button.text(), "button text after focus" );
+
+ element[ 0 ].selectedIndex = 0;
+ element.selectmenu( "refresh" );
+ equal( element.find( "option:selected" ).text(), button.text(), "button text after changing selected option" );
+
+ element.find( "option" ).removeAttr( "selected" );
+ element.prepend( "Selected option " );
+ element.selectmenu( "refresh" );
+ equal( element.find( "option:selected" ).text(), button.text(), "button text after adding selected option" );
+
+ start();
+ }, 1 );
+});
+
+
+test( "refresh - disabled select", function () {
+ expect( 4 );
+
+ var element = $( "#speed" ).selectmenu(),
+ button = element.selectmenu( "widget" ),
+ menu = element.selectmenu( "menuWidget" );
+
+ element.attr( "disabled", "disabled" );
+ element.selectmenu( "refresh" );
+
+ ok( element.selectmenu( "option", "disabled" ), "widget option" );
+ equal( button.attr( "aria-disabled" ), "true", "button wrapper ARIA" );
+ equal( button.attr( "tabindex" ), -1, "button tabindex" );
+ equal( menu.attr( "aria-disabled" ), "true", "menu wrapper ARIA" );
+});
+
+
+test( "refresh - disabled option", function () {
+ expect(1);
+
+ var disabledItem,
+ element = $( "#speed" ).selectmenu(),
+ menu = element.selectmenu( "menuWidget" ).parent();
+
+ element.attr( "disabled", "disabled" );
+ element.find( "option" ).eq( 2 ).attr( "disabled", "disabled" );
+ element.selectmenu( "refresh" );
+
+ disabledItem = menu.find( "li" ).not( ".ui-selectmenu-optgroup" ).eq(2);
+ ok( disabledItem.hasClass( "ui-state-disabled" ), "class" );
+});
+
+
+test( "refresh - disabled optgroup", function () {
+
+ var i, item,
+ element = $( "#files" ).selectmenu(),
+ menu = element.selectmenu( "menuWidget" ).parent(),
+ originalDisabledOptgroup = element.find( "optgroup" ).first(),
+ originalDisabledOptions = originalDisabledOptgroup.find( "option" );
+
+ expect( 2 + originalDisabledOptions.length );
+
+ originalDisabledOptgroup.attr( "disabled", "disabled" );
+ element.selectmenu( "refresh" );
+
+ item = menu.find( "li.ui-selectmenu-optgroup" ).first();
+ ok( item.hasClass( "ui-state-disabled" ), "class" );
+
+ equal( menu.find( "li" ).not( ".ui-selectmenu-optgroup" ).filter( ".ui-state-disabled" ).length, originalDisabledOptions.length, "disabled options" );
+ for ( i = 0; i < originalDisabledOptions.length; i++ ) {
+ item = item.next( "li" );
+ ok( item.hasClass( "ui-state-disabled" ), "item #" + i + ": class" );
+ }
+});
+
+test( "widget and menuWidget", function() {
+ expect( 4 );
+ var element = $( "#speed" ).selectmenu(),
+ button = element.selectmenu( "widget" ),
+ menu = element.selectmenu( "menuWidget" );
+
+ element.selectmenu( "refresh" );
+
+ equal( button.length, 1, "button: one element" );
+ ok( button.is( ".ui-selectmenu-button" ), "button: class" );
+
+ equal( menu.length, 1, "Menu Widget: one element" );
+ ok( menu.is( "ul.ui-menu" ), "Menu Widget: element and class" );
+});
+
+})( jQuery );
diff --git a/tests/unit/selectmenu/selectmenu_options.js b/tests/unit/selectmenu/selectmenu_options.js
new file mode 100644
index 0000000000..82ea6a8b4e
--- /dev/null
+++ b/tests/unit/selectmenu/selectmenu_options.js
@@ -0,0 +1,60 @@
+(function ( $ ) {
+
+module( "selectmenu: options" );
+
+test( "appendTo another element", function () {
+ expect( 8 );
+
+ var detached = $( "" ),
+ element = $( "#speed" ).selectmenu();
+ equal( element.selectmenu( "menuWidget" ).parent().parent()[ 0 ], document.body, "defaults to body" );
+ element.selectmenu( "destroy" );
+
+ element.selectmenu({
+ appendTo: ".selectmenu-wrap"
+ });
+ equal( element.selectmenu( "menuWidget" ).parent().parent()[ 0 ], $( "#selectmenu-wrap1" )[ 0 ], "first found element" );
+ equal( $( "#selectmenu-wrap2 .ui-selectmenu" ).length, 0, "only appends to one element" );
+ element.selectmenu( "destroy" );
+
+ $( "#selectmenu-wrap2" ).addClass( "ui-front" );
+ element.selectmenu();
+ equal( element.selectmenu( "menuWidget" ).parent().parent()[ 0 ], $( "#selectmenu-wrap2" )[ 0 ], "null, inside .ui-front" );
+ element.selectmenu( "destroy" );
+ $( "#selectmenu-wrap2" ).removeClass( "ui-front" );
+
+ element.selectmenu().selectmenu( "option", "appendTo", "#selectmenu-wrap1" );
+ equal( element.selectmenu( "menuWidget" ).parent().parent()[ 0 ], $( "#selectmenu-wrap1" )[ 0 ], "modified after init" );
+ element.selectmenu( "destroy" );
+
+ element.selectmenu({
+ appendTo: detached
+ });
+ equal( element.selectmenu( "menuWidget" ).parent().parent()[ 0 ], detached[ 0 ], "detached jQuery object" );
+ element.selectmenu( "destroy" );
+
+ element.selectmenu({
+ appendTo: detached[ 0 ]
+ });
+ equal( element.selectmenu( "menuWidget" ).parent().parent()[ 0 ], detached[ 0 ], "detached DOM element" );
+ element.selectmenu( "destroy" );
+
+ element.selectmenu().selectmenu( "option", "appendTo", detached );
+ equal( element.selectmenu( "menuWidget" ).parent().parent()[ 0 ], detached[ 0 ], "detached DOM element via option()" );
+ element.selectmenu( "destroy" );
+});
+
+
+test( "CSS styles", function () {
+ expect( 2 );
+
+ var element = $( "#speed" ).selectmenu(),
+ button = element.selectmenu( "widget" ),
+ menu = element.selectmenu( "menuWidget" );
+
+ element.selectmenu( "open" );
+ ok( button.hasClass( "ui-corner-top" ) && !button.hasClass( "ui-corner-all" ) && button.find( "span.ui-icon" ).hasClass( "ui-icon-triangle-1-s" ), "button styles dropdown" );
+ ok( menu.hasClass( "ui-corner-bottom" ) && !menu.hasClass( "ui-corner-all" ), "menu styles dropdown" );
+});
+
+})( jQuery );
diff --git a/tests/visual/compound/dialog_widgets.html b/tests/visual/compound/dialog_widgets.html
index f5b0be95e1..25bbd123f9 100644
--- a/tests/visual/compound/dialog_widgets.html
+++ b/tests/visual/compound/dialog_widgets.html
@@ -22,8 +22,10 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Slower
+ Slow
+ Medium
+ Fast
+ Faster
+
+
+
+
+ Slower
+ Slow
+ Medium
+ Fast
+ Faster
+
+
+
+
+
+