Skip to content

Commit 8a0df90

Browse files
committed
Accessibility / bug fixes for menubar
1 parent f89f0ca commit 8a0df90

File tree

1 file changed

+70
-18
lines changed

1 file changed

+70
-18
lines changed

tests/visual/menu/menubar.js

Lines changed: 70 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,28 @@ $.widget("ui.menubar", {
1313
},
1414
_create: function() {
1515
var self = this;
16-
var items = this.items = this.element.children("button, a");
16+
var items = this.items = this.element.children("li")
17+
.addClass("ui-menubar-item")
18+
.attr("role", "presentation")
19+
.children("button, a");
1720
items.slice(1).attr("tabIndex", -1);
1821
var o = this.options;
1922

20-
this.element.addClass('ui-menubar ui-widget-header ui-helper-clearfix');
23+
this.element.addClass('ui-menubar ui-widget-header ui-helper-clearfix').attr("role", "menubar");
2124
this._focusable(items);
2225
this._hoverable(items);
2326
items.next("ul").each(function(i, elm) {
2427
$(elm).menu({
2528
select: function(event, ui) {
26-
ui.item.parents("ul:last").hide()
27-
self.options.select.apply(this, arguments);
29+
ui.item.parents("ul.ui-menu:last").hide();
30+
self._trigger( "select", event, ui );
31+
self._close();
32+
$(event.target).prev().focus();
2833
}
29-
}).hide().keydown(function(event) {
34+
}).hide()
35+
.attr("aria-hidden", "true")
36+
.attr("aria-expanded", "false")
37+
.keydown(function(event) {
3038
var menu = $(this);
3139
if (menu.is(":hidden"))
3240
return;
@@ -40,9 +48,13 @@ $.widget("ui.menubar", {
4048
self._right(event);
4149
event.preventDefault();
4250
break;
51+
case $.ui.keyCode.TAB:
52+
self.open= false;
53+
break;
4354
};
4455
}).blur(function( event ) {
45-
self._close( event );
56+
if (!self.open)
57+
self._close( event );
4658
});
4759
});
4860
items.each(function() {
@@ -60,7 +72,7 @@ $.widget("ui.menubar", {
6072
self._close();
6173
return;
6274
}
63-
if (self.open || event.type == "click") {
75+
if ((self.open && event.type == "mouseenter") || event.type == "click") {
6476
self._open(event, menu);
6577
}
6678
})
@@ -83,6 +95,8 @@ $.widget("ui.menubar", {
8395
}
8496
})
8597
.addClass("ui-button ui-widget ui-button-text-only ui-menubar-link")
98+
.attr("role", "menuitem")
99+
.attr("aria-haspopup", "true")
86100
.wrapInner("<span class='ui-button-text'></span>");
87101

88102
if (o.menuIcon) {
@@ -108,15 +122,45 @@ $.widget("ui.menubar", {
108122
if (self.active.menu("left", event) !== true) {
109123
var active = self.active;
110124
self.active.blur();
125+
self._close( event );
111126
active.prev().focus();
112127
}
113128
}
114129
}
115130
});
116131
},
132+
_destroy : function() {
133+
var items = this.element.children("li")
134+
.removeClass("ui-menubar-item")
135+
.removeAttr("role", "presentation")
136+
.children("button, a");
137+
138+
this.element.removeClass('ui-menubar ui-widget-header ui-helper-clearfix').removeAttr("role", "menubar").unbind(".menubar");;
139+
items.unbind("focusin focusout click focus mouseenter keydown");
140+
141+
items
142+
.removeClass("ui-button ui-widget ui-button-text-only ui-menubar-link")
143+
.removeAttr("role", "menuitem")
144+
.removeAttr("aria-haspopup", "true")
145+
.children("span.ui-button-text").each(function(i, e) {
146+
var item = $(this);
147+
item.parent().html(item.html());
148+
});
149+
$(document).unbind(".menubar");
150+
151+
//TODO remove icons
152+
153+
this.element.find(":ui-menu").menu("destroy")
154+
.show()
155+
.removeAttr("aria-hidden", "true")
156+
.removeAttr("aria-expanded", "false")
157+
.removeAttr("tabindex")
158+
.unbind("keydown", "blur")
159+
;
160+
},
117161

118162
_close: function() {
119-
this.active.menu("closeAll").hide();
163+
this.active.menu("closeAll").hide().attr("aria-hidden", "true").attr("aria-expanded", "false");
120164
this.active.prev().removeClass("ui-state-active").removeAttr("tabIndex");
121165
this.active = null;
122166
var self = this;
@@ -133,7 +177,7 @@ $.widget("ui.menubar", {
133177
}
134178
// almost the same as _close above, but don't remove tabIndex
135179
if (this.active) {
136-
this.active.menu("closeAll").hide();
180+
this.active.menu("closeAll").hide().attr("aria-hidden", "true").attr("aria-expanded", "false");
137181
this.active.prev().removeClass("ui-state-active");
138182
}
139183
clearTimeout(this.timer);
@@ -144,44 +188,52 @@ $.widget("ui.menubar", {
144188
my: "left top",
145189
at: "left bottom",
146190
of: button
147-
}).focus();
191+
})
192+
.removeAttr("aria-hidden").attr("aria-expanded", "true")
193+
.menu("focus", event, menu.children("li").first())
194+
.focus();
195+
148196
},
149197

150198
_prev: function( event, button ) {
151199
button.attr("tabIndex", -1);
152-
var prev = button.prevAll( ".ui-button" ).eq( 0 );
200+
var prev = button.parent().prevAll("li").children( ".ui-button" ).eq( 0 );
153201
if (prev.length) {
154202
prev.removeAttr("tabIndex")[0].focus();
155203
} else {
156-
this.element.children(".ui-button:last").removeAttr("tabIndex")[0].focus();
204+
var lastItem = this.element.children("li:last").children(".ui-button:last");
205+
lastItem.removeAttr("tabIndex")[0].focus();
157206
}
158207
},
159208

160209
_next: function( event, button ) {
161210
button.attr("tabIndex", -1);
162-
var next = button.nextAll( ".ui-button" ).eq( 0 );
211+
var next = button.parent().nextAll("li").children( ".ui-button" ).eq( 0 );
163212
if (next.length) {
164213
next.removeAttr("tabIndex")[0].focus();
165214
} else {
166-
this.element.children(".ui-button:first").removeAttr("tabIndex")[0].focus();
215+
var firstItem = this.element.children("li:first").children(".ui-button:first");
216+
firstItem.removeAttr("tabIndex")[0].focus();
167217
}
168218
},
169219

170220
_left: function(event) {
171-
var prev = this.active.prevAll( ".ui-menu" ).eq( 0 );
221+
var prev = this.active.parent().prevAll("li:eq(0)").children( ".ui-menu" ).eq( 0 );
172222
if (prev.length) {
173223
this._open(event, prev);
174224
} else {
175-
this._open(event, this.element.children(".ui-menu:last"));
225+
var lastItem = this.element.children("li:last").children(".ui-menu:first");
226+
this._open(event, lastItem);
176227
}
177228
},
178229

179230
_right: function(event) {
180-
var next = this.active.nextAll( ".ui-menu" ).eq( 0 );
231+
var next = this.active.parent().nextAll("li:eq(0)").children( ".ui-menu" ).eq( 0 );
181232
if (next.length) {
182233
this._open(event, next);
183234
} else {
184-
this._open(event, this.element.children(".ui-menu:first"));
235+
var firstItem = this.element.children("li:first").children(".ui-menu:first");
236+
this._open(event, firstItem);
185237
}
186238
}
187239
});

0 commit comments

Comments
 (0)