From 79f1eea6dc874accae3447891783566337e97736 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Wed, 4 Apr 2012 10:52:41 +0200 Subject: Build: Filter filters for linting to exclude some to-be-rewritten ones. Fix lint in those remaining --- ui/jquery.ui.menu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui/jquery.ui.menu.js') diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index af22c19b0..526789e9e 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -189,7 +189,7 @@ $.widget( "ui.menu", { character = prev + character; } function escape( value ) { - return value.replace( /[-[\]{}()*+?.,\\^$|#\s]/g , "\\$&" ); + return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); } match = this.activeMenu.children( ".ui-menu-item" ).filter( function() { return new RegExp("^" + escape(character), "i") -- cgit v1.2.3 From 44ef35eb6f8aa33c2a2a9e4145e79df74d190d5c Mon Sep 17 00:00:00 2001 From: kborchers Date: Sat, 7 Apr 2012 15:38:27 -0500 Subject: Menu: Add dividers using empty list items --- tests/visual/menu/menu.html | 1 + themes/base/jquery.ui.menu.css | 1 + ui/jquery.ui.menu.js | 11 ++++++++--- 3 files changed, 10 insertions(+), 3 deletions(-) (limited to 'ui/jquery.ui.menu.js') diff --git a/tests/visual/menu/menu.html b/tests/visual/menu/menu.html index f88d1d542..d67083663 100644 --- a/tests/visual/menu/menu.html +++ b/tests/visual/menu/menu.html @@ -78,6 +78,7 @@
  • Ada
  • Adamsville
  • Addyston
  • +
  • Delphi
      diff --git a/themes/base/jquery.ui.menu.css b/themes/base/jquery.ui.menu.css index 4469e74d3..d53bdc6e0 100644 --- a/themes/base/jquery.ui.menu.css +++ b/themes/base/jquery.ui.menu.css @@ -10,6 +10,7 @@ .ui-menu { list-style:none; padding: 2px; margin: 0; display:block; outline: none; } .ui-menu .ui-menu { margin-top: -3px; position: absolute; } .ui-menu .ui-menu-item { margin: 0; padding: 0; zoom: 1; width: 100%; } +.ui-menu .ui-menu-divider { margin: 5px -2px 5px -2px; height: 0; font-size: 0; line-height: 0; } .ui-menu .ui-menu-item a { text-decoration: none; display: block; padding: 2px .4em; line-height: 1.5; zoom: 1; font-weight: normal; } .ui-menu .ui-menu-item a.ui-state-focus, .ui-menu .ui-menu-item a.ui-state-active { font-weight: normal; margin: -1px; } diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index 526789e9e..34a339157 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -260,7 +260,8 @@ $.widget( "ui.menu", { refresh: function() { // initialize nested menus - var menuId, + var menus, + menuId = this.menuId, submenus = this.element.find( this.options.menus + ":not( .ui-menu )" ) .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) .hide() @@ -271,8 +272,9 @@ $.widget( "ui.menu", { }); // don't refresh list items that are already adapted - menuId = this.menuId; - submenus.add( this.element ).children( ":not( .ui-menu-item ):has( a )" ) + menus = submenus.add( this.element ); + + menus.children( ":not( .ui-menu-item ):has( a )" ) .addClass( "ui-menu-item" ) .attr( "role", "presentation" ) .children( "a" ) @@ -283,6 +285,9 @@ $.widget( "ui.menu", { return menuId + "-" + i; }); + // initialize unlinked menu-items as dividers + menus.children( ":not( .ui-menu-item )" ).addClass( "ui-widget-content ui-menu-divider" ); + submenus.each( function() { var menu = $( this ), item = menu.prev( "a" ); -- cgit v1.2.3 From 92c74818ff73ce6534a34fb3a83a0cb928c4bb3f Mon Sep 17 00:00:00 2001 From: Scott González Date: Tue, 10 Apr 2012 08:39:18 -0400 Subject: Menu: Cleanup. --- ui/jquery.ui.menu.js | 343 ++++++++++++++++++++++++++------------------------- 1 file changed, 178 insertions(+), 165 deletions(-) (limited to 'ui/jquery.ui.menu.js') diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index 34a339157..6982da3c3 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -41,18 +41,21 @@ $.widget( "ui.menu", { .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) .attr({ id: this.menuId, - role: "menu" + role: "menu", + tabIndex: 0 }) // need to catch all clicks on disabled menu // not possible through _bind - .bind( "click.menu", $.proxy( function( event ) { + .bind( "click.menu", $.proxy(function( event ) { if ( this.options.disabled ) { event.preventDefault(); } - }, this)); + }, this )); + if ( this.options.disabled ) { this.element.addClass( "ui-state-disabled" ); } + this._bind({ // Prevent focus from sticking to links inside menu after clicking // them (focus should always stay on UL during navigation). @@ -64,21 +67,22 @@ $.widget( "ui.menu", { }, "click .ui-menu-item:has(a)": function( event ) { event.stopImmediatePropagation(); - //Don't select disabled menu items + // Don't select disabled menu items if ( !$( event.target ).closest( ".ui-menu-item" ).is( ".ui-state-disabled" ) ) { this.select( event ); // Redirect focus to the menu with a delay for firefox - this._delay( function() { + this._delay(function() { if ( !this.element.is(":focus") ) { this.element.focus(); } - }, 20); + }, 20 ); } }, "mouseover .ui-menu-item": function( event ) { event.stopImmediatePropagation(); var target = $( event.currentTarget ); - // Remove ui-state-active class from siblings of the newly focused menu item to avoid a jump caused by adjacent elements both having a class with a border + // Remove ui-state-active class from siblings of the newly focused menu item + // to avoid a jump caused by adjacent elements both having a class with a border target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); this.focus( event, target ); }, @@ -88,7 +92,7 @@ $.widget( "ui.menu", { var menu = this.element, firstItem = menu.children( ".ui-menu-item" ).not( ".ui-state-disabled" ).eq( 0 ); if ( this._hasScroll() && !this.active ) { - menu.children().each( function() { + menu.children().each(function() { var currentItem = $( this ); if ( currentItem.offset().top - menu.offset().top >= 0 ) { firstItem = currentItem; @@ -101,125 +105,17 @@ $.widget( "ui.menu", { this.focus( event, firstItem ); }, blur: function( event ) { - this._delay( function() { - if ( ! $.contains( this.element[0], this.document[0].activeElement ) ) { + this._delay(function() { + if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { this.collapseAll( event ); } - }, 0); - } + }); + }, + "keydown": "_keydown" }); this.refresh(); - this.element.attr( "tabIndex", 0 ); - this._bind({ - "keydown": function( event ) { - switch ( event.keyCode ) { - case $.ui.keyCode.PAGE_UP: - this.previousPage( event ); - event.preventDefault(); - event.stopImmediatePropagation(); - break; - case $.ui.keyCode.PAGE_DOWN: - this.nextPage( event ); - event.preventDefault(); - event.stopImmediatePropagation(); - break; - case $.ui.keyCode.HOME: - this._move( "first", "first", event ); - event.preventDefault(); - event.stopImmediatePropagation(); - break; - case $.ui.keyCode.END: - this._move( "last", "last", event ); - event.preventDefault(); - event.stopImmediatePropagation(); - break; - case $.ui.keyCode.UP: - this.previous( event ); - event.preventDefault(); - event.stopImmediatePropagation(); - break; - case $.ui.keyCode.DOWN: - this.next( event ); - event.preventDefault(); - event.stopImmediatePropagation(); - break; - case $.ui.keyCode.LEFT: - if (this.collapse( event )) { - event.stopImmediatePropagation(); - } - event.preventDefault(); - break; - case $.ui.keyCode.RIGHT: - if (this.expand( event )) { - event.stopImmediatePropagation(); - } - event.preventDefault(); - break; - case $.ui.keyCode.ENTER: - if ( this.active.children( "a[aria-haspopup='true']" ).length ) { - if ( this.expand( event ) ) { - event.stopImmediatePropagation(); - } - } - else { - this.select( event ); - event.stopImmediatePropagation(); - } - event.preventDefault(); - break; - case $.ui.keyCode.ESCAPE: - if ( this.collapse( event ) ) { - event.stopImmediatePropagation(); - } - event.preventDefault(); - break; - default: - event.stopPropagation(); - clearTimeout( this.filterTimer ); - var match, - prev = this.previousFilter || "", - character = String.fromCharCode( event.keyCode ), - skip = false; - - if (character === prev) { - skip = true; - } else { - character = prev + character; - } - function escape( value ) { - return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); - } - match = this.activeMenu.children( ".ui-menu-item" ).filter( function() { - return new RegExp("^" + escape(character), "i") - .test( $( this ).children( "a" ).text() ); - }); - match = skip && match.index(this.active.next()) !== -1 ? this.active.nextAll(".ui-menu-item") : match; - if ( !match.length ) { - character = String.fromCharCode(event.keyCode); - match = this.activeMenu.children(".ui-menu-item").filter( function() { - return new RegExp("^" + escape(character), "i") - .test( $( this ).children( "a" ).text() ); - }); - } - if ( match.length ) { - this.focus( event, match ); - if (match.length > 1) { - this.previousFilter = character; - this.filterTimer = this._delay( function() { - delete this.previousFilter; - }, 1000 ); - } else { - delete this.previousFilter; - } - } else { - delete this.previousFilter; - } - } - } - }); - this._bind( this.document, { click: function( event ) { if ( !$( event.target ).closest( ".ui-menu" ).length ) { @@ -230,39 +126,146 @@ $.widget( "ui.menu", { }, _destroy: function() { - //destroy (sub)menus + // destroy (sub)menus this.element .removeAttr( "aria-activedescendant" ) - .find( ".ui-menu" ) - .andSelf() - .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) - .removeAttr( "role" ) - .removeAttr( "tabIndex" ) - .removeAttr( "aria-labelledby" ) - .removeAttr( "aria-expanded" ) - .removeAttr( "aria-hidden" ) - .show(); - - //destroy menu items + .find( ".ui-menu" ).andSelf() + .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) + .removeAttr( "role" ) + .removeAttr( "tabIndex" ) + .removeAttr( "aria-labelledby" ) + .removeAttr( "aria-expanded" ) + .removeAttr( "aria-hidden" ) + .show(); + + // destroy menu items this.element.find( ".ui-menu-item" ) .unbind( ".menu" ) .removeClass( "ui-menu-item" ) .removeAttr( "role" ) .children( "a" ) - .removeClass( "ui-corner-all ui-state-hover" ) - .removeAttr( "tabIndex" ) - .removeAttr( "role" ) - .removeAttr( "aria-haspopup" ) - .removeAttr( "id" ) - .children( ".ui-icon" ) - .remove(); + .removeClass( "ui-corner-all ui-state-hover" ) + .removeAttr( "tabIndex" ) + .removeAttr( "role" ) + .removeAttr( "aria-haspopup" ) + .removeAttr( "id" ) + .children( ".ui-icon" ) + .remove(); + }, + + _keydown: function( event ) { + switch ( event.keyCode ) { + case $.ui.keyCode.PAGE_UP: + this.previousPage( event ); + event.preventDefault(); + event.stopImmediatePropagation(); + break; + case $.ui.keyCode.PAGE_DOWN: + this.nextPage( event ); + event.preventDefault(); + event.stopImmediatePropagation(); + break; + case $.ui.keyCode.HOME: + this._move( "first", "first", event ); + event.preventDefault(); + event.stopImmediatePropagation(); + break; + case $.ui.keyCode.END: + this._move( "last", "last", event ); + event.preventDefault(); + event.stopImmediatePropagation(); + break; + case $.ui.keyCode.UP: + this.previous( event ); + event.preventDefault(); + event.stopImmediatePropagation(); + break; + case $.ui.keyCode.DOWN: + this.next( event ); + event.preventDefault(); + event.stopImmediatePropagation(); + break; + case $.ui.keyCode.LEFT: + if (this.collapse( event )) { + event.stopImmediatePropagation(); + } + event.preventDefault(); + break; + case $.ui.keyCode.RIGHT: + if (this.expand( event )) { + event.stopImmediatePropagation(); + } + event.preventDefault(); + break; + case $.ui.keyCode.ENTER: + if ( this.active.children( "a[aria-haspopup='true']" ).length ) { + if ( this.expand( event ) ) { + event.stopImmediatePropagation(); + } + } + else { + this.select( event ); + event.stopImmediatePropagation(); + } + event.preventDefault(); + break; + case $.ui.keyCode.ESCAPE: + if ( this.collapse( event ) ) { + event.stopImmediatePropagation(); + } + event.preventDefault(); + break; + default: + event.stopPropagation(); + clearTimeout( this.filterTimer ); + var match, + prev = this.previousFilter || "", + character = String.fromCharCode( event.keyCode ), + skip = false; + + if ( character === prev ) { + skip = true; + } else { + character = prev + character; + } + function escape( value ) { + return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); + } + match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { + return new RegExp( "^" + escape( character ), "i" ) + .test( $( this ).children( "a" ).text() ); + }); + match = skip && match.index(this.active.next()) !== -1 ? + this.active.nextAll(".ui-menu-item") : + match; + if ( !match.length ) { + character = String.fromCharCode(event.keyCode); + match = this.activeMenu.children(".ui-menu-item").filter(function() { + return new RegExp( "^" + escape(character), "i" ) + .test( $( this ).children( "a" ).text() ); + }); + } + if ( match.length ) { + this.focus( event, match ); + if ( match.length > 1 ) { + this.previousFilter = character; + this.filterTimer = this._delay(function() { + delete this.previousFilter; + }, 1000 ); + } else { + delete this.previousFilter; + } + } else { + delete this.previousFilter; + } + } }, refresh: function() { // initialize nested menus var menus, menuId = this.menuId, - submenus = this.element.find( this.options.menus + ":not( .ui-menu )" ) + submenus = this.element.find( this.options.menus + ":not(.ui-menu)" ) .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) .hide() .attr({ @@ -286,9 +289,9 @@ $.widget( "ui.menu", { }); // initialize unlinked menu-items as dividers - menus.children( ":not( .ui-menu-item )" ).addClass( "ui-widget-content ui-menu-divider" ); + menus.children( ":not(.ui-menu-item)" ).addClass( "ui-widget-content ui-menu-divider" ); - submenus.each( function() { + submenus.each(function() { var menu = $( this ), item = menu.prev( "a" ); @@ -317,16 +320,16 @@ $.widget( "ui.menu", { } } - this.active = item.first() - .children( "a" ) + this.active = item.first(); + this.element.attr( "aria-activedescendant", + this.active.children( "a" ) .addClass( "ui-state-focus" ) - .end(); - this.element.attr( "aria-activedescendant", this.active.children( "a" ).attr( "id" ) ); + .attr( "id" ) ); // highlight active parent menu item, if any this.active.parent().closest( ".ui-menu-item" ).children( "a:first" ).addClass( "ui-state-active" ); - this.timer = this._delay( function() { + this.timer = this._delay(function() { this._close(); }, this.delay ); @@ -361,7 +364,7 @@ $.widget( "ui.menu", { return; } - this.timer = this._delay( function() { + this.timer = this._delay(function() { this._close(); this._open( submenu ); }, this.delay ); @@ -369,20 +372,19 @@ $.widget( "ui.menu", { _open: function( submenu ) { clearTimeout( this.timer ); - this.element - .find( ".ui-menu" ) - .not( submenu.parents() ) + this.element.find( ".ui-menu" ).not( submenu.parents() ) .hide() .attr( "aria-hidden", "true" ); - var position = $.extend({}, { + var position = $.extend( {}, { of: this.active }, $.type(this.options.position) === "function" ? this.options.position(this.active) : this.options.position ); - submenu.show() + submenu + .show() .removeAttr( "aria-hidden" ) .attr( "aria-expanded", "true" ) .position( position ); @@ -390,7 +392,7 @@ $.widget( "ui.menu", { collapseAll: function( event, all ) { clearTimeout( this.timer ); - this.timer = this._delay( function() { + this.timer = this._delay(function() { // if we were passed an event, look for the submenu that contains the event var currentMenu = all ? this.element : $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); @@ -404,7 +406,7 @@ $.widget( "ui.menu", { this.blur( event ); this.activeMenu = currentMenu; - }, this.delay); + }, this.delay ); }, // With no arguments, closes the currently active menu - if nothing is active @@ -421,11 +423,12 @@ $.widget( "ui.menu", { .attr( "aria-expanded", "false" ) .end() .find( "a.ui-state-active" ) - .removeClass( "ui-state-active" ); + .removeClass( "ui-state-active" ); }, collapse: function( event ) { - var newItem = this.active && this.active.parent().closest( ".ui-menu-item", this.element ); + var newItem = this.active && + this.active.parent().closest( ".ui-menu-item", this.element ); if ( newItem && newItem.length ) { this._close(); this.focus( event, newItem ); @@ -434,13 +437,18 @@ $.widget( "ui.menu", { }, expand: function( event ) { - var newItem = this.active && this.active.children( ".ui-menu " ).children( ".ui-menu-item" ).not( ".ui-state-disabled" ).first(); + var newItem = this.active && + this.active + .children( ".ui-menu " ) + .children( ".ui-menu-item" ) + .not( ".ui-state-disabled" ) + .first(); if ( newItem && newItem.length ) { this._open( newItem.parent() ); //timeout so Firefox will not hide activedescendant change in expanding submenu from AT - this._delay( function() { + this._delay(function() { this.focus( event, newItem ); }, 20 ); return true; @@ -467,9 +475,15 @@ $.widget( "ui.menu", { var next; if ( this.active ) { if ( direction === "first" || direction === "last" ) { - next = this.active[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ).not( ".ui-state-disabled" ).eq( -1 ); + next = this.active + [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) + .not( ".ui-state-disabled" ) + .eq( -1 ); } else { - next = this.active[ direction + "All" ]( ".ui-menu-item" ).not( ".ui-state-disabled" ).eq( 0 ); + next = this.active + [ direction + "All" ]( ".ui-menu-item" ) + .not( ".ui-state-disabled" ) + .eq( 0 ); } } if ( !next || !next.length || !this.active ) { @@ -494,7 +508,7 @@ $.widget( "ui.menu", { var base = this.active.offset().top, height = this.element.height(), result; - this.active.nextAll( ".ui-menu-item" ).not( ".ui-state-disabled" ).each( function() { + this.active.nextAll( ".ui-menu-item" ).not( ".ui-state-disabled" ).each(function() { result = $( this ); return $( this ).offset().top - base - height < 0; }); @@ -518,7 +532,7 @@ $.widget( "ui.menu", { var base = this.active.offset().top, height = this.element.height(), result; - this.active.prevAll( ".ui-menu-item" ).not( ".ui-state-disabled" ).each( function() { + this.active.prevAll( ".ui-menu-item" ).not( ".ui-state-disabled" ).each(function() { result = $( this ); return $(this).offset().top - base + height > 0; }); @@ -534,7 +548,6 @@ $.widget( "ui.menu", { }, select: function( event ) { - // save active reference before collapseAll triggers blur var ui = { item: this.active -- cgit v1.2.3 From 26d6952bd2b81de2ad2adb0bb77c1be6f2d717c2 Mon Sep 17 00:00:00 2001 From: kborchers Date: Sat, 14 Apr 2012 15:33:48 -0400 Subject: Menu: Remove most event.stopImmediatePropagation() to allow proper event bubbling --- ui/jquery.ui.menu.js | 61 +++++++++++++++++++++++----------------------------- 1 file changed, 27 insertions(+), 34 deletions(-) (limited to 'ui/jquery.ui.menu.js') diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index 6982da3c3..01b7d0992 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -13,7 +13,8 @@ */ (function($) { -var idIncrement = 0; +var idIncrement = 0, + currentEventTarget; $.widget( "ui.menu", { version: "@VERSION", @@ -66,16 +67,22 @@ $.widget( "ui.menu", { event.preventDefault(); }, "click .ui-menu-item:has(a)": function( event ) { - event.stopImmediatePropagation(); - // Don't select disabled menu items - if ( !$( event.target ).closest( ".ui-menu-item" ).is( ".ui-state-disabled" ) ) { - this.select( event ); - // Redirect focus to the menu with a delay for firefox - this._delay(function() { - if ( !this.element.is(":focus") ) { - this.element.focus(); - } - }, 20 ); + var target = $( event.target ); + if ( target[0] != currentEventTarget ) { + currentEventTarget = target[0]; + target.one( "click", function( event ) { + currentEventTarget = ""; + }); + // Don't select disabled menu items + if ( !target.closest( ".ui-menu-item" ).is( ".ui-state-disabled" ) ) { + this.select( event ); + // Redirect focus to the menu with a delay for firefox + this._delay(function() { + if ( !this.element.is(":focus") ) { + this.element.focus(); + } + }, 20 ); + } } }, "mouseover .ui-menu-item": function( event ) { @@ -158,65 +165,49 @@ $.widget( "ui.menu", { case $.ui.keyCode.PAGE_UP: this.previousPage( event ); event.preventDefault(); - event.stopImmediatePropagation(); break; case $.ui.keyCode.PAGE_DOWN: this.nextPage( event ); event.preventDefault(); - event.stopImmediatePropagation(); break; case $.ui.keyCode.HOME: this._move( "first", "first", event ); event.preventDefault(); - event.stopImmediatePropagation(); break; case $.ui.keyCode.END: this._move( "last", "last", event ); event.preventDefault(); - event.stopImmediatePropagation(); break; case $.ui.keyCode.UP: this.previous( event ); event.preventDefault(); - event.stopImmediatePropagation(); break; case $.ui.keyCode.DOWN: this.next( event ); event.preventDefault(); - event.stopImmediatePropagation(); break; case $.ui.keyCode.LEFT: - if (this.collapse( event )) { - event.stopImmediatePropagation(); - } + this.collapse( event ); event.preventDefault(); break; case $.ui.keyCode.RIGHT: - if (this.expand( event )) { - event.stopImmediatePropagation(); - } + this.expand( event ); event.preventDefault(); break; case $.ui.keyCode.ENTER: if ( this.active.children( "a[aria-haspopup='true']" ).length ) { - if ( this.expand( event ) ) { - event.stopImmediatePropagation(); - } + this.expand( event ); } else { this.select( event ); - event.stopImmediatePropagation(); } event.preventDefault(); break; case $.ui.keyCode.ESCAPE: - if ( this.collapse( event ) ) { - event.stopImmediatePropagation(); - } + this.collapse( event ); event.preventDefault(); break; default: - event.stopPropagation(); clearTimeout( this.filterTimer ); var match, prev = this.previousFilter || "", @@ -303,7 +294,7 @@ $.widget( "ui.menu", { focus: function( event, item ) { var nested, borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; - this.blur( event ); + this.blur( event, event.type == "focus" ); if ( this._hasScroll() ) { borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; @@ -342,8 +333,10 @@ $.widget( "ui.menu", { this._trigger( "focus", event, { item: item } ); }, - blur: function( event ) { - clearTimeout( this.timer ); + blur: function( event, fromFocus ) { + if ( !fromFocus ) { + clearTimeout( this.timer ); + } if ( !this.active ) { return; -- cgit v1.2.3 From e2a6cdd5256e0befe8f75590499d501141a46463 Mon Sep 17 00:00:00 2001 From: kborchers Date: Sat, 14 Apr 2012 16:00:19 -0400 Subject: Menu: Check that the event object is defined before checking type --- ui/jquery.ui.menu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui/jquery.ui.menu.js') diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index 01b7d0992..5e6b335ba 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -294,7 +294,7 @@ $.widget( "ui.menu", { focus: function( event, item ) { var nested, borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; - this.blur( event, event.type == "focus" ); + this.blur( event, event && event.type == "focus" ); if ( this._hasScroll() ) { borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; -- cgit v1.2.3 From 9a6392033a0ee2b79999777a5e279e6aa3cfb12a Mon Sep 17 00:00:00 2001 From: kborchers Date: Mon, 16 Apr 2012 07:02:28 -0500 Subject: Menu: Add aria-disabled attribute to disabled items, namespace and cleanup the currentEventTarget click event --- ui/jquery.ui.menu.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'ui/jquery.ui.menu.js') diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index 5e6b335ba..ec7a69754 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -14,7 +14,7 @@ (function($) { var idIncrement = 0, - currentEventTarget; + currentEventTarget = null; $.widget( "ui.menu", { version: "@VERSION", @@ -54,7 +54,9 @@ $.widget( "ui.menu", { }, this )); if ( this.options.disabled ) { - this.element.addClass( "ui-state-disabled" ); + this.element + .addClass( "ui-state-disabled" ) + .attr( "aria-disabled", "true" ); } this._bind({ @@ -70,8 +72,8 @@ $.widget( "ui.menu", { var target = $( event.target ); if ( target[0] != currentEventTarget ) { currentEventTarget = target[0]; - target.one( "click", function( event ) { - currentEventTarget = ""; + target.one( "click.menu", function( event ) { + currentEventTarget = null; }); // Don't select disabled menu items if ( !target.closest( ".ui-menu-item" ).is( ".ui-state-disabled" ) ) { @@ -158,6 +160,9 @@ $.widget( "ui.menu", { .removeAttr( "id" ) .children( ".ui-icon" ) .remove(); + + // unbind currentEventTarget click event handler + $( currentEventTarget ).unbind( "click.menu" ); }, _keydown: function( event ) { @@ -282,6 +287,9 @@ $.widget( "ui.menu", { // initialize unlinked menu-items as dividers menus.children( ":not(.ui-menu-item)" ).addClass( "ui-widget-content ui-menu-divider" ); + // add aria-disabled attribut to any disabled menu item + menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); + submenus.each(function() { var menu = $( this ), item = menu.prev( "a" ); -- cgit v1.2.3 From fac809f9e5e30cb46053710970fb2a0e855ce9e1 Mon Sep 17 00:00:00 2001 From: kborchers Date: Mon, 16 Apr 2012 07:05:02 -0500 Subject: Menu: Fixed typo in comment --- ui/jquery.ui.menu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui/jquery.ui.menu.js') diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index ec7a69754..dd099395d 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -287,7 +287,7 @@ $.widget( "ui.menu", { // initialize unlinked menu-items as dividers menus.children( ":not(.ui-menu-item)" ).addClass( "ui-widget-content ui-menu-divider" ); - // add aria-disabled attribut to any disabled menu item + // add aria-disabled attribute to any disabled menu item menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); submenus.each(function() { -- cgit v1.2.3 From 1ce42f4328167826e9868ee1bf21f96317927dec Mon Sep 17 00:00:00 2001 From: kborchers Date: Mon, 16 Apr 2012 23:30:33 -0500 Subject: Menu: Modified interactions to allow keyboard navigation to disabled items so that they are announced by screen readers but prevent selection of and navigation to sub-menus of disabled items --- tests/visual/menu/menu.html | 2 +- ui/jquery.ui.menu.js | 30 +++++++++++++----------------- 2 files changed, 14 insertions(+), 18 deletions(-) (limited to 'ui/jquery.ui.menu.js') diff --git a/tests/visual/menu/menu.html b/tests/visual/menu/menu.html index d67083663..e62e18ae5 100644 --- a/tests/visual/menu/menu.html +++ b/tests/visual/menu/menu.html @@ -118,7 +118,7 @@
    • Ada
    • Adamsville
    • Addyston
    • -
    • +
    • Delphi
      • Ada
      • diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index dd099395d..0e70f6774 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -99,7 +99,7 @@ $.widget( "ui.menu", { "mouseleave .ui-menu": "collapseAll", "focus": function( event ) { var menu = this.element, - firstItem = menu.children( ".ui-menu-item" ).not( ".ui-state-disabled" ).eq( 0 ); + firstItem = menu.children( ".ui-menu-item" ).eq( 0 ); if ( this._hasScroll() && !this.active ) { menu.children().each(function() { var currentItem = $( this ); @@ -196,15 +196,17 @@ $.widget( "ui.menu", { event.preventDefault(); break; case $.ui.keyCode.RIGHT: - this.expand( event ); + !this.active.is(".ui-state-disabled") && this.expand( event ); event.preventDefault(); break; case $.ui.keyCode.ENTER: - if ( this.active.children( "a[aria-haspopup='true']" ).length ) { - this.expand( event ); - } - else { - this.select( event ); + if ( !this.active.is(".ui-state-disabled") ) { + if ( this.active.children( "a[aria-haspopup='true']" ).length ) { + this.expand( event ); + } + else { + this.select( event ); + } } event.preventDefault(); break; @@ -442,7 +444,6 @@ $.widget( "ui.menu", { this.active .children( ".ui-menu " ) .children( ".ui-menu-item" ) - .not( ".ui-state-disabled" ) .first(); if ( newItem && newItem.length ) { @@ -478,12 +479,10 @@ $.widget( "ui.menu", { if ( direction === "first" || direction === "last" ) { next = this.active [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) - .not( ".ui-state-disabled" ) .eq( -1 ); } else { next = this.active [ direction + "All" ]( ".ui-menu-item" ) - .not( ".ui-state-disabled" ) .eq( 0 ); } } @@ -492,9 +491,6 @@ $.widget( "ui.menu", { } this.focus( event, next ); - if ( next.is( ".ui-state-disabled" ) ) { - this._move( direction, filter, event ); - } }, nextPage: function( event ) { @@ -509,14 +505,14 @@ $.widget( "ui.menu", { var base = this.active.offset().top, height = this.element.height(), result; - this.active.nextAll( ".ui-menu-item" ).not( ".ui-state-disabled" ).each(function() { + this.active.nextAll( ".ui-menu-item" ).each(function() { result = $( this ); return $( this ).offset().top - base - height < 0; }); this.focus( event, result ); } else { - this.focus( event, this.activeMenu.children( ".ui-menu-item" ).not( ".ui-state-disabled" ) + this.focus( event, this.activeMenu.children( ".ui-menu-item" ) [ !this.active ? "first" : "last" ]() ); } }, @@ -533,14 +529,14 @@ $.widget( "ui.menu", { var base = this.active.offset().top, height = this.element.height(), result; - this.active.prevAll( ".ui-menu-item" ).not( ".ui-state-disabled" ).each(function() { + this.active.prevAll( ".ui-menu-item" ).each(function() { result = $( this ); return $(this).offset().top - base + height > 0; }); this.focus( event, result ); } else { - this.focus( event, this.activeMenu.children( ".ui-menu-item" ).not( ".ui-state-disabled" ).first() ); + this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); } }, -- cgit v1.2.3 From 49f85509fe17b99ce0470bf011c49e03c338fb2c Mon Sep 17 00:00:00 2001 From: kborchers Date: Wed, 18 Apr 2012 21:30:07 -0500 Subject: Menu: Whitespace --- ui/jquery.ui.menu.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'ui/jquery.ui.menu.js') diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index 0e70f6774..b991b30e8 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -196,15 +196,16 @@ $.widget( "ui.menu", { event.preventDefault(); break; case $.ui.keyCode.RIGHT: - !this.active.is(".ui-state-disabled") && this.expand( event ); + if ( !this.active.is( ".ui-state-disabled" ) ) { + this.expand( event ); + } event.preventDefault(); break; case $.ui.keyCode.ENTER: - if ( !this.active.is(".ui-state-disabled") ) { + if ( !this.active.is( ".ui-state-disabled" ) ) { if ( this.active.children( "a[aria-haspopup='true']" ).length ) { this.expand( event ); - } - else { + } else { this.select( event ); } } -- cgit v1.2.3 From 72a0f5c5129b77c6e06c9936d290e89bd35a9eaa Mon Sep 17 00:00:00 2001 From: Scott González Date: Thu, 19 Apr 2012 10:29:55 -0400 Subject: Menu: Lint. --- ui/jquery.ui.menu.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ui/jquery.ui.menu.js') diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index b991b30e8..abc759f1a 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -70,7 +70,7 @@ $.widget( "ui.menu", { }, "click .ui-menu-item:has(a)": function( event ) { var target = $( event.target ); - if ( target[0] != currentEventTarget ) { + if ( target[0] !== currentEventTarget ) { currentEventTarget = target[0]; target.one( "click.menu", function( event ) { currentEventTarget = null; @@ -305,7 +305,7 @@ $.widget( "ui.menu", { focus: function( event, item ) { var nested, borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; - this.blur( event, event && event.type == "focus" ); + this.blur( event, event && event.type === "focus" ); if ( this._hasScroll() ) { borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; -- cgit v1.2.3 From 00306d6bbdf6c12ae1499ec090ef62dfd1a59ec5 Mon Sep 17 00:00:00 2001 From: kborchers Date: Thu, 19 Apr 2012 23:49:33 -0500 Subject: Menu: Bind to mouseenter instead of mouseover to avoid use of stopImmediatePropagation --- ui/jquery.ui.menu.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'ui/jquery.ui.menu.js') diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index abc759f1a..bcefd5822 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -87,8 +87,7 @@ $.widget( "ui.menu", { } } }, - "mouseover .ui-menu-item": function( event ) { - event.stopImmediatePropagation(); + "mouseenter .ui-menu-item": function( event ) { var target = $( event.currentTarget ); // Remove ui-state-active class from siblings of the newly focused menu item // to avoid a jump caused by adjacent elements both having a class with a border -- cgit v1.2.3 From 97cb7deceeeeac93e583044886d8ed1966d8baf5 Mon Sep 17 00:00:00 2001 From: kborchers Date: Tue, 8 May 2012 23:53:14 -0500 Subject: Menu: Remove close delay for keyboard interaction to fix an issue with properly adding and removing ui-state-active class during quick navigation through submenus --- ui/jquery.ui.menu.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'ui/jquery.ui.menu.js') diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index bcefd5822..8956d6404 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -330,9 +330,13 @@ $.widget( "ui.menu", { // highlight active parent menu item, if any this.active.parent().closest( ".ui-menu-item" ).children( "a:first" ).addClass( "ui-state-active" ); - this.timer = this._delay(function() { - this._close(); - }, this.delay ); + if ( event.type === "keydown" ) { + this._close(); + } else { + this.timer = this._delay(function() { + this._close(); + }, this.delay ); + } nested = $( "> .ui-menu", item ); if ( nested.length && ( /^mouse/.test( event.type ) ) ) { -- cgit v1.2.3 From 4e2850039173819eb612d4d2a7cebe155f0e94cc Mon Sep 17 00:00:00 2001 From: kborchers Date: Tue, 8 May 2012 23:57:56 -0500 Subject: Menu: Whitespace --- ui/jquery.ui.menu.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'ui/jquery.ui.menu.js') diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index 8956d6404..7704521fb 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -331,12 +331,12 @@ $.widget( "ui.menu", { this.active.parent().closest( ".ui-menu-item" ).children( "a:first" ).addClass( "ui-state-active" ); if ( event.type === "keydown" ) { - this._close(); - } else { - this.timer = this._delay(function() { + this._close(); + } else { + this.timer = this._delay(function() { this._close(); }, this.delay ); - } + } nested = $( "> .ui-menu", item ); if ( nested.length && ( /^mouse/.test( event.type ) ) ) { -- cgit v1.2.3