From 85ff5205605ad591af9e9848a78334ee44b2284e Mon Sep 17 00:00:00 2001 From: Alexander Schmitz Date: Mon, 24 Aug 2015 08:59:13 -0400 Subject: [PATCH] Menu: Style updates Ref #14246 --- tests/unit/menu/common.js | 2 +- tests/unit/menu/core.js | 16 ++-- tests/unit/menu/events.js | 162 +++++++++++++++++++------------------ tests/unit/menu/methods.js | 24 +++--- tests/unit/menu/options.js | 66 +++++++-------- ui/widgets/menu.js | 3 + 6 files changed, 139 insertions(+), 134 deletions(-) diff --git a/tests/unit/menu/common.js b/tests/unit/menu/common.js index adb74cf0a..96815c6b2 100644 --- a/tests/unit/menu/common.js +++ b/tests/unit/menu/common.js @@ -24,6 +24,6 @@ common.testWidget( "menu", { focus: null, select: null } -}); +} ); } ); diff --git a/tests/unit/menu/core.js b/tests/unit/menu/core.js index 68f613ee1..a8e0ece00 100644 --- a/tests/unit/menu/core.js +++ b/tests/unit/menu/core.js @@ -23,9 +23,9 @@ test( "markup structure", function( assert ) { equal( items.eq( 1 ).children().length, 1, "Item has exactly 1 child when it does not have a sub menu" ); assert.hasClasses( items[ 2 ], "ui-menu-item" ); equal( items.eq( 2 ).children().length, 1, "Item has exactly 1 child when it does not have a sub menu" ); -}); +} ); -test( "accessibility", function () { +test( "accessibility", function() { expect( 4 ); var element = $( "#menu1" ).menu(); @@ -39,7 +39,7 @@ test( "accessibility", function () { ok( /^ui-id-\d+$/.test( element.attr( "aria-activedescendant" ) ), "aria-activedescendant from generated id" ); // Item roles are tested in the role option tests -}); +} ); asyncTest( "#9044: Autofocus issue with dialog opened from menu widget", function() { expect( 1 ); @@ -49,15 +49,15 @@ asyncTest( "#9044: Autofocus issue with dialog opened from menu widget", functio $( "#testID1" ).on( "click", function() { $( "#test9044" ).trigger( "focus" ); - }); + } ); testHelper.click( element, "3" ); setTimeout( function() { equal( document.activeElement.id, "test9044", "Focus was swallowed by menu" ); $( "#test9044" ).remove(); start(); - }); -}); + } ); +} ); asyncTest( "#9532: Need a way in Menu to keep ui-state-active class on selected item for Selectmenu", function( assert ) { expect( 1 ); @@ -70,7 +70,7 @@ asyncTest( "#9532: Need a way in Menu to keep ui-state-active class on selected setTimeout( function() { assert.hasClasses( wrapper, "ui-state-active" ); start(); - }); -}); + } ); +} ); } ); diff --git a/tests/unit/menu/events.js b/tests/unit/menu/events.js index 790e5912c..1500c3478 100644 --- a/tests/unit/menu/events.js +++ b/tests/unit/menu/events.js @@ -12,15 +12,15 @@ module( "menu: events", { setup: function() { testHelper.clearLog(); } -}); +} ); test( "handle click on menu", function() { expect( 1 ); - var element = $( "#menu1" ).menu({ + var element = $( "#menu1" ).menu( { select: function() { log(); } - }); + } ); log( "click", true ); click( element, "1" ); log( "afterclick" ); @@ -28,16 +28,16 @@ test( "handle click on menu", function() { click( element, "3" ); click( element, "1" ); equal( logOutput(), "click,1,afterclick,2,3,1", "Click order not valid." ); -}); +} ); test( "handle click on custom item menu", function() { expect( 1 ); - var element = $( "#menu5" ).menu({ + var element = $( "#menu5" ).menu( { select: function() { log(); }, menus: ".menu" - }); + } ); log( "click", true ); click( element, "1" ); log( "afterclick" ); @@ -45,75 +45,77 @@ test( "handle click on custom item menu", function() { click( element, "3" ); click( element, "1" ); equal( logOutput(), "click,1,afterclick,2,3,1", "Click order not valid." ); -}); +} ); asyncTest( "handle blur", function() { expect( 1 ); var blurHandled = false, - element = $( "#menu1" ).menu({ + element = $( "#menu1" ).menu( { blur: function( event ) { + // Ignore duplicate blur event fired by IE if ( !blurHandled ) { blurHandled = true; equal( event.type, "menublur", "blur event.type is 'menublur'" ); } } - }); + } ); click( element, "1" ); - setTimeout(function() { + setTimeout( function() { element.trigger( "blur" ); - setTimeout(function() { + setTimeout( function() { start(); }, 350 ); - }); -}); + } ); +} ); asyncTest( "handle blur via click outside", function() { expect( 1 ); var blurHandled = false, - element = $( "#menu1" ).menu({ + element = $( "#menu1" ).menu( { blur: function( event ) { + // Ignore duplicate blur event fired by IE if ( !blurHandled ) { blurHandled = true; equal( event.type, "menublur", "blur event.type is 'menublur'" ); } } - }); + } ); click( element, "1" ); - setTimeout(function() { - $( "", { id: "remove"} ).appendTo( "body" ).trigger( "click" ); - setTimeout(function() { + setTimeout( function() { + $( "", { id: "remove" } ).appendTo( "body" ).trigger( "click" ); + setTimeout( function() { start(); }, 350 ); - }); -}); + } ); +} ); asyncTest( "handle focus of menu with active item", function() { expect( 1 ); - var element = $( "#menu1" ).menu({ + var element = $( "#menu1" ).menu( { focus: function( event ) { log( $( event.target ).find( ".ui-menu-item-wrapper.ui-state-active" ).parent().index() ); } - }); + } ); log( "focus", true ); element[ 0 ].focus(); - setTimeout(function() { + setTimeout( function() { element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); element[ 0 ].blur(); - setTimeout(function() { + setTimeout( function() { element[ 0 ].focus(); - setTimeout(function() { + setTimeout( function() { equal( logOutput(), "focus,0,1,2,2", "current active item remains active" ); start(); - }); - }); - }); -}); + } ); + } ); + } ); +} ); test( "handle mouseenter on nested menu item", function( assert ) { assert.expect( 8 ); @@ -186,12 +188,12 @@ asyncTest( "handle submenu auto collapse: mouseleave, default markup", function( element.find( "li:nth-child(7)" ).trigger( "mouseenter" ); setTimeout( menumouseleave1, 25 ); -}); +} ); asyncTest( "handle submenu auto collapse: mouseleave, custom markup", function() { expect( 4 ); $.ui.menu.prototype.delay = 1; - var element = $( "#menu5" ).menu({ menus: ".menu" }), + var element = $( "#menu5" ).menu( { menus: ".menu" } ), event = $.Event( "mouseenter" ); function menumouseleave1() { @@ -217,22 +219,22 @@ asyncTest( "handle submenu auto collapse: mouseleave, custom markup", function() element.find( ":nth-child(7)" ).trigger( "mouseenter" ); setTimeout( menumouseleave1, 25 ); -}); +} ); asyncTest( "handle keyboard navigation on menu without scroll and without submenus", function() { expect( 12 ); - var element = $( "#menu1" ).menu({ + var element = $( "#menu1" ).menu( { select: function( event, ui ) { log( $( ui.item[ 0 ] ).text() ); }, focus: function( event ) { log( $( event.target ).find( ".ui-menu-item-wrapper.ui-state-active" ).parent().index() ); } - }); + } ); log( "keydown", true ); element[ 0 ].focus(); - setTimeout(function() { + setTimeout( function() { element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); equal( logOutput(), "keydown,0,1,2", "Keydown DOWN" ); @@ -282,19 +284,19 @@ asyncTest( "handle keyboard navigation on menu without scroll and without submen equal( logOutput(), "keydown,Aberdeen", "Keydown ENTER" ); start(); - }); -}); + } ); +} ); asyncTest( "handle keyboard navigation on menu without scroll and with submenus", function() { expect( 16 ); - var element = $( "#menu2" ).menu({ + var element = $( "#menu2" ).menu( { select: function( event, ui ) { - log( $( ui.item[0] ).text() ); + log( $( ui.item[ 0 ] ).text() ); }, focus: function( event ) { log( $( event.target ).find( ".ui-menu-item-wrapper.ui-state-active:last" ).parent().index() ); } - }); + } ); log( "keydown", true ); element.one( "menufocus", function() { @@ -302,7 +304,7 @@ asyncTest( "handle keyboard navigation on menu without scroll and with submenus" element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); equal( logOutput(), "keydown,1,2", "Keydown DOWN" ); setTimeout( menukeyboard1 ); - }); + } ); element.trigger( "focus" ); function menukeyboard1() { @@ -322,7 +324,7 @@ asyncTest( "handle keyboard navigation on menu without scroll and with submenus" element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); element.simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } ); - setTimeout(function() { + setTimeout( function() { equal( logOutput(), "keydown,1,2,3,4,0", "Keydown RIGHT (open submenu)" ); setTimeout( menukeyboard2 ); } ); @@ -403,22 +405,22 @@ asyncTest( "handle keyboard navigation on menu without scroll and with submenus" equal( logOutput(), "keydown,Ada", "Keydown ENTER (open submenu)" ); start(); } -}); +} ); asyncTest( "handle keyboard navigation on menu with scroll and without submenus", function() { expect( 14 ); - var element = $( "#menu3" ).menu({ + var element = $( "#menu3" ).menu( { select: function( event, ui ) { log( $( ui.item[ 0 ] ).text() ); }, focus: function( event ) { log( $( event.target ).find( ".ui-menu-item-wrapper.ui-state-active:last" ).parent().index() ); } - }); + } ); log( "keydown", true ); element[ 0 ].focus(); - setTimeout(function() { + setTimeout( function() { element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); equal( logOutput(), "keydown,0,1,2", "Keydown DOWN" ); @@ -477,19 +479,19 @@ asyncTest( "handle keyboard navigation on menu with scroll and without submenus" equal( logOutput(), "keydown,Aberdeen", "Keydown ENTER" ); start(); - }); -}); + } ); +} ); asyncTest( "handle keyboard navigation on menu with scroll and with submenus", function() { expect( 14 ); - var element = $( "#menu4" ).menu({ + var element = $( "#menu4" ).menu( { select: function( event, ui ) { log( $( ui.item[ 0 ] ).text() ); }, focus: function( event ) { - log( $( event.target ).find( ".ui-menu-item-wrapper.ui-state-active:last" ).parent().index()); + log( $( event.target ).find( ".ui-menu-item-wrapper.ui-state-active:last" ).parent().index() ); } - }); + } ); log( "keydown", true ); element.one( "menufocus", function() { @@ -497,7 +499,7 @@ asyncTest( "handle keyboard navigation on menu with scroll and with submenus", f element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); equal( logOutput(), "keydown,1,2", "Keydown DOWN" ); setTimeout( menukeyboard1 ); - }); + } ); element.trigger( "focus" ); function menukeyboard1() { @@ -573,18 +575,18 @@ asyncTest( "handle keyboard navigation on menu with scroll and with submenus", f start(); } -}); +} ); asyncTest( "handle keyboard navigation and mouse click on menu with disabled items", function() { expect( 6 ); - var element = $( "#menu6" ).menu({ + var element = $( "#menu6" ).menu( { select: function( event, ui ) { - log( $( ui.item[0] ).text() ); + log( $( ui.item[ 0 ] ).text() ); }, focus: function( event ) { - log( $( event.target ).find( ".ui-menu-item-wrapper.ui-state-active" ).parent().index()); + log( $( event.target ).find( ".ui-menu-item-wrapper.ui-state-active" ).parent().index() ); } - }); + } ); log( "keydown", true ); element.one( "menufocus", function() { @@ -592,7 +594,7 @@ asyncTest( "handle keyboard navigation and mouse click on menu with disabled ite element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); equal( logOutput(), "keydown,1", "Keydown focus but not select disabled item" ); setTimeout( menukeyboard1, 50 ); - }); + } ); element.trigger( "focus" ); function menukeyboard1() { @@ -624,19 +626,19 @@ asyncTest( "handle keyboard navigation and mouse click on menu with disabled ite }, 50 ); }, 50 ); } -}); +} ); asyncTest( "handle keyboard navigation and mouse click on menu with dividers and group labels", function() { expect( 2 ); - var element = $( "#menu7" ).menu({ + var element = $( "#menu7" ).menu( { items: "> :not('.ui-menu-group')", select: function( event, ui ) { - log( $( ui.item[0] ).text() ); + log( $( ui.item[ 0 ] ).text() ); }, focus: function( event ) { log( $( event.target ).find( ".ui-menu-item-wrapper.ui-state-active" ).parent().index() ); } - }); + } ); log( "keydown", true ); element.one( "menufocus", function() { @@ -644,7 +646,7 @@ asyncTest( "handle keyboard navigation and mouse click on menu with dividers and element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); equal( logOutput(), "keydown,2,Ada", "Keydown skips initial group label" ); setTimeout( menukeyboard1, 50 ); - }); + } ); element.trigger( "focus" ); function menukeyboard1() { @@ -655,15 +657,15 @@ asyncTest( "handle keyboard navigation and mouse click on menu with dividers and equal( logOutput(), "keydown,3,4,7", "Keydown focus skips divider and group label" ); start(); } -}); +} ); asyncTest( "handle keyboard navigation with spelling of menu items", function() { expect( 3 ); - var element = $( "#menu2" ).menu({ + var element = $( "#menu2" ).menu( { focus: function( event ) { log( $( event.target ).find( ".ui-menu-item-wrapper.ui-state-active" ).parent().index() ); } - }); + } ); log( "keydown", true ); element.one( "menufocus", function() { @@ -676,17 +678,17 @@ asyncTest( "handle keyboard navigation with spelling of menu items", function() element.simulate( "keydown", { keyCode: 83 } ); equal( logOutput(), "keydown,0,1,3,4,5", "Keydown focus Saarland ignoring leading space" ); start(); - }); + } ); element[ 0 ].focus(); -}); +} ); asyncTest( "Keep focus on selected item (see #10644)", function() { expect( 1 ); - var element = $( "#menu2" ).menu({ + var element = $( "#menu2" ).menu( { focus: function( event ) { log( $( event.target ).find( ".ui-menu-item-wrapper.ui-state-active" ).parent().index() ); } - }); + } ); log( "keydown", true ); element.one( "menufocus", function() { @@ -698,40 +700,40 @@ asyncTest( "Keep focus on selected item (see #10644)", function() { equal( logOutput(), "keydown,0,1,3,3,3", "Focus stays on 'Addyston', even after other options are eliminated" ); start(); - }); + } ); element[ 0 ].focus(); -}); +} ); test( "#9469: Stopping propagation in a select event should not suppress subsequent select events.", function() { expect( 1 ); - var element = $( "#menu1" ).menu({ + var element = $( "#menu1" ).menu( { select: function( event ) { log(); event.stopPropagation(); } - }); + } ); click( element, "1" ); click( element, "2" ); equal( logOutput(), "1,2", "Both select events were not triggered." ); -}); +} ); asyncTest( "#10571: When typing in a menu, only menu-items should be focused", function( assert ) { expect( 3 ); - var element = $( "#menu8" ).menu({ + var element = $( "#menu8" ).menu( { focus: function( event, ui ) { equal( ui.item.length, 1, "There should only be one match when filtering" ); assert.hasClasses( ui.item, "ui-menu-item" ); equal( ui.item.text(), "-Saarland", "element has correct text" ); } - }); + } ); - setTimeout(function() { + setTimeout( function() { element.menu( "widget" ).simulate( "keydown", { keyCode: "-".charCodeAt( 0 ) } ); start(); - }); -}); + } ); +} ); } ); diff --git a/tests/unit/menu/methods.js b/tests/unit/menu/methods.js index 28482d65d..dc857cc42 100644 --- a/tests/unit/menu/methods.js +++ b/tests/unit/menu/methods.js @@ -12,25 +12,25 @@ module( "menu: methods", { setup: function() { testHelper.clearLog(); } -}); +} ); test( "destroy", function( assert ) { expect( 2 ); assert.domEqual( "#menu2", function() { $( "#menu2" ).menu().menu( "destroy" ); - }); + } ); assert.domEqual( "#menu5", function() { - $( "#menu5").menu().menu( "destroy" ); - }); -}); + $( "#menu5" ).menu().menu( "destroy" ); + } ); +} ); test( "enable/disable", function( assert ) { expect( 3 ); - var element = $( "#menu1" ).menu({ + var element = $( "#menu1" ).menu( { select: function() { log(); } - }); + } ); element.menu( "disable" ); assert.hasClasses( element, "ui-state-disabled" ); log( "click", true ); @@ -42,7 +42,7 @@ test( "enable/disable", function( assert ) { click( element, "1" ); log( "afterclick" ); equal( logOutput(), "click,afterclick,click,1,afterclick", "Click order not valid." ); -}); +} ); test( "refresh", function() { expect( 5 ); @@ -56,7 +56,7 @@ test( "refresh", function() { equal( element.find( ".ui-menu-item" ).length, 5, "Incorrect number of menu items" ); element.children( ":last" ).remove().end().menu( "refresh" ); equal( element.find( ".ui-menu-item" ).length, 5, "Incorrect number of menu items" ); -}); +} ); test( "refresh submenu", function() { expect( 2 ); @@ -65,7 +65,7 @@ test( "refresh submenu", function() { element.find( "ul" ).addBack().append( "
  • New Item
  • " ); element.menu( "refresh" ); equal( element.find( "ul:first .ui-menu-item" ).length, 4 ); -}); +} ); test( "refresh icons (see #9377)", function( assert ) { expect( 3 ); @@ -79,7 +79,7 @@ test( "refresh icons (see #9377)", function( assert ) { element.find( "li:first .ui-menu-item-wrapper" ).html( "Save" ); element.menu( "refresh" ); assert.lacksClasses( element, "ui-menu-icons" ); -}); +} ); test( "widget", function() { expect( 2 ); @@ -87,7 +87,7 @@ test( "widget", function() { widgetElement = element.menu( "widget" ); equal( widgetElement.length, 1, "one element" ); strictEqual( widgetElement[ 0 ], element[ 0 ], "same element" ); -}); +} ); // TODO: test focus method diff --git a/tests/unit/menu/options.js b/tests/unit/menu/options.js index e22adccf6..dd27ec5c2 100644 --- a/tests/unit/menu/options.js +++ b/tests/unit/menu/options.js @@ -12,62 +12,62 @@ module( "menu: options", { setup: function() { testHelper.clearLog(); } -}); +} ); test( "{ disabled: true }", function( assert ) { expect( 2 ); - var element = $( "#menu1" ).menu({ + var element = $( "#menu1" ).menu( { disabled: true, select: function() { log(); } - }); + } ); assert.hasClasses( element, "ui-state-disabled" ); log( "click", true ); click( element, "1" ); log( "afterclick" ); equal( logOutput(), "click,afterclick", "Click order not valid." ); -}); +} ); test( "{ disabled: false }", function( assert ) { expect( 2 ); - var element = $( "#menu1" ).menu({ + var element = $( "#menu1" ).menu( { disabled: false, select: function() { log(); } - }); + } ); assert.lacksClasses( element, "ui-state-disabled" ); log( "click", true ); click( element, "1" ); log( "afterclick" ); equal( logOutput(), "click,1,afterclick", "Click order not valid." ); -}); +} ); test( "{ icons: default }", function( assert ) { expect( 8 ); var element = $( "#menu2" ).menu(); element.find( ".ui-menu-icon" ).each( function() { assert.hasClasses( this, "ui-menu-icon ui-icon ui-icon-caret-1-e" ); - }); + } ); element.menu( "option", "icons.submenu", "ui-icon-triangle-1-e" ); element.find( ".ui-menu-icon" ).each( function() { assert.hasClasses( this, "ui-menu-icon ui-icon ui-icon-triangle-1-e" ); - }); -}); + } ); +} ); test( "{ icons: { submenu: 'custom' } }", function( assert ) { expect( 4 ); - var element = $( "#menu2" ).menu({ + var element = $( "#menu2" ).menu( { icons: { submenu: "custom-class" } - }); + } ); element.find( ".ui-menu-icon" ).each( function() { assert.hasClasses( this, "ui-menu-icon ui-icon custom-class" ); - }); -}); + } ); +} ); // TODO: test menus option @@ -79,47 +79,47 @@ test( "{ role: 'menu' } ", function( assert ) { expect( 2 + 3 * items.length ); equal( element.attr( "role" ), "menu" ); ok( items.length > 0, "number of menu items" ); - items.each(function( item ) { + items.each( function( item ) { assert.hasClasses( $( this ), "ui-menu-item" ); equal( $( this ).find( ".ui-menu-item-wrapper" ).attr( "role" ), - "menuitem", "menu item ("+ item + ") role" ); + "menuitem", "menu item (" + item + ") role" ); equal( $( this ).find( ".ui-menu-item-wrapper" ).attr( "tabindex" ), "-1", - "tabindex for menu item ("+ item + ")" ); - }); -}); + "tabindex for menu item (" + item + ")" ); + } ); +} ); test( "{ role: 'listbox' } ", function( assert ) { - var element = $( "#menu1" ).menu({ + var element = $( "#menu1" ).menu( { role: "listbox" - }), + } ), items = element.find( "li" ); expect( 2 + 3 * items.length ); equal( element.attr( "role" ), "listbox" ); ok( items.length > 0, "number of menu items" ); - items.each(function( item ) { + items.each( function( item ) { assert.hasClasses( $( this ), "ui-menu-item" ); equal( $( this ).find( ".ui-menu-item-wrapper" ).attr( "role" ), "option", - "menu item ("+ item + ") role" ); + "menu item (" + item + ") role" ); equal( $( this ).find( ".ui-menu-item-wrapper" ).attr( "tabindex" ), "-1", - "tabindex for menu item ("+ item + ")" ); - }); -}); + "tabindex for menu item (" + item + ")" ); + } ); +} ); test( "{ role: null }", function( assert ) { - var element = $( "#menu1" ).menu({ + var element = $( "#menu1" ).menu( { role: null - }), + } ), items = element.find( "li" ); expect( 2 + 3 * items.length ); equal( element.attr( "role" ), null ); ok( items.length > 0, "number of menu items" ); - items.each(function( item ) { + items.each( function( item ) { assert.hasClasses( $( this ), "ui-menu-item" ); equal( $( this ).find( ".ui-menu-item-wrapper" ).attr( "role" ), null, - "menu item ("+ item + ") role" ); + "menu item (" + item + ") role" ); equal( $( this ).find( ".ui-menu-item-wrapper" ).attr( "tabindex" ), "-1", - "tabindex for menu item ("+ item + ")" ); - }); -}); + "tabindex for menu item (" + item + ")" ); + } ); +} ); } ); diff --git a/ui/widgets/menu.js b/ui/widgets/menu.js index 48258e85e..f7fa2b651 100644 --- a/ui/widgets/menu.js +++ b/ui/widgets/menu.js @@ -136,6 +136,7 @@ return $.widget( "ui.menu", { mouseleave: "collapseAll", "mouseleave .ui-menu": "collapseAll", focus: function( event, keepActiveItem ) { + // If there's already an active item, keep it active // If not, activate the first item var item = this.active || this.element.find( this.options.items ).eq( 0 ); @@ -475,6 +476,7 @@ return $.widget( "ui.menu", { collapseAll: function( event, all ) { clearTimeout( this.timer ); this.timer = this._delay( function() { + // If we were passed an event, look for the submenu that contains the event var currentMenu = all ? this.element : $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); @@ -633,6 +635,7 @@ return $.widget( "ui.menu", { }, select: function( event ) { + // TODO: It should never be possible to not have an active item at this // point, but the tests don't trigger mouseenter before click. this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); -- 2.39.5