mirror of
https://github.com/jquery/jquery-ui.git
synced 2024-11-21 11:04:24 +00:00
Menu: Add support for structures other than UL/LI plus visual and unit tests
This commit is contained in:
parent
cedac75bcc
commit
9e617bbad1
@ -207,6 +207,44 @@
|
||||
<li class="foo"><a class="foo" href="#">Amesville</a></li>
|
||||
</ul>
|
||||
|
||||
<div id="menu5">
|
||||
<blockquote><a href="#">Aberdeen</a></blockquote>
|
||||
<blockquote><a href="#">Ada</a></blockquote>
|
||||
<blockquote><a href="#">Adamsville</a></blockquote>
|
||||
<blockquote><a href="#">Addyston</a></blockquote>
|
||||
<blockquote>
|
||||
<a href="#">Delphi</a>
|
||||
<div>
|
||||
<blockquote><a href="#">Ada</a></blockquote>
|
||||
<blockquote><a href="#">Saarland</a></blockquote>
|
||||
<blockquote><a href="#">Salzburg</a></blockquote>
|
||||
</div>
|
||||
</blockquote>
|
||||
<blockquote><a href="#">Saarland</a></blockquote>
|
||||
<blockquote>
|
||||
<a href="#">Salzburg</a>
|
||||
<div>
|
||||
<blockquote>
|
||||
<a href="#">Delphi</a>
|
||||
<div>
|
||||
<blockquote><a href="#">Ada</a></blockquote>
|
||||
<blockquote><a href="#">Saarland</a></blockquote>
|
||||
<blockquote><a href="#">Salzburg</a></blockquote>
|
||||
</div>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<a href="#">Delphi</a>
|
||||
<div>
|
||||
<blockquote><a href="#">Ada</a></blockquote>
|
||||
<blockquote><a href="#">Saarland</a></blockquote>
|
||||
<blockquote><a href="#">Salzburg</a></blockquote>
|
||||
</div>
|
||||
</blockquote>
|
||||
<blockquote><a href="#">Perch</a></blockquote>
|
||||
</div>
|
||||
</blockquote>
|
||||
</div>
|
||||
|
||||
<div id="log"></div>
|
||||
|
||||
</div>
|
||||
|
@ -5,6 +5,7 @@ commonWidgetTests( "menu", {
|
||||
my: "left top",
|
||||
at: "right top"
|
||||
},
|
||||
items: "ul",
|
||||
|
||||
// callbacks
|
||||
create: null
|
||||
|
@ -21,6 +21,23 @@ test("handle click on menu", function() {
|
||||
equals( $("#log").html(), "1,3,2,afterclick,1,click,", "Click order not valid.");
|
||||
});
|
||||
|
||||
test("handle click on custom item menu", function() {
|
||||
expect(1);
|
||||
var ac = $('#menu5').menu({
|
||||
select: function(event, ui) {
|
||||
menu_log();
|
||||
},
|
||||
items: "div"
|
||||
});
|
||||
menu_log("click",true);
|
||||
menu_click($('#menu5'),"1");
|
||||
menu_log("afterclick");
|
||||
menu_click( ac,"2");
|
||||
menu_click($('#menu5'),"3");
|
||||
menu_click( ac,"1");
|
||||
equals( $("#log").html(), "1,3,2,afterclick,1,click,", "Click order not valid.");
|
||||
});
|
||||
|
||||
test( "handle blur: click", function() {
|
||||
expect( 4 );
|
||||
var $menu = $( "#menu1" ).menu({
|
||||
@ -41,6 +58,27 @@ test( "handle blur: click", function() {
|
||||
$("#remove").remove();
|
||||
});
|
||||
|
||||
test( "handle blur on custom item menu: click", function() {
|
||||
expect( 4 );
|
||||
var $menu = $( "#menu5" ).menu({
|
||||
focus: function( event, ui ) {
|
||||
equal( event.originalEvent.type, "click", "focus triggered 'click'" );
|
||||
equal( event.type, "menufocus", "focus event.type is 'menufocus'" );
|
||||
|
||||
},
|
||||
blur: function( event, ui ) {
|
||||
equal( event.originalEvent.type, "click", "blur triggered 'click'" );
|
||||
equal( event.type, "menublur", "blur event.type is 'menublur'" );
|
||||
},
|
||||
items: "div"
|
||||
});
|
||||
|
||||
menu_click($('#menu5'),"1");
|
||||
$( "<a>", { id: "remove"} ).appendTo("body").trigger( "click" );
|
||||
|
||||
$("#remove").remove();
|
||||
});
|
||||
|
||||
asyncTest( "handle submenu auto collapse: mouseleave", function() {
|
||||
expect( 4 );
|
||||
var $menu = $( "#menu2" ).menu();
|
||||
@ -60,6 +98,25 @@ asyncTest( "handle submenu auto collapse: mouseleave", function() {
|
||||
}, 200);
|
||||
});
|
||||
|
||||
asyncTest( "handle custom menu item submenu auto collapse: mouseleave", function() {
|
||||
expect( 4 );
|
||||
var $menu = $( "#menu5" ).menu( { items: "div" } );
|
||||
|
||||
$menu.children( ":nth-child(7)" ).trigger( "mouseover" );
|
||||
setTimeout(function() {
|
||||
equal( $menu.find( "div[aria-expanded='true']" ).length, 1, "first submenu expanded" );
|
||||
$menu.children( ":nth-child(7)" ).find( "div:first" ).children( ":first" ).trigger( "mouseover" );
|
||||
setTimeout(function() {
|
||||
equal( $menu.find( "div[aria-expanded='true']" ).length, 2, "second submenu expanded" );
|
||||
$menu.find( "div[aria-expanded='true']:first" ).trigger( "mouseleave" );
|
||||
equal( $menu.find( "div[aria-expanded='true']" ).length, 1, "second submenu collapsed" );
|
||||
$menu.trigger( "mouseleave" );
|
||||
equal( $menu.find( "div[aria-expanded='true']" ).length, 0, "first submenu collapsed" );
|
||||
start();
|
||||
}, 400);
|
||||
}, 200);
|
||||
});
|
||||
|
||||
test("handle keyboard navigation on menu without scroll and without submenus", function() {
|
||||
expect(12);
|
||||
var element = $('#menu1').menu({
|
||||
|
@ -10,5 +10,5 @@ function menu_log( message, clear ) {
|
||||
|
||||
function menu_click( menu, item ) {
|
||||
$( "#log" ).data( "lastItem", item );
|
||||
menu.find( "li:eq(" + item + ") a" ).trigger( "click" );
|
||||
}
|
||||
menu.children( ":eq(" + item + ")" ).find( "a:first" ).trigger( "click" );
|
||||
}
|
@ -23,8 +23,22 @@
|
||||
$("<div/>").text("Selected: " + ui.item.text()).appendTo("#log");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$("#menu5").menu({
|
||||
select: function(event, ui) {
|
||||
$("<div/>").text("Selected: " + ui.item.text()).appendTo("#log");
|
||||
},
|
||||
items: "div"
|
||||
});
|
||||
|
||||
$("#menu6").menu({
|
||||
select: function(event, ui) {
|
||||
$("<div/>").text("Selected: " + ui.item.text()).appendTo("#log");
|
||||
},
|
||||
items: ".menuElement"
|
||||
});
|
||||
}
|
||||
|
||||
var menus = $("#menu1, #menu2, #menu3, .menu4");
|
||||
create();
|
||||
|
||||
@ -42,6 +56,9 @@
|
||||
body { font-size:62.5%; }
|
||||
.ui-menu { width: 200px; margin-bottom: 2em; }
|
||||
.menu4 { height: 200px; overflow: auto; }
|
||||
.address-item { border-bottom: 1px solid #999; }
|
||||
.address-header { display: block; margin-bottom: .2em; font-weight: bold; }
|
||||
.address-content { display: block; margin-bottom: .2em; padding-left: 10px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@ -173,6 +190,87 @@
|
||||
<li><a href="#">Amesville</a></li>
|
||||
</ul>
|
||||
|
||||
<div id="menu5">
|
||||
<blockquote><a href="#">Aberdeen</a></blockquote>
|
||||
<blockquote><a href="#">Ada</a></blockquote>
|
||||
<blockquote><a href="#">Adamsville</a></blockquote>
|
||||
<blockquote><a href="#">Addyston</a></blockquote>
|
||||
<blockquote>
|
||||
<a href="#">Delphi</a>
|
||||
<div>
|
||||
<blockquote><a href="#">Ada</a></blockquote>
|
||||
<blockquote><a href="#">Saarland</a></blockquote>
|
||||
<blockquote><a href="#">Salzburg</a></blockquote>
|
||||
</div>
|
||||
</blockquote>
|
||||
<blockquote><a href="#">Saarland</a></blockquote>
|
||||
<blockquote>
|
||||
<a href="#">Salzburg</a>
|
||||
<div>
|
||||
<blockquote>
|
||||
<a href="#">Delphi</a>
|
||||
<div>
|
||||
<blockquote><a href="#">Ada</a></blockquote>
|
||||
<blockquote><a href="#">Saarland</a></blockquote>
|
||||
<blockquote><a href="#">Salzburg</a></blockquote>
|
||||
</div>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<a href="#">Delphi</a>
|
||||
<div>
|
||||
<blockquote><a href="#">Ada</a></blockquote>
|
||||
<blockquote><a href="#">Saarland</a></blockquote>
|
||||
<blockquote><a href="#">Salzburg</a></blockquote>
|
||||
</div>
|
||||
</blockquote>
|
||||
<blockquote><a href="#">Perch</a></blockquote>
|
||||
</div>
|
||||
</blockquote>
|
||||
</div>
|
||||
|
||||
<div class="menuElement" id="menu6">
|
||||
<div class="address-item">
|
||||
<a href="#">
|
||||
<span class="address-header">John Doe</span>
|
||||
<span class="address-content">78 West Main St Apt 3A</span>
|
||||
<span class="address-content">Bloomsburg, PA 12345</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="address-item">
|
||||
<a href="#">
|
||||
<span class="address-header">Jane Doe</span>
|
||||
<span class="address-content">78 West Main St Apt 3A</span>
|
||||
<span class="address-content">Bloomsburg, PA 12345</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="address-item">
|
||||
<a href="#">
|
||||
<span class="address-header">James Doe</span>
|
||||
<span class="address-content">78 West Main St Apt 3A</span>
|
||||
<span class="address-content">Bloomsburg, PA 12345</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="address-item">
|
||||
<a href="#">
|
||||
<span class="address-header">Jenny Doe</span>
|
||||
<span class="address-content">78 West Main St Apt 3A</span>
|
||||
<span class="address-content">Bloomsburg, PA 12345</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="address-item">
|
||||
<a href="#">
|
||||
<span class="address-header">John Doe</span>
|
||||
<span class="address-content">78 West Main St Apt 3A</span>
|
||||
<span class="address-content">Bloomsburg, PA 12345</span>
|
||||
</a>
|
||||
<div class="menuElement">
|
||||
<div><a href="#">Ada</a></div>
|
||||
<div><a href="#">Saarland</a></div>
|
||||
<div><a href="#">Salzburg</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui-widget" style="clear: left; margin-top:2em; font-family:Arial">
|
||||
Log:
|
||||
<div id="log" style="height: 400px; width: 300px; overflow: auto;" class="ui-widget-content"></div>
|
||||
@ -182,4 +280,4 @@
|
||||
<button id="toggle-destroy">Destroy / Create</button>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
23
ui/jquery.ui.menu.js
vendored
23
ui/jquery.ui.menu.js
vendored
@ -20,6 +20,7 @@ $.widget( "ui.menu", {
|
||||
defaultElement: "<ul>",
|
||||
delay: 150,
|
||||
options: {
|
||||
items: "ul",
|
||||
position: {
|
||||
my: "left top",
|
||||
at: "right top"
|
||||
@ -194,7 +195,7 @@ $.widget( "ui.menu", {
|
||||
//destroy (sub)menus
|
||||
this.element
|
||||
.removeAttr( "aria-activedescendant" )
|
||||
.find( "ul" )
|
||||
.find( ".ui-menu" )
|
||||
.andSelf()
|
||||
.removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
|
||||
.removeAttr( "role" )
|
||||
@ -221,7 +222,7 @@ $.widget( "ui.menu", {
|
||||
|
||||
refresh: function() {
|
||||
// initialize nested menus
|
||||
var submenus = this.element.find( "ul:not(.ui-menu)" )
|
||||
var submenus = this.element.find( this.options.items + ":not( .ui-menu )" )
|
||||
.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
|
||||
.attr( "role", "menu" )
|
||||
.hide()
|
||||
@ -230,7 +231,7 @@ $.widget( "ui.menu", {
|
||||
|
||||
// don't refresh list items that are already adapted
|
||||
var menuId = this.menuId;
|
||||
submenus.add( this.element ).children( "li:not(.ui-menu-item):has(a)" )
|
||||
submenus.add( this.element ).children( ":not( .ui-menu-item ):has( a )" )
|
||||
.addClass( "ui-menu-item" )
|
||||
.attr( "role", "presentation" )
|
||||
.children( "a" )
|
||||
@ -273,16 +274,16 @@ $.widget( "ui.menu", {
|
||||
.children( "a" )
|
||||
.addClass( "ui-state-focus" )
|
||||
.end();
|
||||
this.element.attr( "aria-activedescendant", this.active.children("a").attr("id") );
|
||||
this.element.attr( "aria-activedescendant", this.active.children( "a" ).attr( "id" ) );
|
||||
|
||||
// highlight active parent menu item, if any
|
||||
this.active.parent().closest(".ui-menu-item").children("a:first").addClass("ui-state-active");
|
||||
this.active.parent().closest( ".ui-menu-item" ).children( "a:first" ).addClass( "ui-state-active" );
|
||||
|
||||
this.timer = this._delay( function() {
|
||||
this._close();
|
||||
}, this.delay );
|
||||
|
||||
var nested = $( ">ul", item );
|
||||
var nested = $( "> .ui-menu", item );
|
||||
if ( nested.length && ( /^mouse/.test( event.type ) ) ) {
|
||||
this._startOpening(nested);
|
||||
}
|
||||
@ -353,19 +354,19 @@ $.widget( "ui.menu", {
|
||||
|
||||
this._close( currentMenu );
|
||||
|
||||
if( !currentMenu ) {
|
||||
if ( !currentMenu ) {
|
||||
this.blur( event );
|
||||
this.activeMenu = this.element;
|
||||
}
|
||||
},
|
||||
|
||||
_close: function( startMenu ) {
|
||||
if( !startMenu ) {
|
||||
if ( !startMenu ) {
|
||||
startMenu = this.active ? this.active.parent() : this.element;
|
||||
}
|
||||
|
||||
startMenu
|
||||
.find( "ul" )
|
||||
.find( ".ui-menu" )
|
||||
.hide()
|
||||
.attr( "aria-hidden", "true" )
|
||||
.attr( "aria-expanded", "false" )
|
||||
@ -375,7 +376,7 @@ $.widget( "ui.menu", {
|
||||
},
|
||||
|
||||
collapse: function( event ) {
|
||||
var newItem = this.active && this.active.parents("li:not(.ui-menubar-item)").first();
|
||||
var newItem = this.active && this.active.parent().closest( ".ui-menu-item", this.element );
|
||||
if ( newItem && newItem.length ) {
|
||||
this._close();
|
||||
this.focus( event, newItem );
|
||||
@ -384,7 +385,7 @@ $.widget( "ui.menu", {
|
||||
},
|
||||
|
||||
expand: function( event ) {
|
||||
var newItem = this.active && this.active.children("ul").children("li").first();
|
||||
var newItem = this.active && this.active.children( ".ui-menu " ).children( ".ui-menu-item" ).first();
|
||||
|
||||
if ( newItem && newItem.length ) {
|
||||
this._open( newItem.parent() );
|
||||
|
Loading…
Reference in New Issue
Block a user