diff options
Diffstat (limited to 'ui/jquery.ui.menu.js')
-rw-r--r-- | ui/jquery.ui.menu.js | 103 |
1 files changed, 88 insertions, 15 deletions
diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index cba42d17f..3915c3301 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -25,6 +25,7 @@ $.widget("ui.menu", { }, _create: function() { var self = this; + this.activeMenu = this.element; this.menuId = this.element.attr( "id" ) || "ui-menu-" + idIncrement++; this.element .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) @@ -48,7 +49,7 @@ $.widget("ui.menu", { return; } var target = $( event.target ).closest( ".ui-menu-item" ); - if ( target.length && target.parent()[0] === self.element[0] ) { + if ( target.length ) { self.focus( event, target ); } }) @@ -57,7 +58,7 @@ $.widget("ui.menu", { return; } var target = $( event.target ).closest( ".ui-menu-item" ); - if ( target.length && target.parent()[0] === self.element[0] ) { + if ( target.length ) { self.blur( event ); } }); @@ -69,25 +70,37 @@ $.widget("ui.menu", { } switch ( event.keyCode ) { case $.ui.keyCode.PAGE_UP: - self.previousPage(); + self.previousPage( event ); event.preventDefault(); event.stopImmediatePropagation(); break; case $.ui.keyCode.PAGE_DOWN: - self.nextPage(); + self.nextPage( event ); event.preventDefault(); event.stopImmediatePropagation(); break; case $.ui.keyCode.UP: - self.previous(); + self.previous( event ); event.preventDefault(); event.stopImmediatePropagation(); break; case $.ui.keyCode.DOWN: - self.next(); + self.next( event ); event.preventDefault(); event.stopImmediatePropagation(); break; + case $.ui.keyCode.LEFT: + if (self.left( event )) { + event.stopImmediatePropagation(); + } + event.preventDefault(); + break; + case $.ui.keyCode.RIGHT: + if (self.right( event )) { + event.stopImmediatePropagation(); + } + event.preventDefault(); + break; case $.ui.keyCode.ENTER: self.select(); event.preventDefault(); @@ -174,7 +187,9 @@ $.widget("ui.menu", { focus: function( event, item ) { var self = this; + this.blur(); + if ( this._hasScroll() ) { var borderTop = parseFloat( $.curCSS( this.element[0], "borderTopWidth", true) ) || 0, paddingtop = parseFloat( $.curCSS( this.element[0], "paddingTop", true) ) || 0, @@ -188,6 +203,7 @@ $.widget("ui.menu", { this.element.attr( "scrollTop", scroll + offset - elementHeight + itemHeight ); } } + this.active = item.first() .children( "a" ) .addClass( "ui-state-focus" ) @@ -198,6 +214,14 @@ $.widget("ui.menu", { // need to remove the attribute before adding it for the screenreader to pick up the change // see http://groups.google.com/group/jquery-a11y/msg/929e0c1e8c5efc8f this.element.removeAttr("aria-activedescendant").attr("aria-activedescendant", self.itemId); + + self._close(); + var nested = $(">ul", item); + if (nested.length && /^mouse/.test(event.type)) { + self._open(nested); + } + this.activeMenu = item.parent(); + this._trigger( "focus", event, { item: item } ); }, @@ -206,15 +230,59 @@ $.widget("ui.menu", { return; } - var self = this; this.active.children( "a" ).removeClass( "ui-state-focus" ); // remove only generated id - $( "#" + self.menuId + "-activedescendant" ).removeAttr( "id" ); + $( "#" + this.menuId + "-activedescendant" ).removeAttr( "id" ); this.element.removeAttr( "aria-activedescenant" ); this._trigger( "blur", event ); this.active = null; }, + _open: function(submenu) { + // TODO restrict to widget + //only one menu can have items open at a time. + //$(document).find(".ui-menu").not(submenu.parents()).hide().data("menu").blur(); + this.element.find(".ui-menu").not(submenu.parents()).hide(); + + var position = $.extend({}, { + of: this.active + }, $.type(this.options.position) == "function" + ? this.options.position(this.active) + : this.options.position + ); + + submenu.show().position(position); + }, + + closeAll: function() { + this.element.find("ul").hide(); + this.blur(); + this.activeMenu = this.element; + }, + + _close: function() { + this.active.parent().find("ul").hide(); + }, + + left: function(event) { + var newItem = this.active && this.active.parents("li").first(); + if (newItem && newItem.length) { + this.active.parent().hide(); + this.focus(event, newItem); + return true; + } + }, + + right: function(event) { + var newItem = this.active && this.active.children("ul").children("li").first(); + if (newItem && newItem.length) { + this._open(newItem.parent()); + var current = this.active; + this.focus(event, newItem); + return true; + } + }, + next: function(event) { this._move( "next", ".ui-menu-item", "first", event ); }, @@ -233,21 +301,21 @@ $.widget("ui.menu", { _move: function(direction, edge, filter, event) { if ( !this.active ) { - this.focus( event, this.element.children(edge)[filter]() ); + this.focus( event, this.activeMenu.children(edge)[filter]() ); return; } var next = this.active[ direction + "All" ]( ".ui-menu-item" ).eq( 0 ); if ( next.length ) { this.focus( event, next ); } else { - this.focus( event, this.element.children(edge)[filter]() ); + this.focus( event, this.activeMenu.children(edge)[filter]() ); } }, nextPage: function( event ) { if ( this._hasScroll() ) { if ( !this.active || this.last() ) { - this.focus( event, this.element.children( ".ui-menu-item" ).first() ); + this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); return; } var base = this.active.offset().top, @@ -260,7 +328,7 @@ $.widget("ui.menu", { this.focus( event, result ); } else { - this.focus( event, this.element.children( ".ui-menu-item" ) + this.focus( event, this.activeMenu.children( ".ui-menu-item" ) [ !this.active || this.last() ? "first" : "last" ]() ); } }, @@ -268,7 +336,7 @@ $.widget("ui.menu", { previousPage: function( event ) { if ( this._hasScroll() ) { if ( !this.active || this.first() ) { - this.focus( event, this.element.children( ".ui-menu-item" ).last() ); + this.focus( event, this.activeMenu.children( ".ui-menu-item" ).last() ); return; } @@ -282,7 +350,7 @@ $.widget("ui.menu", { this.focus( event, result ); } else { - this.focus( event, this.element.children( ".ui-menu-item" ) + this.focus( event, this.activeMenu.children( ".ui-menu-item" ) [ !this.active || this.first() ? ":last" : ":first" ]() ); } }, @@ -292,7 +360,12 @@ $.widget("ui.menu", { }, select: function( event ) { - this._trigger( "select", event, { item: this.active } ); + // save active reference before closeAll triggers blur + var ui = { + item: this.active + }; + this.closeAll(); + this._trigger( "select", event, ui ); } }); |