diff options
Diffstat (limited to 'ui/jquery.ui.menu.js')
-rw-r--r-- | ui/jquery.ui.menu.js | 116 |
1 files changed, 54 insertions, 62 deletions
diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index 0263cff65..83ea3c3c0 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -18,14 +18,13 @@ var idIncrement = 0; $.widget( "ui.menu", { version: "@VERSION", defaultElement: "<ul>", - delay: 150, + delay: 300, options: { menus: "ul", position: { my: "left top", at: "right top" - }, - trigger: null + } }, _create: function() { this.activeMenu = this.element; @@ -54,14 +53,13 @@ $.widget( "ui.menu", { }, "click .ui-menu-item:has(a)": function( event ) { event.stopImmediatePropagation(); - var target = $( event.currentTarget ); - // it's possible to click an item without hovering it (#7085) - if ( !this.active || ( this.active[ 0 ] !== target[ 0 ] ) ) { - this.focus( event, target ); - } this.select( event ); - // Redirect focus to the menu. - this.element.focus(); + // 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 ) { event.stopImmediatePropagation(); @@ -72,9 +70,21 @@ $.widget( "ui.menu", { }, "mouseleave": "collapseAll", "mouseleave .ui-menu": "collapseAll", - "mouseout .ui-menu-item": "blur", "focus": function( event ) { - this.focus( event, $( event.target ).children( ".ui-menu-item:first" ) ); + var firstItem = this.element.children( ".ui-menu-item" ).eq( 0 ); + if ( this._hasScroll() && !this.active ) { + var menu = this.element; + menu.children().each( function() { + var currentItem = $( this ); + if ( currentItem.offset().top - menu.offset().top >= 0 ) { + firstItem = currentItem; + return false; + } + }); + } else if ( this.active ) { + firstItem = this.active; + } + this.focus( event, firstItem ); }, blur: function( event ) { this._delay( function() { @@ -203,24 +213,10 @@ $.widget( "ui.menu", { } } }); - - if ( this.options.trigger ) { - this.element.popup({ - trigger: this.options.trigger, - managed: true, - focusPopup: $.proxy( function( event, ui ) { - this.focus( event, this.element.children( ".ui-menu-item" ).first() ); - this.element.focus( 1 ); - }, this) - }); - } }, _destroy: function() { //destroy (sub)menus - if ( this.options.trigger ) { - this.element.popup( "destroy" ); - } this.element .removeAttr( "aria-activedescendant" ) .find( ".ui-menu" ) @@ -321,12 +317,12 @@ $.widget( "ui.menu", { }, blur: function( event ) { + clearTimeout( this.timer ); + if ( !this.active ) { return; } - clearTimeout( this.timer ); - this.active.children( "a" ).removeClass( "ui-state-focus" ); this.active = null; @@ -370,20 +366,22 @@ $.widget( "ui.menu", { }, collapseAll: function( event, all ) { + clearTimeout( this.timer ); + 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" ) ); - // 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" ) ); - - // if we found no valid submenu ancestor, use the main menu to close all sub menus anyway - if ( !currentMenu.length ) { - currentMenu = this.element; - } + // if we found no valid submenu ancestor, use the main menu to close all sub menus anyway + if ( !currentMenu.length ) { + currentMenu = this.element; + } - this._close( currentMenu ); + this._close( currentMenu ); - this.blur( event ); - this.activeMenu = currentMenu; + this.blur( event ); + this.activeMenu = currentMenu; + }, this.delay); }, // With no arguments, closes the currently active menu - if nothing is active @@ -434,11 +432,11 @@ $.widget( "ui.menu", { this._move( "prev", "last", event ); }, - first: function() { + isFirstItem: function() { return this.active && !this.active.prevAll( ".ui-menu-item" ).length; }, - last: function() { + isLastItem: function() { return this.active && !this.active.nextAll( ".ui-menu-item" ).length; }, @@ -463,15 +461,14 @@ $.widget( "ui.menu", { }, nextPage: function( event ) { + if ( !this.active ) { + this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); + return; + } + if ( this.isLastItem() ) { + return; + } if ( this._hasScroll() ) { - if ( !this.active ) { - this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); - return; - } - if ( this.last() ) { - return; - } - var base = this.active.offset().top, height = this.element.height(), result; @@ -488,15 +485,14 @@ $.widget( "ui.menu", { }, previousPage: function( event ) { + if ( !this.active ) { + this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); + return; + } + if ( this.isFirstItem() ) { + return; + } if ( this._hasScroll() ) { - if ( !this.active ) { - this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); - return; - } - if ( this.first() ) { - return; - } - var base = this.active.offset().top, height = this.element.height(), result; @@ -512,7 +508,7 @@ $.widget( "ui.menu", { }, _hasScroll: function() { - return this.element.height() < this.element.prop( "scrollHeight" ); + return this.element.outerHeight() < this.element.prop( "scrollHeight" ); }, select: function( event ) { @@ -522,10 +518,6 @@ $.widget( "ui.menu", { item: this.active }; this.collapseAll( event, true ); - if ( this.options.trigger ) { - $( this.options.trigger ).focus( 1 ); - this.element.popup( "close" ); - } this._trigger( "select", event, ui ); } }); |