Skip to content

Menubar: Allow structures other than just UL/LI and combine the _next, _prev, _right and _left into _move #541

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Dec 7, 2011
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions demos/menubar/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@
},
select: select
});

$("#bar3").menubar({
position: {
within: $("#demo-frame").add(window).first()
},
select: select,
items: ".menubarItem",
menuElement: ".menuElement"
});
});
</script>
<style>
Expand Down Expand Up @@ -136,6 +145,52 @@
</li>
</ul>

<div id="bar3" class="menubar">
<div class="menubarItem">
<a href="#File">File</a>
<div class="menuElement">
<div><a href="#Open...">Open...</a></div>
<div class="ui-state-disabled">Open recent...</div>
<div><a href="#Save">Save</a></div>
<div><a href="#Save as...">Save as...</a></div>
<div><a href="#Close">Close</a></div>
<div><a href="#Quit">Quit</a></div>
</div>
</div>
<div class="menubarItem">
<a href="#Edit">Edit</a>
<div class="menuElement">
<div><a href="#Copy">Copy</a></div>
<div><a href="#Cut">Cut</a></div>
<div class="ui-state-disabled">Paste</div>
</div>
</div>
<div class="menubarItem">
<a href="#View">View</a>
<div class="menuElement">
<div><a href="#Fullscreen">Fullscreen</a></div>
<div><a href="#Fit into view">Fit into view</a></div>
<div>
<a href="#Encoding">Encoding</a>
<div class="menuElement">
<div class="ui-state-disabled">Auto-detect</div>
<div><a href="#UTF-8">UTF-8</a></div>
<div>
<a href="#UTF-16">UTF-16</a>
<div class="menuElement">
<div><a href="#Option 1">Option 1</a></div>
<div><a href="#Option 2">Option 2</a></div>
<div class="ui-state-disabled">Option 3</div>
<div><a href="#Option 4">Option 4</a></div>
</div>
</div>
</div>
</div>
<div><a href="#Customize...">Customize...</a></div>
</div>
</div>
</div>

<div class="ui-widget" style="margin-top:2em; font-family:Arial">
Log:
<div id="log" style="height: 100px; width: 300px; overflow: auto;" class="ui-widget-content"></div>
Expand Down
2 changes: 1 addition & 1 deletion themes/base/jquery.ui.menu.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
.ui-menu .ui-menu-item a.ui-state-focus,
.ui-menu .ui-menu-item a.ui-state-active { font-weight: normal; margin: -1px; }

.ui-menu li.ui-state-disabled { font-weight: normal; padding: .0em .4em; margin: .4em 0 .2em; line-height: 1.5; }
.ui-menu .ui-state-disabled { font-weight: normal; padding: .0em .4em; margin: .4em 0 .2em; line-height: 1.5; }

/* icon support */
.ui-menu-icons { position: relative; }
Expand Down
2 changes: 1 addition & 1 deletion themes/base/jquery.ui.menubar.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
.ui-menubar .ui-button { float: left; font-weight: normal; border-top-width: 0 !important; border-bottom-width: 0 !important; margin: 0; outline: none; }
.ui-menubar .ui-menubar-link { border-right: 1px dashed transparent; border-left: 1px dashed transparent; }

.ui-menubar .ui-menu { width: 200px; position: absolute; z-index: 9999; }
.ui-menubar .ui-menu { width: 200px; position: absolute; z-index: 9999; font-weight: normal; }
101 changes: 49 additions & 52 deletions ui/jquery.ui.menubar.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ $.widget( "ui.menubar", {
options: {
autoExpand: false,
buttons: false,
items: "li",
menuElement: "ul",
menuIcon: false,
position: {
my: "left top",
Expand All @@ -30,19 +32,21 @@ $.widget( "ui.menubar", {
},
_create: function() {
var that = this;
var items = this.items = this.element.children( "li" )
this.menuItems = this.element.children( this.options.items );
this.items = this.menuItems.children( "button, a" );

this.menuItems
.addClass( "ui-menubar-item" )
.attr( "role", "presentation" )
.children( "button, a" );
.attr( "role", "presentation" );
// let only the first item receive focus
items.slice(1).attr( "tabIndex", -1 );
this.items.slice(1).attr( "tabIndex", -1 );

this.element
.addClass( "ui-menubar ui-widget-header ui-helper-clearfix" )
.attr( "role", "menubar" );
this._focusable( items );
this._hoverable( items );
items.next( "ul" )
this._focusable( this.items );
this._hoverable( this.items );
this.items.siblings( this.options.menuElement )
.menu({
position: {
within: this.options.position.within
Expand All @@ -53,7 +57,8 @@ $.widget( "ui.menubar", {
// TODO what is this targetting? there's probably a better way to access it
$(event.target).prev().focus();
that._trigger( "select", event, ui );
}
},
menus: that.options.menuElement
})
.hide()
.attr({
Expand All @@ -66,19 +71,19 @@ $.widget( "ui.menubar", {
return;
switch ( event.keyCode ) {
case $.ui.keyCode.LEFT:
that._left( event );
that.previous( event );
event.preventDefault();
break;
case $.ui.keyCode.RIGHT:
that._right( event );
that.next( event );
event.preventDefault();
break;
};
});
items.each(function() {
this.items.each(function() {
var input = $(this),
// TODO menu var is only used on two places, doesn't quite justify the .each
menu = input.next( "ul" );
menu = input.next( that.options.menuElement );

input.bind( "click.menubar focus.menubar mouseenter.menubar", function( event ) {
// ignore triggered focus event
Expand Down Expand Up @@ -109,11 +114,11 @@ $.widget( "ui.menubar", {
event.preventDefault();
break;
case $.ui.keyCode.LEFT:
that._prev( event, $( this ) );
that.previous( event );
event.preventDefault();
break;
case $.ui.keyCode.RIGHT:
that._next( event, $( this ) );
that.next( event );
event.preventDefault();
break;
}
Expand Down Expand Up @@ -166,17 +171,16 @@ $.widget( "ui.menubar", {
},

_destroy : function() {
var items = this.element.children( "li" )
this.menuItems
.removeClass( "ui-menubar-item" )
.removeAttr( "role" )
.children( "button, a" );
.removeAttr( "role" );

this.element
.removeClass( "ui-menubar ui-widget-header ui-helper-clearfix" )
.removeAttr( "role" )
.unbind( ".menubar" );

items
this.items
.unbind( ".menubar" )
.removeClass( "ui-button ui-widget ui-button-text-only ui-menubar-link ui-state-default" )
.removeAttr( "role" )
Expand Down Expand Up @@ -243,55 +247,48 @@ $.widget( "ui.menubar", {
}, this.options.position ) )
.removeAttr( "aria-hidden" )
.attr( "aria-expanded", "true" )
.menu("focus", event, menu.children( "li" ).first() )
.menu("focus", event, menu.children( ".ui-menu-item" ).first() )
// TODO need a comment here why both events are triggered
.focus()
.focusin();
this.open = true;
},

// TODO refactor this and the next three methods
_prev: function( event, button ) {
button.attr( "tabIndex", -1 );
var prev = button.parent().prevAll( "li" ).children( ".ui-button" ).eq( 0 );
if ( prev.length ) {
prev.removeAttr( "tabIndex" )[0].focus();
} else {
var lastItem = this.element.children( "li:last" ).children( ".ui-button:last" );
lastItem.removeAttr( "tabIndex" )[0].focus();
}
next: function( event ) {
this._move( "next", "first", event );
},

_next: function( event, button ) {
button.attr( "tabIndex", -1 );
var next = button.parent().nextAll( "li" ).children( ".ui-button" ).eq( 0 );
if ( next.length ) {
next.removeAttr( "tabIndex")[0].focus();
} else {
var firstItem = this.element.children( "li:first" ).children( ".ui-button:first" );
firstItem.removeAttr( "tabIndex" )[0].focus();
}
previous: function( event ) {
this._move( "prev", "last", event );
},

// TODO rename to parent
_left: function( event ) {
var prev = this.active.parent().prevAll( "li:eq(0)" ).children( ".ui-menu" ).eq( 0 );
if ( prev.length ) {
this._open( event, prev );
_move: function( direction, filter, event ) {
var next,
wrapItem;
if ( this.open ) {
next = this.active.closest( ".ui-menubar-item" )[ direction + "All" ]( this.options.items ).first().children( ".ui-menu" ).eq( 0 );
wrapItem = this.menuItems[ filter ]().children( ".ui-menu" ).eq( 0 );
} else {
var lastItem = this.element.children( "li:last" ).children( ".ui-menu:first" );
this._open( event, lastItem );
if ( event ) {
next = $( event.target ).closest( ".ui-menubar-item" )[ direction + "All" ]( this.options.items ).children( ".ui-menubar-link" ).eq( 0 );
wrapItem = this.menuItems[ filter ]().children( ".ui-menubar-link" ).eq( 0 );
} else {
next = wrapItem = this.menuItems.children( "a" ).eq( 0 );
}
}
},

// TODO rename to child (or something like that)
_right: function( event ) {
var next = this.active.parent().nextAll( "li:eq(0)" ).children( ".ui-menu" ).eq( 0 );
if ( next.length ) {
this._open( event, next );
if ( this.open ) {
this._open( event, next );
} else {
next.removeAttr( "tabIndex")[0].focus();
}
} else {
var firstItem = this.element.children( "li:first" ).children( ".ui-menu:first" );
this._open( event, firstItem );
if ( this.open ) {
this._open( event, wrapItem );
} else {
wrapItem.removeAttr( "tabIndex")[0].focus();
}
}
}
});
Expand Down