Skip to content

Commit 1748b5f

Browse files
committed
Merge pull request jquery#541 from kborchers/menubar_otherStructures
Menubar: Allow structures other than just UL/LI and combine the _next, _prev, _right and _left into _move
2 parents ce7918f + aa267fb commit 1748b5f

File tree

4 files changed

+106
-54
lines changed

4 files changed

+106
-54
lines changed

demos/menubar/default.html

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@
3535
},
3636
select: select
3737
});
38+
39+
$("#bar3").menubar({
40+
position: {
41+
within: $("#demo-frame").add(window).first()
42+
},
43+
select: select,
44+
items: ".menubarItem",
45+
menuElement: ".menuElement"
46+
});
3847
});
3948
</script>
4049
<style>
@@ -136,6 +145,52 @@
136145
</li>
137146
</ul>
138147

148+
<div id="bar3" class="menubar">
149+
<div class="menubarItem">
150+
<a href="#File">File</a>
151+
<div class="menuElement">
152+
<div><a href="#Open...">Open...</a></div>
153+
<div class="ui-state-disabled">Open recent...</div>
154+
<div><a href="#Save">Save</a></div>
155+
<div><a href="#Save as...">Save as...</a></div>
156+
<div><a href="#Close">Close</a></div>
157+
<div><a href="#Quit">Quit</a></div>
158+
</div>
159+
</div>
160+
<div class="menubarItem">
161+
<a href="#Edit">Edit</a>
162+
<div class="menuElement">
163+
<div><a href="#Copy">Copy</a></div>
164+
<div><a href="#Cut">Cut</a></div>
165+
<div class="ui-state-disabled">Paste</div>
166+
</div>
167+
</div>
168+
<div class="menubarItem">
169+
<a href="#View">View</a>
170+
<div class="menuElement">
171+
<div><a href="#Fullscreen">Fullscreen</a></div>
172+
<div><a href="#Fit into view">Fit into view</a></div>
173+
<div>
174+
<a href="#Encoding">Encoding</a>
175+
<div class="menuElement">
176+
<div class="ui-state-disabled">Auto-detect</div>
177+
<div><a href="#UTF-8">UTF-8</a></div>
178+
<div>
179+
<a href="#UTF-16">UTF-16</a>
180+
<div class="menuElement">
181+
<div><a href="#Option 1">Option 1</a></div>
182+
<div><a href="#Option 2">Option 2</a></div>
183+
<div class="ui-state-disabled">Option 3</div>
184+
<div><a href="#Option 4">Option 4</a></div>
185+
</div>
186+
</div>
187+
</div>
188+
</div>
189+
<div><a href="#Customize...">Customize...</a></div>
190+
</div>
191+
</div>
192+
</div>
193+
139194
<div class="ui-widget" style="margin-top:2em; font-family:Arial">
140195
Log:
141196
<div id="log" style="height: 100px; width: 300px; overflow: auto;" class="ui-widget-content"></div>

themes/base/jquery.ui.menu.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
.ui-menu .ui-menu-item a.ui-state-focus,
1515
.ui-menu .ui-menu-item a.ui-state-active { font-weight: normal; margin: -1px; }
1616

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

1919
/* icon support */
2020
.ui-menu-icons { position: relative; }

themes/base/jquery.ui.menubar.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@
1212
.ui-menubar .ui-button { float: left; font-weight: normal; border-top-width: 0 !important; border-bottom-width: 0 !important; margin: 0; outline: none; }
1313
.ui-menubar .ui-menubar-link { border-right: 1px dashed transparent; border-left: 1px dashed transparent; }
1414

15-
.ui-menubar .ui-menu { width: 200px; position: absolute; z-index: 9999; }
15+
.ui-menubar .ui-menu { width: 200px; position: absolute; z-index: 9999; font-weight: normal; }

ui/jquery.ui.menubar.js

Lines changed: 49 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ $.widget( "ui.menubar", {
2222
options: {
2323
autoExpand: false,
2424
buttons: false,
25+
items: "li",
26+
menuElement: "ul",
2527
menuIcon: false,
2628
position: {
2729
my: "left top",
@@ -30,19 +32,21 @@ $.widget( "ui.menubar", {
3032
},
3133
_create: function() {
3234
var that = this;
33-
var items = this.items = this.element.children( "li" )
35+
this.menuItems = this.element.children( this.options.items );
36+
this.items = this.menuItems.children( "button, a" );
37+
38+
this.menuItems
3439
.addClass( "ui-menubar-item" )
35-
.attr( "role", "presentation" )
36-
.children( "button, a" );
40+
.attr( "role", "presentation" );
3741
// let only the first item receive focus
38-
items.slice(1).attr( "tabIndex", -1 );
42+
this.items.slice(1).attr( "tabIndex", -1 );
3943

4044
this.element
4145
.addClass( "ui-menubar ui-widget-header ui-helper-clearfix" )
4246
.attr( "role", "menubar" );
43-
this._focusable( items );
44-
this._hoverable( items );
45-
items.next( "ul" )
47+
this._focusable( this.items );
48+
this._hoverable( this.items );
49+
this.items.siblings( this.options.menuElement )
4650
.menu({
4751
position: {
4852
within: this.options.position.within
@@ -53,7 +57,8 @@ $.widget( "ui.menubar", {
5357
// TODO what is this targetting? there's probably a better way to access it
5458
$(event.target).prev().focus();
5559
that._trigger( "select", event, ui );
56-
}
60+
},
61+
menus: that.options.menuElement
5762
})
5863
.hide()
5964
.attr({
@@ -66,19 +71,19 @@ $.widget( "ui.menubar", {
6671
return;
6772
switch ( event.keyCode ) {
6873
case $.ui.keyCode.LEFT:
69-
that._left( event );
74+
that.previous( event );
7075
event.preventDefault();
7176
break;
7277
case $.ui.keyCode.RIGHT:
73-
that._right( event );
78+
that.next( event );
7479
event.preventDefault();
7580
break;
7681
};
7782
});
78-
items.each(function() {
83+
this.items.each(function() {
7984
var input = $(this),
8085
// TODO menu var is only used on two places, doesn't quite justify the .each
81-
menu = input.next( "ul" );
86+
menu = input.next( that.options.menuElement );
8287

8388
input.bind( "click.menubar focus.menubar mouseenter.menubar", function( event ) {
8489
// ignore triggered focus event
@@ -109,11 +114,11 @@ $.widget( "ui.menubar", {
109114
event.preventDefault();
110115
break;
111116
case $.ui.keyCode.LEFT:
112-
that._prev( event, $( this ) );
117+
that.previous( event );
113118
event.preventDefault();
114119
break;
115120
case $.ui.keyCode.RIGHT:
116-
that._next( event, $( this ) );
121+
that.next( event );
117122
event.preventDefault();
118123
break;
119124
}
@@ -166,17 +171,16 @@ $.widget( "ui.menubar", {
166171
},
167172

168173
_destroy : function() {
169-
var items = this.element.children( "li" )
174+
this.menuItems
170175
.removeClass( "ui-menubar-item" )
171-
.removeAttr( "role" )
172-
.children( "button, a" );
176+
.removeAttr( "role" );
173177

174178
this.element
175179
.removeClass( "ui-menubar ui-widget-header ui-helper-clearfix" )
176180
.removeAttr( "role" )
177181
.unbind( ".menubar" );
178182

179-
items
183+
this.items
180184
.unbind( ".menubar" )
181185
.removeClass( "ui-button ui-widget ui-button-text-only ui-menubar-link ui-state-default" )
182186
.removeAttr( "role" )
@@ -243,55 +247,48 @@ $.widget( "ui.menubar", {
243247
}, this.options.position ) )
244248
.removeAttr( "aria-hidden" )
245249
.attr( "aria-expanded", "true" )
246-
.menu("focus", event, menu.children( "li" ).first() )
250+
.menu("focus", event, menu.children( ".ui-menu-item" ).first() )
247251
// TODO need a comment here why both events are triggered
248252
.focus()
249253
.focusin();
250254
this.open = true;
251255
},
252256

253-
// TODO refactor this and the next three methods
254-
_prev: function( event, button ) {
255-
button.attr( "tabIndex", -1 );
256-
var prev = button.parent().prevAll( "li" ).children( ".ui-button" ).eq( 0 );
257-
if ( prev.length ) {
258-
prev.removeAttr( "tabIndex" )[0].focus();
259-
} else {
260-
var lastItem = this.element.children( "li:last" ).children( ".ui-button:last" );
261-
lastItem.removeAttr( "tabIndex" )[0].focus();
262-
}
257+
next: function( event ) {
258+
this._move( "next", "first", event );
263259
},
264260

265-
_next: function( event, button ) {
266-
button.attr( "tabIndex", -1 );
267-
var next = button.parent().nextAll( "li" ).children( ".ui-button" ).eq( 0 );
268-
if ( next.length ) {
269-
next.removeAttr( "tabIndex")[0].focus();
270-
} else {
271-
var firstItem = this.element.children( "li:first" ).children( ".ui-button:first" );
272-
firstItem.removeAttr( "tabIndex" )[0].focus();
273-
}
261+
previous: function( event ) {
262+
this._move( "prev", "last", event );
274263
},
275264

276-
// TODO rename to parent
277-
_left: function( event ) {
278-
var prev = this.active.parent().prevAll( "li:eq(0)" ).children( ".ui-menu" ).eq( 0 );
279-
if ( prev.length ) {
280-
this._open( event, prev );
265+
_move: function( direction, filter, event ) {
266+
var next,
267+
wrapItem;
268+
if ( this.open ) {
269+
next = this.active.closest( ".ui-menubar-item" )[ direction + "All" ]( this.options.items ).first().children( ".ui-menu" ).eq( 0 );
270+
wrapItem = this.menuItems[ filter ]().children( ".ui-menu" ).eq( 0 );
281271
} else {
282-
var lastItem = this.element.children( "li:last" ).children( ".ui-menu:first" );
283-
this._open( event, lastItem );
272+
if ( event ) {
273+
next = $( event.target ).closest( ".ui-menubar-item" )[ direction + "All" ]( this.options.items ).children( ".ui-menubar-link" ).eq( 0 );
274+
wrapItem = this.menuItems[ filter ]().children( ".ui-menubar-link" ).eq( 0 );
275+
} else {
276+
next = wrapItem = this.menuItems.children( "a" ).eq( 0 );
277+
}
284278
}
285-
},
286279

287-
// TODO rename to child (or something like that)
288-
_right: function( event ) {
289-
var next = this.active.parent().nextAll( "li:eq(0)" ).children( ".ui-menu" ).eq( 0 );
290280
if ( next.length ) {
291-
this._open( event, next );
281+
if ( this.open ) {
282+
this._open( event, next );
283+
} else {
284+
next.removeAttr( "tabIndex")[0].focus();
285+
}
292286
} else {
293-
var firstItem = this.element.children( "li:first" ).children( ".ui-menu:first" );
294-
this._open( event, firstItem );
287+
if ( this.open ) {
288+
this._open( event, wrapItem );
289+
} else {
290+
wrapItem.removeAttr( "tabIndex")[0].focus();
291+
}
295292
}
296293
}
297294
});

0 commit comments

Comments
 (0)