2014-10-07 17:28:24 +02:00
|
|
|
/*!
|
2015-03-11 16:12:27 +01:00
|
|
|
* jQuery UI Menu 1.11.4
|
2014-10-07 17:28:24 +02:00
|
|
|
* http://jqueryui.com
|
|
|
|
*
|
2015-02-27 11:21:26 +01:00
|
|
|
* Copyright jQuery Foundation and other contributors
|
2014-10-07 17:28:24 +02:00
|
|
|
* Released under the MIT license.
|
|
|
|
* http://jquery.org/license
|
|
|
|
*
|
|
|
|
* http://api.jqueryui.com/menu/
|
|
|
|
*/
|
2015-11-05 18:47:30 +01:00
|
|
|
!function(a){"function"==typeof define&&define.amd?
|
|
|
|
// AMD. Register as an anonymous module.
|
|
|
|
define(["jquery","./core","./widget","./position"],a):
|
|
|
|
// Browser globals
|
|
|
|
a(jQuery)}(function(a){return a.widget("ui.menu",{version:"1.11.4",defaultElement:"<ul>",delay:300,options:{icons:{submenu:"ui-icon-carat-1-e"},items:"> *",menus:"ul",position:{my:"left-1 top",at:"right top"},role:"menu",
|
|
|
|
// callbacks
|
|
|
|
blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,
|
|
|
|
// Flag used to prevent firing of the click handler
|
|
|
|
// as the event bubbles up through nested menus
|
|
|
|
this.mouseHandled=!1,this.element.uniqueId().addClass("ui-menu ui-widget ui-widget-content").toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length).attr({role:this.options.role,tabIndex:0}),this.options.disabled&&this.element.addClass("ui-state-disabled").attr("aria-disabled","true"),this._on({
|
|
|
|
// Prevent focus from sticking to links inside menu after clicking
|
|
|
|
// them (focus should always stay on UL during navigation).
|
|
|
|
"mousedown .ui-menu-item":function(a){a.preventDefault()},"click .ui-menu-item":function(b){var c=a(b.target);!this.mouseHandled&&c.not(".ui-state-disabled").length&&(this.select(b),
|
|
|
|
// Only set the mouseHandled flag if the event will bubble, see #9469.
|
|
|
|
b.isPropagationStopped()||(this.mouseHandled=!0),
|
|
|
|
// Open submenu on click
|
|
|
|
c.has(".ui-menu").length?this.expand(b):!this.element.is(":focus")&&a(this.document[0].activeElement).closest(".ui-menu").length&&(
|
|
|
|
// Redirect focus to the menu
|
|
|
|
this.element.trigger("focus",[!0]),
|
|
|
|
// If the active item is on the top level, let it stay active.
|
|
|
|
// Otherwise, blur the active item since it is no longer visible.
|
|
|
|
this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(b){
|
|
|
|
// Ignore mouse events while typeahead is active, see #10458.
|
|
|
|
// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
|
|
|
|
// is over an item in the menu
|
|
|
|
if(!this.previousFilter){var c=a(b.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
|
|
|
|
c.siblings(".ui-state-active").removeClass("ui-state-active"),this.focus(b,c)}},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(a,b){
|
|
|
|
// If there's already an active item, keep it active
|
|
|
|
// If not, activate the first item
|
|
|
|
var c=this.active||this.element.find(this.options.items).eq(0);b||this.focus(a,c)},blur:function(b){this._delay(function(){a.contains(this.element[0],this.document[0].activeElement)||this.collapseAll(b)})},keydown:"_keydown"}),this.refresh(),
|
|
|
|
// Clicks outside of a menu collapse any open menus
|
|
|
|
this._on(this.document,{click:function(a){this._closeOnDocumentClick(a)&&this.collapseAll(a),
|
|
|
|
// Reset the mouseHandled flag
|
|
|
|
this.mouseHandled=!1}})},_destroy:function(){
|
|
|
|
// Destroy (sub)menus
|
|
|
|
this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeClass("ui-menu ui-widget ui-widget-content ui-menu-icons ui-front").removeAttr("role").removeAttr("tabIndex").removeAttr("aria-labelledby").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-disabled").removeUniqueId().show(),
|
|
|
|
// Destroy menu items
|
|
|
|
this.element.find(".ui-menu-item").removeClass("ui-menu-item").removeAttr("role").removeAttr("aria-disabled").removeUniqueId().removeClass("ui-state-hover").removeAttr("tabIndex").removeAttr("role").removeAttr("aria-haspopup").children().each(function(){var b=a(this);b.data("ui-menu-submenu-carat")&&b.remove()}),
|
|
|
|
// Destroy menu dividers
|
|
|
|
this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content")},_keydown:function(b){var c,d,e,f,g=!0;switch(b.keyCode){case a.ui.keyCode.PAGE_UP:this.previousPage(b);break;case a.ui.keyCode.PAGE_DOWN:this.nextPage(b);break;case a.ui.keyCode.HOME:this._move("first","first",b);break;case a.ui.keyCode.END:this._move("last","last",b);break;case a.ui.keyCode.UP:this.previous(b);break;case a.ui.keyCode.DOWN:this.next(b);break;case a.ui.keyCode.LEFT:this.collapse(b);break;case a.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(b);break;case a.ui.keyCode.ENTER:case a.ui.keyCode.SPACE:this._activate(b);break;case a.ui.keyCode.ESCAPE:this.collapse(b);break;default:g=!1,d=this.previousFilter||"",e=String.fromCharCode(b.keyCode),f=!1,clearTimeout(this.filterTimer),e===d?f=!0:e=d+e,c=this._filterMenuItems(e),c=f&&-1!==c.index(this.active.next())?this.active.nextAll(".ui-menu-item"):c,
|
|
|
|
// If no matches on the current filter, reset to the last character pressed
|
|
|
|
// to move down the menu to the first item that starts with that character
|
|
|
|
c.length||(e=String.fromCharCode(b.keyCode),c=this._filterMenuItems(e)),c.length?(this.focus(b,c),this.previousFilter=e,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}g&&b.preventDefault()},_activate:function(a){this.active.is(".ui-state-disabled")||(this.active.is("[aria-haspopup='true']")?this.expand(a):this.select(a))},refresh:function(){var b,c,d=this,e=this.options.icons.submenu,f=this.element.find(this.options.menus);this.element.toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length),
|
|
|
|
// Initialize nested menus
|
|
|
|
f.filter(":not(.ui-menu)").addClass("ui-menu ui-widget ui-widget-content ui-front").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var b=a(this),c=b.parent(),d=a("<span>").addClass("ui-menu-icon ui-icon "+e).data("ui-menu-submenu-carat",!0);c.attr("aria-haspopup","true").prepend(d),b.attr("aria-labelledby",c.attr("id"))}),b=f.add(this.element),c=b.find(this.options.items),c.not(".ui-menu-item").each(function(){var b=a(this);d._isDivider(b)&&b.addClass("ui-widget-content ui-menu-divider")}),c.not(".ui-menu-item, .ui-menu-divider").addClass("ui-menu-item").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),c.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!a.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(a,b){"icons"===a&&this.element.find(".ui-menu-icon").removeClass(this.options.icons.submenu).addClass(b.submenu),"disabled"===a&&this.element.toggleClass("ui-state-disabled",!!b).attr("aria-disabled",b),this._super(a,b)},focus:function(a,b){var c,d;this.blur(a,a&&"focus"===a.type),this._scrollIntoView(b),this.active=b.first(),d=this.active.addClass("ui-state-focus").removeClass("ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",d.attr("id")),this.active.parent().closest(".ui-menu-item").addClass("ui-state-active"),a&&"keydown"===a.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),c=b.children(".ui-menu"),c.length&&a&&/^mouse/.test(a.type)&&this._startOpening(c),this.activeMenu=b.parent(),this._trigger("focus",a,{item:b})},_scrollIntoView:function(b){var c,d,e,f,g,h;this._hasScroll()&&(c=parseFloat(a.css(this.activeMenu[0],"borderTopWidth"))||0,d=parseFloat(a.css(this.activeMenu[0],"paddingTop"))||0,e=b.offset().top-this.activeMenu.offset().top-c-d,f=this.activeMenu.scrollTop(),g=this.activeMenu.height(),h=b.outerHeight(),0>e?this.activeMenu.scrollTop(f+e):e+h>g&&this.activeMenu.scrollTop(f+e-g+h))},blur:function(a,b){b||clearTimeout(this.timer),this.active&&(this.active.removeClass("ui-state-focus"),this.active=null,this._trigger("blur",a,{item:this.active}))},_startOpening:function(a){clearTimeout(this.timer),
|
|
|
|
// Don't open if already open fixes a Firefox bug that caused a .5 pixel
|
|
|
|
// shift in the submenu position when mousing over the carat icon
|
|
|
|
"true"===a.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(a)},this.delay))},_open:function(b){var c=a.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(b.parents(".ui-menu")).hide().attr("aria-hidden","true"),b.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(c)},collapseAll:function(b,c){clearTimeout(this.timer),this.timer=this._delay(function(){
|
|
|
|
// If we were passed an event, look for the submenu that contains the event
|
|
|
|
var d=c?this.element:a(b&&b.target).closest(this.element.find(".ui-menu"));
|
|
|
|
// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
|
|
|
|
d.length||(d=this.element),this._close(d),this.blur(b),this.activeMenu=d},this.delay)},
|
|
|
|
// With no arguments, closes the currently active menu - if nothing is active
|
|
|
|
// it closes all menus. If passed an argument, it will search for menus BELOW
|
|
|
|
_close:function(a){a||(a=this.active?this.active.parent():this.element),a.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false").end().find(".ui-state-active").not(".ui-state-focus").removeClass("ui-state-active")},_closeOnDocumentClick:function(b){return!a(b.target).closest(".ui-menu").length},_isDivider:function(a){
|
|
|
|
// Match hyphen, em dash, en dash
|
|
|
|
return!/[^\-\u2014\u2013\s]/.test(a.text())},collapse:function(a){var b=this.active&&this.active.parent().closest(".ui-menu-item",this.element);b&&b.length&&(this._close(),this.focus(a,b))},expand:function(a){var b=this.active&&this.active.children(".ui-menu ").find(this.options.items).first();b&&b.length&&(this._open(b.parent()),
|
|
|
|
// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
|
|
|
|
this._delay(function(){this.focus(a,b)}))},next:function(a){this._move("next","first",a)},previous:function(a){this._move("prev","last",a)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(a,b,c){var d;this.active&&(d="first"===a||"last"===a?this.active["first"===a?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[a+"All"](".ui-menu-item").eq(0)),d&&d.length&&this.active||(d=this.activeMenu.find(this.options.items)[b]()),this.focus(c,d)},nextPage:function(b){var c,d,e;return this.active?void(this.isLastItem()||(this._hasScroll()?(d=this.active.offset().top,e=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return c=a(this),c.offset().top-d-e<0}),this.focus(b,c)):this.focus(b,this.activeMenu.find(this.options.items)[this.active?"last":"first"]()))):void this.next(b)},previousPage:function(b){var c,d,e;return this.active?void(this.isFirstItem()||(this._hasScroll()?(d=this.active.offset().top,e=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return c=a(this),c.offset().top-d+e>0}),this.focus(b,c)):this.focus(b,this.activeMenu.find(this.options.items).first()))):void this.next(b)},_hasScroll:function(){return this.element.outerHeight()<this.element.prop("scrollHeight")},select:function(b){
|
|
|
|
// TODO: It should never be possible to not have an active item at this
|
|
|
|
// point, but the tests don't trigger mouseenter before click.
|
|
|
|
this.active=this.active||a(b.target).closest(".ui-menu-item");var c={item:this.active};this.active.has(".ui-menu").length||this.collapseAll(b,!0),this._trigger("select",b,c)},_filterMenuItems:function(b){var c=b.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&"),d=new RegExp("^"+c,"i");return this.activeMenu.find(this.options.items).filter(".ui-menu-item").filter(function(){return d.test(a.trim(a(this).text()))})}})});
|