Skip to content
Permalink
Browse files

Merge pull request #541 from kborchers/menubar_otherStructures

Menubar: Allow structures other than just UL/LI and combine the _next, _prev, _right and _left into _move
  • Loading branch information
kborchers committed Dec 7, 2011
2 parents ce7918f + aa267fb commit 1748b5f404c4a8ffe9d5bd8954aa0764fea27d70
Showing with 106 additions and 54 deletions.
  1. +55 −0 demos/menubar/default.html
  2. +1 −1 themes/base/jquery.ui.menu.css
  3. +1 −1 themes/base/jquery.ui.menubar.css
  4. +49 −52 ui/jquery.ui.menubar.js
@@ -35,6 +35,15 @@
},
select: select
});

$("#bar3").menubar({
position: {
within: $("#demo-frame").add(window).first()
},
select: select,
items: ".menubarItem",
menuElement: ".menuElement"
});
});
</script>
<style>
@@ -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>
@@ -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; }
@@ -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; }
@@ -22,6 +22,8 @@ $.widget( "ui.menubar", {
options: {
autoExpand: false,
buttons: false,
items: "li",
menuElement: "ul",
menuIcon: false,
position: {
my: "left top",
@@ -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
@@ -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({
@@ -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
@@ -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;
}
@@ -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" )
@@ -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();
}
}
}
});

0 comments on commit 1748b5f

Please sign in to comment.
You can’t perform that action at this time.